correct memoization methods and test

This commit is contained in:
Niels Lyngsø
2023-03-21 15:54:07 +01:00
parent a688541f85
commit bcc681976a
2 changed files with 65 additions and 13 deletions

View File

@@ -95,6 +95,59 @@ describe('UmbExtensionRegistry', () => {
})
.unsubscribe();
});
it('Observable only trigged when changes made to the scope of it', (done) => {
let amountOfTimesTriggered = -1;
let lastAmount = 0;
extensionRegistry
.extensionsOfType('section')
.subscribe((extensions) => {
amountOfTimesTriggered++;
const newAmount = extensions?.length ?? 0;
if (amountOfTimesTriggered === 0) {
expect(newAmount).to.eq(3);
}
if (amountOfTimesTriggered === 1) {
expect(newAmount).to.eq(4);
}
if (lastAmount === newAmount) {
expect(null).to.eq('Update was triggered without a change, this test should fail.');
} else {
lastAmount = newAmount;
if (lastAmount === 3) {
// We registerer a extension that should not affect this observable.
extensionRegistry.register({
type: 'workspace',
name: 'test-editor-2',
alias: 'Umb.Test.Editor.2',
meta: {
entityType: 'testEntity',
},
});
// And then register a extension that triggers this observable.
extensionRegistry.register({
type: 'section',
name: 'test-section-4',
alias: 'Umb.Test.Section.4',
weight: 9999,
meta: {
label: 'Test Section 4',
pathname: 'test-section-4',
},
});
}
if (newAmount === 4) {
expect(amountOfTimesTriggered).to.eq(1);
expect(extensions?.[0]?.alias).to.eq('Umb.Test.Section.4');
done();
}
}
})
.unsubscribe();
});
});
});

View File

@@ -1,4 +1,4 @@
import { BehaviorSubject, withLatestFrom, map, Observable, distinctUntilChanged } from 'rxjs';
import { BehaviorSubject, map, Observable, distinctUntilChanged, combineLatest } from 'rxjs';
import type {
ManifestTypes,
ManifestTypeMap,
@@ -14,13 +14,13 @@ function extensionArrayMemoization<T extends { alias: string }>(
): boolean {
// If length is different, data is different:
if (previousValue.length !== currentValue.length) {
return true;
return false;
}
// previousValue has an alias that is not present in currentValue:
if (previousValue.find((p) => !currentValue.find((c) => c.alias === p.alias))) {
return true;
return false;
}
return false;
return true;
}
function extensionSingleMemoization<T extends { alias: string }>(
@@ -28,9 +28,9 @@ function extensionSingleMemoization<T extends { alias: string }>(
currentValue: T | undefined
): boolean {
if (previousValue && currentValue) {
return previousValue.alias !== currentValue.alias;
return previousValue.alias === currentValue.alias;
}
return previousValue !== currentValue;
return previousValue === currentValue;
}
const sortExtensions = (a: ManifestBase, b: ManifestBase) => (b.weight || 0) - (a.weight || 0);
@@ -124,9 +124,10 @@ export class UmbExtensionRegistry {
Key extends keyof ManifestTypeMap | string,
T extends ManifestBase = SpecificManifestTypeOrManifestBase<Key>
>(type: Key, alias: string) {
return this.extensions.pipe(
map((exts) => exts.find((ext) => ext.type === type && ext.alias === alias)),
withLatestFrom(this._kindsOfType(type)),
return combineLatest([
this.extensions.pipe(map((exts) => exts.find((ext) => ext.type === type && ext.alias === alias))),
this._kindsOfType(type),
]).pipe(
map(([ext, kinds]) => {
// TODO: share one merge function between the different methods of this class:
// Specific Extension Meta merge (does not merge conditions)
@@ -150,8 +151,7 @@ export class UmbExtensionRegistry {
Key extends keyof ManifestTypeMap | string,
T extends ManifestBase = SpecificManifestTypeOrManifestBase<Key>
>(type: Key) {
return this._extensionsOfType(type).pipe(
withLatestFrom(this._kindsOfType(type)),
return combineLatest([this._extensionsOfType(type), this._kindsOfType(type)]).pipe(
map(([exts, kinds]) =>
exts
.map((ext) => {
@@ -175,8 +175,7 @@ export class UmbExtensionRegistry {
extensionsOfTypes<ExtensionTypes extends ManifestBase = ManifestBase>(
types: string[]
): Observable<Array<ExtensionTypes>> {
return this._extensionsOfTypes(types).pipe(
withLatestFrom(this._kindsOfTypes(types)),
return combineLatest([this._extensionsOfTypes(types), this._kindsOfTypes(types)]).pipe(
map(([exts, kinds]) =>
exts
.map((ext) => {