From f4d109020da80983115f7a2c1f42af965d8fcdcb Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Fri, 17 Apr 2020 09:14:17 +0200 Subject: [PATCH] Start services (#63720) (#63773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add createStartServicesGetter() to /public kibana_util * test: 💍 add createStartServicesGetter() tests --- .../core/create_start_service_getter.test.ts | 78 +++++++++++++++++++ .../core/create_start_service_getter.ts | 56 +++++++++++++ src/plugins/kibana_utils/public/core/index.ts | 1 + 3 files changed, 135 insertions(+) create mode 100644 src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts create mode 100644 src/plugins/kibana_utils/public/core/create_start_service_getter.ts diff --git a/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts b/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts new file mode 100644 index 0000000000000..9d9b21269e102 --- /dev/null +++ b/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts @@ -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(); + 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(); + 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(); + 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, + }); + }); +}); diff --git a/src/plugins/kibana_utils/public/core/create_start_service_getter.ts b/src/plugins/kibana_utils/public/core/create_start_service_getter.ts new file mode 100644 index 0000000000000..e507d1ae778e5 --- /dev/null +++ b/src/plugins/kibana_utils/public/core/create_start_service_getter.ts @@ -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: Plugins; + self: OwnContract; + core: CoreStart; +} + +export type StartServicesGetter = () => StartServices< + Plugins, + OwnContract +>; + +export const createStartServicesGetter = ( + accessor: StartServicesAccessor +): StartServicesGetter => { + let services: StartServices | 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; + }; +}; diff --git a/src/plugins/kibana_utils/public/core/index.ts b/src/plugins/kibana_utils/public/core/index.ts index 3f08d591300a2..8bbb2129071f5 100644 --- a/src/plugins/kibana_utils/public/core/index.ts +++ b/src/plugins/kibana_utils/public/core/index.ts @@ -18,3 +18,4 @@ */ export * from './create_kibana_utils_core'; +export * from './create_start_service_getter';