mirror of
https://github.com/yjs/yjs.git
synced 2026-02-23 19:49:59 +01:00
add missing meta apis (mostly contentIds & contentMaps)
This commit is contained in:
@@ -3,7 +3,7 @@ import {
|
||||
findIndexInIdRanges,
|
||||
findRangeStartInIdRanges,
|
||||
_deleteRangeFromIdSet,
|
||||
DSDecoderV1, DSDecoderV2, IdSetEncoderV1, IdSetEncoderV2, IdSet, ID, // eslint-disable-line
|
||||
IdSetDecoderV1, IdSetDecoderV2, IdSetEncoderV1, IdSetEncoderV2, IdSet, ID, // eslint-disable-line
|
||||
_insertIntoIdSet,
|
||||
_intersectSets,
|
||||
createIdSet,
|
||||
@@ -534,7 +534,7 @@ export const encodeIdMap = idmap => {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DSDecoderV1 | DSDecoderV2} decoder
|
||||
* @param {IdSetDecoderV1 | IdSetDecoderV2} decoder
|
||||
* @return {IdMap<any>}
|
||||
*
|
||||
* @private
|
||||
@@ -596,7 +596,7 @@ export const readIdMap = decoder => {
|
||||
* @param {Uint8Array} data
|
||||
* @return {IdMap<any>}
|
||||
*/
|
||||
export const decodeIdMap = data => readIdMap(new DSDecoderV2(decoding.createDecoder(data)))
|
||||
export const decodeIdMap = data => readIdMap(new IdSetDecoderV2(decoding.createDecoder(data)))
|
||||
|
||||
/**
|
||||
* @template Attrs
|
||||
@@ -645,7 +645,7 @@ export const intersectMaps = _intersectSets
|
||||
*
|
||||
* @template Attrs
|
||||
* @param {IdMap<Attrs>} idmap
|
||||
* @param {(attr: ContentAttribute<Attrs>) => boolean} predicate
|
||||
* @param {(attr: Array<ContentAttribute<Attrs>>) => boolean} predicate
|
||||
* @return {IdMap<Attrs>}
|
||||
*/
|
||||
export const filterIdMap = (idmap, predicate) => {
|
||||
@@ -656,7 +656,7 @@ export const filterIdMap = (idmap, predicate) => {
|
||||
*/
|
||||
const attrRanges = []
|
||||
ranges.getIds().forEach((range) => {
|
||||
if (range.attrs.some(predicate)) {
|
||||
if (predicate(range.attrs)) {
|
||||
const rangeCpy = range.copyWith(range.clock, range.len)
|
||||
attrRanges.push(rangeCpy)
|
||||
rangeCpy.attrs.forEach(attr => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
IdMap,
|
||||
AttrRanges,
|
||||
AttrRange,
|
||||
Skip, AbstractStruct, DSDecoderV1, IdSetEncoderV1, DSDecoderV2, IdSetEncoderV2, Item, GC, StructStore, Transaction, ID // eslint-disable-line
|
||||
Skip, AbstractStruct, IdSetDecoderV1, IdSetEncoderV1, IdSetDecoderV2, IdSetEncoderV2, Item, GC, StructStore, Transaction, ID // eslint-disable-line
|
||||
} from '../internals.js'
|
||||
|
||||
import * as array from 'lib0/array'
|
||||
@@ -703,7 +703,7 @@ export const writeIdSet = (encoder, idSet) => {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DSDecoderV1 | DSDecoderV2} decoder
|
||||
* @param {IdSetDecoderV1 | IdSetDecoderV2} decoder
|
||||
* @return {IdSet}
|
||||
*
|
||||
* @private
|
||||
@@ -735,7 +735,7 @@ export const readIdSet = decoder => {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {DSDecoderV1 | DSDecoderV2} decoder
|
||||
* @param {IdSetDecoderV1 | IdSetDecoderV2} decoder
|
||||
* @param {Transaction} transaction
|
||||
* @param {StructStore} store
|
||||
* @return {Uint8Array<ArrayBuffer>|null} Returns a v2 update containing all deletes that couldn't be applied yet; or null if all deletes were applied successfully.
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
applyUpdateV2,
|
||||
LazyStructReader,
|
||||
equalIdSets,
|
||||
UpdateDecoderV1, UpdateDecoderV2, IdSetEncoderV1, IdSetEncoderV2, DSDecoderV1, DSDecoderV2, Transaction, Doc, IdSet, Item, // eslint-disable-line
|
||||
UpdateDecoderV1, UpdateDecoderV2, IdSetEncoderV1, IdSetEncoderV2, IdSetDecoderV1, IdSetDecoderV2, Transaction, Doc, IdSet, Item, // eslint-disable-line
|
||||
mergeIdSets
|
||||
} from '../internals.js'
|
||||
|
||||
@@ -80,10 +80,10 @@ export const encodeSnapshot = snapshot => encodeSnapshotV2(snapshot, new IdSetEn
|
||||
|
||||
/**
|
||||
* @param {Uint8Array} buf
|
||||
* @param {DSDecoderV1 | DSDecoderV2} [decoder]
|
||||
* @param {IdSetDecoderV1 | IdSetDecoderV2} [decoder]
|
||||
* @return {Snapshot}
|
||||
*/
|
||||
export const decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(decoding.createDecoder(buf))) => {
|
||||
export const decodeSnapshotV2 = (buf, decoder = new IdSetDecoderV2(decoding.createDecoder(buf))) => {
|
||||
return new Snapshot(readIdSet(decoder), readStateVector(decoder))
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export const decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(decoding.createD
|
||||
* @param {Uint8Array} buf
|
||||
* @return {Snapshot}
|
||||
*/
|
||||
export const decodeSnapshot = buf => decodeSnapshotV2(buf, new DSDecoderV1(decoding.createDecoder(buf)))
|
||||
export const decodeSnapshot = buf => decodeSnapshotV2(buf, new IdSetDecoderV1(decoding.createDecoder(buf)))
|
||||
|
||||
/**
|
||||
* @param {IdSet} ds
|
||||
|
||||
@@ -4,7 +4,11 @@ import {
|
||||
ID, createID
|
||||
} from '../internals.js'
|
||||
|
||||
export class DSDecoderV1 {
|
||||
/**
|
||||
* @typedef {IdSetDecoderV1 | IdSetDecoderV2} IdSetDecoder
|
||||
*/
|
||||
|
||||
export class IdSetDecoderV1 {
|
||||
/**
|
||||
* @param {decoding.Decoder} decoder
|
||||
*/
|
||||
@@ -31,7 +35,7 @@ export class DSDecoderV1 {
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateDecoderV1 extends DSDecoderV1 {
|
||||
export class UpdateDecoderV1 extends IdSetDecoderV1 {
|
||||
/**
|
||||
* @return {ID}
|
||||
*/
|
||||
@@ -122,7 +126,7 @@ export class UpdateDecoderV1 extends DSDecoderV1 {
|
||||
}
|
||||
}
|
||||
|
||||
export class DSDecoderV2 {
|
||||
export class IdSetDecoderV2 {
|
||||
/**
|
||||
* @param {decoding.Decoder} decoder
|
||||
*/
|
||||
@@ -156,7 +160,7 @@ export class DSDecoderV2 {
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateDecoderV2 extends DSDecoderV2 {
|
||||
export class UpdateDecoderV2 extends IdSetDecoderV2 {
|
||||
/**
|
||||
* @param {decoding.Decoder} decoder
|
||||
*/
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
UpdateEncoderV1,
|
||||
UpdateEncoderV2,
|
||||
IdSetEncoderV2,
|
||||
DSDecoderV1,
|
||||
IdSetDecoderV1,
|
||||
IdSetEncoderV1,
|
||||
mergeUpdates,
|
||||
mergeUpdatesV2,
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
readStructSet,
|
||||
removeRangesFromStructSet,
|
||||
createIdSet,
|
||||
StructSet, IdSet, DSDecoderV2, Doc, Transaction, GC, Item, StructStore, // eslint-disable-line
|
||||
StructSet, IdSet, IdSetDecoderV2, Doc, Transaction, GC, Item, StructStore, // eslint-disable-line
|
||||
createID,
|
||||
IdRange
|
||||
} from '../internals.js'
|
||||
@@ -536,7 +536,7 @@ export const encodeStateAsUpdate = (doc, encodedTargetStateVector) => encodeStat
|
||||
/**
|
||||
* Read state vector from Decoder and return as Map
|
||||
*
|
||||
* @param {DSDecoderV1 | DSDecoderV2} decoder
|
||||
* @param {IdSetDecoderV1 | IdSetDecoderV2} decoder
|
||||
* @return {Map<number,number>} Maps `client` to the number next expected `clock` from that client.
|
||||
*
|
||||
* @function
|
||||
@@ -570,7 +570,7 @@ export const readStateVector = decoder => {
|
||||
*
|
||||
* @function
|
||||
*/
|
||||
export const decodeStateVector = decodedState => readStateVector(new DSDecoderV1(decoding.createDecoder(decodedState)))
|
||||
export const decodeStateVector = decodedState => readStateVector(new IdSetDecoderV1(decoding.createDecoder(decodedState)))
|
||||
|
||||
/**
|
||||
* @param {IdSetEncoderV1 | IdSetEncoderV2} encoder
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import * as idmap from './IdMap.js'
|
||||
import * as idset from './IdSet.js'
|
||||
import { IdSetEncoderV2 } from './UpdateEncoder.js'
|
||||
import { IdSetDecoderV2 } from './UpdateDecoder.js'
|
||||
import * as decoding from 'lib0/decoding'
|
||||
|
||||
/**
|
||||
* @typedef {{ inserts: import('./IdSet.js').IdSet, deletes: import('./IdSet.js').IdSet }} ContentIds
|
||||
@@ -18,7 +20,7 @@ import { IdSetEncoderV2 } from './UpdateEncoder.js'
|
||||
* @param {import('./IdSet.js').IdSet} inserts
|
||||
* @param {import('./IdSet.js').IdSet} deletes
|
||||
*/
|
||||
export const createContentIds = (inserts, deletes) => ({ inserts, deletes })
|
||||
export const createContentIds = (inserts = idset.createIdSet(), deletes = idset.createIdSet()) => ({ inserts, deletes })
|
||||
|
||||
/**
|
||||
* @param {ContentMap} contentMap
|
||||
@@ -50,6 +52,31 @@ export const createContentIdsFromDocDiff = (ydocPrev, ydocNext) =>
|
||||
export const excludeContentIds = (content, excludeContent) =>
|
||||
createContentIds(idset.diffIdSet(content.inserts, excludeContent.inserts), idset.diffIdSet(content.deletes, excludeContent.deletes))
|
||||
|
||||
/**
|
||||
* @param {ContentMap} content
|
||||
* @param {ContentIds | ContentMap} excludeContent
|
||||
*/
|
||||
export const excludeContentMaps = (content, excludeContent) => createContentMap(
|
||||
idmap.diffIdMap(content.inserts, excludeContent.inserts),
|
||||
idmap.diffIdMap(content.deletes, excludeContent.deletes)
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {Array<ContentMap>} contents
|
||||
*/
|
||||
export const mergeContentMaps = contents => createContentMap(
|
||||
idmap.mergeIdMaps(contents.map(c => c.inserts)),
|
||||
idmap.mergeIdMaps(contents.map(c => c.deletes))
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {Array<ContentIds>} contents
|
||||
*/
|
||||
export const mergeContentIds = contents => createContentIds(
|
||||
idset.mergeIdSets(contents.map(c => c.inserts)),
|
||||
idset.mergeIdSets(contents.map(c => c.deletes))
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {import('./IdMap.js').IdMap<any>} inserts
|
||||
* @param {import('./IdMap.js').IdMap<any>} deletes
|
||||
@@ -78,7 +105,27 @@ export const writeContentIds = (encoder, contentIds) => {
|
||||
/**
|
||||
* @param {ContentIds} contentIds
|
||||
*/
|
||||
export const encodeContentIds = contentIds => writeContentIds(new IdSetEncoderV2(), contentIds)
|
||||
export const encodeContentIds = contentIds => {
|
||||
const encoder = new IdSetEncoderV2()
|
||||
writeContentIds(encoder, contentIds)
|
||||
return encoder.toUint8Array()
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo this encoding needs to be heavily optimized for production
|
||||
*
|
||||
* @param {import('./UpdateDecoder.js').IdSetDecoder} decoder
|
||||
* @return {ContentIds}
|
||||
*/
|
||||
export const readContentIds = decoder => createContentIds(
|
||||
idset.readIdSet(decoder),
|
||||
idset.readIdSet(decoder)
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {Uint8Array<any>} buf
|
||||
*/
|
||||
export const decodeContentIds = buf => readContentIds(new IdSetDecoderV2(decoding.createDecoder(buf)))
|
||||
|
||||
/**
|
||||
* @todo this encoding needs to be heavily optimized for production
|
||||
@@ -91,7 +138,54 @@ export const writeContentMap = (encoder, contentMap) => {
|
||||
idmap.writeIdMap(encoder, contentMap.deletes)
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo this encoding needs to be heavily optimized for production
|
||||
*
|
||||
* @param {import('./UpdateDecoder.js').IdSetDecoder} decoder
|
||||
* @return {ContentMap} contentMap
|
||||
*/
|
||||
export const readContentMap = (decoder) => createContentMap(
|
||||
idmap.readIdMap(decoder),
|
||||
idmap.readIdMap(decoder)
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {ContentMap} contentMap
|
||||
*/
|
||||
export const encodeContentMap = contentMap => writeContentMap(new IdSetEncoderV2(), contentMap)
|
||||
export const encodeContentMap = contentMap => {
|
||||
const encoder = new IdSetEncoderV2()
|
||||
writeContentMap(encoder, contentMap)
|
||||
return encoder.toUint8Array()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ContentMap} mapA
|
||||
* @param {ContentMap|ContentIds} mapB
|
||||
*/
|
||||
export const intersectContentMap = (mapA, mapB) => createContentMap(
|
||||
idmap.intersectMaps(mapA.inserts, mapB.inserts),
|
||||
idmap.intersectMaps(mapA.deletes, mapB.deletes)
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {ContentIds} setA
|
||||
* @param {ContentIds|ContentMap} setB
|
||||
*/
|
||||
export const intersectContentIds = (setA, setB) => createContentIds(
|
||||
idset.intersectSets(setA.inserts, setB.inserts),
|
||||
idset.intersectSets(setA.deletes, setB.deletes)
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {Uint8Array<any>} buf
|
||||
*/
|
||||
export const decodeContentMap = buf => readContentMap(new IdSetDecoderV2(decoding.createDecoder(buf)))
|
||||
|
||||
/**
|
||||
* @todo filter by array of content instead
|
||||
* @param {ContentMap} contentMap
|
||||
* @param {(c:Array<idmap.ContentAttribute<any>>)=>boolean} insertPredicate
|
||||
* @param {(c:Array<idmap.ContentAttribute<any>>)=>boolean} deletePredicate
|
||||
*/
|
||||
export const filterContentMap = (contentMap, insertPredicate, deletePredicate) => createContentMap(idmap.filterIdMap(contentMap.inserts, insertPredicate), idmap.filterIdMap(contentMap.deletes, deletePredicate))
|
||||
|
||||
|
||||
@@ -160,8 +160,8 @@ export const testAttributionSession1 = tc => {
|
||||
t.compare(d2, delta.create().insert('a').insert('b', null, { delete: ['0'] }).insert('c', null, { insert: ['1'] }))
|
||||
|
||||
const onlyUser0ChangesAttributed = {
|
||||
inserts: Y.filterIdMap(globalAttributions.inserts, attr => attr.name === 'insert' && attr.val === '0'),
|
||||
deletes: Y.filterIdMap(globalAttributions.deletes, attr => attr.name === 'delete' && attr.val === '0')
|
||||
inserts: Y.filterIdMap(globalAttributions.inserts, attrs => attrs.some(attr => attr.name === 'insert' && attr.val === '0')),
|
||||
deletes: Y.filterIdMap(globalAttributions.deletes, attrs => attrs.some(attr => attr.name === 'delete' && attr.val === '0'))
|
||||
}
|
||||
const amUser0 = new Y.TwosetAttributionManager(onlyUser0ChangesAttributed.inserts, onlyUser0ChangesAttributed.deletes)
|
||||
const d3 = text0.toDelta(amUser0)
|
||||
|
||||
Reference in New Issue
Block a user