backend-plugin-api: allow service factories to be sync
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -26,7 +26,7 @@ export const loggerFactory = createServiceFactory({
|
||||
rootLogger: coreServices.rootLogger,
|
||||
plugin: coreServices.pluginMetadata,
|
||||
},
|
||||
async factory({ rootLogger, plugin }) {
|
||||
factory({ rootLogger, plugin }) {
|
||||
return rootLogger.child({ plugin: plugin.getId() });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -305,14 +305,14 @@ export interface PluginServiceFactoryConfig<
|
||||
// (undocumented)
|
||||
createRootContext?(
|
||||
deps: ServiceRefsToInstances<TDeps, 'root'>,
|
||||
): Promise<TContext>;
|
||||
): TContext | Promise<TContext>;
|
||||
// (undocumented)
|
||||
deps: TDeps;
|
||||
// (undocumented)
|
||||
factory(
|
||||
deps: ServiceRefsToInstances<TDeps>,
|
||||
context: TContext,
|
||||
): Promise<TImpl>;
|
||||
): TImpl | Promise<TImpl>;
|
||||
// (undocumented)
|
||||
service: ServiceRef<TService, 'plugin'>;
|
||||
}
|
||||
@@ -383,7 +383,7 @@ export interface RootServiceFactoryConfig<
|
||||
// (undocumented)
|
||||
deps: TDeps;
|
||||
// (undocumented)
|
||||
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): Promise<TImpl>;
|
||||
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;
|
||||
// (undocumented)
|
||||
service: ServiceRef<TService, 'root'>;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,56 @@ interface TestOptions {
|
||||
function unused(..._any: any[]) {}
|
||||
|
||||
describe('createServiceFactory', () => {
|
||||
it('should create a meta factory with no options', () => {
|
||||
it('should create a sync factory with no options', () => {
|
||||
const metaFactory = createServiceFactory({
|
||||
service: ref,
|
||||
deps: {},
|
||||
createRootContext() {},
|
||||
factory(_deps) {
|
||||
return 'x';
|
||||
},
|
||||
});
|
||||
expect(metaFactory).toEqual(expect.any(Function));
|
||||
expect(metaFactory().service).toBe(ref);
|
||||
|
||||
// @ts-expect-error
|
||||
metaFactory('string');
|
||||
// @ts-expect-error
|
||||
metaFactory({});
|
||||
// @ts-expect-error
|
||||
metaFactory({ x: 1 });
|
||||
// @ts-expect-error
|
||||
metaFactory(null);
|
||||
// @ts-expect-error
|
||||
metaFactory(undefined);
|
||||
metaFactory();
|
||||
});
|
||||
|
||||
it('should create a sync root factory with no options', () => {
|
||||
const metaFactory = createServiceFactory({
|
||||
service: rootDep,
|
||||
deps: {},
|
||||
factory(_deps) {
|
||||
return 0;
|
||||
},
|
||||
});
|
||||
expect(metaFactory).toEqual(expect.any(Function));
|
||||
expect(metaFactory().service).toBe(rootDep);
|
||||
|
||||
// @ts-expect-error
|
||||
metaFactory('string');
|
||||
// @ts-expect-error
|
||||
metaFactory({});
|
||||
// @ts-expect-error
|
||||
metaFactory({ x: 1 });
|
||||
// @ts-expect-error
|
||||
metaFactory(null);
|
||||
// @ts-expect-error
|
||||
metaFactory(undefined);
|
||||
metaFactory();
|
||||
});
|
||||
|
||||
it('should create a factory with no options', () => {
|
||||
const metaFactory = createServiceFactory({
|
||||
service: ref,
|
||||
deps: {},
|
||||
@@ -51,7 +100,7 @@ describe('createServiceFactory', () => {
|
||||
metaFactory();
|
||||
});
|
||||
|
||||
it('should create a meta factory with optional options', () => {
|
||||
it('should create a factory with optional options', () => {
|
||||
const metaFactory = createServiceFactory((_opts?: { x: number }) => ({
|
||||
service: ref,
|
||||
deps: {},
|
||||
@@ -75,7 +124,7 @@ describe('createServiceFactory', () => {
|
||||
metaFactory();
|
||||
});
|
||||
|
||||
it('should create a meta factory with required options', () => {
|
||||
it('should create a factory with required options', () => {
|
||||
const metaFactory = createServiceFactory((_opts: { x: number }) => ({
|
||||
service: ref,
|
||||
deps: {},
|
||||
@@ -101,7 +150,7 @@ describe('createServiceFactory', () => {
|
||||
metaFactory();
|
||||
});
|
||||
|
||||
it('should create a meta factory with optional options as interface', () => {
|
||||
it('should create a factory with optional options as interface', () => {
|
||||
const metaFactory = createServiceFactory((_opts?: TestOptions) => ({
|
||||
service: ref,
|
||||
deps: {},
|
||||
@@ -125,7 +174,7 @@ describe('createServiceFactory', () => {
|
||||
metaFactory();
|
||||
});
|
||||
|
||||
it('should create a meta factory with required options as interface', () => {
|
||||
it('should create a factory with required options as interface', () => {
|
||||
const metaFactory = createServiceFactory((_opts: TestOptions) => ({
|
||||
service: ref,
|
||||
deps: {},
|
||||
|
||||
@@ -144,7 +144,7 @@ export interface RootServiceFactoryConfig<
|
||||
> {
|
||||
service: ServiceRef<TService, 'root'>;
|
||||
deps: TDeps;
|
||||
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): Promise<TImpl>;
|
||||
factory(deps: ServiceRefsToInstances<TDeps, 'root'>): TImpl | Promise<TImpl>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
@@ -158,11 +158,11 @@ export interface PluginServiceFactoryConfig<
|
||||
deps: TDeps;
|
||||
createRootContext?(
|
||||
deps: ServiceRefsToInstances<TDeps, 'root'>,
|
||||
): Promise<TContext>;
|
||||
): TContext | Promise<TContext>;
|
||||
factory(
|
||||
deps: ServiceRefsToInstances<TDeps>,
|
||||
context: TContext,
|
||||
): Promise<TImpl>;
|
||||
): TImpl | Promise<TImpl>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,6 +278,16 @@ export function createServiceFactory<
|
||||
const configCallback = typeof config === 'function' ? config : () => config;
|
||||
return (options: TOpts) => {
|
||||
const c = configCallback(options);
|
||||
return { ...c, scope: c.service.scope } as ServiceFactory<TService>;
|
||||
return {
|
||||
...c,
|
||||
...('createRootContext' in c
|
||||
? {
|
||||
createRootContext: async (deps: TDeps) =>
|
||||
c?.createRootContext?.(deps),
|
||||
}
|
||||
: {}),
|
||||
factory: async (deps: TDeps, ctx: TContext) => c.factory(deps, ctx),
|
||||
scope: c.service.scope,
|
||||
} as ServiceFactory<TService>;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user