diff --git a/__tests__/lossless.ts b/__tests__/lossless.ts index fc7356c..2863cb9 100644 --- a/__tests__/lossless.ts +++ b/__tests__/lossless.ts @@ -33,47 +33,54 @@ describe('Lossless', () => { expect(lossless.view()).toEqual({ keanu: { - roles: [{ - creator: "a", - host: "h", - pointers: [ - {actor: "keanu"}, - {role: "neo"}, - {film: "the_matrix"}, - {base_salary: 1000000}, - {salary_currency: "usd"}, - ], - }], + referencedAs: ["actor"], + properties: { + roles: [{ + creator: "a", + host: "h", + pointers: [ + {actor: "keanu"}, + {role: "neo"}, + {film: "the_matrix"}, + {base_salary: 1000000}, + {salary_currency: "usd"}, + ], + }], + }, }, neo: { - actor: [{ - creator: "a", - host: "h", - pointers: [ - {actor: "keanu"}, - {role: "neo"}, - {film: "the_matrix"}, - {base_salary: 1000000}, - {salary_currency: "usd"}, - ], - }], + referencedAs: ["role"], + properties: { + actor: [{ + creator: "a", + host: "h", + pointers: [ + {actor: "keanu"}, + {role: "neo"}, + {film: "the_matrix"}, + {base_salary: 1000000}, + {salary_currency: "usd"}, + ], + }], + }, }, the_matrix: { - cast: [{ - creator: "a", - host: "h", - pointers: [ - {actor: "keanu"}, - {role: "neo"}, - {film: "the_matrix"}, - {base_salary: 1000000}, - {salary_currency: "usd"}, - ], - }], - } + referencedAs: ["film"], + properties: { + cast: [{ + creator: "a", + host: "h", + pointers: [ + {actor: "keanu"}, + {role: "neo"}, + {film: "the_matrix"}, + {base_salary: 1000000}, + {salary_currency: "usd"}, + ], + }], + }, + }, }); - - }); describe('can filter deltas', () => { @@ -103,19 +110,22 @@ describe('Lossless', () => { expect(lossless.view()).toEqual({ ace: { - value: [{ - creator: 'A', - host: 'H', - pointers: [ - {"1": "ace"}, - ] - }, { - creator: 'B', - host: 'H', - pointers: [ - {"14": "ace"}, - ] - }], + referencedAs: ["1", "14"], + properties: { + value: [{ + creator: 'A', + host: 'H', + pointers: [ + {"1": "ace"}, + ] + }, { + creator: 'B', + host: 'H', + pointers: [ + {"14": "ace"}, + ] + }], + } } }); }); @@ -127,13 +137,16 @@ describe('Lossless', () => { expect(lossless.view(filter)).toEqual({ ace: { - value: [{ - creator: 'A', - host: 'H', - pointers: [ - {"1": "ace"}, - ] - }] + referencedAs: ["1"], + properties: { + value: [{ + creator: 'A', + host: 'H', + pointers: [ + {"1": "ace"}, + ] + }] + } } }); }); diff --git a/src/lossless.ts b/src/lossless.ts index 865b874..54beb0c 100644 --- a/src/lossless.ts +++ b/src/lossless.ts @@ -6,11 +6,19 @@ import {Delta, DeltaFilter, PropertyTypes} from "./types"; type DomainEntityID = string; type PropertyID = string; -export type LosslessView = {[key: string]: {[key: string]: Delta[]}}; export type CollapsedPointer = {[key: string]: PropertyTypes}; export type CollapsedDelta = Omit & { pointers: CollapsedPointer[]; }; +export type LosslessViewOne = { + referencedAs: string[]; + properties: { + [key: PropertyID]: CollapsedDelta[] + } +}; +export type LosslessViewMany = { + [key: DomainEntityID]: LosslessViewOne; +}; class DomainEntityMap extends Map {}; @@ -66,26 +74,34 @@ export class Lossless { } //TODO: json logic -- view(deltaFilter?: FilterExpr) { - view(deltaFilter?: DeltaFilter) { - const view: {[key: DomainEntityID]: {[key: PropertyID]: CollapsedDelta[]}} = {}; + view(deltaFilter?: DeltaFilter): LosslessViewMany { + const view: LosslessViewMany = {}; for (const ent of this.domainEntities.values()) { - // const obj: {[key: PropertyID]: CollapsedDelta[]} = {}; - view[ent.id] = {}; + const referencedAs = new Set(); + view[ent.id] = { + referencedAs: [], + properties: {} + }; 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) { if (deltaFilter) { const include = deltaFilter(delta); 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 = { ...delta, - pointers: delta.pointers - .map(({localContext, target}) => ({ - [localContext]: target - })) + pointers }; - view[ent.id][prop.id].push(collapsedDelta); + view[ent.id].referencedAs = Array.from(referencedAs.values()); + view[ent.id].properties[prop.id].push(collapsedDelta); } } }