added lossy view

This commit is contained in:
Ladd Hoffman 2024-12-23 23:30:21 -06:00
parent 68e611a050
commit 42df273052
2 changed files with 96 additions and 67 deletions

View File

@ -33,47 +33,54 @@ describe('Lossless', () => {
expect(lossless.view()).toEqual({ expect(lossless.view()).toEqual({
keanu: { keanu: {
roles: [{ referencedAs: ["actor"],
creator: "a", properties: {
host: "h", roles: [{
pointers: [ creator: "a",
{actor: "keanu"}, host: "h",
{role: "neo"}, pointers: [
{film: "the_matrix"}, {actor: "keanu"},
{base_salary: 1000000}, {role: "neo"},
{salary_currency: "usd"}, {film: "the_matrix"},
], {base_salary: 1000000},
}], {salary_currency: "usd"},
],
}],
},
}, },
neo: { neo: {
actor: [{ referencedAs: ["role"],
creator: "a", properties: {
host: "h", actor: [{
pointers: [ creator: "a",
{actor: "keanu"}, host: "h",
{role: "neo"}, pointers: [
{film: "the_matrix"}, {actor: "keanu"},
{base_salary: 1000000}, {role: "neo"},
{salary_currency: "usd"}, {film: "the_matrix"},
], {base_salary: 1000000},
}], {salary_currency: "usd"},
],
}],
},
}, },
the_matrix: { the_matrix: {
cast: [{ referencedAs: ["film"],
creator: "a", properties: {
host: "h", cast: [{
pointers: [ creator: "a",
{actor: "keanu"}, host: "h",
{role: "neo"}, pointers: [
{film: "the_matrix"}, {actor: "keanu"},
{base_salary: 1000000}, {role: "neo"},
{salary_currency: "usd"}, {film: "the_matrix"},
], {base_salary: 1000000},
}], {salary_currency: "usd"},
} ],
}],
},
},
}); });
}); });
describe('can filter deltas', () => { describe('can filter deltas', () => {
@ -103,19 +110,22 @@ describe('Lossless', () => {
expect(lossless.view()).toEqual({ expect(lossless.view()).toEqual({
ace: { ace: {
value: [{ referencedAs: ["1", "14"],
creator: 'A', properties: {
host: 'H', value: [{
pointers: [ creator: 'A',
{"1": "ace"}, host: 'H',
] pointers: [
}, { {"1": "ace"},
creator: 'B', ]
host: 'H', }, {
pointers: [ creator: 'B',
{"14": "ace"}, host: 'H',
] pointers: [
}], {"14": "ace"},
]
}],
}
} }
}); });
}); });
@ -127,13 +137,16 @@ describe('Lossless', () => {
expect(lossless.view(filter)).toEqual({ expect(lossless.view(filter)).toEqual({
ace: { ace: {
value: [{ referencedAs: ["1"],
creator: 'A', properties: {
host: 'H', value: [{
pointers: [ creator: 'A',
{"1": "ace"}, host: 'H',
] pointers: [
}] {"1": "ace"},
]
}]
}
} }
}); });
}); });

View File

@ -6,11 +6,19 @@ import {Delta, DeltaFilter, PropertyTypes} from "./types";
type DomainEntityID = string; type DomainEntityID = string;
type PropertyID = string; type PropertyID = string;
export type LosslessView = {[key: string]: {[key: string]: Delta[]}};
export type CollapsedPointer = {[key: string]: PropertyTypes}; export type CollapsedPointer = {[key: string]: PropertyTypes};
export type CollapsedDelta = Omit<Delta, 'pointers'> & { export type CollapsedDelta = Omit<Delta, 'pointers'> & {
pointers: CollapsedPointer[]; pointers: CollapsedPointer[];
}; };
export type LosslessViewOne = {
referencedAs: string[];
properties: {
[key: PropertyID]: CollapsedDelta[]
}
};
export type LosslessViewMany = {
[key: DomainEntityID]: LosslessViewOne;
};
class DomainEntityMap extends Map<DomainEntityID, DomainEntity> {}; class DomainEntityMap extends Map<DomainEntityID, DomainEntity> {};
@ -66,26 +74,34 @@ export class Lossless {
} }
//TODO: json logic -- view(deltaFilter?: FilterExpr) { //TODO: json logic -- view(deltaFilter?: FilterExpr) {
view(deltaFilter?: DeltaFilter) { view(deltaFilter?: DeltaFilter): LosslessViewMany {
const view: {[key: DomainEntityID]: {[key: PropertyID]: CollapsedDelta[]}} = {}; const view: LosslessViewMany = {};
for (const ent of this.domainEntities.values()) { for (const ent of this.domainEntities.values()) {
// const obj: {[key: PropertyID]: CollapsedDelta[]} = {}; const referencedAs = new Set<string>();
view[ent.id] = {}; view[ent.id] = {
referencedAs: [],
properties: {}
};
for (const prop of ent.properties.values()) { for (const prop of ent.properties.values()) {
view[ent.id][prop.id] = view[ent.id][prop.id] || []; view[ent.id].properties[prop.id] = view[ent.id].properties[prop.id] || [];
for (const delta of prop.deltas) { for (const delta of prop.deltas) {
if (deltaFilter) { if (deltaFilter) {
const include = deltaFilter(delta); const include = deltaFilter(delta);
if (!include) continue; if (!include) continue;
} }
const pointers: CollapsedPointer[] = [];
for (const {localContext, target} of delta.pointers) {
pointers.push({[localContext]: target});
if (target === ent.id) {
referencedAs.add(localContext);
}
}
const collapsedDelta: CollapsedDelta = { const collapsedDelta: CollapsedDelta = {
...delta, ...delta,
pointers: delta.pointers pointers
.map(({localContext, target}) => ({
[localContext]: target
}))
}; };
view[ent.id][prop.id].push(collapsedDelta); view[ent.id].referencedAs = Array.from(referencedAs.values());
view[ent.id].properties[prop.id].push(collapsedDelta);
} }
} }
} }