@sovereignbase/convergent-replicated-struct 0.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +402 -271
- package/dist/index.cjs +432 -275
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +264 -96
- package/dist/index.d.ts +264 -96
- package/dist/index.js +430 -273
- package/dist/index.js.map +1 -1
- package/package.json +87 -89
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/OOStruct/class.ts","../src/.errors/class.ts","../src/OOStruct/parseSnapshotEntryToStateEntry/index.ts","../src/OOStruct/parseStateEntryToSnapshotEntry/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from 'uuid'\nimport type {\n OOStructChange,\n OOStructDelta,\n OOStructEventListenerFor,\n OOStructEventMap,\n OOStructSnapshot,\n OOStructSnapshotEntry,\n OOStructState,\n OOStructStateEntry,\n OOStructAck,\n} from '../.types/index.js'\nimport { OOStructError } from '../.errors/class.js'\nimport { parseSnapshotEntryToStateEntry } from './parseSnapshotEntryToStateEntry/index.js'\nimport { parseStateEntryToSnapshotEntry } from './parseStateEntryToSnapshotEntry/index.js'\nimport { isUuidV7, prototype, safeStructuredClone } from '@sovereignbase/utils'\n\n/**\n * Represents an observed-overwrite struct replica.\n *\n * The struct shape is fixed by the provided default values.\n */\nexport class OOStruct<T extends Record<string, unknown>> {\n private readonly __eventTarget = new EventTarget()\n private readonly __defaults: T\n private readonly __state: OOStructState<T>\n private __live: T\n\n /**\n * Creates a replica from default values and an optional snapshot.\n *\n * @param defaults - The default field values that define the struct shape.\n * @param snapshot - An optional serialized snapshot used for hydration.\n * @throws {OOStructError} Thrown when the default values are not supported by `structuredClone`.\n */\n constructor(\n defaults: { [K in keyof T]: T[K] },\n snapshot?: OOStructSnapshot<T>\n ) {\n const [cloned, copiedDefaults] = safeStructuredClone(defaults)\n if (!cloned)\n throw new OOStructError(\n 'DEFAULTS_NOT_CLONEABLE',\n 'Default values must be supported by structuredClone.'\n )\n this.__defaults = copiedDefaults\n this.__state = {} as OOStructState<T>\n this.__live = {} as T\n\n const snapshotIsObject = snapshot && prototype(snapshot) === 'record'\n\n for (const key of Object.keys(this.__defaults)) {\n const defaultValue = this.__defaults[key as keyof T]\n if (snapshotIsObject && Object.hasOwn(snapshot, key)) {\n const valid = parseSnapshotEntryToStateEntry(\n defaultValue,\n snapshot[key as keyof T]\n )\n if (valid) {\n this.__live[key as keyof T] = valid.__value\n this.__state[key as keyof T] = valid\n continue\n }\n }\n this.__live[key as keyof T] = defaultValue\n const root = uuidv7()\n this.__state[key as keyof T] = {\n __uuidv7: uuidv7(),\n __after: root,\n __value: defaultValue,\n __overwrites: new Set([root]),\n }\n }\n }\n\n /**CRUD*/\n /**\n * Creates a new replica.\n *\n * @param defaults - The default field values that define the struct shape.\n * @param snapshot - An optional serialized snapshot used for hydration.\n * @returns A new OO-Struct replica.\n */\n static create<T extends Record<string, unknown>>(\n defaults: { [K in keyof T]: T[K] },\n snapshot?: OOStructSnapshot<T>\n ): OOStruct<T> {\n return new OOStruct(defaults, snapshot)\n }\n\n /**\n * Reads the current value of a field.\n *\n * @param key - The field key to read.\n * @returns A cloned copy of the field's current value.\n */\n read<K extends keyof T>(key: K): T[K] {\n return structuredClone(this.__live[key])\n }\n\n /**\n * Overwrites a field with a new value.\n *\n * @param key - The field key to overwrite.\n * @param value - The next value for the field.\n * @throws {OOStructError} Thrown when the value is not supported by `structuredClone`.\n * @throws {OOStructError} Thrown when the value runtime type does not match the default value runtime type.\n */\n update<K extends keyof T>(key: K, value: T[K]): void {\n const [cloned, copiedValue] = safeStructuredClone(value)\n if (!cloned)\n throw new OOStructError(\n 'VALUE_NOT_CLONEABLE',\n 'Updated values must be supported by structuredClone.'\n )\n\n if (prototype(copiedValue) !== prototype(this.__defaults[key]))\n throw new OOStructError(\n 'VALUE_TYPE_MISMATCH',\n 'Updated value must match the default value runtime type.'\n )\n const delta: OOStructDelta<T> = {}\n const change: OOStructChange<T> = {}\n delta[key] = this.overwriteAndReturnSnapshotEntry(key, copiedValue)\n change[key] = structuredClone(copiedValue)\n this.__eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n this.__eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n }\n\n /**\n * Resets one field or the entire struct back to default values.\n *\n * @param key - The optional field key to reset. When omitted, every field is reset.\n */\n delete<K extends keyof T>(key?: K): void {\n const delta: OOStructDelta<T> = {}\n const change: OOStructChange<T> = {}\n\n if (key !== undefined) {\n if (!Object.hasOwn(this.__defaults, key)) return\n const value = this.__defaults[key]\n delta[key] = this.overwriteAndReturnSnapshotEntry(key, value)\n change[key] = structuredClone(value)\n } else {\n for (const [key, value] of Object.entries(this.__defaults)) {\n delta[key as K] = this.overwriteAndReturnSnapshotEntry(\n key as K,\n value as T[K]\n )\n change[key as K] = structuredClone(value as T[K])\n }\n }\n this.__eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n this.__eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n }\n\n /**MAGS*/\n /**\n * Merges an incoming delta into the current replica.\n *\n * @param replica - The incoming partial snapshot projection to merge.\n */\n merge<K extends keyof T>(replica: OOStructDelta<T>): void {\n if (!replica || typeof replica !== 'object' || Array.isArray(replica))\n return\n\n const delta: OOStructDelta<T> = {}\n const change: OOStructChange<T> = {}\n let hasDelta = false\n let hasChange = false\n\n for (const [key, value] of Object.entries(replica)) {\n if (!Object.hasOwn(this.__state, key)) continue\n\n const candidate = parseSnapshotEntryToStateEntry(\n this.__defaults[key as K],\n value as OOStructSnapshotEntry<T[K]>\n )\n if (!candidate) continue\n\n const target = this.__state[key as K]\n const current = { ...target }\n let frontier = ''\n for (const overwrite of target.__overwrites) {\n if (frontier < overwrite) frontier = overwrite\n }\n\n for (const overwrite of candidate.__overwrites) {\n if (overwrite <= frontier || target.__overwrites.has(overwrite))\n continue\n target.__overwrites.add(overwrite)\n }\n\n if (target.__overwrites.has(candidate.__uuidv7)) continue\n\n if (current.__uuidv7 === candidate.__uuidv7) {\n if (current.__after < candidate.__after) {\n target.__value = candidate.__value\n target.__after = candidate.__after\n target.__overwrites.add(candidate.__after)\n this.__live[key as K] = candidate.__value\n change[key as K] = structuredClone(candidate.__value)\n hasChange = true\n } else {\n delta[key as K] = this.overwriteAndReturnSnapshotEntry(\n key as K,\n current.__value\n )\n hasDelta = true\n }\n continue\n }\n\n if (\n current.__uuidv7 === candidate.__after ||\n target.__overwrites.has(current.__uuidv7) ||\n candidate.__uuidv7 > current.__uuidv7\n ) {\n target.__uuidv7 = candidate.__uuidv7\n target.__value = candidate.__value\n target.__after = candidate.__after\n target.__overwrites.add(candidate.__after)\n target.__overwrites.add(current.__uuidv7)\n this.__live[key as K] = candidate.__value\n change[key as K] = structuredClone(candidate.__value)\n hasChange = true\n continue\n }\n\n target.__overwrites.add(candidate.__uuidv7)\n delta[key as K] = parseStateEntryToSnapshotEntry(target)\n hasDelta = true\n }\n if (hasDelta)\n this.__eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n if (hasChange)\n this.__eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n }\n\n /**\n * Emits the current acknowledgement frontier for each field.\n */\n acknowledge<K extends Extract<keyof T, string>>(): void {\n const ack: OOStructAck<T> = {}\n for (const [key, value] of Object.entries(this.__state)) {\n let max = ''\n for (const overwrite of (value as OOStructStateEntry<T[K]>)\n .__overwrites) {\n if (max < overwrite) max = overwrite\n }\n ack[key as K] = max\n }\n this.__eventTarget.dispatchEvent(new CustomEvent('ack', { detail: ack }))\n }\n\n /**\n * Removes overwritten identifiers that every provided frontier has acknowledged.\n *\n * @param frontiers - A collection of acknowledgement frontiers to compact against.\n */\n garbageCollect<K extends Extract<keyof T, string>>(\n frontiers: Array<OOStructAck<T>>\n ): void {\n if (!Array.isArray(frontiers) || frontiers.length < 1) return\n const smallestAcknowledgementsPerKey: OOStructAck<T> = {}\n\n for (const frontier of frontiers) {\n for (const [key, value] of Object.entries(frontier)) {\n if (!Object.hasOwn(this.__state, key) || !isUuidV7(value)) continue\n\n const current = smallestAcknowledgementsPerKey[key as K]\n if (typeof current === 'string' && current <= value) continue\n smallestAcknowledgementsPerKey[key as K] = value\n }\n }\n\n for (const [key, value] of Object.entries(smallestAcknowledgementsPerKey)) {\n const target = this.__state[key]\n const smallest = value as string\n for (const uuidv7 of target.__overwrites) {\n if (uuidv7 === target.__after || uuidv7 > smallest) continue\n target.__overwrites.delete(uuidv7)\n }\n }\n }\n\n /**\n * Emits a serialized snapshot of the current replica state.\n */\n snapshot(): void {\n const snapshot = {} as OOStructSnapshot<T>\n\n for (const [key, value] of Object.entries(this.__state)) {\n snapshot[key as keyof T] = parseStateEntryToSnapshotEntry(\n value as OOStructStateEntry<T[keyof T]>\n )\n }\n\n this.__eventTarget.dispatchEvent(\n new CustomEvent('snapshot', { detail: snapshot })\n )\n }\n\n /**ADDITIONAL*/\n\n /**\n * Returns the struct field keys.\n *\n * @returns The field keys in the current replica.\n */\n keys<K extends keyof T>(): Array<K> {\n return Object.keys(this.__live) as Array<K>\n }\n\n /**\n * Returns cloned copies of the current field values.\n *\n * @returns The current field values.\n */\n values<K extends keyof T>(): Array<T[K]> {\n return Object.values(this.__live).map((value) =>\n structuredClone(value)\n ) as Array<T[K]>\n }\n\n /**\n * Returns cloned key-value pairs for the current replica state.\n *\n * @returns The current field entries.\n */\n entries<K extends keyof T>(): Array<[K, T[K]]> {\n return Object.entries(this.__live).map(([key, value]) => [\n key as K,\n structuredClone(value as T[K]),\n ])\n }\n\n /**EVENTS*/\n\n /**\n * Registers an event listener.\n *\n * @param type - The event type to listen for.\n * @param listener - The listener to register.\n * @param options - Listener registration options.\n */\n addEventListener<K extends keyof OOStructEventMap<T>>(\n type: K,\n listener: OOStructEventListenerFor<T, K> | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n this.__eventTarget.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**\n * Removes an event listener.\n *\n * @param type - The event type to stop listening for.\n * @param listener - The listener to remove.\n * @param options - Listener removal options.\n */\n removeEventListener<K extends keyof OOStructEventMap<T>>(\n type: K,\n listener: OOStructEventListenerFor<T, K> | null,\n options?: boolean | EventListenerOptions\n ): void {\n this.__eventTarget.removeEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**HELPERS*/\n\n /**\n * Overwrites a field and returns the serialized delta entry for that overwrite.\n *\n * @param key - The field key to overwrite.\n * @param value - The next value for the field.\n * @returns The serialized snapshot entry for the new winning value.\n */\n private overwriteAndReturnSnapshotEntry<K extends keyof T>(\n key: K,\n value: T[K]\n ): OOStructSnapshotEntry<T[K]> {\n const target = this.__state[key]\n const old = { ...target }\n target.__uuidv7 = uuidv7()\n target.__value = value\n target.__after = old.__uuidv7\n target.__overwrites.add(old.__uuidv7)\n this.__live[key] = value\n return parseStateEntryToSnapshotEntry(target)\n }\n}\n","/**\n * Error codes thrown by {@link OOStruct}.\n */\nexport type OOStructErrorCode =\n | 'DEFAULTS_NOT_CLONEABLE'\n | 'VALUE_NOT_CLONEABLE'\n | 'VALUE_TYPE_MISMATCH'\n\n/**\n * Represents a typed OO-Struct runtime error.\n */\nexport class OOStructError extends Error {\n /**\n * The semantic error code for the failure.\n */\n readonly code: OOStructErrorCode\n\n /**\n * Creates a typed OO-Struct error.\n *\n * @param code - The semantic error code.\n * @param message - An optional human-readable detail message.\n */\n constructor(code: OOStructErrorCode, message?: string) {\n const detail = message ?? code\n super(`{@sovereignbase/observed-overwrite-struct} ${detail}`)\n this.code = code\n this.name = 'OOStructError'\n }\n}\n","import type {\n OOStructSnapshotEntry,\n OOStructStateEntry,\n} from '../../.types/index.js'\nimport { isUuidV7, prototype, safeStructuredClone } from '@sovereignbase/utils'\n\n/**\n * Validates and converts a serialized field entry into internal replica state.\n *\n * Invalid entries are rejected by returning `false`.\n *\n * @param defaultValue - The default value for the field used for runtime type comparison.\n * @param snapshotEntry - The serialized entry to validate and parse.\n * @returns The parsed state entry, or `false` when the entry is invalid.\n */\nexport function parseSnapshotEntryToStateEntry<V>(\n defaultValue: V,\n snapshotEntry: OOStructSnapshotEntry<V>\n): OOStructStateEntry<V> | false {\n if (\n prototype(snapshotEntry) !== 'record' ||\n !Object.hasOwn(snapshotEntry, '__value') ||\n !isUuidV7(snapshotEntry.__uuidv7) ||\n !isUuidV7(snapshotEntry.__after) ||\n !Array.isArray(snapshotEntry.__overwrites)\n )\n return false\n\n const [cloned, copiedValue] = safeStructuredClone(snapshotEntry.__value)\n if (!cloned || prototype(copiedValue) !== prototype(defaultValue))\n return false\n\n const overwrites = new Set<string>([])\n for (const overwrite of snapshotEntry.__overwrites) {\n if (\n !isUuidV7(overwrite) ||\n overwrite ===\n snapshotEntry.__uuidv7 /**if it was actually overwritten the current uuid would be different so this must be malicious*/\n )\n continue\n overwrites.add(overwrite)\n }\n\n if (!overwrites.has(snapshotEntry.__after)) return false\n\n return {\n __uuidv7: snapshotEntry.__uuidv7,\n __value: copiedValue,\n __after: snapshotEntry.__after,\n __overwrites: overwrites,\n }\n}\n","import type {\n OOStructStateEntry,\n OOStructSnapshotEntry,\n} from '../../.types/index.js'\n\n/**\n * Serializes a field state entry into a snapshot entry.\n *\n * @param stateEntry - The internal state entry to serialize.\n * @returns The serialized snapshot entry.\n */\nexport function parseStateEntryToSnapshotEntry<K>(\n stateEntry: OOStructStateEntry<K>\n): OOStructSnapshotEntry<K> {\n return {\n __uuidv7: stateEntry.__uuidv7,\n __value: structuredClone(stateEntry.__value),\n __after: stateEntry.__after,\n __overwrites: Array.from(stateEntry.__overwrites),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,MAAM,cAAc;;;ACWtB,IAAM,gBAAN,cAA4B,MAAM;AAAA;AAAA;AAAA;AAAA,EAI9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQT,YAAY,MAAyB,SAAkB;AACrD,UAAM,SAAS,WAAW;AAC1B,UAAM,8CAA8C,MAAM,EAAE;AAC5D,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;;;ACzBA,SAAS,UAAU,WAAW,2BAA2B;AAWlD,SAAS,+BACd,cACA,eAC+B;AAC/B,MACE,UAAU,aAAa,MAAM,YAC7B,CAAC,OAAO,OAAO,eAAe,SAAS,KACvC,CAAC,SAAS,cAAc,QAAQ,KAChC,CAAC,SAAS,cAAc,OAAO,KAC/B,CAAC,MAAM,QAAQ,cAAc,YAAY;AAEzC,WAAO;AAET,QAAM,CAAC,QAAQ,WAAW,IAAI,oBAAoB,cAAc,OAAO;AACvE,MAAI,CAAC,UAAU,UAAU,WAAW,MAAM,UAAU,YAAY;AAC9D,WAAO;AAET,QAAM,aAAa,oBAAI,IAAY,CAAC,CAAC;AACrC,aAAW,aAAa,cAAc,cAAc;AAClD,QACE,CAAC,SAAS,SAAS,KACnB,cACE,cAAc;AAEhB;AACF,eAAW,IAAI,SAAS;AAAA,EAC1B;AAEA,MAAI,CAAC,WAAW,IAAI,cAAc,OAAO,EAAG,QAAO;AAEnD,SAAO;AAAA,IACL,UAAU,cAAc;AAAA,IACxB,SAAS;AAAA,IACT,SAAS,cAAc;AAAA,IACvB,cAAc;AAAA,EAChB;AACF;;;ACxCO,SAAS,+BACd,YAC0B;AAC1B,SAAO;AAAA,IACL,UAAU,WAAW;AAAA,IACrB,SAAS,gBAAgB,WAAW,OAAO;AAAA,IAC3C,SAAS,WAAW;AAAA,IACpB,cAAc,MAAM,KAAK,WAAW,YAAY;AAAA,EAClD;AACF;;;AHLA,SAAS,YAAAA,WAAU,aAAAC,YAAW,uBAAAC,4BAA2B;AAOlD,IAAM,WAAN,MAAM,UAA4C;AAAA,EACtC,gBAAgB,IAAI,YAAY;AAAA,EAChC;AAAA,EACA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASR,YACE,UACA,UACA;AACA,UAAM,CAAC,QAAQ,cAAc,IAAIA,qBAAoB,QAAQ;AAC7D,QAAI,CAAC;AACH,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AACF,SAAK,aAAa;AAClB,SAAK,UAAU,CAAC;AAChB,SAAK,SAAS,CAAC;AAEf,UAAM,mBAAmB,YAAYD,WAAU,QAAQ,MAAM;AAE7D,eAAW,OAAO,OAAO,KAAK,KAAK,UAAU,GAAG;AAC9C,YAAM,eAAe,KAAK,WAAW,GAAc;AACnD,UAAI,oBAAoB,OAAO,OAAO,UAAU,GAAG,GAAG;AACpD,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,SAAS,GAAc;AAAA,QACzB;AACA,YAAI,OAAO;AACT,eAAK,OAAO,GAAc,IAAI,MAAM;AACpC,eAAK,QAAQ,GAAc,IAAI;AAC/B;AAAA,QACF;AAAA,MACF;AACA,WAAK,OAAO,GAAc,IAAI;AAC9B,YAAM,OAAO,OAAO;AACpB,WAAK,QAAQ,GAAc,IAAI;AAAA,QAC7B,UAAU,OAAO;AAAA,QACjB,SAAS;AAAA,QACT,SAAS;AAAA,QACT,cAAc,oBAAI,IAAI,CAAC,IAAI,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,OACL,UACA,UACa;AACb,WAAO,IAAI,UAAS,UAAU,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAwB,KAAc;AACpC,WAAO,gBAAgB,KAAK,OAAO,GAAG,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAA0B,KAAQ,OAAmB;AACnD,UAAM,CAAC,QAAQ,WAAW,IAAIC,qBAAoB,KAAK;AACvD,QAAI,CAAC;AACH,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAEF,QAAID,WAAU,WAAW,MAAMA,WAAU,KAAK,WAAW,GAAG,CAAC;AAC3D,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AACF,UAAM,QAA0B,CAAC;AACjC,UAAM,SAA4B,CAAC;AACnC,UAAM,GAAG,IAAI,KAAK,gCAAgC,KAAK,WAAW;AAClE,WAAO,GAAG,IAAI,gBAAgB,WAAW;AACzC,SAAK,cAAc;AAAA,MACjB,IAAI,YAAY,SAAS,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC5C;AACA,SAAK,cAAc;AAAA,MACjB,IAAI,YAAY,UAAU,EAAE,QAAQ,OAAO,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAA0B,KAAe;AACvC,UAAM,QAA0B,CAAC;AACjC,UAAM,SAA4B,CAAC;AAEnC,QAAI,QAAQ,QAAW;AACrB,UAAI,CAAC,OAAO,OAAO,KAAK,YAAY,GAAG,EAAG;AAC1C,YAAM,QAAQ,KAAK,WAAW,GAAG;AACjC,YAAM,GAAG,IAAI,KAAK,gCAAgC,KAAK,KAAK;AAC5D,aAAO,GAAG,IAAI,gBAAgB,KAAK;AAAA,IACrC,OAAO;AACL,iBAAW,CAACE,MAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,UAAU,GAAG;AAC1D,cAAMA,IAAQ,IAAI,KAAK;AAAA,UACrBA;AAAA,UACA;AAAA,QACF;AACA,eAAOA,IAAQ,IAAI,gBAAgB,KAAa;AAAA,MAClD;AAAA,IACF;AACA,SAAK,cAAc;AAAA,MACjB,IAAI,YAAY,SAAS,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC5C;AACA,SAAK,cAAc;AAAA,MACjB,IAAI,YAAY,UAAU,EAAE,QAAQ,OAAO,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAyB,SAAiC;AACxD,QAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO;AAClE;AAEF,UAAM,QAA0B,CAAC;AACjC,UAAM,SAA4B,CAAC;AACnC,QAAI,WAAW;AACf,QAAI,YAAY;AAEhB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,UAAI,CAAC,OAAO,OAAO,KAAK,SAAS,GAAG,EAAG;AAEvC,YAAM,YAAY;AAAA,QAChB,KAAK,WAAW,GAAQ;AAAA,QACxB;AAAA,MACF;AACA,UAAI,CAAC,UAAW;AAEhB,YAAM,SAAS,KAAK,QAAQ,GAAQ;AACpC,YAAM,UAAU,EAAE,GAAG,OAAO;AAC5B,UAAI,WAAW;AACf,iBAAW,aAAa,OAAO,cAAc;AAC3C,YAAI,WAAW,UAAW,YAAW;AAAA,MACvC;AAEA,iBAAW,aAAa,UAAU,cAAc;AAC9C,YAAI,aAAa,YAAY,OAAO,aAAa,IAAI,SAAS;AAC5D;AACF,eAAO,aAAa,IAAI,SAAS;AAAA,MACnC;AAEA,UAAI,OAAO,aAAa,IAAI,UAAU,QAAQ,EAAG;AAEjD,UAAI,QAAQ,aAAa,UAAU,UAAU;AAC3C,YAAI,QAAQ,UAAU,UAAU,SAAS;AACvC,iBAAO,UAAU,UAAU;AAC3B,iBAAO,UAAU,UAAU;AAC3B,iBAAO,aAAa,IAAI,UAAU,OAAO;AACzC,eAAK,OAAO,GAAQ,IAAI,UAAU;AAClC,iBAAO,GAAQ,IAAI,gBAAgB,UAAU,OAAO;AACpD,sBAAY;AAAA,QACd,OAAO;AACL,gBAAM,GAAQ,IAAI,KAAK;AAAA,YACrB;AAAA,YACA,QAAQ;AAAA,UACV;AACA,qBAAW;AAAA,QACb;AACA;AAAA,MACF;AAEA,UACE,QAAQ,aAAa,UAAU,WAC/B,OAAO,aAAa,IAAI,QAAQ,QAAQ,KACxC,UAAU,WAAW,QAAQ,UAC7B;AACA,eAAO,WAAW,UAAU;AAC5B,eAAO,UAAU,UAAU;AAC3B,eAAO,UAAU,UAAU;AAC3B,eAAO,aAAa,IAAI,UAAU,OAAO;AACzC,eAAO,aAAa,IAAI,QAAQ,QAAQ;AACxC,aAAK,OAAO,GAAQ,IAAI,UAAU;AAClC,eAAO,GAAQ,IAAI,gBAAgB,UAAU,OAAO;AACpD,oBAAY;AACZ;AAAA,MACF;AAEA,aAAO,aAAa,IAAI,UAAU,QAAQ;AAC1C,YAAM,GAAQ,IAAI,+BAA+B,MAAM;AACvD,iBAAW;AAAA,IACb;AACA,QAAI;AACF,WAAK,cAAc;AAAA,QACjB,IAAI,YAAY,SAAS,EAAE,QAAQ,MAAM,CAAC;AAAA,MAC5C;AACF,QAAI;AACF,WAAK,cAAc;AAAA,QACjB,IAAI,YAAY,UAAU,EAAE,QAAQ,OAAO,CAAC;AAAA,MAC9C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAwD;AACtD,UAAM,MAAsB,CAAC;AAC7B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,OAAO,GAAG;AACvD,UAAI,MAAM;AACV,iBAAW,aAAc,MACtB,cAAc;AACf,YAAI,MAAM,UAAW,OAAM;AAAA,MAC7B;AACA,UAAI,GAAQ,IAAI;AAAA,IAClB;AACA,SAAK,cAAc,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eACE,WACM;AACN,QAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,UAAU,SAAS,EAAG;AACvD,UAAM,iCAAiD,CAAC;AAExD,eAAW,YAAY,WAAW;AAChC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,YAAI,CAAC,OAAO,OAAO,KAAK,SAAS,GAAG,KAAK,CAACH,UAAS,KAAK,EAAG;AAE3D,cAAM,UAAU,+BAA+B,GAAQ;AACvD,YAAI,OAAO,YAAY,YAAY,WAAW,MAAO;AACrD,uCAA+B,GAAQ,IAAI;AAAA,MAC7C;AAAA,IACF;AAEA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,8BAA8B,GAAG;AACzE,YAAM,SAAS,KAAK,QAAQ,GAAG;AAC/B,YAAM,WAAW;AACjB,iBAAWI,WAAU,OAAO,cAAc;AACxC,YAAIA,YAAW,OAAO,WAAWA,UAAS,SAAU;AACpD,eAAO,aAAa,OAAOA,OAAM;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAiB;AACf,UAAM,WAAW,CAAC;AAElB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,OAAO,GAAG;AACvD,eAAS,GAAc,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc;AAAA,MACjB,IAAI,YAAY,YAAY,EAAE,QAAQ,SAAS,CAAC;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAoC;AAClC,WAAO,OAAO,KAAK,KAAK,MAAM;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAyC;AACvC,WAAO,OAAO,OAAO,KAAK,MAAM,EAAE;AAAA,MAAI,CAAC,UACrC,gBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAA+C;AAC7C,WAAO,OAAO,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,MACvD;AAAA,MACA,gBAAgB,KAAa;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,iBACE,MACA,UACA,SACM;AACN,SAAK,cAAc;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBACE,MACA,UACA,SACM;AACN,SAAK,cAAc;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,gCACN,KACA,OAC6B;AAC7B,UAAM,SAAS,KAAK,QAAQ,GAAG;AAC/B,UAAM,MAAM,EAAE,GAAG,OAAO;AACxB,WAAO,WAAW,OAAO;AACzB,WAAO,UAAU;AACjB,WAAO,UAAU,IAAI;AACrB,WAAO,aAAa,IAAI,IAAI,QAAQ;AACpC,SAAK,OAAO,GAAG,IAAI;AACnB,WAAO,+BAA+B,MAAM;AAAA,EAC9C;AACF;","names":["isUuidV7","prototype","safeStructuredClone","key","uuidv7"]}
|
|
1
|
+
{"version":3,"sources":["../src/.helpers/overwriteAndReturnSnapshotEntry/index.ts","../src/.helpers/parseSnapshotEntryToStateEntry/index.ts","../src/.helpers/parseStateEntryToSnapshotEntry/index.ts","../src/core/mags/merge/index.ts","../src/core/mags/acknowledge/index.ts","../src/core/mags/garbageCollect/index.ts","../src/core/mags/snapshot/index.ts","../src/core/crud/create/index.ts","../src/.errors/class.ts","../src/core/crud/read/index.ts","../src/core/crud/update/index.ts","../src/core/crud/delete/index.ts","../src/CRStruct/class.ts"],"sourcesContent":["import type {\n CRStructState,\n CRStructSnapshotEntry,\n} from '../../.types/index.js'\nimport { parseStateEntryToSnapshotEntry } from '../index.js'\nimport { v7 as uuidv7 } from 'uuid'\n/**\n * Overwrites a field and returns the serialized delta entry for that overwrite.\n *\n * @param key - The field key to overwrite.\n * @param value - The next value for the field.\n * @returns The serialized snapshot entry for the new winning value.\n */\nexport function overwriteAndReturnSnapshotEntry<\n T extends Record<string, unknown>,\n>(\n key: keyof T,\n value: T[keyof T],\n crStructReplica: CRStructState<T>\n): CRStructSnapshotEntry<T[keyof T]> {\n const target = crStructReplica.entries[key]\n const oldUuidv7 = target.uuidv7\n target.uuidv7 = uuidv7()\n target.value = value\n target.predecessor = oldUuidv7\n target.tombstones.add(oldUuidv7)\n return parseStateEntryToSnapshotEntry(target)\n}\n","import type {\n CRStructSnapshotEntry,\n CRStructStateEntry,\n} from '../../.types/index.js'\nimport { isUuidV7, prototype, safeStructuredClone } from '@sovereignbase/utils'\n\n/**\n * Validates and converts a serialized field entry into internal replica state.\n *\n * Invalid entries are rejected by returning `false`.\n *\n * @param defaultValue - The default value for the field used for runtime type comparison.\n * @param snapshotEntry - The serialized entry to validate and parse.\n * @returns The parsed state entry, or `false` when the entry is invalid.\n */\nexport function parseSnapshotEntryToStateEntry<V>(\n defaultValue: V,\n snapshotEntry: CRStructSnapshotEntry<V>\n): CRStructStateEntry<V> | false {\n if (\n prototype(snapshotEntry) !== 'record' ||\n !Object.hasOwn(snapshotEntry, 'value') ||\n !isUuidV7(snapshotEntry.uuidv7) ||\n !isUuidV7(snapshotEntry.predecessor) ||\n !Array.isArray(snapshotEntry.tombstones)\n )\n return false\n\n const [cloned, copiedValue] = safeStructuredClone(snapshotEntry.value)\n if (!cloned || prototype(copiedValue) !== prototype(defaultValue))\n return false\n\n const tombstones = new Set<string>([])\n for (const overwrite of snapshotEntry.tombstones) {\n if (\n !isUuidV7(overwrite) ||\n overwrite ===\n snapshotEntry.uuidv7 /**if it was actually overwritten the current uuid would be different so this must be malicious*/\n )\n continue\n tombstones.add(overwrite)\n }\n\n if (!tombstones.has(snapshotEntry.predecessor)) return false\n\n return {\n uuidv7: snapshotEntry.uuidv7,\n value: copiedValue,\n predecessor: snapshotEntry.predecessor,\n tombstones: tombstones,\n }\n}\n","import type {\n CRStructStateEntry,\n CRStructSnapshotEntry,\n} from '../../.types/index.js'\n\n/**\n * Serializes a field state entry into a snapshot entry.\n *\n * @param stateEntry - The internal state entry to serialize.\n * @returns The serialized snapshot entry.\n */\nexport function parseStateEntryToSnapshotEntry<K>(\n stateEntry: CRStructStateEntry<K>\n): CRStructSnapshotEntry<K> {\n return {\n uuidv7: stateEntry.uuidv7,\n value: structuredClone(stateEntry.value),\n predecessor: stateEntry.predecessor,\n tombstones: Array.from(stateEntry.tombstones),\n }\n}\n","import type {\n CRStructState,\n CRStructDelta,\n CRStructChange,\n CRStructStateEntry,\n} from '../../../.types/index.js'\nimport {\n parseSnapshotEntryToStateEntry,\n parseStateEntryToSnapshotEntry,\n overwriteAndReturnSnapshotEntry,\n} from '../../../.helpers/index.js'\n\n/**\n * Merges an incoming delta into the current replica.\n *\n * Unknown fields and invalid snapshot entries are ignored. Accepted candidates\n * extend local tombstone knowledge, may advance the current winning value, and\n * may emit a return delta when the local state already dominates the incoming\n * entry.\n *\n * @param crStructDelta - The incoming partial snapshot projection to merge.\n * @param crStructReplica - The local replica state to merge into.\n *\n * @returns\n * The visible change projection and reply delta, or `false` when the input is\n * invalid or produces no outbound effect.\n *\n * Time complexity: O(d + l + i + c), worst case O(d + l + i + c)\n *\n * d = incoming delta field count\n * l = local tombstone count processed across touched fields\n * i = incoming tombstone count processed across accepted delta entries\n * c = cloned and serialized payload size across emitted changes and reply deltas\n *\n * Space complexity: O(d + l + c)\n */\nexport function __merge<T extends Record<string, unknown>>(\n crStructDelta: CRStructDelta<T>,\n crStructReplica: CRStructState<T>\n): { change: CRStructChange<T>; delta: CRStructDelta<T> } | false {\n if (\n !crStructDelta ||\n typeof crStructDelta !== 'object' ||\n Array.isArray(crStructDelta)\n )\n return false\n\n const delta: CRStructDelta<T> = {}\n const change: CRStructChange<T> = {}\n let hasDelta = false\n let hasChange = false\n\n for (const [key, value] of Object.entries(crStructDelta)) {\n if (!Object.hasOwn(crStructReplica.defaults, key)) continue\n\n const candidate = parseSnapshotEntryToStateEntry(\n crStructReplica.defaults[key],\n value\n ) as CRStructStateEntry<T[keyof T]>\n if (!candidate) continue\n\n const target = crStructReplica.entries[key] as CRStructStateEntry<\n T[keyof T]\n >\n const current = { ...target }\n let frontier = ''\n for (const overwrite of target.tombstones) {\n if (frontier < overwrite) frontier = overwrite\n }\n\n for (const overwrite of candidate.tombstones) {\n if (overwrite <= frontier || target.tombstones.has(overwrite)) continue\n target.tombstones.add(overwrite)\n }\n\n if (target.tombstones.has(candidate.uuidv7)) continue\n\n if (current.uuidv7 === candidate.uuidv7) {\n if (current.predecessor < candidate.predecessor) {\n target.value = candidate.value\n target.predecessor = candidate.predecessor\n target.tombstones.add(candidate.predecessor)\n change[key as keyof T] = structuredClone(candidate.value)\n hasChange = true\n } else {\n delta[key as keyof T] = overwriteAndReturnSnapshotEntry(\n key,\n current.value,\n crStructReplica\n )\n hasDelta = true\n }\n continue\n }\n\n if (\n current.uuidv7 === candidate.predecessor ||\n target.tombstones.has(current.uuidv7) ||\n candidate.uuidv7 > current.uuidv7\n ) {\n target.uuidv7 = candidate.uuidv7\n target.value = candidate.value\n target.predecessor = candidate.predecessor\n target.tombstones.add(candidate.predecessor)\n target.tombstones.add(current.uuidv7)\n change[key as keyof T] = structuredClone(candidate.value)\n hasChange = true\n continue\n }\n\n target.tombstones.add(candidate.uuidv7)\n delta[key as keyof T] = parseStateEntryToSnapshotEntry(target)\n hasDelta = true\n }\n if (!hasDelta && !hasChange) return false\n return { change, delta }\n}\n","import type {\n CRStructAck,\n CRStructState,\n CRStructStateEntry,\n} from '../../../.types/index.js'\n/**\n * Emits the current acknowledgement frontier for each field.\n *\n * Each field reports the largest tombstone identifier currently known for that\n * field.\n *\n * @param crStructReplica - The replica state to summarize.\n *\n * @returns\n * An acknowledgement frontier keyed by field name.\n *\n * Time complexity: O(k + t), worst case O(k + t)\n *\n * k = replica field count\n * t = total tombstone count across all fields\n *\n * Space complexity: O(k)\n */\nexport function __acknowledge<T extends Record<string, unknown>>(\n crStructReplica: CRStructState<T>\n): CRStructAck<T> | false {\n const ack: CRStructAck<T> = {}\n for (const [key, value] of Object.entries(crStructReplica.entries)) {\n let max = ''\n for (const tombstone of (value as CRStructStateEntry<T[keyof T]>)\n .tombstones) {\n if (max < tombstone) max = tombstone\n }\n ack[key as keyof T] = max\n }\n return ack\n}\n","import { CRStructState, CRStructAck } from '../../../.types/index.js'\nimport { isUuidV7 } from '@sovereignbase/utils'\n\n/**\n * Removes overwritten identifiers that every provided frontier has acknowledged.\n *\n * The smallest valid acknowledgement per field is collected first, then local\n * tombstones at or below that frontier are removed while keeping the current\n * predecessor identifier intact.\n *\n * @param frontiers - A collection of acknowledgement frontiers to compact against.\n * @param crStructReplica - The replica state to compact.\n *\n * Time complexity: O(a + t), worst case O(a + t)\n *\n * a = acknowledgement entries scanned across all provided frontiers\n * t = tombstone count scanned across compacted fields\n *\n * Space complexity: O(k)\n *\n * k = fields that receive a valid acknowledgement frontier\n */\nexport function __garbageCollect<T extends Record<string, unknown>>(\n frontiers: Array<CRStructAck<T>>,\n crStructReplica: CRStructState<T>\n): void {\n if (!Array.isArray(frontiers) || frontiers.length < 1) return\n const smallestAcknowledgementsPerKey: CRStructAck<T> = {}\n\n for (const frontier of frontiers) {\n for (const [key, value] of Object.entries(frontier)) {\n if (!Object.hasOwn(crStructReplica.entries, key) || !isUuidV7(value))\n continue\n\n const current = smallestAcknowledgementsPerKey[key]\n if (typeof current === 'string' && current <= value) continue\n smallestAcknowledgementsPerKey[key as keyof T] = value\n }\n }\n\n for (const [key, value] of Object.entries(smallestAcknowledgementsPerKey)) {\n const target = crStructReplica.entries[key]\n const smallest = value as string\n for (const uuidv7 of target.tombstones) {\n if (uuidv7 === target.predecessor || uuidv7 > smallest) continue\n target.tombstones.delete(uuidv7)\n }\n }\n}\n","import type {\n CRStructState,\n CRStructSnapshot,\n CRStructStateEntry,\n} from '../../../.types/index.js'\nimport { parseStateEntryToSnapshotEntry } from '../../../.helpers/parseStateEntryToSnapshotEntry/index.js'\n\n/**\n * Serializes the current replica state into a snapshot projection.\n *\n * Each processed state entry is converted into its serializable snapshot form.\n *\n * @param crStructReplica - The replica state to serialize.\n *\n * @returns\n * A serializable snapshot projection of the replica state.\n *\n * Time complexity: O(k + t + c), worst case O(k + t + c)\n *\n * k = state entry count processed by the serializer\n * t = tombstone count serialized across processed entries\n * c = serialized payload size across processed values\n *\n * Space complexity: O(k + t + c)\n */\nexport function __snapshot<T extends Record<string, unknown>>(\n crStructReplica: CRStructState<T>\n): CRStructSnapshot<T> {\n const snapshot = {} as CRStructSnapshot<T>\n\n for (const [key, value] of Object.entries(crStructReplica.entries)) {\n snapshot[key as keyof T] = parseStateEntryToSnapshotEntry(\n value as CRStructStateEntry<T[keyof T]>\n )\n }\n return snapshot\n}\n","import type {\n CRStructState,\n CRStructStateEntry,\n CRStructSnapshot,\n} from '../../../.types/index.js'\nimport { safeStructuredClone, prototype } from '@sovereignbase/utils'\nimport { CRStructError } from '../../../.errors/class.js'\nimport { parseSnapshotEntryToStateEntry } from '../../../.helpers/parseSnapshotEntryToStateEntry/index.js'\nimport { v7 as uuidv7 } from 'uuid'\n\n/**\n * Creates internal CR-Struct state from default values and an optional snapshot.\n *\n * Default values define the replica field set. Compatible snapshot entries are\n * parsed into live state entries, and invalid snapshot entries are ignored so\n * the corresponding field falls back to a freshly initialized default-backed\n * entry.\n *\n * @param defaults - Default field values that define the replica shape.\n * @param snapshot - Optional serialized state used to hydrate matching fields.\n *\n * @returns\n * A hydrated internal CR-Struct state object.\n *\n * @throws {CRStructError} Thrown when the default values are not supported by `structuredClone`.\n *\n * Time complexity: O(k + c + s + t), worst case O(k + c + s + t)\n *\n * k = default field count\n * c = total cloned payload size across defaults and accepted snapshot values\n * s = snapshot entries inspected for matching fields\n * t = tombstone count materialized for accepted snapshot entries\n *\n * Space complexity: O(k + c + t)\n */\nexport function __create<T extends Record<string, unknown>>(\n defaults: T,\n snapshot?: CRStructSnapshot<T>\n): CRStructState<T> {\n const [cloned, copiedDefaults] = safeStructuredClone(defaults)\n if (!cloned)\n throw new CRStructError(\n 'DEFAULTS_NOT_CLONEABLE',\n 'Default values must be supported by structuredClone.'\n )\n const state: CRStructState<T> = {\n entries: {} as { [K in keyof T]: CRStructStateEntry<T[K]> },\n defaults: copiedDefaults,\n }\n\n const snapshotIsObject = snapshot && prototype(snapshot) === 'record'\n\n for (const key of Object.keys(defaults)) {\n const defaultValue = copiedDefaults[key as keyof T]\n if (snapshotIsObject && Object.hasOwn(snapshot, key)) {\n const valid = parseSnapshotEntryToStateEntry(\n defaultValue,\n snapshot[key as keyof T]\n )\n if (valid) {\n state.entries[key as keyof T] = valid\n continue\n }\n }\n const root = uuidv7()\n state.entries[key as keyof T] = {\n uuidv7: uuidv7(),\n predecessor: root,\n value: defaultValue,\n tombstones: new Set([root]),\n }\n }\n return state\n}\n","/**\n * Error codes thrown by {@link OOStruct}.\n */\nexport type CRStructErrorCode =\n | 'DEFAULTS_NOT_CLONEABLE'\n | 'VALUE_NOT_CLONEABLE'\n | 'VALUE_TYPE_MISMATCH'\n\n/**\n * Represents a typed CR-Struct runtime error.\n */\nexport class CRStructError extends Error {\n /**\n * The semantic error code for the failure.\n */\n readonly code: CRStructErrorCode\n\n /**\n * Creates a typed CR-Struct error.\n *\n * @param code - The semantic error code.\n * @param message - An optional human-readable detail message.\n */\n constructor(code: CRStructErrorCode, message?: string) {\n const detail = message ?? code\n super(`{@sovereignbase/convergent-replicated-struct} ${detail}`)\n this.code = code\n this.name = 'CRStructError'\n }\n}\n","import type { CRStructState } from '../../../.types/index.js'\n\n/**\n * Reads and clones the current value of a single field.\n *\n * @param key - The field key to read.\n * @param crStructReplica - The replica state that owns the field.\n *\n * @returns\n * A cloned copy of the field's current value.\n *\n * Time complexity: O(c), worst case O(c)\n *\n * c = cloned field payload size\n *\n * Space complexity: O(c)\n */\nexport function __read<T extends Record<string, unknown>>(\n key: keyof T,\n crStructReplica: CRStructState<T>\n): T[keyof T] {\n return structuredClone(crStructReplica.entries[key].value)\n}\n","import type {\n CRStructChange,\n CRStructDelta,\n CRStructState,\n} from '../../../.types/index.js'\nimport { safeStructuredClone, prototype } from '@sovereignbase/utils'\nimport { CRStructError } from '../../../.errors/class.js'\nimport { overwriteAndReturnSnapshotEntry } from '../../../.helpers/index.js'\n\n/**\n * Overwrites a field with a new value and emits the resulting projections.\n *\n * The incoming value is cloned first, validated against the default field\n * runtime type, and then written back as the current winning value for the\n * target field.\n *\n * @param key - The field key to overwrite.\n * @param value - The next value for the field.\n * @param crStructReplica - The replica state that owns the field.\n *\n * @returns\n * The visible change projection and serialized delta for the overwrite.\n *\n * @throws {CRStructError} Thrown when the value is not supported by `structuredClone`.\n * @throws {CRStructError} Thrown when the value runtime type does not match the default value runtime type.\n *\n * Time complexity: O(c + t), worst case O(c + t)\n *\n * c = cloned and serialized payload size for the updated value\n * t = tombstone count serialized for the target field\n *\n * Space complexity: O(c + t)\n */\nexport function __update<T extends Record<string, unknown>>(\n key: keyof T,\n value: T[keyof T],\n crStructReplica: CRStructState<T>\n): { change: CRStructChange<T>; delta: CRStructDelta<T> } | false {\n const [cloned, copiedValue] = safeStructuredClone(value)\n if (!cloned)\n throw new CRStructError(\n 'VALUE_NOT_CLONEABLE',\n 'Updated values must be supported by structuredClone.'\n )\n\n if (prototype(copiedValue) !== prototype(crStructReplica.defaults[key]))\n throw new CRStructError(\n 'VALUE_TYPE_MISMATCH',\n 'Updated value must match the default value runtime type.'\n )\n const delta: CRStructDelta<T> = {}\n const change: CRStructChange<T> = {}\n delta[key] = overwriteAndReturnSnapshotEntry(\n key,\n copiedValue,\n crStructReplica\n )\n change[key] = structuredClone(copiedValue)\n return { change, delta }\n}\n","import { overwriteAndReturnSnapshotEntry } from '../../../.helpers/index.js'\nimport type {\n CRStructState,\n CRStructDelta,\n CRStructChange,\n} from '../../../.types/index.js'\n\n/**\n * Resets one field or the entire struct back to default values.\n *\n * Each touched field is overwritten from the replica defaults and contributes a\n * visible change projection plus a serialized delta describing the reset.\n *\n * @param crStructReplica - The replica state to reset.\n * @param key - The optional field key to reset. When omitted, every field is reset.\n *\n * @returns\n * The visible change projection and serialized delta for the reset, or `false`\n * when a keyed reset targets a field outside the replica.\n *\n * Time complexity: O(k + c + t), worst case O(k + c + t)\n *\n * k = number of fields being reset\n * c = cloned and serialized payload size across reset field values\n * t = tombstone count serialized across reset fields\n *\n * Space complexity: O(k + c + t)\n */\nexport function __delete<T extends Record<string, unknown>>(\n crStructReplica: CRStructState<T>,\n key?: keyof T\n): { change: CRStructChange<T>; delta: CRStructDelta<T> } | false {\n const delta: CRStructDelta<T> = {}\n const change: CRStructChange<T> = {}\n\n if (key !== undefined) {\n if (!Object.hasOwn(crStructReplica.defaults, key)) return false\n const value = crStructReplica.defaults[key]\n delta[key] = overwriteAndReturnSnapshotEntry<T>(key, value, crStructReplica)\n change[key] = structuredClone(value)\n } else {\n for (const [key, value] of Object.entries(crStructReplica.defaults)) {\n delta[key as keyof T] = overwriteAndReturnSnapshotEntry<T>(\n key,\n value as T[keyof T],\n crStructReplica\n )\n change[key as keyof T] = structuredClone(value as T[keyof T])\n }\n }\n return { change, delta }\n}\n","import type {\n CRStructDelta,\n CRStructEventListenerFor,\n CRStructEventMap,\n CRStructSnapshot,\n CRStructState,\n CRStructAck,\n} from '../.types/index.js'\n\nimport {\n __merge,\n __acknowledge,\n __garbageCollect,\n __snapshot,\n} from '../core/mags/index.js'\nimport { __create, __read, __update, __delete } from '../core/crud/index.js'\n\n/**\n * Runtime implementation for a proxy-backed CR-Struct replica.\n */\nclass CRStructRaw<T extends Record<string, unknown>> {\n declare private readonly state: CRStructState<T>\n declare private readonly eventTarget: EventTarget\n\n /**\n * Creates a replica from default values and an optional snapshot.\n *\n * The struct shape is fixed by the provided default values. The returned\n * proxy exposes those fields as direct properties on the instance.\n *\n * @param defaults - The default field values that define the struct shape.\n * @param snapshot - An optional serialized snapshot used to hydrate the replica.\n * @throws {CRStructError} Thrown when the default values are not supported by `structuredClone`.\n */\n constructor(defaults: T, snapshot?: CRStructSnapshot<T>) {\n Object.defineProperties(this, {\n state: {\n value: __create<T>(defaults, snapshot),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n eventTarget: {\n value: new EventTarget(),\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n const keys = new Set(Object.keys(defaults))\n return new Proxy(this, {\n get(target, key, receiver) {\n // Preserve normal property access for unknown keys.\n if (typeof key !== 'string' || !keys.has(key))\n return Reflect.get(target, key, receiver)\n return __read(key, target.state)\n },\n has(target, key) {\n // Preserve normal property checks for unknown keys.\n if (typeof key !== 'string' || !keys.has(key))\n return Reflect.has(target, key)\n return true\n },\n set(target, key, value) {\n if (typeof key !== 'string' || !keys.has(key)) return false\n try {\n const result = __update<T>(key, value, target.state)\n /* c8 ignore next -- __update either throws or returns a result object. */\n if (!result) return false\n const { delta, change } = result\n if (delta)\n void target.eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n if (change)\n void target.eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n return true\n } catch {\n return false\n }\n },\n deleteProperty(target, key) {\n if (typeof key !== 'string' || !keys.has(key)) return false\n try {\n const result = __delete<T>(target.state, key)\n if (!result) return false\n const { delta, change } = result\n if (delta) {\n void target.eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n }\n if (change) {\n void target.eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n }\n return true\n } catch {\n return false\n }\n },\n ownKeys(target) {\n return [\n ...Reflect.ownKeys(target),\n ...Reflect.ownKeys(target.state.defaults),\n ]\n },\n getOwnPropertyDescriptor(target, key) {\n // Preserve normal property checks for unknown keys.\n if (typeof key !== 'string' || !keys.has(key))\n return Reflect.getOwnPropertyDescriptor(target, key)\n return {\n value: __read(key, target.state),\n writable: true,\n enumerable: true,\n configurable: true,\n }\n },\n })\n }\n\n /**\n * Applies a remote or local delta to the replica state.\n *\n * @param crStructDelta - The partial serialized field state to merge.\n */\n merge(crStructDelta: CRStructDelta<T>): void {\n const result = __merge<T>(crStructDelta, this.state)\n if (!result) return\n const { delta, change } = result\n if (delta) {\n void this.eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n }\n if (change) {\n void this.eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n }\n }\n\n /**\n * Emits the current acknowledgement frontier for each field.\n */\n acknowledge(): void {\n const ack = __acknowledge<T>(this.state)\n if (ack) {\n void this.eventTarget.dispatchEvent(\n new CustomEvent('ack', { detail: ack })\n )\n }\n }\n\n /**\n * Removes overwritten identifiers that every provided frontier has acknowledged.\n *\n * @param frontiers - A collection of acknowledgement frontiers to compact against.\n */\n garbageCollect(frontiers: Array<CRStructAck<T>>): void {\n void __garbageCollect<T>(frontiers, this.state)\n }\n\n /**\n * Emits a serialized snapshot of the current replica state.\n */\n snapshot(): void {\n const snapshot = __snapshot<T>(this.state)\n if (snapshot) {\n void this.eventTarget.dispatchEvent(\n new CustomEvent('snapshot', { detail: snapshot })\n )\n }\n }\n\n /**\n * Returns the struct field keys.\n *\n * @returns The field keys in the current replica.\n */\n keys<K extends keyof T>(): Array<K> {\n return Object.keys(this.state.entries) as Array<K>\n }\n\n /**\n * Resets every field in the replica back to its default value.\n */\n clear(): void {\n const result = __delete(this.state)\n if (result) {\n const { delta, change } = result\n if (delta) {\n void this.eventTarget.dispatchEvent(\n new CustomEvent('delta', { detail: delta })\n )\n }\n if (change) {\n void this.eventTarget.dispatchEvent(\n new CustomEvent('change', { detail: change })\n )\n }\n }\n }\n\n /**\n * Returns a cloned plain object view of the current replica fields.\n *\n * @returns The current field values keyed by field name.\n */\n clone(): T {\n const out = {} as T\n for (const [key, entry] of Object.entries(this.state.entries)) {\n out[key as keyof T] = structuredClone(entry.value as T[keyof T])\n }\n return out\n }\n\n /**\n * Returns cloned copies of the current field values.\n *\n * @returns The current field values.\n */\n values<K extends keyof T>(): Array<T[K]> {\n return Object.values(this.state.entries).map((entry) =>\n structuredClone(entry.value)\n ) as Array<T[K]>\n }\n\n /**\n * Returns cloned key-value pairs for the current replica state.\n *\n * @returns The current field entries.\n */\n entries<K extends keyof T>(): Array<[K, T[K]]> {\n return Object.entries(this.state.entries).map(([key, entry]) => [\n key as K,\n structuredClone(entry.value as T[K]),\n ])\n }\n\n /**\n * Returns a serializable snapshot representation of this replica.\n *\n * Called automatically by `JSON.stringify`.\n */\n toJSON(): CRStructSnapshot<T> {\n return __snapshot<T>(this.state)\n }\n /**\n * Returns this replica as a JSON string.\n */\n toString(): string {\n return JSON.stringify(this)\n }\n /**\n * Returns the Node.js console inspection representation.\n */\n [Symbol.for('nodejs.util.inspect.custom')](): CRStructSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Returns the Deno console inspection representation.\n */\n [Symbol.for('Deno.customInspect')](): CRStructSnapshot<T> {\n return this.toJSON()\n }\n /**\n * Iterates over the current live field entries.\n */\n *[Symbol.iterator](): IterableIterator<[keyof T, T[keyof T]]> {\n for (const [key, entry] of Object.entries(this.state.entries)) {\n yield [key, structuredClone(entry.value)]\n }\n }\n\n /**\n * Registers an event listener.\n *\n * @param type - The event type to listen for.\n * @param listener - The listener to register.\n * @param options - Listener registration options.\n */\n addEventListener<K extends keyof CRStructEventMap<T>>(\n type: K,\n listener: CRStructEventListenerFor<T, K> | null,\n options?: boolean | AddEventListenerOptions\n ): void {\n this.eventTarget.addEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n\n /**\n * Removes an event listener.\n *\n * @param type - The event type to stop listening for.\n * @param listener - The listener to remove.\n * @param options - Listener removal options.\n */\n removeEventListener<K extends keyof CRStructEventMap<T>>(\n type: K,\n listener: CRStructEventListenerFor<T, K> | null,\n options?: boolean | EventListenerOptions\n ): void {\n this.eventTarget.removeEventListener(\n type,\n listener as EventListenerOrEventListenerObject | null,\n options\n )\n }\n}\n\nexport type CRStruct<T extends Record<string, unknown>> = CRStructRaw<T> & T\n\nexport const CRStruct = CRStructRaw as {\n new <T extends Record<string, unknown>>(\n defaults: T,\n snapshot?: CRStructSnapshot<T>\n ): CRStruct<T>\n}\n"],"mappings":"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","names":["isUuidV7","uuidv7","safeStructuredClone","prototype","uuidv7","safeStructuredClone","prototype","safeStructuredClone","prototype","safeStructuredClone","prototype","key"]}
|
package/package.json
CHANGED
|
@@ -1,89 +1,87 @@
|
|
|
1
|
-
{
|
|
2
|
-
"type": "module",
|
|
3
|
-
"license": "Apache-2.0",
|
|
4
|
-
"name": "@sovereignbase/convergent-replicated-struct",
|
|
5
|
-
"version": "
|
|
6
|
-
"description": "
|
|
7
|
-
"keywords": [
|
|
8
|
-
"crdt",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"homepage": "https://sovereignbase.github.io/convergent-replicated-struct"
|
|
89
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"license": "Apache-2.0",
|
|
4
|
+
"name": "@sovereignbase/convergent-replicated-struct",
|
|
5
|
+
"version": "1.1.0",
|
|
6
|
+
"description": "Convergent Replicated Struct (CR-Struct), a delta CRDT for an fixed-key object structs.",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"crdt",
|
|
9
|
+
"struct",
|
|
10
|
+
"replicated",
|
|
11
|
+
"convergent",
|
|
12
|
+
"local-first",
|
|
13
|
+
"distributed-systems",
|
|
14
|
+
"delta-sync",
|
|
15
|
+
"gossip",
|
|
16
|
+
"typescript",
|
|
17
|
+
"sovereignbase"
|
|
18
|
+
],
|
|
19
|
+
"main": "./dist/index.cjs",
|
|
20
|
+
"module": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"require": "./dist/index.cjs",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"LICENSE",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"sideEffects": false,
|
|
40
|
+
"scripts": {
|
|
41
|
+
"format": "prettier . --write",
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"test": "npm run build && node test/run-coverage.mjs && node test/e2e/run.mjs",
|
|
44
|
+
"bench": "npm run build && node benchmark/bench.js",
|
|
45
|
+
"prepare": "husky",
|
|
46
|
+
"prepublishOnly": "npm run test && npm run bench"
|
|
47
|
+
},
|
|
48
|
+
"c8": {
|
|
49
|
+
"all": true,
|
|
50
|
+
"include": [
|
|
51
|
+
"dist/**/*.js"
|
|
52
|
+
],
|
|
53
|
+
"exclude": [
|
|
54
|
+
"dist/**/*.d.ts",
|
|
55
|
+
"test/**",
|
|
56
|
+
"benchmark/**",
|
|
57
|
+
"playwright.config.ts"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@commitlint/cli": "^20.5.0",
|
|
62
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
63
|
+
"@playwright/test": "^1.59.1",
|
|
64
|
+
"@types/node": "^25.5.0",
|
|
65
|
+
"c8": "^11.0.0",
|
|
66
|
+
"edge-runtime": "^4.0.1",
|
|
67
|
+
"fast-glob": "^3.3.3",
|
|
68
|
+
"husky": "^9.1.7",
|
|
69
|
+
"playwright": "^1.59.1",
|
|
70
|
+
"prettier": "^3.8.1",
|
|
71
|
+
"tsup": "^8.5.1",
|
|
72
|
+
"typescript": "^5.9.3",
|
|
73
|
+
"wrangler": "^4.79.0"
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@sovereignbase/utils": "^1.1.0",
|
|
77
|
+
"uuid": "^13.0.0"
|
|
78
|
+
},
|
|
79
|
+
"repository": {
|
|
80
|
+
"type": "git",
|
|
81
|
+
"url": "git+https://github.com/sovereignbase/convergent-replicated-struct.git"
|
|
82
|
+
},
|
|
83
|
+
"bugs": {
|
|
84
|
+
"url": "https://github.com/sovereignbase/convergent-replicated-struct/issues"
|
|
85
|
+
},
|
|
86
|
+
"homepage": "https://sovereignbase.github.io/convergent-replicated-struct"
|
|
87
|
+
}
|