type rework, updates are now Uint8Array<ArrayBuffer>

This commit is contained in:
Kevin Jahns
2025-11-18 00:26:25 +01:00
parent 5f347730f9
commit a4aa2f87bf
9 changed files with 28 additions and 22 deletions

View File

@@ -212,7 +212,7 @@ export class Doc extends ObservableV2 {
* Define all types right after the Y.Doc instance is created and store them in a separate object.
* Also use the typed methods `getText(name)`, `getArray(name)`, ..
*
* @template {YTypeConstructors} TypeC
* @template {YTypeConstructors} [TypeC=typeof AbstractType]
* @example
* const ydoc = new Y.Doc(..)
* const appState = {
@@ -222,7 +222,7 @@ export class Doc extends ObservableV2 {
*
* @param {string} name
* @param {TypeC} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ...
* @return {InstanceType<TypeC>} The created type. Constructed with TypeConstructor
* @return {AbstractType} The created type. Constructed with TypeConstructor
*
* @public
*/
@@ -279,7 +279,7 @@ export class Doc extends ObservableV2 {
* @public
*/
getText (name = '') {
return this.get(name, YText)
return /** @type {YText} */ (this.get(name, YText))
}
/**
@@ -310,7 +310,7 @@ export class Doc extends ObservableV2 {
* @public
*/
getXmlFragment (name = '') {
return this.get(name, YXmlFragment)
return /** @type {YXmlFragment} */ (this.get(name, YXmlFragment))
}
/**

View File

@@ -736,7 +736,7 @@ export const readIdSet = decoder => {
* @param {DSDecoderV1 | DSDecoderV2} decoder
* @param {Transaction} transaction
* @param {StructStore} store
* @return {Uint8Array|null} Returns a v2 update containing all deletes that couldn't be applied yet; or null if all deletes were applied successfully.
* @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.
*
* @private
* @function

View File

@@ -20,11 +20,11 @@ export class StructStore {
this.clients = new Map()
// this.ds = new IdSet()
/**
* @type {null | { missing: Map<number, number>, update: Uint8Array }}
* @type {null | { missing: Map<number, number>, update: Uint8Array<ArrayBuffer> }}
*/
this.pendingStructs = null
/**
* @type {null | Uint8Array}
* @type {null | Uint8Array<ArrayBuffer>}
*/
this.pendingDs = null
this.skips = createIdSet()

View File

@@ -181,7 +181,7 @@ export const writeStructsFromIdSet = (encoder, store, idset) => {
* @param {Transaction} transaction
* @param {StructStore} store
* @param {StructSet} clientsStructRefs
* @return { null | { update: Uint8Array, missing: Map<number,number> } }
* @return { null | { update: Uint8Array<ArrayBuffer>, missing: Map<number,number> } }
*
* @private
* @function
@@ -501,9 +501,6 @@ export const writeStateAsUpdate = (encoder, doc, targetStateVector = new Map())
export const encodeStateAsUpdateV2 = (doc, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => {
const targetStateVector = decodeStateVector(encodedTargetStateVector)
writeStateAsUpdate(encoder, doc, targetStateVector)
/**
* @type {Uint8Array<ArrayBufferLike>[]}
*/
const updates = [encoder.toUint8Array()]
// also add the pending updates (if there are any)
if (doc.store.pendingDs) {

View File

@@ -17,5 +17,12 @@
*/
/**
* @typedef {typeof import('../types/AbstractType.js').AbstractType<any,any>} YTypeConstructors
* @typedef {typeof import('../types/YArray.js').YArray<any>
* | typeof import('../types/YMap.js').YMap<any>
* | typeof import('../types/YText.js').YText<any>
* | typeof import('../types/YXmlFragment.js').YXmlFragment<any,any>
* | typeof import('../types/YXmlElement.js').YXmlElement<any,any>
* | typeof import('../types/YXmlHook.js').YXmlHook
* | typeof import('../types/YXmlText.js').YXmlText
* | typeof import('../types/AbstractType.js').AbstractType} YTypeConstructors
*/

View File

@@ -620,6 +620,7 @@ const createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {
if (type instanceof YXmlElement) {
type.nodeName = map.setIfUndefined(nodeNameCache, type.nodeName, () => 'node-' + i)
}
// @ts-ignore
if (type instanceof YXmlHook) {
type.hookName = map.setIfUndefined(nodeNameCache, type.hookName, () => 'hook-' + i)
}

View File

@@ -16,9 +16,9 @@ import {
import * as Y from '../src/index.js'
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testStructReferences = tc => {
export const testStructReferences = _tc => {
t.assert(contentRefs.length === 11)
t.assert(contentRefs[1] === readContentDeleted)
t.assert(contentRefs[2] === readContentJSON) // TODO: deprecate content json?
@@ -34,9 +34,9 @@ export const testStructReferences = tc => {
/**
* Reported here: https://github.com/yjs/yjs/issues/308
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testDiffStateVectorOfUpdateIsEmpty = tc => {
export const testDiffStateVectorOfUpdateIsEmpty = _tc => {
const ydoc = new Y.Doc()
/**
* @type {any}
@@ -53,12 +53,12 @@ export const testDiffStateVectorOfUpdateIsEmpty = tc => {
/**
* Reported here: https://github.com/yjs/yjs/issues/308
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testDiffStateVectorOfUpdateIgnoresSkips = tc => {
export const testDiffStateVectorOfUpdateIgnoresSkips = _tc => {
const ydoc = new Y.Doc()
/**
* @type {Array<Uint8Array>}
* @type {Array<Uint8Array<ArrayBuffer>>}
*/
const updates = []
ydoc.on('update', update => {

View File

@@ -87,11 +87,11 @@ export class TestYInstance extends Y.Doc {
/**
* The list of received updates.
* We are going to merge them later using Y.mergeUpdates and check if the resulting document is correct.
* @type {Array<Uint8Array>}
* @type {Array<Uint8Array<ArrayBuffer>>}
*/
this.updates = []
// set up observe on local model
this.on(enc.updateEventName, /** @param {Uint8Array} update @param {any} origin */ (update, origin) => {
this.on(enc.updateEventName, (update, origin) => {
if (origin !== testConnector) {
const encoder = encoding.createEncoder()
syncProtocol.writeUpdate(encoder, update)
@@ -460,6 +460,7 @@ export const compare = users => {
users.push(.../** @type {any} */(mergedDocs))
const userArrayValues = users.map(u => u.getArray('array').toJSON())
const userMapValues = users.map(u => u.getMap('map').toJSON())
const q = users[0].get('xml', Y.XmlElement)
const userXmlValues = users.map(u => /** @type {Y.XmlElement} */ (u.get('xml', Y.XmlElement)).toString())
const userTextValues = users.map(u => u.getText('text').getContentDeep())
for (const u of users) {

View File

@@ -1735,7 +1735,7 @@ export const testLargeFragmentedDocument = _tc => {
*/
export const testIncrementalUpdatesPerformanceOnLargeFragmentedDocument = _tc => {
const itemsToInsert = largeDocumentSize
const updates = /** @type {Array<Uint8Array>} */ ([])
const updates = /** @type {Array<Uint8Array<ArrayBuffer>>} */ ([])
;(() => {
const doc1 = new Y.Doc()
doc1.on('update', update => {