From 157359a07be6559a2dbb2209bfeb001321fa1666 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Wed, 17 Dec 2025 16:17:28 +0100 Subject: [PATCH 1/3] refactor: minor cleanup of duplicate function --- src/utils/IdMap.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/utils/IdMap.js b/src/utils/IdMap.js index 96590e92..8efab82b 100644 --- a/src/utils/IdMap.js +++ b/src/utils/IdMap.js @@ -37,16 +37,6 @@ export class AttributionItem { } } -/** - * @param {AttributionItem} attr - */ -const _hashAttribution = attr => { - const encoder = encoding.createEncoder() - encoding.writeVarString(encoder, attr.name) - encoding.writeAny(encoder, attr.val) - return buf.toBase64(rabin.fingerprint(rabin.StandardIrreducible128, encoding.toUint8Array(encoder))) -} - /** * @todo rename this to `createAttribute` * @template V @@ -596,7 +586,7 @@ export const decodeIdMap = data => readIdMap(new DSDecoderV2(decoding.createDeco const _ensureAttrs = (idmap, attrs) => attrs.map(attr => idmap.attrs.has(attr) ? attr - : map.setIfUndefined(idmap.attrsH, _hashAttribution(attr), () => { + : map.setIfUndefined(idmap.attrsH, attr.hash(), () => { idmap.attrs.add(attr) return attr })) From ca7c98fa35b63804c12617e372ddf9638e4b0393 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Wed, 17 Dec 2025 16:20:46 +0100 Subject: [PATCH 2/3] feat: support attributing the content for `DiffAttributionManager` & `SnapshotAttributionManager` --- src/utils/AttributionManager.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/utils/AttributionManager.js b/src/utils/AttributionManager.js index 3bfb4278..04fddf5c 100644 --- a/src/utils/AttributionManager.js +++ b/src/utils/AttributionManager.js @@ -349,15 +349,16 @@ export class DiffAttributionManager extends ObservableV2 { /** * @param {Doc} prevDoc * @param {Doc} nextDoc + * @param {Array>} [attrs] - the attributes to apply to the diff */ - constructor (prevDoc, nextDoc) { + constructor (prevDoc, nextDoc, attrs = [createAttributionItem('change', '')]) { super() const _nextDocInserts = createInsertSetFromStructStore(nextDoc.store, false) // unmaintained const _prevDocInserts = createInsertSetFromStructStore(prevDoc.store, false) // unmaintained const nextDocDeletes = createDeleteSetFromStructStore(nextDoc.store) // maintained const prevDocDeletes = createDeleteSetFromStructStore(prevDoc.store) // maintained - this.inserts = createIdMapFromIdSet(diffIdSet(_nextDocInserts, _prevDocInserts), []) - this.deletes = createIdMapFromIdSet(diffIdSet(nextDocDeletes, prevDocDeletes), []) + this.inserts = createIdMapFromIdSet(diffIdSet(_nextDocInserts, _prevDocInserts), attrs) + this.deletes = createIdMapFromIdSet(diffIdSet(nextDocDeletes, prevDocDeletes), attrs) this._prevDoc = prevDoc this._prevDocStore = prevDoc.store this._nextDoc = nextDoc @@ -365,10 +366,10 @@ export class DiffAttributionManager extends ObservableV2 { this._nextBOH = nextDoc.on('beforeObserverCalls', tr => { // update inserts const diffInserts = diffIdSet(tr.insertSet, _prevDocInserts) - insertIntoIdMap(this.inserts, createIdMapFromIdSet(diffInserts, [])) + insertIntoIdMap(this.inserts, createIdMapFromIdSet(diffInserts, attrs)) // update deletes const diffDeletes = diffIdSet(diffIdSet(tr.deleteSet, prevDocDeletes), this.inserts) - insertIntoIdMap(this.deletes, createIdMapFromIdSet(diffDeletes, [])) + insertIntoIdMap(this.deletes, createIdMapFromIdSet(diffDeletes, attrs)) // @todo fire update ranges on `diffInserts` and `diffDeletes` }) this._prevBOH = prevDoc.on('beforeObserverCalls', tr => { @@ -538,8 +539,9 @@ export class DiffAttributionManager extends ObservableV2 { * * @param {Doc} prevDoc * @param {Doc} nextDoc + * @param {Array>} [attrs] - the attributes to apply to the diff */ -export const createAttributionManagerFromDiff = (prevDoc, nextDoc) => new DiffAttributionManager(prevDoc, nextDoc) +export const createAttributionManagerFromDiff = (prevDoc, nextDoc, attrs) => new DiffAttributionManager(prevDoc, nextDoc, attrs) /** * Intended for projects that used the v13 snapshot feature. With this AttributionManager you can @@ -553,17 +555,18 @@ export class SnapshotAttributionManager extends ObservableV2 { /** * @param {Snapshot} prevSnapshot * @param {Snapshot} nextSnapshot + * @param {Array>} [attrs] */ - constructor (prevSnapshot, nextSnapshot) { + constructor (prevSnapshot, nextSnapshot, attrs = [createAttributionItem('change', '')]) { super() this.prevSnapshot = prevSnapshot this.nextSnapshot = nextSnapshot const inserts = createIdMap() - const deletes = createIdMapFromIdSet(diffIdSet(nextSnapshot.ds, prevSnapshot.ds), [createAttributionItem('change', '')]) + const deletes = createIdMapFromIdSet(diffIdSet(nextSnapshot.ds, prevSnapshot.ds), attrs) nextSnapshot.sv.forEach((clock, client) => { const prevClock = prevSnapshot.sv.get(client) || 0 inserts.add(client, 0, prevClock, []) // content is included in prevSnapshot is rendered without attributes - inserts.add(client, prevClock, clock - prevClock, [createAttributionItem('change', '')]) // content is rendered as "inserted" + inserts.add(client, prevClock, clock - prevClock, attrs) // content is rendered as "inserted" }) this.attrs = mergeIdMaps([diffIdMap(inserts, prevSnapshot.ds), deletes]) } @@ -615,5 +618,6 @@ export class SnapshotAttributionManager extends ObservableV2 { /** * @param {Snapshot} prevSnapshot * @param {Snapshot} nextSnapshot + * @param {Array>} [attrs] */ -export const createAttributionManagerFromSnapshots = (prevSnapshot, nextSnapshot = prevSnapshot) => new SnapshotAttributionManager(prevSnapshot, nextSnapshot) +export const createAttributionManagerFromSnapshots = (prevSnapshot, nextSnapshot = prevSnapshot, attrs) => new SnapshotAttributionManager(prevSnapshot, nextSnapshot, attrs) From 48fc7e494c8b5707f4f3a0b1083c452a1efb9f71 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Wed, 17 Dec 2025 16:42:03 +0100 Subject: [PATCH 3/3] fix: remove default attributions --- src/utils/AttributionManager.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/utils/AttributionManager.js b/src/utils/AttributionManager.js index 04fddf5c..f74e368f 100644 --- a/src/utils/AttributionManager.js +++ b/src/utils/AttributionManager.js @@ -9,7 +9,6 @@ import { insertIntoIdSet, diffIdMap, createIdMap, - createAttributionItem, mergeIdMaps, createID, mergeIdSets, @@ -349,9 +348,10 @@ export class DiffAttributionManager extends ObservableV2 { /** * @param {Doc} prevDoc * @param {Doc} nextDoc - * @param {Array>} [attrs] - the attributes to apply to the diff + * @param {Object} [options] - options for the attribution manager + * @param {Array>} [options.attrs] - the attributes to apply to the diff */ - constructor (prevDoc, nextDoc, attrs = [createAttributionItem('change', '')]) { + constructor (prevDoc, nextDoc, { attrs = [] } = {}) { super() const _nextDocInserts = createInsertSetFromStructStore(nextDoc.store, false) // unmaintained const _prevDocInserts = createInsertSetFromStructStore(prevDoc.store, false) // unmaintained @@ -539,9 +539,10 @@ export class DiffAttributionManager extends ObservableV2 { * * @param {Doc} prevDoc * @param {Doc} nextDoc - * @param {Array>} [attrs] - the attributes to apply to the diff + * @param {Object} [options] - options for the attribution manager + * @param {Array>} [options.attrs] - the attributes to apply to the diff */ -export const createAttributionManagerFromDiff = (prevDoc, nextDoc, attrs) => new DiffAttributionManager(prevDoc, nextDoc, attrs) +export const createAttributionManagerFromDiff = (prevDoc, nextDoc, options) => new DiffAttributionManager(prevDoc, nextDoc, options) /** * Intended for projects that used the v13 snapshot feature. With this AttributionManager you can @@ -555,9 +556,10 @@ export class SnapshotAttributionManager extends ObservableV2 { /** * @param {Snapshot} prevSnapshot * @param {Snapshot} nextSnapshot - * @param {Array>} [attrs] + * @param {Object} [options] - options for the attribution manager + * @param {Array>} [options.attrs] - the attributes to apply to the diff */ - constructor (prevSnapshot, nextSnapshot, attrs = [createAttributionItem('change', '')]) { + constructor (prevSnapshot, nextSnapshot, { attrs = [] } = {}) { super() this.prevSnapshot = prevSnapshot this.nextSnapshot = nextSnapshot @@ -618,6 +620,7 @@ export class SnapshotAttributionManager extends ObservableV2 { /** * @param {Snapshot} prevSnapshot * @param {Snapshot} nextSnapshot - * @param {Array>} [attrs] + * @param {Object} [options] - options for the attribution manager + * @param {Array>} [options.attrs] - the attributes to apply to the diff */ -export const createAttributionManagerFromSnapshots = (prevSnapshot, nextSnapshot = prevSnapshot, attrs) => new SnapshotAttributionManager(prevSnapshot, nextSnapshot, attrs) +export const createAttributionManagerFromSnapshots = (prevSnapshot, nextSnapshot = prevSnapshot, options) => new SnapshotAttributionManager(prevSnapshot, nextSnapshot, options)