MOBILE-4529 addons: Fix lazy instances overrides
parent
69cf1ead4c
commit
b39dc1b90e
|
@ -51,7 +51,14 @@ export function getPrefetchHandlerInstance(): CoreCourseModulePrefetchHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
prefetchHandlerInstance.setEagerInstance(new AddonModSurveyPrefetchHandlerService());
|
prefetchHandlerInstance.setEagerInstance(new AddonModSurveyPrefetchHandlerService());
|
||||||
prefetchHandlerInstance.setLazyInstanceMethods(['sync']);
|
prefetchHandlerInstance.setLazyMethods(['sync']);
|
||||||
|
prefetchHandlerInstance.setLazyOverrides([
|
||||||
|
'prefetch',
|
||||||
|
'isEnabled',
|
||||||
|
'invalidateModule',
|
||||||
|
'invalidateContent',
|
||||||
|
'getIntroFiles',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return prefetchHandlerInstance;
|
return prefetchHandlerInstance;
|
||||||
|
|
|
@ -39,7 +39,7 @@ export function getCronHandlerInstance(): CoreCronHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModSurveySyncCronHandlerService());
|
lazyHandler.setEagerInstance(new AddonModSurveySyncCronHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods(['execute', 'getInterval']);
|
lazyHandler.setLazyMethods(['execute', 'getInterval']);
|
||||||
|
|
||||||
return lazyHandler;
|
return lazyHandler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ export function getAssessmentStrategyHandlerInstance(): AddonWorkshopAssessmentS
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyAccumulativeHandlerService());
|
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyAccumulativeHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods([
|
lazyHandler.setLazyMethods([
|
||||||
'getComponent',
|
'getComponent',
|
||||||
'getOriginalValues',
|
'getOriginalValues',
|
||||||
'hasDataChanged',
|
'hasDataChanged',
|
||||||
|
|
|
@ -51,7 +51,7 @@ export function getAssessmentStrategyHandlerInstance(): AddonWorkshopAssessmentS
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyCommentsHandlerService());
|
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyCommentsHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods([
|
lazyHandler.setLazyMethods([
|
||||||
'getComponent',
|
'getComponent',
|
||||||
'getOriginalValues',
|
'getOriginalValues',
|
||||||
'hasDataChanged',
|
'hasDataChanged',
|
||||||
|
|
|
@ -51,7 +51,7 @@ export function getAssessmentStrategyHandlerInstance(): AddonWorkshopAssessmentS
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyNumErrorsHandlerService());
|
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyNumErrorsHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods([
|
lazyHandler.setLazyMethods([
|
||||||
'getComponent',
|
'getComponent',
|
||||||
'getOriginalValues',
|
'getOriginalValues',
|
||||||
'hasDataChanged',
|
'hasDataChanged',
|
||||||
|
|
|
@ -51,7 +51,7 @@ export function getAssessmentStrategyHandlerInstance(): AddonWorkshopAssessmentS
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyRubricHandlerService());
|
lazyHandler.setEagerInstance(new AddonModWorkshopAssessmentStrategyRubricHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods([
|
lazyHandler.setLazyMethods([
|
||||||
'getComponent',
|
'getComponent',
|
||||||
'getOriginalValues',
|
'getOriginalValues',
|
||||||
'hasDataChanged',
|
'hasDataChanged',
|
||||||
|
|
|
@ -48,7 +48,13 @@ export function getPrefetchHandlerInstance(): CoreCourseModulePrefetchHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModWorkshopPrefetchHandlerService());
|
lazyHandler.setEagerInstance(new AddonModWorkshopPrefetchHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods(['sync']);
|
lazyHandler.setLazyMethods(['sync']);
|
||||||
|
lazyHandler.setLazyOverrides([
|
||||||
|
'getFiles',
|
||||||
|
'invalidateContent',
|
||||||
|
'isDownloadable',
|
||||||
|
'prefetch',
|
||||||
|
]);
|
||||||
|
|
||||||
return lazyHandler;
|
return lazyHandler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ export function getCronHandlerInstance(): CoreCronHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
lazyHandler.setEagerInstance(new AddonModWorkshopSyncCronHandlerService());
|
lazyHandler.setEagerInstance(new AddonModWorkshopSyncCronHandlerService());
|
||||||
lazyHandler.setLazyInstanceMethods(['execute', 'getInterval']);
|
lazyHandler.setLazyMethods(['execute', 'getInterval']);
|
||||||
|
|
||||||
return lazyHandler;
|
return lazyHandler;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,15 +28,19 @@ function createAsyncInstanceWrapper<
|
||||||
lazyConstructor?: () => TLazyInstance | Promise<TLazyInstance>,
|
lazyConstructor?: () => TLazyInstance | Promise<TLazyInstance>,
|
||||||
): AsyncInstanceWrapper<TLazyInstance, TEagerInstance> {
|
): AsyncInstanceWrapper<TLazyInstance, TEagerInstance> {
|
||||||
let promisedInstance: CorePromisedValue<TLazyInstance> | null = null;
|
let promisedInstance: CorePromisedValue<TLazyInstance> | null = null;
|
||||||
let lazyInstanceMethods: Array<string | symbol>;
|
let lazyMethods: Array<string | number | symbol> | null = null;
|
||||||
|
let lazyOverrides: Array<keyof TEagerInstance> | null = null;
|
||||||
let eagerInstance: TEagerInstance;
|
let eagerInstance: TEagerInstance;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
get instance() {
|
get instance() {
|
||||||
return promisedInstance?.value ?? undefined;
|
return promisedInstance?.value ?? undefined;
|
||||||
},
|
},
|
||||||
get lazyInstanceMethods() {
|
get lazyMethods() {
|
||||||
return lazyInstanceMethods;
|
return lazyMethods;
|
||||||
|
},
|
||||||
|
get lazyOverrides() {
|
||||||
|
return lazyOverrides;
|
||||||
},
|
},
|
||||||
get eagerInstance() {
|
get eagerInstance() {
|
||||||
return eagerInstance;
|
return eagerInstance;
|
||||||
|
@ -68,8 +72,11 @@ function createAsyncInstanceWrapper<
|
||||||
|
|
||||||
promisedInstance.resolve(instance);
|
promisedInstance.resolve(instance);
|
||||||
},
|
},
|
||||||
setLazyInstanceMethods(methods) {
|
setLazyMethods(methods) {
|
||||||
lazyInstanceMethods = methods;
|
lazyMethods = methods;
|
||||||
|
},
|
||||||
|
setLazyOverrides(overrides) {
|
||||||
|
lazyOverrides = overrides;
|
||||||
},
|
},
|
||||||
setEagerInstance(instance) {
|
setEagerInstance(instance) {
|
||||||
eagerInstance = instance;
|
eagerInstance = instance;
|
||||||
|
@ -116,14 +123,16 @@ export interface AsyncInstanceWrapper<
|
||||||
TEagerInstance extends AsyncObject = Partial<TLazyInstance>
|
TEagerInstance extends AsyncObject = Partial<TLazyInstance>
|
||||||
> {
|
> {
|
||||||
instance?: TLazyInstance;
|
instance?: TLazyInstance;
|
||||||
lazyInstanceMethods?: Array<string | symbol>;
|
lazyMethods?: Array<string | number | symbol> | null;
|
||||||
|
lazyOverrides?: Array<keyof TEagerInstance> | null;
|
||||||
eagerInstance?: TEagerInstance;
|
eagerInstance?: TEagerInstance;
|
||||||
getInstance(): Promise<TLazyInstance>;
|
getInstance(): Promise<TLazyInstance>;
|
||||||
getProperty<P extends keyof TLazyInstance>(property: P): Promise<TLazyInstance[P]>;
|
getProperty<P extends keyof TLazyInstance>(property: P): Promise<TLazyInstance[P]>;
|
||||||
setInstance(instance: TLazyInstance): void;
|
setInstance(instance: TLazyInstance): void;
|
||||||
setLazyInstanceMethods<const T extends Array<string | symbol>>(
|
setLazyMethods<const T extends Array<string | number | symbol>>(
|
||||||
methods: LazyMethodsGuard<T, TLazyInstance, TEagerInstance>,
|
methods: LazyMethodsGuard<T, TLazyInstance, TEagerInstance>,
|
||||||
): void;
|
): void;
|
||||||
|
setLazyOverrides(methods: Array<keyof TEagerInstance>): void;
|
||||||
setEagerInstance(eagerInstance: TEagerInstance): void;
|
setEagerInstance(eagerInstance: TEagerInstance): void;
|
||||||
setLazyConstructor(lazyConstructor: () => TLazyInstance | Promise<TLazyInstance>): void;
|
setLazyConstructor(lazyConstructor: () => TLazyInstance | Promise<TLazyInstance>): void;
|
||||||
resetInstance(): void;
|
resetInstance(): void;
|
||||||
|
@ -156,7 +165,7 @@ export type AsyncInstance<TLazyInstance extends TEagerInstance, TEagerInstance e
|
||||||
/**
|
/**
|
||||||
* Guard type to make sure that lazy methods match what the lazy class implements.
|
* Guard type to make sure that lazy methods match what the lazy class implements.
|
||||||
*/
|
*/
|
||||||
export type LazyMethodsGuard<TMethods extends Array<string | symbol>, TLazyInstance, TEagerInstance> =
|
export type LazyMethodsGuard<TMethods extends Array<string | number | symbol>, TLazyInstance, TEagerInstance> =
|
||||||
TupleMatches<TMethods, Exclude<keyof TLazyInstance, keyof TEagerInstance>> extends true ? TMethods : never;
|
TupleMatches<TMethods, Exclude<keyof TLazyInstance, keyof TEagerInstance>> extends true ? TMethods : never;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,7 +181,9 @@ export function asyncInstance<TLazyInstance extends TEagerInstance, TEagerInstan
|
||||||
const wrapper = createAsyncInstanceWrapper<TLazyInstance, TEagerInstance>(lazyConstructor);
|
const wrapper = createAsyncInstanceWrapper<TLazyInstance, TEagerInstance>(lazyConstructor);
|
||||||
|
|
||||||
return new Proxy(wrapper, {
|
return new Proxy(wrapper, {
|
||||||
get: (target, property, receiver) => {
|
get: (target, p, receiver) => {
|
||||||
|
const property = p as keyof TEagerInstance;
|
||||||
|
|
||||||
if (property in target) {
|
if (property in target) {
|
||||||
return Reflect.get(target, property, receiver);
|
return Reflect.get(target, property, receiver);
|
||||||
}
|
}
|
||||||
|
@ -185,11 +196,19 @@ export function asyncInstance<TLazyInstance extends TEagerInstance, TEagerInstan
|
||||||
: value;
|
: value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrapper.eagerInstance && property in wrapper.eagerInstance) {
|
if (
|
||||||
|
wrapper.eagerInstance &&
|
||||||
|
property in wrapper.eagerInstance &&
|
||||||
|
!wrapper.lazyOverrides?.includes(property)
|
||||||
|
) {
|
||||||
return Reflect.get(wrapper.eagerInstance, property, receiver);
|
return Reflect.get(wrapper.eagerInstance, property, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrapper.lazyInstanceMethods && !wrapper.lazyInstanceMethods.includes(property)) {
|
if (
|
||||||
|
wrapper.lazyMethods &&
|
||||||
|
!wrapper.lazyMethods.includes(property) &&
|
||||||
|
!wrapper.lazyOverrides?.includes(property)
|
||||||
|
) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,20 @@ describe('AsyncInstance', () => {
|
||||||
expect(await asyncService.isEager()).toBe(false);
|
expect(await asyncService.isEager()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('initialize instance for forced eager properties', async () => {
|
||||||
|
const asyncService = asyncInstance(() => new LazyService());
|
||||||
|
|
||||||
|
asyncService.setEagerInstance(new EagerService());
|
||||||
|
asyncService.setLazyOverrides(['isEager']);
|
||||||
|
|
||||||
|
expect(await asyncService.isEager()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('does not return undefined methods when they are declared', async () => {
|
it('does not return undefined methods when they are declared', async () => {
|
||||||
const asyncService = asyncInstance<LazyService, EagerService>(() => new LazyService());
|
const asyncService = asyncInstance<LazyService, EagerService>(() => new LazyService());
|
||||||
|
|
||||||
asyncService.setEagerInstance(new EagerService());
|
asyncService.setEagerInstance(new EagerService());
|
||||||
asyncService.setLazyInstanceMethods(['hello', 'goodbye']);
|
asyncService.setLazyMethods(['hello', 'goodbye']);
|
||||||
|
|
||||||
expect(asyncService.hello).not.toBeUndefined();
|
expect(asyncService.hello).not.toBeUndefined();
|
||||||
expect(asyncService.goodbye).not.toBeUndefined();
|
expect(asyncService.goodbye).not.toBeUndefined();
|
||||||
|
|
Loading…
Reference in New Issue