Skip to content

Commit

Permalink
[mergeable] Change order of stamp
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesgpearce committed Apr 17, 2024
1 parent b4bf2b2 commit d51e468
Show file tree
Hide file tree
Showing 15 changed files with 3,092 additions and 3,107 deletions.
66 changes: 32 additions & 34 deletions src/mergeable-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,22 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
): Changes => {
const tablesChanges = {};
const valuesChanges = {};
const [[incomingTablesTime, tablesObj, incomingTablesHash], values] =
const [[tablesObj, incomingTablesTime, incomingTablesHash], values] =
contentOrChanges as MergeableContent;
const [tablesStampMap, valuesStampMap] = contentStampMap;
const [oldTablesTime, tableStampMaps, oldTablesHash] = tablesStampMap;
const [tableStampMaps, oldTablesTime, oldTablesHash] = tablesStampMap;

let tablesHash = hasHashes ? incomingTablesHash : oldTablesHash;
let tablesTime = incomingTablesTime;

objForEach(
tablesObj,
([incomingTableTime, rowsObj, incomingTableHash], tableId) => {
([rowsObj, incomingTableTime, incomingTableHash], tableId) => {
const tableStampMap = mapEnsure<Id, TableStampMap>(
tableStampMaps,
tableId,
stampNewMap,
);
const [oldTableTime, rowStampMaps, oldTableHash] = tableStampMap;
const [rowStampMaps, oldTableTime, oldTableHash] = tableStampMap;
let tableHash = hasHashes ? incomingTableHash : oldTableHash;
let tableTime = incomingTableTime;
objForEach(rowsObj, (row, rowId) => {
Expand Down Expand Up @@ -227,7 +226,6 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
);

seenHlc(getLatestTime(tablesTime, valuesTime));

return [tablesChanges, valuesChanges, 1];
};

Expand All @@ -237,19 +235,19 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
thingsChanges: {[thingId: Id]: Thing},
hasHashes: 0 | 1,
): [thingsTime: Time, oldThingsHash: number, newThingsHash: number] => {
const [incomingThingsTime, thingsObj, incomingThingsHash] = things;
const [oldThingsTime, thingStampMaps, oldThingsHash] = thingsStampMap;
const [thingsObj, incomingThingsTime, incomingThingsHash] = things;
const [thingStampMaps, oldThingsTime, oldThingsHash] = thingsStampMap;

let thingsTime = incomingThingsTime;
let thingsHash = hasHashes ? incomingThingsHash : oldThingsHash;

objForEach(thingsObj, ([thingTime, thing, incomingThingHash], thingId) => {
objForEach(thingsObj, ([thing, thingTime, incomingThingHash], thingId) => {
const thingStampMap = mapEnsure<Id, Stamp<Thing, true>>(
thingStampMaps,
thingId,
() => [EMPTY_STRING, undefined as any, 0],
() => [undefined as any, EMPTY_STRING, 0],
);
const [oldThingTime, , oldThingHash] = thingStampMap;
const [, oldThingTime, oldThingHash] = thingStampMap;

if (!oldThingTime || thingTime > oldThingTime) {
stampUpdate(
Expand All @@ -259,7 +257,7 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
: getHash(jsonStringWithMap(thing ?? null) + ':' + thingTime),
thingTime,
);
thingStampMap[1] = thing;
thingStampMap[0] = thing;
thingsChanges[thingId] = thing;
thingsHash ^= hasHashes
? 0
Expand Down Expand Up @@ -306,11 +304,11 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
];

const getMergeableTableHashes = (): TableHashes =>
mapToObj(contentStampMap[0][1], getStampHash);
mapToObj(contentStampMap[0][0], getStampHash);

const getMergeableTableIdsDiff = (relativeTo: TableHashes): TableIdsDiff => {
const tableIds: Ids = [];
mapForEach(contentStampMap[0][1], (tableId, [, , hash]) => {
mapForEach(contentStampMap[0][0], (tableId, [, , hash]) => {
if (hash !== relativeTo?.[tableId]) {
arrayPush(tableIds, tableId);
}
Expand All @@ -322,15 +320,15 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
objNew(
arrayMap(tablesDelta, (tableId) => [
tableId,
mapToObj(mapGet(contentStampMap[0][1], tableId)?.[1], getStampHash),
mapToObj(mapGet(contentStampMap[0][0], tableId)?.[0], getStampHash),
]),
);

const getMergeableRowIdsDiff = (relativeTo: RowHashes): RowIdsDiff =>
objMap(relativeTo, (rowHashes, tableId) => {
const rowIds: Ids = [];
mapForEach(
mapGet(contentStampMap[0][1], tableId)?.[1],
mapGet(contentStampMap[0][0], tableId)?.[0],
(rowId, [, , hash]) => {
if (hash !== rowHashes?.[rowId]) {
arrayPush(rowIds, rowId);
Expand All @@ -346,55 +344,55 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
arrayMap(rowIds, (rowId) => [
rowId,
mapToObj(
mapGet(mapGet(contentStampMap[0][1], tableId)?.[1], rowId)?.[1],
mapGet(mapGet(contentStampMap[0][0], tableId)?.[0], rowId)?.[0],
getStampHash,
),
]),
),
);

const getMergeableTablesChanges = (relativeTo: CellHashes): TablesStamp => {
const [[tablesTime, tableStampMaps]] = contentStampMap;
const tables: TablesStamp[1] = {};
const [[tableStampMaps, tablesTime]] = contentStampMap;
const tables: TablesStamp[0] = {};
objForEach(relativeTo, (rowCellHashes, tableId) =>
ifNotUndefined(
mapGet(tableStampMaps, tableId),
([tableTime, rowStampMaps]) => {
const table: TableStamp[1] = {};
([rowStampMaps, tableTime]) => {
const table: TableStamp[0] = {};
objForEach(rowCellHashes, (cellHashes, rowId) =>
ifNotUndefined(
mapGet(rowStampMaps, rowId),
([rowTime, cellStampMaps]) => {
const row: RowStamp[1] = mapToObj(
([cellStampMaps, rowTime]) => {
const row: RowStamp[0] = mapToObj(
cellStampMaps,
stampClone,
([, , hash], cellId) => hash == cellHashes?.[cellId],
);
if (!objIsEmpty(row)) {
table[rowId] = [rowTime, row];
table[rowId] = [row, rowTime];
}
},
),
);
if (!objIsEmpty(table)) {
tables[tableId] = [tableTime, table];
tables[tableId] = [table, tableTime];
}
},
),
);
return [tablesTime, tables];
return [tables, tablesTime];
};

const getMergeableValuesHashes = (): ValuesHashes =>
mapToObj(contentStampMap[1][1], getStampHash);
mapToObj(contentStampMap[1][0], getStampHash);

const getMergeableValuesChanges = (relativeTo: ValuesHashes): ValuesStamp => [
contentStampMap[1][0],
mapToObj(
contentStampMap[1][1],
contentStampMap[1][0],
stampClone,
([, , hash], valueId) => hash == relativeTo?.[valueId],
),
contentStampMap[1][1],
];

const setMergeableContent = (
Expand Down Expand Up @@ -425,21 +423,21 @@ export const createMergeableStore = ((id: Id): MergeableStore => {
: EMPTY_STRING;
const changes: MergeableChanges = [stampNewObj(), stampNewObj(), 1];

const [[, tablesObj], [, valuesObj]] = changes;
const [[tablesObj], [valuesObj]] = changes;

objToArray(changedCells, (changedTable, tableId) => {
const [, rowsObj] = (tablesObj[tableId] = stampNewObj());
const [rowsObj] = (tablesObj[tableId] = stampNewObj());
objToArray(changedTable, (changedRow, rowId) => {
const [, cellsObj] = (rowsObj[rowId] = stampNewObj());
const [cellsObj] = (rowsObj[rowId] = stampNewObj());
objToArray(
changedRow,
([, newCell], cellId) => (cellsObj[cellId] = [time, newCell]),
([, newCell], cellId) => (cellsObj[cellId] = [newCell, time]),
);
});
});
objToArray(
changedValues,
([, newValue], valueId) => (valuesObj[valueId] = [time, newValue]),
([, newValue], valueId) => (valuesObj[valueId] = [newValue, time]),
);

return changes;
Expand Down
26 changes: 13 additions & 13 deletions src/mergeable-store/stamps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ export type TableStampMap = StampMap<RowStampMap>;
export type RowStampMap = StampMap<CellStamp<true>>;
export type ValuesStampMap = StampMap<ValueStamp<true>>;

const stampCloneWithHash = <Value>([time, value, hash]: Stamp<
const stampCloneWithHash = <Value>([value, time, hash]: Stamp<
Value,
true
>): Stamp<Value, true> => [time, value, hash];
>): Stamp<Value, true> => [value, time, hash];

export const stampClone = <Value>([time, value]: Stamp<
export const stampClone = <Value>([value, time]: Stamp<
Value,
boolean
>): Stamp<Value> => [time, value];
>): Stamp<Value> => [value, time];

export const getStampHash = (stamp: Stamp<unknown, true>): Hash => stamp[2];

Expand All @@ -45,33 +45,33 @@ export const stampUpdate = (
time: Time,
) => {
stamp[2] = hash >>> 0;
if (time > stamp[0]) {
stamp[0] = time;
if (time > stamp[1]) {
stamp[1] = time;
}
};

export const stampNewObj = <Thing>(
time: Time = EMPTY_STRING,
): Stamp<IdObj<Thing>> => [time, objNew<Thing>()];
): Stamp<IdObj<Thing>> => [objNew<Thing>(), time];

export const stampNewMap = <Thing>(time = EMPTY_STRING): StampMap<Thing> => [
time,
mapNew<Id, Thing>(),
time,
0,
];

export const stampMapToObjWithHash = <From, To = From>(
[time, map, hash]: Stamp<IdMap<From>, true>,
[map, time, hash]: Stamp<IdMap<From>, true>,
mapper: (mapValue: From) => To = stampCloneWithHash as any,
): Stamp<IdObj<To>, true> => [time, mapToObj(map, mapper), hash];
): Stamp<IdObj<To>, true> => [mapToObj(map, mapper), time, hash];

export const stampValidate = (
stamp: Stamp<any, true>,
validateThing: (thing: any) => boolean,
) =>
isArray(stamp) &&
size(stamp) == 3 &&
isString(stamp[0]) &&
validateThing(stamp[1]) &&
isString(stamp[1]) &&
getTypeOf(stamp[2]) == NUMBER &&
isFiniteNumber(stamp[2]);
isFiniteNumber(stamp[2]) &&
validateThing(stamp[0]);
2 changes: 1 addition & 1 deletion src/persisters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const getStoreFunctions = (
1,
store.getMergeableContent,
store.getTransactionMergeableChanges,
([[, changedTables], [, changedValues]]: MergeableChanges) =>
([[changedTables], [changedValues]]: MergeableChanges) =>
!objIsEmpty(changedTables) || !objIsEmpty(changedValues),
store.setDefaultContent,
];
Expand Down
3 changes: 1 addition & 2 deletions src/synchronizers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export const createCustomSynchronizer = (
if (DEBUG) {
receives++;
}

if (messageType == RESPONSE) {
ifNotUndefined(
mapGet(pendingRequests, requestId),
Expand Down Expand Up @@ -180,7 +179,7 @@ export const createCustomSynchronizer = (

const getPersisted = async (): Promise<any> => {
const changes = await getChangesFromOtherStore();
return !objIsEmpty(changes[0][1]) || !objIsEmpty(changes[1][1])
return !objIsEmpty(changes[0][0]) || !objIsEmpty(changes[1][0])
? changes
: undefined;
};
Expand Down
4 changes: 2 additions & 2 deletions src/types/mergeable-store.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export type Time = string;

/// Stamp
export type Stamp<Thing, Hashed extends boolean = false> = Hashed extends true
? [time: Time, thing: Thing, hash: Hash]
: [time: Time, thing: Thing];
? [thing: Thing, time: Time, hash: Hash]
: [thing: Thing, time: Time];

// ContentHashes
export type ContentHashes = [tablesHash: Hash, valuesHash: Hash];
Expand Down
4 changes: 2 additions & 2 deletions src/types/with-schemas/mergeable-store.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export type Time = string;

/// Stamp
export type Stamp<Thing, Hashed extends boolean = false> = Hashed extends true
? [time: Time, thing: Thing, hash: Hash]
: [time: Time, thing: Thing];
? [thing: Thing, time: Time, hash: Hash]
: [thing: Thing, time: Time];

// ContentHashes
export type ContentHashes = [[tablesHash: Hash, valuesHash: Hash], time: Time];
Expand Down
4 changes: 2 additions & 2 deletions test/unit/common/mergeable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export const time = (offset: number, counter: number, storeId: string = 's1') =>
encodeHlc(START_TIME + offset, counter, STORE_ID_HASHES[storeId]);

export const stamped = (offset: number, counter: number, thing: any) => [
time(offset, counter, 's1'),
thing,
time(offset, counter, 's1'),
];

export const nullStamped = <Thing>(thing: Thing): Stamp<Thing> => ['', thing];
export const nullStamped = <Thing>(thing: Thing): Stamp<Thing> => [thing, ''];
Loading

0 comments on commit d51e468

Please sign in to comment.