refactor: use string types for service instance occurrences

Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2024-07-12 11:22:31 +02:00
committed by Patrik Oldsberg
parent 11aaaa496a
commit 7c5f3b0297
38 changed files with 374 additions and 236 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-app-api': patch
---
Update the `ServiceRegister` implementation to enable registering multiple service implementations for a given service ref.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-test-utils': patch
---
Update the `ServiceFactoryTester` to be able to test services that enables multi implementation installation.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-defaults': patch
---
Update the `UrlReader` service to depends on multiple instances of `UrlReaderFactoryProvider` service.
+58
View File
@@ -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<ReaderFactory>({
+ 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;
},
}));
...
```
+6
View File
@@ -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.
+1 -1
View File
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const featureDiscoveryServiceFactory: ServiceFactoryCompat<
FeatureDiscoveryService,
'root',
true,
'singleton',
undefined
>;
+19 -19
View File
@@ -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<RootHttpRouterService, 'root', true>) &
ServiceFactory<RootHttpRouterService, 'root', true>;
) => ServiceFactory<RootHttpRouterService, 'root', 'singleton'>) &
ServiceFactory<RootHttpRouterService, 'root', 'singleton'>;
// @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
>;
@@ -60,14 +60,14 @@ export class ServiceRegistry {
static create(factories: Array<ServiceFactory>): ServiceRegistry {
const factoryMap = new Map<string, InternalServiceFactory[]>();
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<T, TSingleton extends boolean>(
ref: ServiceRef<T, 'plugin' | 'root', TSingleton>,
get<T, TInstances extends 'singleton' | 'multiton'>(
ref: ServiceRef<T, 'plugin' | 'root', TInstances>,
pluginId: string,
): Promise<TSingleton extends true ? T : T[]> | undefined {
): Promise<TInstances extends 'multiton' ? T[] : T> | undefined {
this.#instantiatedFactories.add(ref.id);
const resolvedFactory = this.#resolveFactory(ref, pluginId);
if (!resolvedFactory) {
return ref.singleton
? undefined
: (Promise.resolve([]) as
| Promise<TSingleton extends true ? T : T[]>
| undefined);
return ref.multiton
? (Promise.resolve([]) as
| Promise<TInstances extends 'multiton' ? T[] : T>
| 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]));
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const authServiceFactory: ServiceFactoryCompat<
AuthService,
'plugin',
true,
'singleton',
undefined
>;
@@ -28,7 +28,7 @@ export type CacheManagerOptions = {
export const cacheServiceFactory: ServiceFactoryCompat<
CacheService,
'plugin',
true,
'singleton',
undefined
>;
@@ -35,7 +35,7 @@ export type DatabaseManagerOptions = {
export const databaseServiceFactory: ServiceFactoryCompat<
DatabaseService,
'plugin',
true,
'singleton',
undefined
>;
@@ -11,7 +11,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const discoveryServiceFactory: ServiceFactoryCompat<
DiscoveryService,
'plugin',
true,
'singleton',
undefined
>;
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const httpAuthServiceFactory: ServiceFactoryCompat<
HttpAuthService,
'plugin',
true,
'singleton',
undefined
>;
@@ -18,7 +18,7 @@ export function createLifecycleMiddleware(
export const httpRouterServiceFactory: ServiceFactoryCompat<
HttpRouterService,
'plugin',
true,
'singleton',
undefined
>;
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const lifecycleServiceFactory: ServiceFactoryCompat<
LifecycleService,
'plugin',
true,
'singleton',
undefined
>;
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const loggerServiceFactory: ServiceFactoryCompat<
LoggerService,
'plugin',
true,
'singleton',
undefined
>;
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const permissionsServiceFactory: ServiceFactoryCompat<
PermissionsService,
'plugin',
true,
'singleton',
undefined
>;
@@ -28,8 +28,8 @@ export interface RootConfigFactoryOptions {
// @public (undocumented)
export const rootConfigServiceFactory: ((
options?: RootConfigFactoryOptions,
) => ServiceFactory<RootConfigService, 'root', true>) &
ServiceFactory<RootConfigService, 'root', true>;
) => ServiceFactory<RootConfigService, 'root', 'singleton'>) &
ServiceFactory<RootConfigService, 'root', 'singleton'>;
// (No @packageDocumentation comment for this package)
```
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const rootHealthServiceFactory: ServiceFactoryCompat<
RootHealthService,
'root',
true,
'singleton',
undefined
>;
@@ -143,8 +143,8 @@ export type RootHttpRouterFactoryOptions = {
// @public (undocumented)
export const rootHttpRouterServiceFactory: ((
options?: RootHttpRouterFactoryOptions,
) => ServiceFactory<RootHttpRouterService, 'root', true>) &
ServiceFactory<RootHttpRouterService, 'root', true>;
) => ServiceFactory<RootHttpRouterService, 'root', 'singleton'>) &
ServiceFactory<RootHttpRouterService, 'root', 'singleton'>;
// (No @packageDocumentation comment for this package)
```
@@ -10,7 +10,7 @@ import { ServiceFactoryCompat } from '@backstage/backend-plugin-api';
export const rootLifecycleServiceFactory: ServiceFactoryCompat<
RootLifecycleService,
'root',
true,
'singleton',
undefined
>;
@@ -14,7 +14,7 @@ import { transport } from 'winston';
export const rootLoggerServiceFactory: ServiceFactoryCompat<
RootLoggerService,
'root',
true,
'singleton',
undefined
>;
@@ -21,7 +21,7 @@ export class DefaultSchedulerService {
export const schedulerServiceFactory: ServiceFactoryCompat<
SchedulerService,
'plugin',
true,
'singleton',
undefined
>;
@@ -429,7 +429,7 @@ export class UrlReaders {
export const urlReaderServiceFactory: ServiceFactoryCompat<
UrlReaderService,
'plugin',
true,
'singleton',
undefined
>;
@@ -10,7 +10,7 @@ import { UserInfoService } from '@backstage/backend-plugin-api';
export const userInfoServiceFactory: ServiceFactoryCompat<
UserInfoService,
'plugin',
true,
'singleton',
undefined
>;
@@ -42,7 +42,7 @@ export const urlReaderProviderFactoriesServiceRef =
createServiceRef<ReaderFactory>({
id: 'core.urlReader.factories',
scope: 'plugin',
singleton: false,
multiton: true,
});
/**
@@ -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)
@@ -18,7 +18,7 @@ export interface FeatureDiscoveryService {
export const featureDiscoveryServiceRef: ServiceRef<
FeatureDiscoveryService,
'root',
true
'singleton'
>;
// (No @packageDocumentation comment for this package)
+64 -60
View File
@@ -189,28 +189,32 @@ export type CacheServiceSetOptions = {
// @public
export namespace coreServices {
const auth: ServiceRef<AuthService, 'plugin', true>;
const userInfo: ServiceRef<UserInfoService, 'plugin', true>;
const cache: ServiceRef<CacheService, 'plugin', true>;
const rootConfig: ServiceRef<RootConfigService, 'root', true>;
const database: ServiceRef<DatabaseService, 'plugin', true>;
const discovery: ServiceRef<DiscoveryService, 'plugin', true>;
const rootHealth: ServiceRef<RootHealthService, 'root', true>;
const httpAuth: ServiceRef<HttpAuthService, 'plugin', true>;
const httpRouter: ServiceRef<HttpRouterService, 'plugin', true>;
const lifecycle: ServiceRef<LifecycleService, 'plugin', true>;
const logger: ServiceRef<LoggerService, 'plugin', true>;
const permissions: ServiceRef<PermissionsService, 'plugin', true>;
const pluginMetadata: ServiceRef<PluginMetadataService, 'plugin', true>;
const rootHttpRouter: ServiceRef<RootHttpRouterService, 'root', true>;
const rootLifecycle: ServiceRef<RootLifecycleService, 'root', true>;
const rootLogger: ServiceRef<RootLoggerService, 'root', true>;
const scheduler: ServiceRef<SchedulerService, 'plugin', true>;
const auth: ServiceRef<AuthService, 'plugin', 'singleton'>;
const userInfo: ServiceRef<UserInfoService, 'plugin', 'singleton'>;
const cache: ServiceRef<CacheService, 'plugin', 'singleton'>;
const rootConfig: ServiceRef<RootConfigService, 'root', 'singleton'>;
const database: ServiceRef<DatabaseService, 'plugin', 'singleton'>;
const discovery: ServiceRef<DiscoveryService, 'plugin', 'singleton'>;
const rootHealth: ServiceRef<RootHealthService, 'root', 'singleton'>;
const httpAuth: ServiceRef<HttpAuthService, 'plugin', 'singleton'>;
const httpRouter: ServiceRef<HttpRouterService, 'plugin', 'singleton'>;
const lifecycle: ServiceRef<LifecycleService, 'plugin', 'singleton'>;
const logger: ServiceRef<LoggerService, 'plugin', 'singleton'>;
const permissions: ServiceRef<PermissionsService, 'plugin', 'singleton'>;
const pluginMetadata: ServiceRef<
PluginMetadataService,
'plugin',
'singleton'
>;
const rootHttpRouter: ServiceRef<RootHttpRouterService, 'root', 'singleton'>;
const rootLifecycle: ServiceRef<RootLifecycleService, 'root', 'singleton'>;
const rootLogger: ServiceRef<RootLoggerService, 'root', 'singleton'>;
const scheduler: ServiceRef<SchedulerService, 'plugin', 'singleton'>;
const // @deprecated
tokenManager: ServiceRef<TokenManagerService, 'plugin', true>;
const urlReader: ServiceRef<UrlReaderService, 'plugin', true>;
tokenManager: ServiceRef<TokenManagerService, 'plugin', 'singleton'>;
const urlReader: ServiceRef<UrlReaderService, 'plugin', 'singleton'>;
const // @deprecated
identity: ServiceRef<IdentityService, 'plugin', true>;
identity: ServiceRef<IdentityService, 'plugin', 'singleton'>;
}
// @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<unknown, 'root'>;
},
TOpts extends object | undefined = undefined,
>(
options: RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TSingleton>;
options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TInstances>;
// @public @deprecated
export function createServiceFactory<
TService,
TSingleton extends boolean,
TInstances extends 'singleton' | 'multiton',
TImpl extends TService,
TDeps extends {
[name in string]: ServiceRef<unknown, 'root'>;
@@ -273,13 +277,13 @@ export function createServiceFactory<
>(
options: (
options?: TOpts,
) => RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TSingleton, TOpts>;
) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TInstances, TOpts>;
// @public
export function createServiceFactory<
TService,
TSingleton extends boolean,
TInstances extends 'singleton' | 'multiton',
TImpl extends TService,
TDeps extends {
[name in string]: ServiceRef<unknown>;
@@ -289,17 +293,17 @@ export function createServiceFactory<
>(
options: PluginServiceFactoryOptions<
TService,
TSingleton,
TInstances,
TContext,
TImpl,
TDeps
>,
): ServiceFactoryCompat<TService, 'plugin', TSingleton>;
): ServiceFactoryCompat<TService, 'plugin', TInstances>;
// @public @deprecated
export function createServiceFactory<
TService,
TSingleton extends boolean,
TInstances extends 'singleton' | 'multiton',
TImpl extends TService,
TDeps extends {
[name in string]: ServiceRef<unknown>;
@@ -311,32 +315,32 @@ export function createServiceFactory<
options?: TOpts,
) => PluginServiceFactoryOptions<
TService,
TSingleton,
TInstances,
TContext,
TImpl,
TDeps
>,
): ServiceFactoryCompat<TService, 'plugin', TSingleton, TOpts>;
): ServiceFactoryCompat<TService, 'plugin', TInstances, TOpts>;
// @public
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'plugin', true>,
): ServiceRef<TService, 'plugin', true>;
options: ServiceRefOptions<TService, 'plugin', 'singleton'>,
): ServiceRef<TService, 'plugin', 'singleton'>;
// @public
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'root', true>,
): ServiceRef<TService, 'root', true>;
options: ServiceRefOptions<TService, 'root', 'singleton'>,
): ServiceRef<TService, 'root', 'singleton'>;
// @public
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'plugin', false>,
): ServiceRef<TService, 'plugin', false>;
options: ServiceRefOptions<TService, 'plugin', 'multiton'>,
): ServiceRef<TService, 'plugin', 'multiton'>;
// @public
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'root', false>,
): ServiceRef<TService, 'root', false>;
options: ServiceRefOptions<TService, 'root', 'multiton'>,
): ServiceRef<TService, 'root', 'multiton'>;
// @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<unknown>;
},
> = PluginServiceFactoryOptions<TService, TSingleton, TContext, TImpl, TDeps>;
> = PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>;
// @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<TImpl>;
initialization?: 'always' | 'lazy';
// (undocumented)
service: ServiceRef<TService, 'plugin', TSingleton>;
service: ServiceRef<TService, 'plugin', TInstances>;
}
// @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<unknown>;
},
> = RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>;
> = RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>;
// @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<unknown>;
@@ -588,7 +592,7 @@ export interface RootServiceFactoryOptions<
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;
initialization?: 'always' | 'lazy';
// (undocumented)
service: ServiceRef<TService, 'root', TSingleton>;
service: ServiceRef<TService, 'root', TInstances>;
}
// @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<TService, TScope, TSingleton>;
service: ServiceRef<TService, TScope, TInstances>;
}
// @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<TService, TScope, TSingleton> {
> extends ServiceFactory<TService, TScope, TInstances> {
// @deprecated (undocumented)
(
...options: undefined extends TOpts ? [] : [options?: TOpts]
): ServiceFactory<TService, TScope, TSingleton>;
): ServiceFactory<TService, TScope, TInstances>;
}
// @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<TService, TScope, TSingleton>;
TInstances extends 'singleton' | 'multiton',
> = ServiceRefOptions<TService, TScope, TInstances>;
// @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
@@ -28,8 +28,8 @@ import {
export type ServiceRefConfig<
TService,
TScope extends 'root' | 'plugin',
TSingleton extends boolean,
> = ServiceRefOptions<TService, TScope, TSingleton>;
TInstances extends 'singleton' | 'multiton',
> = ServiceRefOptions<TService, TScope, TInstances>;
/**
* @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<unknown> },
> = RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>;
> = RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>;
/**
* @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<unknown> },
> = PluginServiceFactoryOptions<TService, TSingleton, TContext, TImpl, TDeps>;
> = PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>;
@@ -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<TService, TScope, TSingleton>;
service: ServiceRef<TService, TScope, TInstances>;
}
/**
@@ -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<TService, TScope, TSingleton> {
> extends ServiceFactory<TService, TScope, TInstances> {
/**
* @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<TService, TScope, TSingleton>;
): ServiceFactory<TService, TScope, TInstances>;
}
/** @internal */
export interface InternalServiceFactory<
TService = unknown,
TScope extends 'plugin' | 'root' = 'plugin' | 'root',
TSingleton extends boolean = boolean,
> extends ServiceFactory<TService, TScope, TSingleton> {
TInstances extends 'singleton' | 'multiton' = 'singleton' | 'multiton',
> extends ServiceFactory<TService, TScope, TInstances> {
version: 'v1';
initialization?: 'always' | 'lazy';
deps: { [key in string]: ServiceRef<unknown> };
@@ -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<TService, TScope>,
): Promise<ServiceFactory>;
@@ -127,8 +127,8 @@ export interface ServiceRefOptions<
* @public
*/
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'plugin', true>,
): ServiceRef<TService, 'plugin', true>;
options: ServiceRefOptions<TService, 'plugin', 'singleton'>,
): ServiceRef<TService, 'plugin', 'singleton'>;
/**
* Creates a new service definition. This overload is used to create root scoped services.
@@ -136,8 +136,8 @@ export function createServiceRef<TService>(
* @public
*/
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'root', true>,
): ServiceRef<TService, 'root', true>;
options: ServiceRefOptions<TService, 'root', 'singleton'>,
): ServiceRef<TService, 'root', 'singleton'>;
/**
* Creates a new service definition. This overload is used to create plugin scoped services.
@@ -145,8 +145,8 @@ export function createServiceRef<TService>(
* @public
*/
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'plugin', false>,
): ServiceRef<TService, 'plugin', false>;
options: ServiceRefOptions<TService, 'plugin', 'multiton'>,
): ServiceRef<TService, 'plugin', 'multiton'>;
/**
* Creates a new service definition. This overload is used to create root scoped services.
@@ -154,16 +154,19 @@ export function createServiceRef<TService>(
* @public
*/
export function createServiceRef<TService>(
options: ServiceRefOptions<TService, 'root', false>,
): ServiceRef<TService, 'root', false>;
export function createServiceRef<TService, TSingleton extends boolean>(
options: ServiceRefOptions<TService, any, TSingleton>,
): ServiceRef<TService, any, TSingleton> {
const { id, scope = 'plugin', singleton = true, defaultFactory } = options;
options: ServiceRefOptions<TService, 'root', 'multiton'>,
): ServiceRef<TService, 'root', 'multiton'>;
export function createServiceRef<
TService,
TInstances extends 'singleton' | 'multiton',
>(
options: ServiceRefOptions<TService, any, TInstances>,
): ServiceRef<TService, any, TInstances> {
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<TService, TSingleton extends boolean>(
},
$$type: '@backstage/ServiceRef',
__defaultFactory: defaultFactory,
} as ServiceRef<TService, typeof scope, TSingleton> & {
} as ServiceRef<TService, typeof scope, TInstances> & {
__defaultFactory?: (
service: ServiceRef<TService>,
) => Promise<ServiceFactory<TService> | (() => ServiceFactory<TService>)>;
@@ -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<T[key]['T']>;
: never]: T[key]['multiton'] extends true
? Array<T[key]['T']>
: 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<unknown> },
> {
@@ -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<TService, 'root', TSingleton>;
service: ServiceRef<TService, 'root', TInstances>;
deps: TDeps;
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;
}
@@ -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<unknown> },
@@ -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<TService, 'plugin', TSingleton>;
service: ServiceRef<TService, 'plugin', TInstances>;
deps: TDeps;
createRootContext?(
deps: ServiceRefsToInstances<TDeps, 'root'>,
@@ -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<unknown, 'root'> },
TOpts extends object | undefined = undefined,
>(
options: RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TSingleton>;
options: RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TInstances>;
/**
* 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<unknown, 'root'> },
TOpts extends object | undefined = undefined,
>(
options: (
options?: TOpts,
) => RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TSingleton, TOpts>;
) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>,
): ServiceFactoryCompat<TService, 'root', TInstances, TOpts>;
/**
* 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<unknown> },
TContext = undefined,
@@ -296,12 +299,12 @@ export function createServiceFactory<
>(
options: PluginServiceFactoryOptions<
TService,
TSingleton,
TInstances,
TContext,
TImpl,
TDeps
>,
): ServiceFactoryCompat<TService, 'plugin', TSingleton>;
): ServiceFactoryCompat<TService, 'plugin', TInstances>;
/**
* 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<unknown> },
TContext = undefined,
@@ -324,44 +327,49 @@ export function createServiceFactory<
options?: TOpts,
) => PluginServiceFactoryOptions<
TService,
TSingleton,
TInstances,
TContext,
TImpl,
TDeps
>,
): ServiceFactoryCompat<TService, 'plugin', TSingleton, TOpts>;
): ServiceFactoryCompat<TService, 'plugin', TInstances, TOpts>;
export function createServiceFactory<
TService,
TSingleton extends boolean,
TInstances extends 'singleton' | 'multiton',
TImpl extends TService,
TDeps extends { [name in string]: ServiceRef<unknown> },
TContext,
TOpts extends object | undefined = undefined,
>(
options:
| RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>
| PluginServiceFactoryOptions<TService, TSingleton, TContext, TImpl, TDeps>
| RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>
| PluginServiceFactoryOptions<TService, TInstances, TContext, TImpl, TDeps>
| ((
options: TOpts,
) => RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>)
) => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>)
| ((
options: TOpts,
) => PluginServiceFactoryOptions<
TService,
TSingleton,
TInstances,
TContext,
TImpl,
TDeps
>)
| (() => RootServiceFactoryOptions<TService, TSingleton, TImpl, TDeps>)
| (() => RootServiceFactoryOptions<TService, TInstances, TImpl, TDeps>)
| (() => PluginServiceFactoryOptions<
TService,
TSingleton,
TInstances,
TContext,
TImpl,
TDeps
>),
): ServiceFactoryCompat<TService, 'root' | 'plugin', boolean, TOpts> {
): 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
+76 -33
View File
@@ -156,7 +156,12 @@ export namespace mockServices {
// (undocumented)
export namespace auth {
const // (undocumented)
factory: ServiceFactoryCompat<AuthService, 'plugin', true, undefined>;
factory: ServiceFactoryCompat<
AuthService,
'plugin',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<AuthService> | undefined,
@@ -165,7 +170,12 @@ export namespace mockServices {
// (undocumented)
export namespace cache {
const // (undocumented)
factory: ServiceFactoryCompat<CacheService, 'plugin', true, undefined>;
factory: ServiceFactoryCompat<
CacheService,
'plugin',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<CacheService> | undefined,
@@ -174,7 +184,12 @@ export namespace mockServices {
// (undocumented)
export namespace database {
const // (undocumented)
factory: ServiceFactoryCompat<DatabaseService, 'plugin', true, undefined>;
factory: ServiceFactoryCompat<
DatabaseService,
'plugin',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<DatabaseService> | 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<EventsService, 'plugin', true, undefined>;
factory: ServiceFactoryCompat<
EventsService,
'plugin',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<EventsService> | undefined,
@@ -213,8 +233,8 @@ export namespace mockServices {
export namespace httpAuth {
const factory: ((options?: {
defaultCredentials?: BackstageCredentials;
}) => ServiceFactory<HttpAuthService, 'plugin', true>) &
ServiceFactory<HttpAuthService, 'plugin', true>;
}) => ServiceFactory<HttpAuthService, 'plugin', 'singleton'>) &
ServiceFactory<HttpAuthService, 'plugin', 'singleton'>;
const // (undocumented)
mock: (
partialImpl?: Partial<HttpAuthService> | 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<IdentityService, 'plugin', true, undefined>;
factory: ServiceFactoryCompat<
IdentityService,
'plugin',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<IdentityService> | 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<LoggerService, 'plugin', true, undefined>;
factory: ServiceFactoryCompat<
LoggerService,
'plugin',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<LoggerService> | 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<RootConfigService, 'root', boolean> &
factory: ServiceFactory<
RootConfigService,
'root',
'singleton' | 'multiton'
> &
((
options?: Options | undefined,
) => ServiceFactory<RootConfigService, 'root', boolean>);
) => ServiceFactory<
RootConfigService,
'root',
'singleton' | 'multiton'
>);
}
// (undocumented)
export namespace rootHealth {
const // (undocumented)
factory: ServiceFactoryCompat<RootHealthService, 'root', true, undefined>;
factory: ServiceFactoryCompat<
RootHealthService,
'root',
'singleton',
undefined
>;
const // (undocumented)
mock: (
partialImpl?: Partial<RootHealthService> | undefined,
@@ -310,8 +353,8 @@ export namespace mockServices {
const // (undocumented)
factory: ((
options?: RootHttpRouterFactoryOptions | undefined,
) => ServiceFactory<RootHttpRouterService, 'root', true>) &
ServiceFactory<RootHttpRouterService, 'root', true>;
) => ServiceFactory<RootHttpRouterService, 'root', 'singleton'>) &
ServiceFactory<RootHttpRouterService, 'root', 'singleton'>;
const // (undocumented)
mock: (
partialImpl?: Partial<RootHttpRouterService> | 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<LoggerService, 'root', boolean> &
factory: ServiceFactory<LoggerService, 'root', 'singleton' | 'multiton'> &
((
options?: Options | undefined,
) => ServiceFactory<LoggerService, 'root', boolean>);
) => ServiceFactory<LoggerService, 'root', 'singleton' | 'multiton'>);
const // (undocumented)
mock: (
partialImpl?: Partial<RootLoggerService> | 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<TService, TScope, TSingleton>,
subject: ServiceFactory<TService, TScope, TInstances>,
options?: ServiceFactoryTesterOptions,
): ServiceFactoryTester<TService, TScope, TSingleton>;
): ServiceFactoryTester<TService, TScope, TInstances>;
// @deprecated
get(
...args: 'root' extends TScope ? [] : [pluginId?: string]
): Promise<TSingleton extends true ? TService : TService[]>;
): Promise<TInstances extends 'multiton' ? TService[] : TService>;
getService<
TGetService,
TGetScope extends 'root' | 'plugin',
TGetSingleton extends boolean,
TGetInstances extends 'singleton' | 'multiton' = 'singleton',
>(
service: ServiceRef<TGetService, TGetScope, TGetSingleton>,
service: ServiceRef<TGetService, TGetScope, TGetInstances>,
...args: 'root' extends TGetScope ? [] : [pluginId?: string]
): Promise<TGetSingleton extends true ? TGetService : TGetService[]>;
): Promise<TGetInstances extends 'multiton' ? TGetService[] : TGetService>;
getSubject(
...args: 'root' extends TScope ? [] : [pluginId?: string]
): Promise<TSingleton extends true ? TService : TService[]>;
): Promise<TInstances extends 'multiton' ? TService[] : TService>;
}
// @public
@@ -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<TService, TScope, TSingleton>;
readonly #subject: ServiceRef<TService, TScope, TInstances>;
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<TService, TScope, TSingleton>,
subject: ServiceFactory<TService, TScope, TInstances>,
options?: ServiceFactoryTesterOptions,
): ServiceFactoryTester<TService, TScope, TSingleton> {
): ServiceFactoryTester<TService, TScope, TInstances> {
const registry = ServiceRegistry.create([
...defaultServiceFactories,
...(options?.dependencies ?? []),
@@ -75,7 +75,7 @@ export class ServiceFactoryTester<
}
private constructor(
subject: ServiceRef<TService, TScope, TSingleton>,
subject: ServiceRef<TService, TScope, TInstances>,
registry: ServiceRegistry,
) {
this.#subject = subject;
@@ -89,7 +89,7 @@ export class ServiceFactoryTester<
*/
async get(
...args: 'root' extends TScope ? [] : [pluginId?: string]
): Promise<TSingleton extends true ? TService : TService[]> {
): Promise<TInstances extends 'multiton' ? TService[] : TService> {
return this.getSubject(...args);
}
@@ -105,7 +105,7 @@ export class ServiceFactoryTester<
*/
async getSubject(
...args: 'root' extends TScope ? [] : [pluginId?: string]
): Promise<TSingleton extends true ? TService : TService[]> {
): Promise<TInstances extends 'multiton' ? TService[] : TService> {
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<TGetService, TGetScope, TGetSingleton>,
service: ServiceRef<TGetService, TGetScope, TGetInstances>,
...args: 'root' extends TGetScope ? [] : [pluginId?: string]
): Promise<TGetSingleton extends true ? TGetService : TGetService[]> {
): Promise<TGetInstances extends 'multiton' ? TGetService[] : TGetService> {
const [pluginId] = args;
const instance = await this.#registry.get(service, pluginId ?? 'test');
if (instance === undefined) {
+1 -1
View File
@@ -88,7 +88,7 @@ export interface CatalogProcessingExtensionPoint {
export const catalogProcessingExtensionPoint: ExtensionPoint<CatalogProcessingExtensionPoint>;
// @alpha
export const catalogServiceRef: ServiceRef<CatalogApi, 'plugin', true>;
export const catalogServiceRef: ServiceRef<CatalogApi, 'plugin', 'singleton'>;
// (No @packageDocumentation comment for this package)
```
+2 -2
View File
@@ -66,12 +66,12 @@ export type EventsServiceEventHandler = (params: EventParams) => Promise<void>;
export const eventsServiceFactory: ServiceFactoryCompat<
EventsService,
'plugin',
true,
'singleton',
undefined
>;
// @public
export const eventsServiceRef: ServiceRef<EventsService, 'plugin', true>;
export const eventsServiceRef: ServiceRef<EventsService, 'plugin', 'singleton'>;
// @public (undocumented)
export type EventsServiceSubscribeOptions = {
+1 -1
View File
@@ -68,7 +68,7 @@ export interface NotificationService {
export const notificationService: ServiceRef<
NotificationService,
'plugin',
true
'singleton'
>;
// @public (undocumented)
@@ -49,7 +49,7 @@ export type SearchIndexServiceInitOptions = {
export const searchIndexServiceRef: ServiceRef<
SearchIndexService,
'plugin',
true
'singleton'
>;
// (No @packageDocumentation comment for this package)
+6 -2
View File
@@ -37,7 +37,7 @@ export type SignalPayload<TMessage extends JsonObject = JsonObject> = {
export interface SignalService extends SignalsService {}
// @public @deprecated (undocumented)
export const signalService: ServiceRef<SignalsService, 'plugin', true>;
export const signalService: ServiceRef<SignalsService, 'plugin', 'singleton'>;
// @public (undocumented)
export interface SignalsService {
@@ -52,7 +52,11 @@ export type SignalsServiceOptions = {
};
// @public (undocumented)
export const signalsServiceRef: ServiceRef<SignalsService, 'plugin', true>;
export const signalsServiceRef: ServiceRef<
SignalsService,
'plugin',
'singleton'
>;
// (No @packageDocumentation comment for this package)
```