Skip to content

Commit

Permalink
Start services (#63720) (#63773)
Browse files Browse the repository at this point in the history
* feat: ๐ŸŽธ add createStartServicesGetter() to /public  kibana_util

* test: ๐Ÿ’ add createStartServicesGetter() tests
  • Loading branch information
streamich committed Apr 17, 2020
1 parent 32ade23 commit f4d1090
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { StartServicesAccessor } from '../../../../core/public';
import { createStartServicesGetter } from './create_start_service_getter';
import { Defer } from '../../common/defer';

describe('createStartServicesGetter', () => {
test('throws if services are accessed before accessor resolves', async () => {
const future = new Defer<any>();
const accessor: StartServicesAccessor = async () => await future.promise;
const start = createStartServicesGetter(accessor);

await new Promise(r => setTimeout(r, 1));

expect(() => start()).toThrowErrorMatchingInlineSnapshot(
`"Trying to access start services before start."`
);
});

test('returns services after accessor resolves even if first time called before it resolved', async () => {
const future = new Defer<any>();
const core = {};
const plugins = {};
const self = {};
const accessor: StartServicesAccessor = async () => await future.promise;
const start = createStartServicesGetter(accessor);

await new Promise(r => setTimeout(r, 1));

expect(() => start()).toThrow();

await new Promise(r => setTimeout(r, 1));
future.resolve([core, plugins, self]);
await future.promise;

expect(start()).toEqual({
core,
plugins,
self,
});
});

test('returns services if called after accessor resolves', async () => {
const future = new Defer<any>();
const core = {};
const plugins = {};
const self = {};
const accessor: StartServicesAccessor = async () => await future.promise;
const start = createStartServicesGetter(accessor);

await new Promise(r => setTimeout(r, 1));
future.resolve([core, plugins, self]);
await future.promise;

expect(start()).toEqual({
core,
plugins,
self,
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { CoreStart, StartServicesAccessor } from '../../../../core/public';

export interface StartServices<Plugins = unknown, OwnContract = unknown> {
plugins: Plugins;
self: OwnContract;
core: CoreStart;
}

export type StartServicesGetter<Plugins = unknown, OwnContract = unknown> = () => StartServices<
Plugins,
OwnContract
>;

export const createStartServicesGetter = <TPluginsStart extends object, TStart>(
accessor: StartServicesAccessor<TPluginsStart, TStart>
): StartServicesGetter<TPluginsStart, TStart> => {
let services: StartServices<TPluginsStart, TStart> | undefined;

accessor().then(
([core, plugins, self]) => {
services = {
core,
plugins,
self,
};
},
error => {
// eslint-disable-next-line no-console
console.error('Could not access start services.', error);
}
);

return () => {
if (!services) throw new Error('Trying to access start services before start.');
return services;
};
};
1 change: 1 addition & 0 deletions src/plugins/kibana_utils/public/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
*/

export * from './create_kibana_utils_core';
export * from './create_start_service_getter';

0 comments on commit f4d1090

Please sign in to comment.