From 7c5f3b02972b1ce53e39f0dd04f6fce4e5511c43 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Fri, 12 Jul 2024 11:22:31 +0200 Subject: [PATCH] refactor: use string types for service instance occurrences Signed-off-by: Camila Belo --- .changeset/mighty-apricots-taste.md | 5 + .changeset/purple-carrots-crash.md | 5 + .changeset/shy-waves-share.md | 5 + .changeset/small-bottles-cough.md | 58 ++++++++ .changeset/thirty-adults-grab.md | 6 + packages/backend-app-api/api-report-alpha.md | 2 +- packages/backend-app-api/api-report.md | 38 +++--- .../src/wiring/ServiceRegistry.ts | 38 +++--- packages/backend-defaults/api-report-auth.md | 2 +- packages/backend-defaults/api-report-cache.md | 2 +- .../backend-defaults/api-report-database.md | 2 +- .../backend-defaults/api-report-discovery.md | 2 +- .../backend-defaults/api-report-httpAuth.md | 2 +- .../backend-defaults/api-report-httpRouter.md | 2 +- .../backend-defaults/api-report-lifecycle.md | 2 +- .../backend-defaults/api-report-logger.md | 2 +- .../api-report-permissions.md | 2 +- .../backend-defaults/api-report-rootConfig.md | 4 +- .../backend-defaults/api-report-rootHealth.md | 2 +- .../api-report-rootHttpRouter.md | 4 +- .../api-report-rootLifecycle.md | 2 +- .../backend-defaults/api-report-rootLogger.md | 2 +- .../backend-defaults/api-report-scheduler.md | 2 +- .../backend-defaults/api-report-urlReader.md | 2 +- .../backend-defaults/api-report-userInfo.md | 2 +- .../urlReader/urlReaderServiceFactory.ts | 2 +- .../api-report.md | 10 +- .../backend-plugin-api/api-report-alpha.md | 2 +- packages/backend-plugin-api/api-report.md | 124 +++++++++--------- packages/backend-plugin-api/src/deprecated.ts | 12 +- .../src/services/system/types.ts | 116 ++++++++-------- packages/backend-test-utils/api-report.md | 109 ++++++++++----- .../src/next/wiring/ServiceFactoryTester.ts | 22 ++-- plugins/catalog-node/api-report-alpha.md | 2 +- plugins/events-node/api-report.md | 4 +- plugins/notifications-node/api-report.md | 2 +- .../search-backend-node/api-report-alpha.md | 2 +- plugins/signals-node/api-report.md | 8 +- 38 files changed, 374 insertions(+), 236 deletions(-) create mode 100644 .changeset/mighty-apricots-taste.md create mode 100644 .changeset/purple-carrots-crash.md create mode 100644 .changeset/shy-waves-share.md create mode 100644 .changeset/small-bottles-cough.md create mode 100644 .changeset/thirty-adults-grab.md diff --git a/.changeset/mighty-apricots-taste.md b/.changeset/mighty-apricots-taste.md new file mode 100644 index 0000000000..80b70020cb --- /dev/null +++ b/.changeset/mighty-apricots-taste.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Update the `ServiceRegister` implementation to enable registering multiple service implementations for a given service ref. diff --git a/.changeset/purple-carrots-crash.md b/.changeset/purple-carrots-crash.md new file mode 100644 index 0000000000..62f90677b8 --- /dev/null +++ b/.changeset/purple-carrots-crash.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Update the `ServiceFactoryTester` to be able to test services that enables multi implementation installation. diff --git a/.changeset/shy-waves-share.md b/.changeset/shy-waves-share.md new file mode 100644 index 0000000000..861590fd01 --- /dev/null +++ b/.changeset/shy-waves-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Update the `UrlReader` service to depends on multiple instances of `UrlReaderFactoryProvider` service. diff --git a/.changeset/small-bottles-cough.md b/.changeset/small-bottles-cough.md new file mode 100644 index 0000000000..40098a84c7 --- /dev/null +++ b/.changeset/small-bottles-cough.md @@ -0,0 +1,58 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +The `createServiceRef` function now accepts a new boolean `multiple` option. The `multiple` option defaults to `false` and when set to `true`, it enables that multiple implementation are installed for the created service ref. + +We're looking for ways to make it possible to augment services without the need to replace the entire service. + +Typical example of that being the ability to install support for additional targets for the `UrlReader` service without replacing the service itself. This achieves that by allowing us to define services that can have multiple simultaneous implementation, allowing the `UrlReader` implementation to depend on such a service to collect all possible implementation of support for external targets: + +```diff +// @backstage/backend-defaults + ++ export const urlReaderFactoriesServiceRef = createServiceRef({ ++ id: 'core.urlReader.factories', ++ scope: 'plugin', ++ multiton: true, ++ }); + +... + +export const urlReaderServiceFactory = createServiceFactory({ + service: coreServices.urlReader, + deps: { + config: coreServices.rootConfig, + logger: coreServices.logger, ++ factories: urlReaderFactoriesServiceRef, + }, +- async factory({ config, logger }) { ++ async factory({ config, logger, factories }) { + return UrlReaders.default({ + config, + logger, ++ factories, + }); + }, +}); +``` + +With that, you can then add more custom `UrlReader` factories by installing more implementations of the `urlReaderFactoriesServiceRef` in your backend instance. Something like: + +```ts +// packages/backend/index.ts +import { createServiceFactory } from '@backstage/backend-plugin-api'; +import { urlReaderFactoriesServiceRef } from '@backstage/backend-defaults'; +... + +backend.add(createServiceFactory({ + service: urlReaderFactoriesServiceRef, + deps: {}, + async factory() { + return CustomUrlReader.factory; + }, +})); + +... + +``` diff --git a/.changeset/thirty-adults-grab.md b/.changeset/thirty-adults-grab.md new file mode 100644 index 0000000000..391e7a39bb --- /dev/null +++ b/.changeset/thirty-adults-grab.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-search-backend-node': patch +'@backstage/plugin-catalog-node': patch +--- + +Explicit declare if the service ref accepts `single` ou `multiple` implementations. diff --git a/packages/backend-app-api/api-report-alpha.md b/packages/backend-app-api/api-report-alpha.md index b811208845..8616eec29a 100644 --- a/packages/backend-app-api/api-report-alpha.md +++ b/packages/backend-app-api/api-report-alpha.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const featureDiscoveryServiceFactory: ServiceFactoryCompat< FeatureDiscoveryService, 'root', - true, + 'singleton', undefined >; diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 4019ad3086..dea309ebb0 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -49,7 +49,7 @@ import { UserInfoService } from '@backstage/backend-plugin-api'; export const authServiceFactory: ServiceFactoryCompat< AuthService, 'plugin', - true, + 'singleton', undefined >; @@ -81,7 +81,7 @@ export interface Backend { export const cacheServiceFactory: ServiceFactoryCompat< CacheService, 'plugin', - true, + 'singleton', undefined >; @@ -115,7 +115,7 @@ export interface CreateSpecializedBackendOptions { export const databaseServiceFactory: ServiceFactoryCompat< DatabaseService, 'plugin', - true, + 'singleton', undefined >; @@ -138,7 +138,7 @@ export type DefaultRootHttpRouterOptions = DefaultRootHttpRouterOptions_2; export const discoveryServiceFactory: ServiceFactoryCompat< DiscoveryService, 'plugin', - true, + 'singleton', undefined >; @@ -165,7 +165,7 @@ export class HostDiscovery implements DiscoveryService { export const httpAuthServiceFactory: ServiceFactoryCompat< HttpAuthService, 'plugin', - true, + 'singleton', undefined >; @@ -173,7 +173,7 @@ export const httpAuthServiceFactory: ServiceFactoryCompat< export const httpRouterServiceFactory: ServiceFactoryCompat< HttpRouterService, 'plugin', - true, + 'singleton', undefined >; @@ -197,7 +197,7 @@ export type IdentityFactoryOptions = { export const identityServiceFactory: ServiceFactoryCompat< IdentityService, 'plugin', - true, + 'singleton', IdentityFactoryOptions >; @@ -210,7 +210,7 @@ export type LifecycleMiddlewareOptions = LifecycleMiddlewareOptions_2; export const lifecycleServiceFactory: ServiceFactoryCompat< LifecycleService, 'plugin', - true, + 'singleton', undefined >; @@ -228,7 +228,7 @@ export function loadBackendConfig(options: { export const loggerServiceFactory: ServiceFactoryCompat< LoggerService, 'plugin', - true, + 'singleton', undefined >; @@ -257,7 +257,7 @@ export type MiddlewareFactoryOptions = MiddlewareFactoryOptions_2; export const permissionsServiceFactory: ServiceFactoryCompat< PermissionsService, 'plugin', - true, + 'singleton', undefined >; @@ -288,7 +288,7 @@ export interface RootConfigFactoryOptions { export const rootConfigServiceFactory: ServiceFactoryCompat< RootConfigService, 'root', - true, + 'singleton', RootConfigFactoryOptions >; @@ -305,14 +305,14 @@ export type RootHttpRouterFactoryOptions = RootHttpRouterFactoryOptions_2; // @public @deprecated (undocumented) export const rootHttpRouterServiceFactory: (( options?: RootHttpRouterFactoryOptions_2 | undefined, -) => ServiceFactory) & - ServiceFactory; +) => ServiceFactory) & + ServiceFactory; // @public @deprecated export const rootLifecycleServiceFactory: ServiceFactoryCompat< RootLifecycleService, 'root', - true, + 'singleton', undefined >; @@ -320,7 +320,7 @@ export const rootLifecycleServiceFactory: ServiceFactoryCompat< export const rootLoggerServiceFactory: ServiceFactoryCompat< RootLoggerService, 'root', - true, + 'singleton', undefined >; @@ -328,7 +328,7 @@ export const rootLoggerServiceFactory: ServiceFactoryCompat< export const schedulerServiceFactory: ServiceFactoryCompat< SchedulerService, 'plugin', - true, + 'singleton', undefined >; @@ -336,7 +336,7 @@ export const schedulerServiceFactory: ServiceFactoryCompat< export const tokenManagerServiceFactory: ServiceFactoryCompat< TokenManagerService, 'plugin', - true, + 'singleton', undefined >; @@ -344,7 +344,7 @@ export const tokenManagerServiceFactory: ServiceFactoryCompat< export const urlReaderServiceFactory: ServiceFactoryCompat< UrlReaderService, 'plugin', - true, + 'singleton', undefined >; @@ -352,7 +352,7 @@ export const urlReaderServiceFactory: ServiceFactoryCompat< export const userInfoServiceFactory: ServiceFactoryCompat< UserInfoService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-app-api/src/wiring/ServiceRegistry.ts b/packages/backend-app-api/src/wiring/ServiceRegistry.ts index e1644dad89..0abd5605ae 100644 --- a/packages/backend-app-api/src/wiring/ServiceRegistry.ts +++ b/packages/backend-app-api/src/wiring/ServiceRegistry.ts @@ -60,14 +60,14 @@ export class ServiceRegistry { static create(factories: Array): ServiceRegistry { const factoryMap = new Map(); for (const factory of factories) { - if (factory.service.singleton) { - factoryMap.set(factory.service.id, [toInternalServiceFactory(factory)]); - } else { + if (factory.service.multiton) { const existing = factoryMap.get(factory.service.id) ?? []; factoryMap.set( factory.service.id, existing.concat(toInternalServiceFactory(factory)), ); + } else { + factoryMap.set(factory.service.id, [toInternalServiceFactory(factory)]); } } const registry = new ServiceRegistry(factoryMap); @@ -155,7 +155,7 @@ export class ServiceRegistry { if (this.#providedFactories.get(ref.id)) { return false; } - if (!ref.singleton) { + if (ref.multiton) { return false; } @@ -205,7 +205,12 @@ export class ServiceRegistry { ); } - if (factory.service.singleton) { + if (factory.service.multiton) { + const newFactories = ( + this.#providedFactories.get(factoryId) ?? [] + ).concat(toInternalServiceFactory(factory)); + this.#providedFactories.set(factoryId, newFactories); + } else { if (this.#addedFactoryIds.has(factoryId)) { throw new Error( `Duplicate service implementations provided for ${factoryId}`, @@ -216,11 +221,6 @@ export class ServiceRegistry { this.#providedFactories.set(factoryId, [ toInternalServiceFactory(factory), ]); - } else { - const newFactories = ( - this.#providedFactories.get(factoryId) ?? [] - ).concat(toInternalServiceFactory(factory)); - this.#providedFactories.set(factoryId, newFactories); } } @@ -240,20 +240,20 @@ export class ServiceRegistry { } } - get( - ref: ServiceRef, + get( + ref: ServiceRef, pluginId: string, - ): Promise | undefined { + ): Promise | undefined { this.#instantiatedFactories.add(ref.id); const resolvedFactory = this.#resolveFactory(ref, pluginId); if (!resolvedFactory) { - return ref.singleton - ? undefined - : (Promise.resolve([]) as - | Promise - | undefined); + return ref.multiton + ? (Promise.resolve([]) as + | Promise + | undefined) + : undefined; } return resolvedFactory @@ -346,6 +346,6 @@ export class ServiceRegistry { }), ); }) - .then(results => (ref.singleton ? results[0] : results)); + .then(results => (ref.multiton ? results : results[0])); } } diff --git a/packages/backend-defaults/api-report-auth.md b/packages/backend-defaults/api-report-auth.md index 85287c524e..5ceca7f72e 100644 --- a/packages/backend-defaults/api-report-auth.md +++ b/packages/backend-defaults/api-report-auth.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const authServiceFactory: ServiceFactoryCompat< AuthService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-cache.md b/packages/backend-defaults/api-report-cache.md index c6debd6a2b..e8b6f075ab 100644 --- a/packages/backend-defaults/api-report-cache.md +++ b/packages/backend-defaults/api-report-cache.md @@ -28,7 +28,7 @@ export type CacheManagerOptions = { export const cacheServiceFactory: ServiceFactoryCompat< CacheService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-database.md b/packages/backend-defaults/api-report-database.md index d7585cc791..8d204db025 100644 --- a/packages/backend-defaults/api-report-database.md +++ b/packages/backend-defaults/api-report-database.md @@ -35,7 +35,7 @@ export type DatabaseManagerOptions = { export const databaseServiceFactory: ServiceFactoryCompat< DatabaseService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-discovery.md b/packages/backend-defaults/api-report-discovery.md index dc0d9b2bbe..1b19a42aa5 100644 --- a/packages/backend-defaults/api-report-discovery.md +++ b/packages/backend-defaults/api-report-discovery.md @@ -11,7 +11,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const discoveryServiceFactory: ServiceFactoryCompat< DiscoveryService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-httpAuth.md b/packages/backend-defaults/api-report-httpAuth.md index d8d283c01e..a65a6e157d 100644 --- a/packages/backend-defaults/api-report-httpAuth.md +++ b/packages/backend-defaults/api-report-httpAuth.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const httpAuthServiceFactory: ServiceFactoryCompat< HttpAuthService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-httpRouter.md b/packages/backend-defaults/api-report-httpRouter.md index 7673367f18..300e75a44d 100644 --- a/packages/backend-defaults/api-report-httpRouter.md +++ b/packages/backend-defaults/api-report-httpRouter.md @@ -18,7 +18,7 @@ export function createLifecycleMiddleware( export const httpRouterServiceFactory: ServiceFactoryCompat< HttpRouterService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-lifecycle.md b/packages/backend-defaults/api-report-lifecycle.md index ad41fd4fcb..54ffb77fed 100644 --- a/packages/backend-defaults/api-report-lifecycle.md +++ b/packages/backend-defaults/api-report-lifecycle.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const lifecycleServiceFactory: ServiceFactoryCompat< LifecycleService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-logger.md b/packages/backend-defaults/api-report-logger.md index c881d20344..40ca4e21b4 100644 --- a/packages/backend-defaults/api-report-logger.md +++ b/packages/backend-defaults/api-report-logger.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const loggerServiceFactory: ServiceFactoryCompat< LoggerService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-permissions.md b/packages/backend-defaults/api-report-permissions.md index 92e3feaeaf..eea11ed7c9 100644 --- a/packages/backend-defaults/api-report-permissions.md +++ b/packages/backend-defaults/api-report-permissions.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const permissionsServiceFactory: ServiceFactoryCompat< PermissionsService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-rootConfig.md b/packages/backend-defaults/api-report-rootConfig.md index 60fed5734b..2935ad1128 100644 --- a/packages/backend-defaults/api-report-rootConfig.md +++ b/packages/backend-defaults/api-report-rootConfig.md @@ -28,8 +28,8 @@ export interface RootConfigFactoryOptions { // @public (undocumented) export const rootConfigServiceFactory: (( options?: RootConfigFactoryOptions, -) => ServiceFactory) & - ServiceFactory; +) => ServiceFactory) & + ServiceFactory; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootHealth.md b/packages/backend-defaults/api-report-rootHealth.md index ca104ecf37..c7580cacd6 100644 --- a/packages/backend-defaults/api-report-rootHealth.md +++ b/packages/backend-defaults/api-report-rootHealth.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const rootHealthServiceFactory: ServiceFactoryCompat< RootHealthService, 'root', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-rootHttpRouter.md b/packages/backend-defaults/api-report-rootHttpRouter.md index a6e5a31428..94c22960ef 100644 --- a/packages/backend-defaults/api-report-rootHttpRouter.md +++ b/packages/backend-defaults/api-report-rootHttpRouter.md @@ -143,8 +143,8 @@ export type RootHttpRouterFactoryOptions = { // @public (undocumented) export const rootHttpRouterServiceFactory: (( options?: RootHttpRouterFactoryOptions, -) => ServiceFactory) & - ServiceFactory; +) => ServiceFactory) & + ServiceFactory; // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-rootLifecycle.md b/packages/backend-defaults/api-report-rootLifecycle.md index 52eaa3fe0e..e522471d04 100644 --- a/packages/backend-defaults/api-report-rootLifecycle.md +++ b/packages/backend-defaults/api-report-rootLifecycle.md @@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api'; export const rootLifecycleServiceFactory: ServiceFactoryCompat< RootLifecycleService, 'root', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-rootLogger.md b/packages/backend-defaults/api-report-rootLogger.md index d91aaf0ae8..3878420192 100644 --- a/packages/backend-defaults/api-report-rootLogger.md +++ b/packages/backend-defaults/api-report-rootLogger.md @@ -14,7 +14,7 @@ import { transport } from 'winston'; export const rootLoggerServiceFactory: ServiceFactoryCompat< RootLoggerService, 'root', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-scheduler.md b/packages/backend-defaults/api-report-scheduler.md index 7d8706def2..9953518e09 100644 --- a/packages/backend-defaults/api-report-scheduler.md +++ b/packages/backend-defaults/api-report-scheduler.md @@ -21,7 +21,7 @@ export class DefaultSchedulerService { export const schedulerServiceFactory: ServiceFactoryCompat< SchedulerService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-urlReader.md b/packages/backend-defaults/api-report-urlReader.md index 431e2af701..ad732101dd 100644 --- a/packages/backend-defaults/api-report-urlReader.md +++ b/packages/backend-defaults/api-report-urlReader.md @@ -429,7 +429,7 @@ export class UrlReaders { export const urlReaderServiceFactory: ServiceFactoryCompat< UrlReaderService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/api-report-userInfo.md b/packages/backend-defaults/api-report-userInfo.md index 31ae1dd8bb..27f73d06e1 100644 --- a/packages/backend-defaults/api-report-userInfo.md +++ b/packages/backend-defaults/api-report-userInfo.md @@ -10,7 +10,7 @@ import { UserInfoService } from '@backstage/backend-plugin-api'; export const userInfoServiceFactory: ServiceFactoryCompat< UserInfoService, 'plugin', - true, + 'singleton', undefined >; diff --git a/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts b/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts index 9859166ba0..b5c22402ff 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts @@ -42,7 +42,7 @@ export const urlReaderProviderFactoriesServiceRef = createServiceRef({ id: 'core.urlReader.factories', scope: 'plugin', - singleton: false, + multiton: true, }); /** diff --git a/packages/backend-dynamic-feature-service/api-report.md b/packages/backend-dynamic-feature-service/api-report.md index b74bbcdc95..97dea60170 100644 --- a/packages/backend-dynamic-feature-service/api-report.md +++ b/packages/backend-dynamic-feature-service/api-report.md @@ -117,7 +117,7 @@ export interface DynamicPluginsFactoryOptions { export const dynamicPluginsFeatureDiscoveryServiceFactory: ServiceFactoryCompat< FeatureDiscoveryService, 'root', - true, + 'singleton', undefined >; @@ -128,7 +128,7 @@ export const dynamicPluginsFrontendSchemas: BackendFeatureCompat; export const dynamicPluginsRootLoggerServiceFactory: ServiceFactoryCompat< RootLoggerService, 'root', - true, + 'singleton', undefined >; @@ -149,7 +149,7 @@ export interface DynamicPluginsSchemasService { export const dynamicPluginsSchemasServiceFactory: ServiceFactoryCompat< DynamicPluginsSchemasService, 'root', - true, + 'singleton', DynamicPluginsSchemasOptions >; @@ -157,7 +157,7 @@ export const dynamicPluginsSchemasServiceFactory: ServiceFactoryCompat< export const dynamicPluginsServiceFactory: ServiceFactoryCompat< DynamicPluginProvider, 'root', - true, + 'singleton', DynamicPluginsFactoryOptions >; @@ -165,7 +165,7 @@ export const dynamicPluginsServiceFactory: ServiceFactoryCompat< export const dynamicPluginsServiceRef: ServiceRef< DynamicPluginProvider, 'root', - true + 'singleton' >; // @public (undocumented) diff --git a/packages/backend-plugin-api/api-report-alpha.md b/packages/backend-plugin-api/api-report-alpha.md index 9a82d3adbe..0f4348336a 100644 --- a/packages/backend-plugin-api/api-report-alpha.md +++ b/packages/backend-plugin-api/api-report-alpha.md @@ -18,7 +18,7 @@ export interface FeatureDiscoveryService { export const featureDiscoveryServiceRef: ServiceRef< FeatureDiscoveryService, 'root', - true + 'singleton' >; // (No @packageDocumentation comment for this package) diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 3925d3b2f4..99c7b1b9fc 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -189,28 +189,32 @@ export type CacheServiceSetOptions = { // @public export namespace coreServices { - const auth: ServiceRef; - const userInfo: ServiceRef; - const cache: ServiceRef; - const rootConfig: ServiceRef; - const database: ServiceRef; - const discovery: ServiceRef; - const rootHealth: ServiceRef; - const httpAuth: ServiceRef; - const httpRouter: ServiceRef; - const lifecycle: ServiceRef; - const logger: ServiceRef; - const permissions: ServiceRef; - const pluginMetadata: ServiceRef; - const rootHttpRouter: ServiceRef; - const rootLifecycle: ServiceRef; - const rootLogger: ServiceRef; - const scheduler: ServiceRef; + const auth: ServiceRef; + const userInfo: ServiceRef; + const cache: ServiceRef; + const rootConfig: ServiceRef; + const database: ServiceRef; + const discovery: ServiceRef; + const rootHealth: ServiceRef; + const httpAuth: ServiceRef; + const httpRouter: ServiceRef; + const lifecycle: ServiceRef; + const logger: ServiceRef; + const permissions: ServiceRef; + const pluginMetadata: ServiceRef< + PluginMetadataService, + 'plugin', + 'singleton' + >; + const rootHttpRouter: ServiceRef; + const rootLifecycle: ServiceRef; + const rootLogger: ServiceRef; + const scheduler: ServiceRef; const // @deprecated - tokenManager: ServiceRef; - const urlReader: ServiceRef; + tokenManager: ServiceRef; + const urlReader: ServiceRef; const // @deprecated - identity: ServiceRef; + identity: ServiceRef; } // @public @@ -251,20 +255,20 @@ export interface CreateExtensionPointOptions { // @public export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef; }, TOpts extends object | undefined = undefined, >( - options: RootServiceFactoryOptions, -): ServiceFactoryCompat; + options: RootServiceFactoryOptions, +): ServiceFactoryCompat; // @public @deprecated export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef; @@ -273,13 +277,13 @@ export function createServiceFactory< >( options: ( options?: TOpts, - ) => RootServiceFactoryOptions, -): ServiceFactoryCompat; + ) => RootServiceFactoryOptions, +): ServiceFactoryCompat; // @public export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef; @@ -289,17 +293,17 @@ export function createServiceFactory< >( options: PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps >, -): ServiceFactoryCompat; +): ServiceFactoryCompat; // @public @deprecated export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef; @@ -311,32 +315,32 @@ export function createServiceFactory< options?: TOpts, ) => PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps >, -): ServiceFactoryCompat; +): ServiceFactoryCompat; // @public export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; // @public export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; // @public export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; // @public export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; // @public export interface DatabaseService { @@ -473,18 +477,18 @@ export interface PluginMetadataService { // @public @deprecated (undocumented) export type PluginServiceFactoryConfig< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TContext, TImpl extends TService, TDeps extends { [name in string]: ServiceRef; }, -> = PluginServiceFactoryOptions; +> = PluginServiceFactoryOptions; // @public (undocumented) export interface PluginServiceFactoryOptions< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TContext, TImpl extends TService, TDeps extends { @@ -504,7 +508,7 @@ export interface PluginServiceFactoryOptions< ): TImpl | Promise; initialization?: 'always' | 'lazy'; // (undocumented) - service: ServiceRef; + service: ServiceRef; } // @public @@ -566,17 +570,17 @@ export interface RootLoggerService extends LoggerService {} // @public @deprecated (undocumented) export type RootServiceFactoryConfig< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef; }, -> = RootServiceFactoryOptions; +> = RootServiceFactoryOptions; // @public (undocumented) export interface RootServiceFactoryOptions< TService, // TODO(Rugvip): Can we forward the entire service ref type here instead of forwarding each type arg once the callback form is gone? - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef; @@ -588,7 +592,7 @@ export interface RootServiceFactoryOptions< factory(deps: ServiceRefsToInstances): TImpl | Promise; initialization?: 'always' | 'lazy'; // (undocumented) - service: ServiceRef; + service: ServiceRef; } // @public @@ -669,23 +673,23 @@ export type SearchResponseFile = UrlReaderServiceSearchResponseFile; export interface ServiceFactory< TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', - TSingleton extends boolean = boolean, + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', > extends BackendFeature { // (undocumented) - service: ServiceRef; + service: ServiceRef; } // @public @deprecated (undocumented) export interface ServiceFactoryCompat< TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', - TSingleton extends boolean = boolean, + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', TOpts extends object | undefined = undefined, -> extends ServiceFactory { +> extends ServiceFactory { // @deprecated (undocumented) ( ...options: undefined extends TOpts ? [] : [options?: TOpts] - ): ServiceFactory; + ): ServiceFactory; } // @public @deprecated @@ -695,11 +699,11 @@ export type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory); export type ServiceRef< TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin', - TSingleton extends boolean = boolean, + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', > = { id: string; scope: TScope; - singleton: TSingleton; + multiton: TInstances extends 'multiton' ? true : false; T: TService; $$type: '@backstage/ServiceRef'; }; @@ -708,14 +712,14 @@ export type ServiceRef< export type ServiceRefConfig< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean, -> = ServiceRefOptions; + TInstances extends 'singleton' | 'multiton', +> = ServiceRefOptions; // @public (undocumented) export interface ServiceRefOptions< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', > { // (undocumented) defaultFactory?( @@ -728,9 +732,9 @@ export interface ServiceRefOptions< // (undocumented) id: string; // (undocumented) - scope?: TScope; + multiton?: TInstances extends 'multiton' ? true : false; // (undocumented) - singleton?: TSingleton; + scope?: TScope; } // @public @deprecated diff --git a/packages/backend-plugin-api/src/deprecated.ts b/packages/backend-plugin-api/src/deprecated.ts index e68affa0fa..0d02f9ed7e 100644 --- a/packages/backend-plugin-api/src/deprecated.ts +++ b/packages/backend-plugin-api/src/deprecated.ts @@ -28,8 +28,8 @@ import { export type ServiceRefConfig< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean, -> = ServiceRefOptions; + TInstances extends 'singleton' | 'multiton', +> = ServiceRefOptions; /** * @public @@ -37,10 +37,10 @@ export type ServiceRefConfig< */ export type RootServiceFactoryConfig< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, -> = RootServiceFactoryOptions; +> = RootServiceFactoryOptions; /** * @public @@ -48,8 +48,8 @@ export type RootServiceFactoryConfig< */ export type PluginServiceFactoryConfig< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TContext, TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, -> = PluginServiceFactoryOptions; +> = PluginServiceFactoryOptions; diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index e856136ddc..7cd18da4d2 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -24,7 +24,7 @@ import { BackendFeature } from '../../types'; export type ServiceRef< TService, TScope extends 'root' | 'plugin' = 'root' | 'plugin', - TSingleton extends boolean = boolean, + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', > = { id: string; @@ -39,7 +39,7 @@ export type ServiceRef< */ scope: TScope; - singleton: TSingleton; + multiton: TInstances extends 'multiton' ? true : false; /** * Utility for getting the type of the service, using `typeof serviceRef.T`. @@ -54,9 +54,9 @@ export type ServiceRef< export interface ServiceFactory< TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', - TSingleton extends boolean = boolean, + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', > extends BackendFeature { - service: ServiceRef; + service: ServiceRef; } /** @@ -66,23 +66,23 @@ export interface ServiceFactory< export interface ServiceFactoryCompat< TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', - TSingleton extends boolean = boolean, + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', TOpts extends object | undefined = undefined, -> extends ServiceFactory { +> extends ServiceFactory { /** * @deprecated Callable service factories will be removed in a future release, please re-implement the service factory using the available APIs instead. If no options are being passed, you can simply remove the trailing `()`. */ ( ...options: undefined extends TOpts ? [] : [options?: TOpts] - ): ServiceFactory; + ): ServiceFactory; } /** @internal */ export interface InternalServiceFactory< TService = unknown, TScope extends 'plugin' | 'root' = 'plugin' | 'root', - TSingleton extends boolean = boolean, -> extends ServiceFactory { + TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton', +> extends ServiceFactory { version: 'v1'; initialization?: 'always' | 'lazy'; deps: { [key in string]: ServiceRef }; @@ -105,11 +105,11 @@ export type ServiceFactoryOrFunction = ServiceFactory | (() => ServiceFactory); export interface ServiceRefOptions< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', > { id: string; scope?: TScope; - singleton?: TSingleton; + multiton?: TInstances extends 'multiton' ? true : false; defaultFactory?( service: ServiceRef, ): Promise; @@ -127,8 +127,8 @@ export interface ServiceRefOptions< * @public */ export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; /** * Creates a new service definition. This overload is used to create root scoped services. @@ -136,8 +136,8 @@ export function createServiceRef( * @public */ export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; /** * Creates a new service definition. This overload is used to create plugin scoped services. @@ -145,8 +145,8 @@ export function createServiceRef( * @public */ export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; + options: ServiceRefOptions, +): ServiceRef; /** * Creates a new service definition. This overload is used to create root scoped services. @@ -154,16 +154,19 @@ export function createServiceRef( * @public */ export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef; -export function createServiceRef( - options: ServiceRefOptions, -): ServiceRef { - const { id, scope = 'plugin', singleton = true, defaultFactory } = options; + options: ServiceRefOptions, +): ServiceRef; +export function createServiceRef< + TService, + TInstances extends 'singleton' | 'multiton', +>( + options: ServiceRefOptions, +): ServiceRef { + const { id, scope = 'plugin', multiton = false, defaultFactory } = options; return { id, scope, - singleton, + multiton, get T(): TService { throw new Error(`tried to read ServiceRef.T of ${this}`); }, @@ -172,7 +175,7 @@ export function createServiceRef( }, $$type: '@backstage/ServiceRef', __defaultFactory: defaultFactory, - } as ServiceRef & { + } as ServiceRef & { __defaultFactory?: ( service: ServiceRef, ) => Promise | (() => ServiceFactory)>; @@ -186,15 +189,15 @@ type ServiceRefsToInstances< > = { [key in keyof T as T[key]['scope'] extends TScope ? key - : never]: T[key]['singleton'] extends true - ? T[key]['T'] - : Array; + : never]: T[key]['multiton'] extends true + ? Array + : T[key]['T']; }; /** @public */ export interface RootServiceFactoryOptions< TService, // TODO(Rugvip): Can we forward the entire service ref type here instead of forwarding each type arg once the callback form is gone? - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, > { @@ -209,7 +212,7 @@ export interface RootServiceFactoryOptions< * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`. */ initialization?: 'always' | 'lazy'; - service: ServiceRef; + service: ServiceRef; deps: TDeps; factory(deps: ServiceRefsToInstances): TImpl | Promise; } @@ -217,7 +220,7 @@ export interface RootServiceFactoryOptions< /** @public */ export interface PluginServiceFactoryOptions< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TContext, TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, @@ -233,7 +236,7 @@ export interface PluginServiceFactoryOptions< * Service factories for root scoped services use `always` as the default, while plugin scoped services use `lazy`. */ initialization?: 'always' | 'lazy'; - service: ServiceRef; + service: ServiceRef; deps: TDeps; createRootContext?( deps: ServiceRefsToInstances, @@ -252,13 +255,13 @@ export interface PluginServiceFactoryOptions< */ export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, TOpts extends object | undefined = undefined, >( - options: RootServiceFactoryOptions, -): ServiceFactoryCompat; + options: RootServiceFactoryOptions, +): ServiceFactoryCompat; /** * Creates a root scoped service factory with optional options. * @@ -271,15 +274,15 @@ export function createServiceFactory< */ export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, TOpts extends object | undefined = undefined, >( options: ( options?: TOpts, - ) => RootServiceFactoryOptions, -): ServiceFactoryCompat; + ) => RootServiceFactoryOptions, +): ServiceFactoryCompat; /** * Creates a plugin scoped service factory without options. * @@ -288,7 +291,7 @@ export function createServiceFactory< */ export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, TContext = undefined, @@ -296,12 +299,12 @@ export function createServiceFactory< >( options: PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps >, -): ServiceFactoryCompat; +): ServiceFactoryCompat; /** * Creates a plugin scoped service factory with optional options. * @@ -314,7 +317,7 @@ export function createServiceFactory< */ export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, TContext = undefined, @@ -324,44 +327,49 @@ export function createServiceFactory< options?: TOpts, ) => PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps >, -): ServiceFactoryCompat; +): ServiceFactoryCompat; export function createServiceFactory< TService, - TSingleton extends boolean, + TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, TContext, TOpts extends object | undefined = undefined, >( options: - | RootServiceFactoryOptions - | PluginServiceFactoryOptions + | RootServiceFactoryOptions + | PluginServiceFactoryOptions | (( options: TOpts, - ) => RootServiceFactoryOptions) + ) => RootServiceFactoryOptions) | (( options: TOpts, ) => PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps >) - | (() => RootServiceFactoryOptions) + | (() => RootServiceFactoryOptions) | (() => PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps >), -): ServiceFactoryCompat { +): ServiceFactoryCompat< + TService, + 'root' | 'plugin', + 'singleton' | 'multiton', + TOpts +> { const configCallback = typeof options === 'function' ? options : () => options; const factory = ( @@ -371,7 +379,7 @@ export function createServiceFactory< if (anyConf.service.scope === 'root') { const c = anyConf as RootServiceFactoryOptions< TService, - TSingleton, + TInstances, TImpl, TDeps >; @@ -387,7 +395,7 @@ export function createServiceFactory< } const c = anyConf as PluginServiceFactoryOptions< TService, - TSingleton, + TInstances, TContext, TImpl, TDeps diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 5a9e016dcd..584fedb1f5 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -156,7 +156,12 @@ export namespace mockServices { // (undocumented) export namespace auth { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + AuthService, + 'plugin', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -165,7 +170,12 @@ export namespace mockServices { // (undocumented) export namespace cache { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + CacheService, + 'plugin', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -174,7 +184,12 @@ export namespace mockServices { // (undocumented) export namespace database { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + DatabaseService, + 'plugin', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -188,7 +203,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< DiscoveryService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -199,7 +214,12 @@ export namespace mockServices { // (undocumented) export namespace events { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + EventsService, + 'plugin', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -213,8 +233,8 @@ export namespace mockServices { export namespace httpAuth { const factory: ((options?: { defaultCredentials?: BackstageCredentials; - }) => ServiceFactory) & - ServiceFactory; + }) => ServiceFactory) & + ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -226,7 +246,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< HttpRouterService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -239,7 +259,12 @@ export namespace mockServices { // (undocumented) export namespace identity { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + IdentityService, + 'plugin', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -251,7 +276,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< LifecycleService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -262,7 +287,12 @@ export namespace mockServices { // (undocumented) export namespace logger { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + LoggerService, + 'plugin', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -274,7 +304,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< PermissionsService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -291,15 +321,28 @@ export namespace mockServices { data?: JsonObject; }; const // (undocumented) - factory: ServiceFactory & + factory: ServiceFactory< + RootConfigService, + 'root', + 'singleton' | 'multiton' + > & (( options?: Options | undefined, - ) => ServiceFactory); + ) => ServiceFactory< + RootConfigService, + 'root', + 'singleton' | 'multiton' + >); } // (undocumented) export namespace rootHealth { const // (undocumented) - factory: ServiceFactoryCompat; + factory: ServiceFactoryCompat< + RootHealthService, + 'root', + 'singleton', + undefined + >; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -310,8 +353,8 @@ export namespace mockServices { const // (undocumented) factory: (( options?: RootHttpRouterFactoryOptions | undefined, - ) => ServiceFactory) & - ServiceFactory; + ) => ServiceFactory) & + ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -323,7 +366,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< RootLifecycleService, 'root', - true, + 'singleton', undefined >; const // (undocumented) @@ -340,10 +383,10 @@ export namespace mockServices { level?: 'none' | 'error' | 'warn' | 'info' | 'debug'; }; const // (undocumented) - factory: ServiceFactory & + factory: ServiceFactory & (( options?: Options | undefined, - ) => ServiceFactory); + ) => ServiceFactory); const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -355,7 +398,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< SchedulerService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -371,7 +414,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< TokenManagerService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -385,7 +428,7 @@ export namespace mockServices { factory: ServiceFactoryCompat< UrlReaderService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -401,7 +444,7 @@ export namespace mockServices { const factory: ServiceFactoryCompat< UserInfoService, 'plugin', - true, + 'singleton', undefined >; const // (undocumented) @@ -422,31 +465,31 @@ export function registerMswTestHooks(worker: { export class ServiceFactoryTester< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean = true, + TInstances extends 'singleton' | 'multiton' = 'singleton', > { static from< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean = true, + TInstances extends 'singleton' | 'multiton' = 'singleton', >( - subject: ServiceFactory, + subject: ServiceFactory, options?: ServiceFactoryTesterOptions, - ): ServiceFactoryTester; + ): ServiceFactoryTester; // @deprecated get( ...args: 'root' extends TScope ? [] : [pluginId?: string] - ): Promise; + ): Promise; getService< TGetService, TGetScope extends 'root' | 'plugin', - TGetSingleton extends boolean, + TGetInstances extends 'singleton' | 'multiton' = 'singleton', >( - service: ServiceRef, + service: ServiceRef, ...args: 'root' extends TGetScope ? [] : [pluginId?: string] - ): Promise; + ): Promise; getSubject( ...args: 'root' extends TScope ? [] : [pluginId?: string] - ): Promise; + ): Promise; } // @public diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts index 94092aff68..e8530f89bf 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts +++ b/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts @@ -46,9 +46,9 @@ export interface ServiceFactoryTesterOptions { export class ServiceFactoryTester< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean = true, + TInstances extends 'singleton' | 'multiton' = 'singleton', > { - readonly #subject: ServiceRef; + readonly #subject: ServiceRef; readonly #registry: ServiceRegistry; /** @@ -61,11 +61,11 @@ export class ServiceFactoryTester< static from< TService, TScope extends 'root' | 'plugin', - TSingleton extends boolean = true, + TInstances extends 'singleton' | 'multiton' = 'singleton', >( - subject: ServiceFactory, + subject: ServiceFactory, options?: ServiceFactoryTesterOptions, - ): ServiceFactoryTester { + ): ServiceFactoryTester { const registry = ServiceRegistry.create([ ...defaultServiceFactories, ...(options?.dependencies ?? []), @@ -75,7 +75,7 @@ export class ServiceFactoryTester< } private constructor( - subject: ServiceRef, + subject: ServiceRef, registry: ServiceRegistry, ) { this.#subject = subject; @@ -89,7 +89,7 @@ export class ServiceFactoryTester< */ async get( ...args: 'root' extends TScope ? [] : [pluginId?: string] - ): Promise { + ): Promise { return this.getSubject(...args); } @@ -105,7 +105,7 @@ export class ServiceFactoryTester< */ async getSubject( ...args: 'root' extends TScope ? [] : [pluginId?: string] - ): Promise { + ): Promise { const [pluginId] = args; const instance = this.#registry.get(this.#subject, pluginId ?? 'test')!; return instance; @@ -121,11 +121,11 @@ export class ServiceFactoryTester< async getService< TGetService, TGetScope extends 'root' | 'plugin', - TGetSingleton extends boolean, + TGetInstances extends 'singleton' | 'multiton' = 'singleton', >( - service: ServiceRef, + service: ServiceRef, ...args: 'root' extends TGetScope ? [] : [pluginId?: string] - ): Promise { + ): Promise { const [pluginId] = args; const instance = await this.#registry.get(service, pluginId ?? 'test'); if (instance === undefined) { diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/api-report-alpha.md index a2579e29f4..daa388d5e3 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/api-report-alpha.md @@ -88,7 +88,7 @@ export interface CatalogProcessingExtensionPoint { export const catalogProcessingExtensionPoint: ExtensionPoint; // @alpha -export const catalogServiceRef: ServiceRef; +export const catalogServiceRef: ServiceRef; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/events-node/api-report.md b/plugins/events-node/api-report.md index e159446103..729f526dee 100644 --- a/plugins/events-node/api-report.md +++ b/plugins/events-node/api-report.md @@ -66,12 +66,12 @@ export type EventsServiceEventHandler = (params: EventParams) => Promise; export const eventsServiceFactory: ServiceFactoryCompat< EventsService, 'plugin', - true, + 'singleton', undefined >; // @public -export const eventsServiceRef: ServiceRef; +export const eventsServiceRef: ServiceRef; // @public (undocumented) export type EventsServiceSubscribeOptions = { diff --git a/plugins/notifications-node/api-report.md b/plugins/notifications-node/api-report.md index fd356131ee..995b98bc21 100644 --- a/plugins/notifications-node/api-report.md +++ b/plugins/notifications-node/api-report.md @@ -68,7 +68,7 @@ export interface NotificationService { export const notificationService: ServiceRef< NotificationService, 'plugin', - true + 'singleton' >; // @public (undocumented) diff --git a/plugins/search-backend-node/api-report-alpha.md b/plugins/search-backend-node/api-report-alpha.md index dc41fa6400..e1d5bd024d 100644 --- a/plugins/search-backend-node/api-report-alpha.md +++ b/plugins/search-backend-node/api-report-alpha.md @@ -49,7 +49,7 @@ export type SearchIndexServiceInitOptions = { export const searchIndexServiceRef: ServiceRef< SearchIndexService, 'plugin', - true + 'singleton' >; // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-node/api-report.md b/plugins/signals-node/api-report.md index b2d5a2b210..a368dd2ece 100644 --- a/plugins/signals-node/api-report.md +++ b/plugins/signals-node/api-report.md @@ -37,7 +37,7 @@ export type SignalPayload = { export interface SignalService extends SignalsService {} // @public @deprecated (undocumented) -export const signalService: ServiceRef; +export const signalService: ServiceRef; // @public (undocumented) export interface SignalsService { @@ -52,7 +52,11 @@ export type SignalsServiceOptions = { }; // @public (undocumented) -export const signalsServiceRef: ServiceRef; +export const signalsServiceRef: ServiceRef< + SignalsService, + 'plugin', + 'singleton' +>; // (No @packageDocumentation comment for this package) ```