added delta filtering for lossless view

This commit is contained in:
Ladd Hoffman 2024-12-23 20:44:54 -06:00
parent 81839bb4fa
commit 68e611a050
3 changed files with 84 additions and 11 deletions

View File

@ -1,8 +1,8 @@
import {Lossless} from '../src/lossless'; import {Lossless} from '../src/lossless';
import {Delta} from '../src/types'; import {Delta, DeltaFilter} from '../src/types';
describe('Lossless', () => { describe('Lossless', () => {
it('creates a lossless view of neo in the matrix', () => { it('creates a lossless view of keanu as neo in the matrix', () => {
const delta: Delta = { const delta: Delta = {
creator: 'a', creator: 'a',
host: 'h', host: 'h',
@ -72,5 +72,70 @@ describe('Lossless', () => {
}], }],
} }
}); });
});
describe('can filter deltas', () => {
const lossless = new Lossless();
beforeAll(() => {
lossless.ingestDelta({
creator: 'A',
host: 'H',
pointers: [{
localContext: "1",
target: "ace",
targetContext: "value"
}]
});
lossless.ingestDelta({
creator: 'B',
host: 'H',
pointers: [{
// 10 11j 12q 13k 14a
localContext: "14",
target: "ace",
targetContext: "value"
}]
});
expect(lossless.view()).toEqual({
ace: {
value: [{
creator: 'A',
host: 'H',
pointers: [
{"1": "ace"},
]
}, {
creator: 'B',
host: 'H',
pointers: [
{"14": "ace"},
]
}],
}
});
});
it('filter by creator and host', () => {
const filter: DeltaFilter = ({creator, host}) => {
return creator === 'A' && host === 'H';
};
expect(lossless.view(filter)).toEqual({
ace: {
value: [{
creator: 'A',
host: 'H',
pointers: [
{"1": "ace"},
]
}]
}
});
});
}); });
}); });

View File

@ -1,7 +1,7 @@
// Deltas target entities. // Deltas target entities.
// We can maintain a record of all the targeted entities, and the deltas that targeted them // We can maintain a record of all the targeted entities, and the deltas that targeted them
import {Delta, PropertyTypes} from "./types"; import {Delta, DeltaFilter, PropertyTypes} from "./types";
type DomainEntityID = string; type DomainEntityID = string;
type PropertyID = string; type PropertyID = string;
@ -65,21 +65,27 @@ export class Lossless {
} }
} }
view() { //TODO: json logic -- view(deltaFilter?: FilterExpr) {
view(deltaFilter?: DeltaFilter) {
const view: {[key: DomainEntityID]: {[key: PropertyID]: CollapsedDelta[]}} = {}; const view: {[key: DomainEntityID]: {[key: PropertyID]: CollapsedDelta[]}} = {};
for (const ent of this.domainEntities.values()) { for (const ent of this.domainEntities.values()) {
const obj: {[key: PropertyID]: CollapsedDelta[]} = {}; // const obj: {[key: PropertyID]: CollapsedDelta[]} = {};
view[ent.id] = obj; view[ent.id] = {};
for (const prop of ent.properties.values()) { for (const prop of ent.properties.values()) {
obj[prop.id] = obj[prop.id] || []; view[ent.id][prop.id] = view[ent.id][prop.id] || [];
for (const delta of prop.deltas) { for (const delta of prop.deltas) {
if (deltaFilter) {
const include = deltaFilter(delta);
if (!include) continue;
}
const collapsedDelta: CollapsedDelta = { const collapsedDelta: CollapsedDelta = {
...delta, ...delta,
pointers: delta.pointers.map(({localContext, target}) => ({ pointers: delta.pointers
.map(({localContext, target}) => ({
[localContext]: target [localContext]: target
})) }))
}; };
obj[prop.id].push(collapsedDelta); view[ent.id][prop.id].push(collapsedDelta);
} }
} }
} }

View File

@ -37,6 +37,8 @@ export type FilterExpr = JSONLogic;
export type FilterGenerator = () => FilterExpr; export type FilterGenerator = () => FilterExpr;
export type DeltaFilter = (delta: Delta) => boolean;
export type PropertyTypes = string | number | undefined; export type PropertyTypes = string | number | undefined;
export type Properties = {[key: string]: PropertyTypes}; export type Properties = {[key: string]: PropertyTypes};