refactor: migrate all delta creation to use DeltaBuilder
- Replace all direct instantiations with - Implement proper transaction handling in DeltaBuilder - Update negation system to work with the builder pattern - Fix type issues with null values in pointers - Update all tests to work with the new implementation - Ensure all tests pass with the refactored code This change improves code consistency and maintainability by using a single, fluent API for all delta creation throughout the codebase.
This commit is contained in:
parent
60ad920b30
commit
795551c623
@ -146,9 +146,11 @@ describe('DeltaBuilder', () => {
|
||||
.buildV1();
|
||||
|
||||
// Check for transaction ID in pointers
|
||||
const txPointer = delta.pointers.find(p => p.localContext === '_transaction');
|
||||
expect(txPointer).toBeDefined();
|
||||
expect(txPointer?.target).toBe(txId);
|
||||
expect(delta.pointers).toContainEqual({
|
||||
localContext: '_transaction',
|
||||
target: txId,
|
||||
targetContext: 'deltas'
|
||||
});
|
||||
});
|
||||
|
||||
it('should support transactions in V2', () => {
|
||||
@ -168,7 +170,7 @@ describe('DeltaBuilder', () => {
|
||||
.buildV1();
|
||||
|
||||
// Check for negation in pointers
|
||||
const negationPointer = delta.pointers.find(p => p.localContext === '_negation');
|
||||
const negationPointer = delta.pointers.find(p => p.localContext === '_negates');
|
||||
expect(negationPointer).toBeDefined();
|
||||
expect(negationPointer?.target).toBe(negatedId);
|
||||
});
|
||||
|
@ -248,8 +248,7 @@ describe('Lossless', () => {
|
||||
losslessT.ingestDelta(
|
||||
createDelta('A', 'H')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('step', 'process1', 'status')
|
||||
.addPointer('value', 'started')
|
||||
.setProperty('process1', 'status', 'started', 'step')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -257,8 +256,7 @@ describe('Lossless', () => {
|
||||
losslessT.ingestDelta(
|
||||
createDelta('B', 'H')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('step', 'process1', 'status')
|
||||
.addPointer('value', 'processing')
|
||||
.setProperty('process1', 'status', 'processing', 'step')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import Debug from 'debug';
|
||||
import { createDelta } from '../src/core/delta-builder';
|
||||
import { Delta } from '../src/core';
|
||||
import { NegationHelper } from '../src/features';
|
||||
import { RhizomeNode } from '../src/node';
|
||||
import { Lossless } from '../src/views';
|
||||
@ -28,15 +27,14 @@ describe('Negation System', () => {
|
||||
'host1'
|
||||
);
|
||||
|
||||
expect(negationDelta.isNegation).toBe(true);
|
||||
expect(negationDelta.negatedDeltaId).toBe(originalDelta.id);
|
||||
expect(negationDelta.creator).toBe('moderator');
|
||||
expect(negationDelta.pointers).toHaveLength(1);
|
||||
expect(negationDelta.pointers[0]).toEqual({
|
||||
localContext: 'negates',
|
||||
localContext: '_negates',
|
||||
target: originalDelta.id,
|
||||
targetContext: 'negated_by'
|
||||
});
|
||||
expect(NegationHelper.isNegationDelta(negationDelta)).toBe(true);
|
||||
});
|
||||
|
||||
it('should identify negation deltas', () => {
|
||||
|
@ -194,14 +194,9 @@ describe('Nested Object Resolution Performance', () => {
|
||||
const currentId = userIds[i];
|
||||
const nextId = userIds[i + 1];
|
||||
|
||||
const linkDelta = new Delta({
|
||||
creator: node.config.creator,
|
||||
host: node.config.peerId,
|
||||
pointers: [
|
||||
{ localContext: 'users', target: currentId, targetContext: 'next' },
|
||||
{ localContext: 'next', target: nextId }
|
||||
]
|
||||
});
|
||||
const linkDelta = createDelta(node.config.creator, node.config.peerId)
|
||||
.setProperty(currentId, 'next', nextId, 'users')
|
||||
.buildV1();
|
||||
node.lossless.ingestDelta(linkDelta);
|
||||
}
|
||||
|
||||
@ -293,14 +288,10 @@ describe('Nested Object Resolution Performance', () => {
|
||||
const connectedIndex = (i + j) % userCount;
|
||||
const connectedId = userIds[connectedIndex];
|
||||
|
||||
const connectionDelta = new Delta({
|
||||
creator: node.config.creator,
|
||||
host: node.config.peerId,
|
||||
pointers: [
|
||||
{ localContext: 'users', target: userId, targetContext: 'connections' },
|
||||
{ localContext: 'connections', target: connectedId }
|
||||
]
|
||||
});
|
||||
const connectionDelta = createDelta(node.config.creator, node.config.peerId)
|
||||
.addPointer('users', userId, 'connections')
|
||||
.addPointer('connections', connectedId)
|
||||
.buildV1();
|
||||
node.lossless.ingestDelta(connectionDelta);
|
||||
}
|
||||
}
|
||||
|
@ -24,15 +24,13 @@ describe('Transactions', () => {
|
||||
// Create first delta in transaction
|
||||
const delta1 = createDelta('user1', 'host1')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('name', 'user123', 'name')
|
||||
.addPointer('value', 'Alice')
|
||||
.setProperty('user123', 'name', 'Alice')
|
||||
.buildV1();
|
||||
|
||||
// Create second delta in transaction
|
||||
const delta2 = createDelta('user1', 'host1')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('age', 'user123', 'age')
|
||||
.addPointer('value', 25)
|
||||
.setProperty('user123', 'age', 25)
|
||||
.buildV1();
|
||||
|
||||
// Ingest transaction declaration and first two deltas
|
||||
@ -47,8 +45,7 @@ describe('Transactions', () => {
|
||||
// Add the third delta to complete the transaction
|
||||
const delta3 = createDelta('user1', 'host1')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('email', 'user123', 'email')
|
||||
.addPointer('value', 'alice@example.com')
|
||||
.setProperty('user123', 'email', 'alice@example.com')
|
||||
.buildV1();
|
||||
|
||||
lossless.ingestDelta(delta3);
|
||||
@ -79,15 +76,13 @@ describe('Transactions', () => {
|
||||
// Add deltas for both transactions
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.inTransaction(tx1)
|
||||
.addPointer('status', 'order1', 'status')
|
||||
.addPointer('value', 'pending')
|
||||
.setProperty('order1', 'status', 'pending')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
lossless.ingestDelta(createDelta('user2', 'host2')
|
||||
.inTransaction(tx2)
|
||||
.addPointer('status', 'order2', 'status')
|
||||
.addPointer('value', 'shipped')
|
||||
.setProperty('order2', 'status', 'shipped')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -99,8 +94,7 @@ describe('Transactions', () => {
|
||||
// Complete tx1
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.inTransaction(tx1)
|
||||
.addPointer('total', 'order1', 'total')
|
||||
.addPointer('value', 100)
|
||||
.setProperty('order1', 'total', 100)
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -114,8 +108,7 @@ describe('Transactions', () => {
|
||||
// Complete tx2
|
||||
lossless.ingestDelta(createDelta('user2', 'host2')
|
||||
.inTransaction(tx2)
|
||||
.addPointer('tracking', 'order2', 'tracking')
|
||||
.addPointer('value', 'TRACK123')
|
||||
.setProperty('order2', 'tracking', 'TRACK123')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -139,15 +132,13 @@ describe('Transactions', () => {
|
||||
// Add both deltas
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('type', 'doc1', 'type')
|
||||
.addPointer('value', 'report')
|
||||
.setProperty('doc1', 'type', 'report')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
lossless.ingestDelta(createDelta('user2', 'host2')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('author', 'doc1', 'author')
|
||||
.addPointer('value', 'Bob')
|
||||
.setProperty('doc1', 'author', 'Bob')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -169,14 +160,13 @@ describe('Transactions', () => {
|
||||
|
||||
// Transaction that updates multiple entities atomically
|
||||
lossless.ingestDelta(createDelta('system', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'size')
|
||||
.addPointer('size', 3)
|
||||
.declareTransaction(transactionId, 3)
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
// Transfer money from account1 to account2
|
||||
lossless.ingestDelta(createDelta('bank', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('balance', 'account1', 'balance')
|
||||
.addPointer('value', 900)
|
||||
.addPointer('operation', 'debit')
|
||||
@ -184,7 +174,7 @@ describe('Transactions', () => {
|
||||
);
|
||||
|
||||
lossless.ingestDelta(createDelta('bank', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('balance', 'account2', 'balance')
|
||||
.addPointer('value', 1100)
|
||||
.addPointer('operation', 'credit')
|
||||
@ -198,7 +188,7 @@ describe('Transactions', () => {
|
||||
|
||||
// Complete transaction with audit log
|
||||
lossless.ingestDelta(createDelta('bank', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.inTransaction(transactionId)
|
||||
.addPointer('transfer', 'transfer123', 'details')
|
||||
.addPointer('from', 'account1')
|
||||
.addPointer('to', 'account2')
|
||||
@ -227,16 +217,14 @@ describe('Transactions', () => {
|
||||
|
||||
// Create transaction
|
||||
lossless.ingestDelta(createDelta('system', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'size')
|
||||
.addPointer('size', 2)
|
||||
.declareTransaction(transactionId, 2)
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
// Add first delta
|
||||
const delta1 = createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('field1', 'entity1', 'field1')
|
||||
.addPointer('value', 'value1')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('entity1', 'field1', 'value1')
|
||||
.buildV1();
|
||||
lossless.ingestDelta(delta1);
|
||||
|
||||
@ -245,9 +233,8 @@ describe('Transactions', () => {
|
||||
|
||||
// Add second delta to complete transaction
|
||||
const delta2 = createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('field2', 'entity1', 'field2')
|
||||
.addPointer('value', 'value2')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('entity1', 'field2', 'value2')
|
||||
.buildV1();
|
||||
lossless.ingestDelta(delta2);
|
||||
|
||||
@ -270,16 +257,14 @@ describe('Transactions', () => {
|
||||
|
||||
// Create transaction
|
||||
lossless.ingestDelta(createDelta('system', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'size')
|
||||
.addPointer('size', 2)
|
||||
.declareTransaction(transactionId, 2)
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
// Add first delta
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('status', 'job1', 'status')
|
||||
.addPointer('value', 'processing')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('job1', 'status', 'processing')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -294,9 +279,8 @@ describe('Transactions', () => {
|
||||
|
||||
// Complete transaction
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('status', 'job1', 'status')
|
||||
.addPointer('value', 'completed')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('job1', 'status', 'completed')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -340,21 +324,20 @@ describe('Transactions', () => {
|
||||
|
||||
// Initially declare transaction with size 2
|
||||
lossless.ingestDelta(createDelta('system', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'size')
|
||||
.addPointer('size', 2)
|
||||
.declareTransaction(transactionId, 2)
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
// Add 2 deltas
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('item1', 'cart1', 'items')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('cart1', 'items', 'item1')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('item2', 'cart1', 'items')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('cart1', 'items', 'item2')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -371,9 +354,8 @@ describe('Transactions', () => {
|
||||
|
||||
// Add delta with transaction reference but no size declaration
|
||||
lossless.ingestDelta(createDelta('user1', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'deltas')
|
||||
.addPointer('data', 'entity1', 'data')
|
||||
.addPointer('value', 'test')
|
||||
.inTransaction(transactionId)
|
||||
.setProperty('entity1', 'data', 'test')
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
@ -386,8 +368,7 @@ describe('Transactions', () => {
|
||||
|
||||
// Declare size after the fact
|
||||
lossless.ingestDelta(createDelta('system', 'host1')
|
||||
.addPointer('_transaction', transactionId, 'size')
|
||||
.addPointer('size', 1)
|
||||
.declareTransaction(transactionId, 1)
|
||||
.buildV1()
|
||||
);
|
||||
|
||||
|
@ -2,6 +2,7 @@ import Debug from 'debug';
|
||||
import {randomUUID} from "node:crypto";
|
||||
import EventEmitter from "node:events";
|
||||
import {Delta} from "../core/delta";
|
||||
import {createDelta} from "../core/delta-builder";
|
||||
import {Entity, EntityProperties} from "../core/entity";
|
||||
import {ResolvedViewOne} from '../views/resolvers/last-write-wins';
|
||||
import {RhizomeNode} from "../node";
|
||||
@ -72,18 +73,11 @@ export abstract class Collection<View> {
|
||||
if (key === 'id') return;
|
||||
|
||||
if (oldProperties[key] !== value && host && creator) {
|
||||
deltas.push(new Delta({
|
||||
creator,
|
||||
host,
|
||||
pointers: [{
|
||||
localContext: this.name,
|
||||
target: entityId,
|
||||
targetContext: key
|
||||
}, {
|
||||
localContext: key,
|
||||
target: value
|
||||
}]
|
||||
}));
|
||||
deltas.push(
|
||||
createDelta(creator, host)
|
||||
.setProperty(entityId, key, value, this.name)
|
||||
.buildV1()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@ -91,18 +85,10 @@ export abstract class Collection<View> {
|
||||
|
||||
if (deltas.length > 1) {
|
||||
// We can generate a separate delta describing this transaction
|
||||
transactionDelta = new Delta({
|
||||
creator,
|
||||
host,
|
||||
pointers: [{
|
||||
localContext: "_transaction",
|
||||
target: transactionId,
|
||||
targetContext: "size"
|
||||
}, {
|
||||
localContext: "size",
|
||||
target: deltas.length
|
||||
}]
|
||||
});
|
||||
transactionDelta = createDelta(creator, host)
|
||||
.addPointer('_transaction', transactionId, 'size')
|
||||
.addPointer('size', deltas.length)
|
||||
.buildV1();
|
||||
|
||||
// Also need to annotate the deltas with the transactionId
|
||||
for (const delta of deltas) {
|
||||
|
@ -13,9 +13,6 @@ export class DeltaBuilder {
|
||||
private host: string;
|
||||
private creator: string;
|
||||
private pointers: Record<string, any> = {};
|
||||
private transactionId?: string;
|
||||
private isNegation: boolean = false;
|
||||
private negatedDeltaId?: string;
|
||||
|
||||
/**
|
||||
* Create a new DeltaBuilder instance
|
||||
@ -48,7 +45,7 @@ export class DeltaBuilder {
|
||||
* Set the transaction ID for this delta
|
||||
*/
|
||||
inTransaction(transactionId: string): this {
|
||||
this.transactionId = transactionId;
|
||||
this.addPointer('_transaction', transactionId, 'deltas');
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -59,8 +56,7 @@ export class DeltaBuilder {
|
||||
* @returns
|
||||
*/
|
||||
declareTransaction(transactionId: string, size: number): this {
|
||||
this.addPointer('_transaction', transactionId, 'size');
|
||||
this.addPointer('size', size)
|
||||
this.setProperty(transactionId, 'size', size, '_transaction');
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -68,15 +64,17 @@ export class DeltaBuilder {
|
||||
* Mark this delta as a negation of another delta
|
||||
*/
|
||||
negate(deltaId: string): this {
|
||||
this.isNegation = true;
|
||||
this.negatedDeltaId = deltaId;
|
||||
this.addPointer('_negates', deltaId, 'negated_by');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pointer to the delta
|
||||
* @param localContext The local context for the pointer
|
||||
* @param target The target value (string, number, boolean, or null)
|
||||
* @param targetContext Optional target context for the pointer
|
||||
*/
|
||||
addPointer(localContext: string, target: string | number | boolean, targetContext?: string): this {
|
||||
addPointer(localContext: string, target: string | number | boolean | null, targetContext?: string): this {
|
||||
if (targetContext && typeof target === 'string') {
|
||||
this.pointers[localContext] = { [target]: targetContext };
|
||||
} else {
|
||||
@ -88,7 +86,7 @@ export class DeltaBuilder {
|
||||
/**
|
||||
* Set a property on an entity
|
||||
*/
|
||||
setProperty(entityId: string, property: string, value: string | number | boolean, entityLabel = "entity"): this {
|
||||
setProperty(entityId: string, property: string, value: string | number | boolean | null, entityLabel = "entity"): this {
|
||||
this.addPointer(entityLabel, entityId, property)
|
||||
this.addPointer(property, value);
|
||||
return this;
|
||||
@ -110,14 +108,6 @@ export class DeltaBuilder {
|
||||
// For V2, we'll store transaction and negation info in the pointers object
|
||||
const pointers = { ...this.pointers };
|
||||
|
||||
if (this.transactionId) {
|
||||
pointers['_transaction'] = { [this.transactionId]: 'deltas' };
|
||||
}
|
||||
|
||||
if (this.isNegation && this.negatedDeltaId) {
|
||||
pointers['_negation'] = this.negatedDeltaId;
|
||||
}
|
||||
|
||||
// Create the delta with all pointers
|
||||
return new DeltaV2({
|
||||
id: this.id,
|
||||
|
@ -1,21 +1,17 @@
|
||||
import Debug from 'debug';
|
||||
import { Delta, DeltaID } from '../core/delta';
|
||||
import { createDelta } from '../core/delta-builder';
|
||||
import { CreatorID, HostID } from '../core/types';
|
||||
|
||||
const debug = Debug('rz:negation');
|
||||
|
||||
// Negation-specific types
|
||||
export interface NegationPointer {
|
||||
localContext: 'negates';
|
||||
localContext: '_negates';
|
||||
target: DeltaID;
|
||||
targetContext: 'negated_by';
|
||||
}
|
||||
|
||||
export interface NegationDelta extends Delta {
|
||||
isNegation: true;
|
||||
negatedDeltaId: DeltaID;
|
||||
}
|
||||
|
||||
// Helper functions for creating and identifying negation deltas
|
||||
export class NegationHelper {
|
||||
|
||||
@ -26,19 +22,10 @@ export class NegationHelper {
|
||||
deltaToNegate: DeltaID,
|
||||
creator: CreatorID,
|
||||
host: HostID
|
||||
): NegationDelta {
|
||||
const negationDelta = new Delta({
|
||||
creator,
|
||||
host,
|
||||
pointers: [{
|
||||
localContext: 'negates',
|
||||
target: deltaToNegate,
|
||||
targetContext: 'negated_by'
|
||||
}]
|
||||
}) as NegationDelta;
|
||||
|
||||
negationDelta.isNegation = true;
|
||||
negationDelta.negatedDeltaId = deltaToNegate;
|
||||
): Delta {
|
||||
const negationDelta = createDelta(creator, host)
|
||||
.negate(deltaToNegate)
|
||||
.buildV1();
|
||||
|
||||
debug(`Created negation delta ${negationDelta.id} negating ${deltaToNegate}`);
|
||||
return negationDelta;
|
||||
@ -47,9 +34,9 @@ export class NegationHelper {
|
||||
/**
|
||||
* Check if a delta is a negation delta
|
||||
*/
|
||||
static isNegationDelta(delta: Delta): delta is NegationDelta {
|
||||
static isNegationDelta(delta: Delta): boolean {
|
||||
return delta.pointers.some(pointer =>
|
||||
pointer.localContext === 'negates' &&
|
||||
pointer.localContext === '_negates' &&
|
||||
pointer.targetContext === 'negated_by'
|
||||
);
|
||||
}
|
||||
@ -59,7 +46,7 @@ export class NegationHelper {
|
||||
*/
|
||||
static getNegatedDeltaId(negationDelta: Delta): DeltaID | null {
|
||||
const negationPointer = negationDelta.pointers.find(pointer =>
|
||||
pointer.localContext === 'negates' &&
|
||||
pointer.localContext === '_negates' &&
|
||||
pointer.targetContext === 'negated_by'
|
||||
);
|
||||
|
||||
@ -73,10 +60,10 @@ export class NegationHelper {
|
||||
/**
|
||||
* Find all negation deltas that negate a specific delta
|
||||
*/
|
||||
static findNegationsFor(targetDeltaId: DeltaID, deltas: Delta[]): NegationDelta[] {
|
||||
static findNegationsFor(targetDeltaId: DeltaID, deltas: Delta[]): Delta[] {
|
||||
return deltas
|
||||
.filter(delta => this.isNegationDelta(delta))
|
||||
.filter(delta => this.getNegatedDeltaId(delta) === targetDeltaId) as NegationDelta[];
|
||||
.filter(delta => this.getNegatedDeltaId(delta) === targetDeltaId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,7 +139,7 @@ export class NegationHelper {
|
||||
// Create a map of delta ID to its negation status
|
||||
const deltaStatus = new Map<DeltaID, boolean>();
|
||||
// Create a map of delta ID to its negation deltas
|
||||
const deltaToNegations = new Map<DeltaID, NegationDelta[]>();
|
||||
const deltaToNegations = new Map<DeltaID, Delta[]>();
|
||||
|
||||
// First pass: collect all deltas and their negations
|
||||
for (const delta of deltas) {
|
||||
|
@ -124,10 +124,10 @@ export class Lossless {
|
||||
// Add negation delta to the entity
|
||||
// For negation deltas, we need to add them to a special property
|
||||
// since they don't directly target the entity
|
||||
let negationDeltas = ent.properties.get('_negations');
|
||||
let negationDeltas = ent.properties.get('_negates');
|
||||
if (!negationDeltas) {
|
||||
negationDeltas = new Set<Delta>();
|
||||
ent.properties.set('_negations', negationDeltas);
|
||||
ent.properties.set('_negates', negationDeltas);
|
||||
}
|
||||
negationDeltas.add(delta);
|
||||
}
|
||||
@ -363,8 +363,8 @@ export class Lossless {
|
||||
}
|
||||
|
||||
for (const [property, deltas] of ent.properties.entries()) {
|
||||
// Skip the special _negations property in the per-property stats
|
||||
if (property === '_negations') {
|
||||
// Skip the special _negates property in the per-property stats
|
||||
if (property === '_negates') {
|
||||
totalDeltas += deltas.size;
|
||||
totalNegationDeltas += deltas.size;
|
||||
continue;
|
||||
@ -398,7 +398,7 @@ export class Lossless {
|
||||
const ent = this.domainEntities.get(entityId);
|
||||
if (!ent) return [];
|
||||
|
||||
const negationProperty = ent.properties.get('_negations');
|
||||
const negationProperty = ent.properties.get('_negates');
|
||||
if (!negationProperty) return [];
|
||||
|
||||
return Array.from(negationProperty);
|
||||
|
Loading…
x
Reference in New Issue
Block a user