Skip to content

Commit 04f4fad

Browse files
committed
Start services (#63720)
* feat: ๐ŸŽธ add createStartServicesGetter() to /public kibana_util * test: ๐Ÿ’ add createStartServicesGetter() tests
1 parent 2bd7a89 commit 04f4fad

3 files changed

Lines changed: 135 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { StartServicesAccessor } from '../../../../core/public';
21+
import { createStartServicesGetter } from './create_start_service_getter';
22+
import { Defer } from '../../common/defer';
23+
24+
describe('createStartServicesGetter', () => {
25+
test('throws if services are accessed before accessor resolves', async () => {
26+
const future = new Defer<any>();
27+
const accessor: StartServicesAccessor = async () => await future.promise;
28+
const start = createStartServicesGetter(accessor);
29+
30+
await new Promise(r => setTimeout(r, 1));
31+
32+
expect(() => start()).toThrowErrorMatchingInlineSnapshot(
33+
`"Trying to access start services before start."`
34+
);
35+
});
36+
37+
test('returns services after accessor resolves even if first time called before it resolved', async () => {
38+
const future = new Defer<any>();
39+
const core = {};
40+
const plugins = {};
41+
const self = {};
42+
const accessor: StartServicesAccessor = async () => await future.promise;
43+
const start = createStartServicesGetter(accessor);
44+
45+
await new Promise(r => setTimeout(r, 1));
46+
47+
expect(() => start()).toThrow();
48+
49+
await new Promise(r => setTimeout(r, 1));
50+
future.resolve([core, plugins, self]);
51+
await future.promise;
52+
53+
expect(start()).toEqual({
54+
core,
55+
plugins,
56+
self,
57+
});
58+
});
59+
60+
test('returns services if called after accessor resolves', async () => {
61+
const future = new Defer<any>();
62+
const core = {};
63+
const plugins = {};
64+
const self = {};
65+
const accessor: StartServicesAccessor = async () => await future.promise;
66+
const start = createStartServicesGetter(accessor);
67+
68+
await new Promise(r => setTimeout(r, 1));
69+
future.resolve([core, plugins, self]);
70+
await future.promise;
71+
72+
expect(start()).toEqual({
73+
core,
74+
plugins,
75+
self,
76+
});
77+
});
78+
});
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { CoreStart, StartServicesAccessor } from '../../../../core/public';
21+
22+
export interface StartServices<Plugins = unknown, OwnContract = unknown> {
23+
plugins: Plugins;
24+
self: OwnContract;
25+
core: CoreStart;
26+
}
27+
28+
export type StartServicesGetter<Plugins = unknown, OwnContract = unknown> = () => StartServices<
29+
Plugins,
30+
OwnContract
31+
>;
32+
33+
export const createStartServicesGetter = <TPluginsStart extends object, TStart>(
34+
accessor: StartServicesAccessor<TPluginsStart, TStart>
35+
): StartServicesGetter<TPluginsStart, TStart> => {
36+
let services: StartServices<TPluginsStart, TStart> | undefined;
37+
38+
accessor().then(
39+
([core, plugins, self]) => {
40+
services = {
41+
core,
42+
plugins,
43+
self,
44+
};
45+
},
46+
error => {
47+
// eslint-disable-next-line no-console
48+
console.error('Could not access start services.', error);
49+
}
50+
);
51+
52+
return () => {
53+
if (!services) throw new Error('Trying to access start services before start.');
54+
return services;
55+
};
56+
};

โ€Žsrc/plugins/kibana_utils/public/core/index.tsโ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@
1818
*/
1919

2020
export * from './create_kibana_utils_core';
21+
export * from './create_start_service_getter';

0 commit comments

Comments
ย (0)