Sid Gifari File Manager
🏠 Root
/
home2
/
meumer25
/
public_html
/
wp-includes
/
js
/
dist
/
Editing: sync.js
"use strict"; var wp; (wp ||= {}).sync = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all2) => { for (var name in all2) __defProp(target, name, { get: all2[name], enumerable: true }); }; var __copyProps = (to, from2, except, desc) => { if (from2 && typeof from2 === "object" || typeof from2 === "function") { for (let key of __getOwnPropNames(from2)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // package-external:@wordpress/private-apis var require_private_apis = __commonJS({ "package-external:@wordpress/private-apis"(exports, module) { module.exports = window.wp.privateApis; } }); // package-external:@wordpress/hooks var require_hooks = __commonJS({ "package-external:@wordpress/hooks"(exports, module) { module.exports = window.wp.hooks; } }); // package-external:@wordpress/api-fetch var require_api_fetch = __commonJS({ "package-external:@wordpress/api-fetch"(exports, module) { module.exports = window.wp.apiFetch; } }); // node_modules/fast-deep-equal/es6/index.js var require_es6 = __commonJS({ "node_modules/fast-deep-equal/es6/index.js"(exports, module) { "use strict"; module.exports = function equal(a, b) { if (a === b) return true; if (a && b && typeof a == "object" && typeof b == "object") { if (a.constructor !== b.constructor) return false; var length3, i, keys2; if (Array.isArray(a)) { length3 = a.length; if (length3 != b.length) return false; for (i = length3; i-- !== 0; ) if (!equal(a[i], b[i])) return false; return true; } if (a instanceof Map && b instanceof Map) { if (a.size !== b.size) return false; for (i of a.entries()) if (!b.has(i[0])) return false; for (i of a.entries()) if (!equal(i[1], b.get(i[0]))) return false; return true; } if (a instanceof Set && b instanceof Set) { if (a.size !== b.size) return false; for (i of a.entries()) if (!b.has(i[0])) return false; return true; } if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { length3 = a.length; if (length3 != b.length) return false; for (i = length3; i-- !== 0; ) if (a[i] !== b[i]) return false; return true; } if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); keys2 = Object.keys(a); length3 = keys2.length; if (length3 !== Object.keys(b).length) return false; for (i = length3; i-- !== 0; ) if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false; for (i = length3; i-- !== 0; ) { var key = keys2[i]; if (!equal(a[key], b[key])) return false; } return true; } return a !== a && b !== b; }; } }); // packages/sync/build-module/index.mjs var index_exports = {}; __export(index_exports, { Awareness: () => Awareness, Y: () => yjs_exports, YJS_VERSION: () => YJS_VERSION, privateApis: () => privateApis }); // node_modules/yjs/dist/yjs.mjs var yjs_exports = {}; __export(yjs_exports, { AbsolutePosition: () => AbsolutePosition, AbstractConnector: () => AbstractConnector, AbstractStruct: () => AbstractStruct, AbstractType: () => AbstractType, Array: () => YArray, ContentAny: () => ContentAny, ContentBinary: () => ContentBinary, ContentDeleted: () => ContentDeleted, ContentDoc: () => ContentDoc, ContentEmbed: () => ContentEmbed, ContentFormat: () => ContentFormat, ContentJSON: () => ContentJSON, ContentString: () => ContentString, ContentType: () => ContentType, Doc: () => Doc, GC: () => GC, ID: () => ID, Item: () => Item, Map: () => YMap, PermanentUserData: () => PermanentUserData, RelativePosition: () => RelativePosition, Skip: () => Skip, Snapshot: () => Snapshot, Text: () => YText, Transaction: () => Transaction, UndoManager: () => UndoManager, UpdateDecoderV1: () => UpdateDecoderV1, UpdateDecoderV2: () => UpdateDecoderV2, UpdateEncoderV1: () => UpdateEncoderV1, UpdateEncoderV2: () => UpdateEncoderV2, XmlElement: () => YXmlElement, XmlFragment: () => YXmlFragment, XmlHook: () => YXmlHook, XmlText: () => YXmlText, YArrayEvent: () => YArrayEvent, YEvent: () => YEvent, YMapEvent: () => YMapEvent, YTextEvent: () => YTextEvent, YXmlEvent: () => YXmlEvent, applyUpdate: () => applyUpdate, applyUpdateV2: () => applyUpdateV2, cleanupYTextFormatting: () => cleanupYTextFormatting, compareIDs: () => compareIDs, compareRelativePositions: () => compareRelativePositions, convertUpdateFormatV1ToV2: () => convertUpdateFormatV1ToV2, convertUpdateFormatV2ToV1: () => convertUpdateFormatV2ToV1, createAbsolutePositionFromRelativePosition: () => createAbsolutePositionFromRelativePosition, createDeleteSet: () => createDeleteSet, createDeleteSetFromStructStore: () => createDeleteSetFromStructStore, createDocFromSnapshot: () => createDocFromSnapshot, createID: () => createID, createRelativePositionFromJSON: () => createRelativePositionFromJSON, createRelativePositionFromTypeIndex: () => createRelativePositionFromTypeIndex, createSnapshot: () => createSnapshot, decodeRelativePosition: () => decodeRelativePosition, decodeSnapshot: () => decodeSnapshot, decodeSnapshotV2: () => decodeSnapshotV2, decodeStateVector: () => decodeStateVector, decodeUpdate: () => decodeUpdate, decodeUpdateV2: () => decodeUpdateV2, diffUpdate: () => diffUpdate, diffUpdateV2: () => diffUpdateV2, emptySnapshot: () => emptySnapshot, encodeRelativePosition: () => encodeRelativePosition, encodeSnapshot: () => encodeSnapshot, encodeSnapshotV2: () => encodeSnapshotV2, encodeStateAsUpdate: () => encodeStateAsUpdate, encodeStateAsUpdateV2: () => encodeStateAsUpdateV2, encodeStateVector: () => encodeStateVector, encodeStateVectorFromUpdate: () => encodeStateVectorFromUpdate, encodeStateVectorFromUpdateV2: () => encodeStateVectorFromUpdateV2, equalDeleteSets: () => equalDeleteSets, equalSnapshots: () => equalSnapshots, findIndexSS: () => findIndexSS, findRootTypeKey: () => findRootTypeKey, getItem: () => getItem, getItemCleanEnd: () => getItemCleanEnd, getItemCleanStart: () => getItemCleanStart, getState: () => getState, getTypeChildren: () => getTypeChildren, isDeleted: () => isDeleted, isParentOf: () => isParentOf, iterateDeletedStructs: () => iterateDeletedStructs, logType: () => logType, logUpdate: () => logUpdate, logUpdateV2: () => logUpdateV2, mergeDeleteSets: () => mergeDeleteSets, mergeUpdates: () => mergeUpdates, mergeUpdatesV2: () => mergeUpdatesV2, obfuscateUpdate: () => obfuscateUpdate, obfuscateUpdateV2: () => obfuscateUpdateV2, parseUpdateMeta: () => parseUpdateMeta, parseUpdateMetaV2: () => parseUpdateMetaV2, readUpdate: () => readUpdate, readUpdateV2: () => readUpdateV2, relativePositionToJSON: () => relativePositionToJSON, snapshot: () => snapshot, snapshotContainsUpdate: () => snapshotContainsUpdate, transact: () => transact, tryGc: () => tryGc, typeListToArraySnapshot: () => typeListToArraySnapshot, typeMapGetAllSnapshot: () => typeMapGetAllSnapshot, typeMapGetSnapshot: () => typeMapGetSnapshot }); // node_modules/lib0/map.js var create = () => /* @__PURE__ */ new Map(); var copy = (m) => { const r = create(); m.forEach((v, k) => { r.set(k, v); }); return r; }; var setIfUndefined = (map2, key, createT) => { let set = map2.get(key); if (set === void 0) { map2.set(key, set = createT()); } return set; }; var map = (m, f) => { const res = []; for (const [key, value] of m) { res.push(f(value, key)); } return res; }; var any = (m, f) => { for (const [key, value] of m) { if (f(value, key)) { return true; } } return false; }; // node_modules/lib0/set.js var create2 = () => /* @__PURE__ */ new Set(); // node_modules/lib0/array.js var last = (arr) => arr[arr.length - 1]; var appendTo = (dest, src) => { for (let i = 0; i < src.length; i++) { dest.push(src[i]); } }; var from = Array.from; var some = (arr, f) => { for (let i = 0; i < arr.length; i++) { if (f(arr[i], i, arr)) { return true; } } return false; }; var unfold = (len, f) => { const array = new Array(len); for (let i = 0; i < len; i++) { array[i] = f(i, array); } return array; }; var isArray = Array.isArray; // node_modules/lib0/observable.js var ObservableV2 = class { constructor() { this._observers = create(); } /** * @template {keyof EVENTS & string} NAME * @param {NAME} name * @param {EVENTS[NAME]} f */ on(name, f) { setIfUndefined( this._observers, /** @type {string} */ name, create2 ).add(f); return f; } /** * @template {keyof EVENTS & string} NAME * @param {NAME} name * @param {EVENTS[NAME]} f */ once(name, f) { const _f = (...args2) => { this.off( name, /** @type {any} */ _f ); f(...args2); }; this.on( name, /** @type {any} */ _f ); } /** * @template {keyof EVENTS & string} NAME * @param {NAME} name * @param {EVENTS[NAME]} f */ off(name, f) { const observers = this._observers.get(name); if (observers !== void 0) { observers.delete(f); if (observers.size === 0) { this._observers.delete(name); } } } /** * Emit a named event. All registered event listeners that listen to the * specified name will receive the event. * * @todo This should catch exceptions * * @template {keyof EVENTS & string} NAME * @param {NAME} name The event name. * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. */ emit(name, args2) { return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); } destroy() { this._observers = create(); } }; var Observable = class { constructor() { this._observers = create(); } /** * @param {N} name * @param {function} f */ on(name, f) { setIfUndefined(this._observers, name, create2).add(f); } /** * @param {N} name * @param {function} f */ once(name, f) { const _f = (...args2) => { this.off(name, _f); f(...args2); }; this.on(name, _f); } /** * @param {N} name * @param {function} f */ off(name, f) { const observers = this._observers.get(name); if (observers !== void 0) { observers.delete(f); if (observers.size === 0) { this._observers.delete(name); } } } /** * Emit a named event. All registered event listeners that listen to the * specified name will receive the event. * * @todo This should catch exceptions * * @param {N} name The event name. * @param {Array<any>} args The arguments that are applied to the event listener. */ emit(name, args2) { return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); } destroy() { this._observers = create(); } }; // node_modules/lib0/math.js var floor = Math.floor; var abs = Math.abs; var min = (a, b) => a < b ? a : b; var max = (a, b) => a > b ? a : b; var isNaN2 = Number.isNaN; var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; // node_modules/lib0/binary.js var BIT1 = 1; var BIT2 = 2; var BIT3 = 4; var BIT4 = 8; var BIT6 = 32; var BIT7 = 64; var BIT8 = 128; var BIT18 = 1 << 17; var BIT19 = 1 << 18; var BIT20 = 1 << 19; var BIT21 = 1 << 20; var BIT22 = 1 << 21; var BIT23 = 1 << 22; var BIT24 = 1 << 23; var BIT25 = 1 << 24; var BIT26 = 1 << 25; var BIT27 = 1 << 26; var BIT28 = 1 << 27; var BIT29 = 1 << 28; var BIT30 = 1 << 29; var BIT31 = 1 << 30; var BIT32 = 1 << 31; var BITS5 = 31; var BITS6 = 63; var BITS7 = 127; var BITS17 = BIT18 - 1; var BITS18 = BIT19 - 1; var BITS19 = BIT20 - 1; var BITS20 = BIT21 - 1; var BITS21 = BIT22 - 1; var BITS22 = BIT23 - 1; var BITS23 = BIT24 - 1; var BITS24 = BIT25 - 1; var BITS25 = BIT26 - 1; var BITS26 = BIT27 - 1; var BITS27 = BIT28 - 1; var BITS28 = BIT29 - 1; var BITS29 = BIT30 - 1; var BITS30 = BIT31 - 1; var BITS31 = 2147483647; // node_modules/lib0/number.js var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; var LOWEST_INT32 = 1 << 31; var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); var isNaN3 = Number.isNaN; var parseInt2 = Number.parseInt; // node_modules/lib0/string.js var fromCharCode = String.fromCharCode; var fromCodePoint = String.fromCodePoint; var MAX_UTF16_CHARACTER = fromCharCode(65535); var toLowerCase = (s) => s.toLowerCase(); var trimLeftRegex = /^\s*/g; var trimLeft = (s) => s.replace(trimLeftRegex, ""); var fromCamelCaseRegex = /([A-Z])/g; var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match) => `${separator}${toLowerCase(match)}`)); var _encodeUtf8Polyfill = (str) => { const encodedString = unescape(encodeURIComponent(str)); const len = encodedString.length; const buf = new Uint8Array(len); for (let i = 0; i < len; i++) { buf[i] = /** @type {number} */ encodedString.codePointAt(i); } return buf; }; var utf8TextEncoder = ( /** @type {TextEncoder} */ typeof TextEncoder !== "undefined" ? new TextEncoder() : null ); var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { utf8TextDecoder = null; } var repeat = (source, n) => unfold(n, () => source).join(""); // node_modules/lib0/encoding.js var Encoder = class { constructor() { this.cpos = 0; this.cbuf = new Uint8Array(100); this.bufs = []; } }; var createEncoder = () => new Encoder(); var length = (encoder) => { let len = encoder.cpos; for (let i = 0; i < encoder.bufs.length; i++) { len += encoder.bufs[i].length; } return len; }; var toUint8Array = (encoder) => { const uint8arr = new Uint8Array(length(encoder)); let curPos = 0; for (let i = 0; i < encoder.bufs.length; i++) { const d = encoder.bufs[i]; uint8arr.set(d, curPos); curPos += d.length; } uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); return uint8arr; }; var verifyLen = (encoder, len) => { const bufferLen = encoder.cbuf.length; if (bufferLen - encoder.cpos < len) { encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); encoder.cpos = 0; } }; var write = (encoder, num) => { const bufferLen = encoder.cbuf.length; if (encoder.cpos === bufferLen) { encoder.bufs.push(encoder.cbuf); encoder.cbuf = new Uint8Array(bufferLen * 2); encoder.cpos = 0; } encoder.cbuf[encoder.cpos++] = num; }; var writeUint8 = write; var writeVarUint = (encoder, num) => { while (num > BITS7) { write(encoder, BIT8 | BITS7 & num); num = floor(num / 128); } write(encoder, BITS7 & num); }; var writeVarInt = (encoder, num) => { const isNegative = isNegativeZero(num); if (isNegative) { num = -num; } write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); num = floor(num / 64); while (num > 0) { write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); num = floor(num / 128); } }; var _strBuffer = new Uint8Array(3e4); var _maxStrBSize = _strBuffer.length / 3; var _writeVarStringNative = (encoder, str) => { if (str.length < _maxStrBSize) { const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; writeVarUint(encoder, written); for (let i = 0; i < written; i++) { write(encoder, _strBuffer[i]); } } else { writeVarUint8Array(encoder, encodeUtf8(str)); } }; var _writeVarStringPolyfill = (encoder, str) => { const encodedString = unescape(encodeURIComponent(str)); const len = encodedString.length; writeVarUint(encoder, len); for (let i = 0; i < len; i++) { write( encoder, /** @type {number} */ encodedString.codePointAt(i) ); } }; var writeVarString = utf8TextEncoder && /** @type {any} */ utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; var writeBinaryEncoder = (encoder, append2) => writeUint8Array(encoder, toUint8Array(append2)); var writeUint8Array = (encoder, uint8Array) => { const bufferLen = encoder.cbuf.length; const cpos = encoder.cpos; const leftCopyLen = min(bufferLen - cpos, uint8Array.length); const rightCopyLen = uint8Array.length - leftCopyLen; encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); encoder.cpos += leftCopyLen; if (rightCopyLen > 0) { encoder.bufs.push(encoder.cbuf); encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); encoder.cpos = rightCopyLen; } }; var writeVarUint8Array = (encoder, uint8Array) => { writeVarUint(encoder, uint8Array.byteLength); writeUint8Array(encoder, uint8Array); }; var writeOnDataView = (encoder, len) => { verifyLen(encoder, len); const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); encoder.cpos += len; return dview; }; var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); var writeBigInt64 = (encoder, num) => ( /** @type {any} */ writeOnDataView(encoder, 8).setBigInt64(0, num, false) ); var floatTestBed = new DataView(new ArrayBuffer(4)); var isFloat32 = (num) => { floatTestBed.setFloat32(0, num); return floatTestBed.getFloat32(0) === num; }; var writeAny = (encoder, data) => { switch (typeof data) { case "string": write(encoder, 119); writeVarString(encoder, data); break; case "number": if (isInteger(data) && abs(data) <= BITS31) { write(encoder, 125); writeVarInt(encoder, data); } else if (isFloat32(data)) { write(encoder, 124); writeFloat32(encoder, data); } else { write(encoder, 123); writeFloat64(encoder, data); } break; case "bigint": write(encoder, 122); writeBigInt64(encoder, data); break; case "object": if (data === null) { write(encoder, 126); } else if (isArray(data)) { write(encoder, 117); writeVarUint(encoder, data.length); for (let i = 0; i < data.length; i++) { writeAny(encoder, data[i]); } } else if (data instanceof Uint8Array) { write(encoder, 116); writeVarUint8Array(encoder, data); } else { write(encoder, 118); const keys2 = Object.keys(data); writeVarUint(encoder, keys2.length); for (let i = 0; i < keys2.length; i++) { const key = keys2[i]; writeVarString(encoder, key); writeAny(encoder, data[key]); } } break; case "boolean": write(encoder, data ? 120 : 121); break; default: write(encoder, 127); } }; var RleEncoder = class extends Encoder { /** * @param {function(Encoder, T):void} writer */ constructor(writer) { super(); this.w = writer; this.s = null; this.count = 0; } /** * @param {T} v */ write(v) { if (this.s === v) { this.count++; } else { if (this.count > 0) { writeVarUint(this, this.count - 1); } this.count = 1; this.w(this, v); this.s = v; } } }; var flushUintOptRleEncoder = (encoder) => { if (encoder.count > 0) { writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); if (encoder.count > 1) { writeVarUint(encoder.encoder, encoder.count - 2); } } }; var UintOptRleEncoder = class { constructor() { this.encoder = new Encoder(); this.s = 0; this.count = 0; } /** * @param {number} v */ write(v) { if (this.s === v) { this.count++; } else { flushUintOptRleEncoder(this); this.count = 1; this.s = v; } } /** * Flush the encoded state and transform this to a Uint8Array. * * Note that this should only be called once. */ toUint8Array() { flushUintOptRleEncoder(this); return toUint8Array(this.encoder); } }; var flushIntDiffOptRleEncoder = (encoder) => { if (encoder.count > 0) { const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); writeVarInt(encoder.encoder, encodedDiff); if (encoder.count > 1) { writeVarUint(encoder.encoder, encoder.count - 2); } } }; var IntDiffOptRleEncoder = class { constructor() { this.encoder = new Encoder(); this.s = 0; this.count = 0; this.diff = 0; } /** * @param {number} v */ write(v) { if (this.diff === v - this.s) { this.s = v; this.count++; } else { flushIntDiffOptRleEncoder(this); this.count = 1; this.diff = v - this.s; this.s = v; } } /** * Flush the encoded state and transform this to a Uint8Array. * * Note that this should only be called once. */ toUint8Array() { flushIntDiffOptRleEncoder(this); return toUint8Array(this.encoder); } }; var StringEncoder = class { constructor() { this.sarr = []; this.s = ""; this.lensE = new UintOptRleEncoder(); } /** * @param {string} string */ write(string) { this.s += string; if (this.s.length > 19) { this.sarr.push(this.s); this.s = ""; } this.lensE.write(string.length); } toUint8Array() { const encoder = new Encoder(); this.sarr.push(this.s); this.s = ""; writeVarString(encoder, this.sarr.join("")); writeUint8Array(encoder, this.lensE.toUint8Array()); return toUint8Array(encoder); } }; // node_modules/lib0/error.js var create3 = (s) => new Error(s); var methodUnimplemented = () => { throw create3("Method unimplemented"); }; var unexpectedCase = () => { throw create3("Unexpected case"); }; // node_modules/lib0/decoding.js var errorUnexpectedEndOfArray = create3("Unexpected end of array"); var errorIntegerOutOfRange = create3("Integer out of Range"); var Decoder = class { /** * @param {Uint8Array} uint8Array Binary data to decode */ constructor(uint8Array) { this.arr = uint8Array; this.pos = 0; } }; var createDecoder = (uint8Array) => new Decoder(uint8Array); var hasContent = (decoder) => decoder.pos !== decoder.arr.length; var readUint8Array = (decoder, len) => { const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); decoder.pos += len; return view; }; var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); var readUint8 = (decoder) => decoder.arr[decoder.pos++]; var readVarUint = (decoder) => { let num = 0; let mult = 1; const len = decoder.arr.length; while (decoder.pos < len) { const r = decoder.arr[decoder.pos++]; num = num + (r & BITS7) * mult; mult *= 128; if (r < BIT8) { return num; } if (num > MAX_SAFE_INTEGER) { throw errorIntegerOutOfRange; } } throw errorUnexpectedEndOfArray; }; var readVarInt = (decoder) => { let r = decoder.arr[decoder.pos++]; let num = r & BITS6; let mult = 64; const sign = (r & BIT7) > 0 ? -1 : 1; if ((r & BIT8) === 0) { return sign * num; } const len = decoder.arr.length; while (decoder.pos < len) { r = decoder.arr[decoder.pos++]; num = num + (r & BITS7) * mult; mult *= 128; if (r < BIT8) { return sign * num; } if (num > MAX_SAFE_INTEGER) { throw errorIntegerOutOfRange; } } throw errorUnexpectedEndOfArray; }; var _readVarStringPolyfill = (decoder) => { let remainingLen = readVarUint(decoder); if (remainingLen === 0) { return ""; } else { let encodedString = String.fromCodePoint(readUint8(decoder)); if (--remainingLen < 100) { while (remainingLen--) { encodedString += String.fromCodePoint(readUint8(decoder)); } } else { while (remainingLen > 0) { const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); decoder.pos += nextLen; encodedString += String.fromCodePoint.apply( null, /** @type {any} */ bytes ); remainingLen -= nextLen; } } return decodeURIComponent(escape(encodedString)); } }; var _readVarStringNative = (decoder) => ( /** @type any */ utf8TextDecoder.decode(readVarUint8Array(decoder)) ); var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; var readFromDataView = (decoder, len) => { const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); decoder.pos += len; return dv; }; var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); var readBigInt64 = (decoder) => ( /** @type {any} */ readFromDataView(decoder, 8).getBigInt64(0, false) ); var readAnyLookupTable = [ (decoder) => void 0, // CASE 127: undefined (decoder) => null, // CASE 126: null readVarInt, // CASE 125: integer readFloat32, // CASE 124: float32 readFloat64, // CASE 123: float64 readBigInt64, // CASE 122: bigint (decoder) => false, // CASE 121: boolean (false) (decoder) => true, // CASE 120: boolean (true) readVarString, // CASE 119: string (decoder) => { const len = readVarUint(decoder); const obj = {}; for (let i = 0; i < len; i++) { const key = readVarString(decoder); obj[key] = readAny(decoder); } return obj; }, (decoder) => { const len = readVarUint(decoder); const arr = []; for (let i = 0; i < len; i++) { arr.push(readAny(decoder)); } return arr; }, readVarUint8Array // CASE 116: Uint8Array ]; var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); var RleDecoder = class extends Decoder { /** * @param {Uint8Array} uint8Array * @param {function(Decoder):T} reader */ constructor(uint8Array, reader) { super(uint8Array); this.reader = reader; this.s = null; this.count = 0; } read() { if (this.count === 0) { this.s = this.reader(this); if (hasContent(this)) { this.count = readVarUint(this) + 1; } else { this.count = -1; } } this.count--; return ( /** @type {T} */ this.s ); } }; var UintOptRleDecoder = class extends Decoder { /** * @param {Uint8Array} uint8Array */ constructor(uint8Array) { super(uint8Array); this.s = 0; this.count = 0; } read() { if (this.count === 0) { this.s = readVarInt(this); const isNegative = isNegativeZero(this.s); this.count = 1; if (isNegative) { this.s = -this.s; this.count = readVarUint(this) + 2; } } this.count--; return ( /** @type {number} */ this.s ); } }; var IntDiffOptRleDecoder = class extends Decoder { /** * @param {Uint8Array} uint8Array */ constructor(uint8Array) { super(uint8Array); this.s = 0; this.count = 0; this.diff = 0; } /** * @return {number} */ read() { if (this.count === 0) { const diff = readVarInt(this); const hasCount = diff & 1; this.diff = floor(diff / 2); this.count = 1; if (hasCount) { this.count = readVarUint(this) + 2; } } this.s += this.diff; this.count--; return this.s; } }; var StringDecoder = class { /** * @param {Uint8Array} uint8Array */ constructor(uint8Array) { this.decoder = new UintOptRleDecoder(uint8Array); this.str = readVarString(this.decoder); this.spos = 0; } /** * @return {string} */ read() { const end = this.spos + this.decoder.read(); const res = this.str.slice(this.spos, end); this.spos = end; return res; } }; // node_modules/lib0/webcrypto.js var subtle = crypto.subtle; var getRandomValues = crypto.getRandomValues.bind(crypto); // node_modules/lib0/random.js var uint32 = () => getRandomValues(new Uint32Array(1))[0]; var uuidv4Template = "10000000-1000-4000-8000" + -1e11; var uuidv4 = () => uuidv4Template.replace( /[018]/g, /** @param {number} c */ (c) => (c ^ uint32() & 15 >> c / 4).toString(16) ); // node_modules/lib0/time.js var getUnixTime = Date.now; // node_modules/lib0/promise.js var create4 = (f) => ( /** @type {Promise<T>} */ new Promise(f) ); var all = Promise.all.bind(Promise); // node_modules/lib0/conditions.js var undefinedToNull = (v) => v === void 0 ? null : v; // node_modules/lib0/storage.js var VarStoragePolyfill = class { constructor() { this.map = /* @__PURE__ */ new Map(); } /** * @param {string} key * @param {any} newValue */ setItem(key, newValue) { this.map.set(key, newValue); } /** * @param {string} key */ getItem(key) { return this.map.get(key); } }; var _localStorage = new VarStoragePolyfill(); var usePolyfill = true; try { if (typeof localStorage !== "undefined" && localStorage) { _localStorage = localStorage; usePolyfill = false; } } catch (e) { } var varStorage = _localStorage; // node_modules/lib0/object.js var assign = Object.assign; var keys = Object.keys; var forEach = (obj, f) => { for (const key in obj) { f(obj[key], key); } }; var length2 = (obj) => keys(obj).length; var size = (obj) => keys(obj).length; var isEmpty = (obj) => { for (const _k in obj) { return false; } return true; }; var every = (obj, f) => { for (const key in obj) { if (!f(obj[key], key)) { return false; } } return true; }; var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); var equalFlat = (a, b) => a === b || size(a) === size(b) && every(a, (val, key) => (val !== void 0 || hasProperty(b, key)) && b[key] === val); var freeze = Object.freeze; var deepFreeze = (o) => { for (const key in o) { const c = o[key]; if (typeof c === "object" || typeof c === "function") { deepFreeze(o[key]); } } return freeze(o); }; // node_modules/lib0/function.js var callAll = (fs, args2, i = 0) => { try { for (; i < fs.length; i++) { fs[i](...args2); } } finally { if (i < fs.length) { callAll(fs, args2, i + 1); } } }; var id = (a) => a; var equalityStrict = (a, b) => a === b; var equalityDeep = (a, b) => { if (a == null || b == null) { return equalityStrict(a, b); } if (a.constructor !== b.constructor) { return false; } if (a === b) { return true; } switch (a.constructor) { case ArrayBuffer: a = new Uint8Array(a); b = new Uint8Array(b); // eslint-disable-next-line no-fallthrough case Uint8Array: { if (a.byteLength !== b.byteLength) { return false; } for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) { return false; } } break; } case Set: { if (a.size !== b.size) { return false; } for (const value of a) { if (!b.has(value)) { return false; } } break; } case Map: { if (a.size !== b.size) { return false; } for (const key of a.keys()) { if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) { return false; } } break; } case Object: if (length2(a) !== length2(b)) { return false; } for (const key in a) { if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) { return false; } } break; case Array: if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!equalityDeep(a[i], b[i])) { return false; } } break; default: return false; } return true; }; var isOneOf = (value, options) => options.includes(value); // node_modules/lib0/environment.js var isNode = typeof process !== "undefined" && process.release && /node|io\.js/.test(process.release.name) && Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]"; var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; var params; var args = []; var computeParams = () => { if (params === void 0) { if (isNode) { params = create(); const pargs = process.argv; let currParamName = null; for (let i = 0; i < pargs.length; i++) { const parg = pargs[i]; if (parg[0] === "-") { if (currParamName !== null) { params.set(currParamName, ""); } currParamName = parg; } else { if (currParamName !== null) { params.set(currParamName, parg); currParamName = null; } else { args.push(parg); } } } if (currParamName !== null) { params.set(currParamName, ""); } } else if (typeof location === "object") { params = create(); (location.search || "?").slice(1).split("&").forEach((kv) => { if (kv.length !== 0) { const [key, value] = kv.split("="); params.set(`--${fromCamelCase(key, "-")}`, value); params.set(`-${fromCamelCase(key, "-")}`, value); } }); } else { params = create(); } } return params; }; var hasParam = (name) => computeParams().has(name); var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; var production = hasConf("production"); var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors !hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); // node_modules/lib0/buffer.js var createUint8ArrayFromLen = (len) => new Uint8Array(len); var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length3) => new Uint8Array(buffer, byteOffset, length3); var toBase64Browser = (bytes) => { let s = ""; for (let i = 0; i < bytes.byteLength; i++) { s += fromCharCode(bytes[i]); } return btoa(s); }; var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); var fromBase64Browser = (s) => { const a = atob(s); const bytes = createUint8ArrayFromLen(a.length); for (let i = 0; i < a.length; i++) { bytes[i] = a.charCodeAt(i); } return bytes; }; var fromBase64Node = (s) => { const buf = Buffer.from(s, "base64"); return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); }; var toBase64 = isBrowser ? toBase64Browser : toBase64Node; var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; var copyUint8Array = (uint8Array) => { const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); newBuf.set(uint8Array); return newBuf; }; // node_modules/lib0/pair.js var Pair = class { /** * @param {L} left * @param {R} right */ constructor(left, right) { this.left = left; this.right = right; } }; var create5 = (left, right) => new Pair(left, right); // node_modules/lib0/dom.js var doc = ( /** @type {Document} */ typeof document !== "undefined" ? document : {} ); var domParser = ( /** @type {DOMParser} */ typeof DOMParser !== "undefined" ? new DOMParser() : null ); var mapToStyleString = (m) => map(m, (value, key) => `${key}:${value};`).join(""); var ELEMENT_NODE = doc.ELEMENT_NODE; var TEXT_NODE = doc.TEXT_NODE; var CDATA_SECTION_NODE = doc.CDATA_SECTION_NODE; var COMMENT_NODE = doc.COMMENT_NODE; var DOCUMENT_NODE = doc.DOCUMENT_NODE; var DOCUMENT_TYPE_NODE = doc.DOCUMENT_TYPE_NODE; var DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE; // node_modules/lib0/symbol.js var create6 = Symbol; // node_modules/lib0/logging.common.js var BOLD = create6(); var UNBOLD = create6(); var BLUE = create6(); var GREY = create6(); var GREEN = create6(); var RED = create6(); var PURPLE = create6(); var ORANGE = create6(); var UNCOLOR = create6(); var computeNoColorLoggingArgs = (args2) => { if (args2.length === 1 && args2[0]?.constructor === Function) { args2 = /** @type {Array<string|Symbol|Object|number>} */ /** @type {[function]} */ args2[0](); } const strBuilder = []; const logArgs = []; let i = 0; for (; i < args2.length; i++) { const arg = args2[i]; if (arg === void 0) { break; } else if (arg.constructor === String || arg.constructor === Number) { strBuilder.push(arg); } else if (arg.constructor === Object) { break; } } if (i > 0) { logArgs.push(strBuilder.join("")); } for (; i < args2.length; i++) { const arg = args2[i]; if (!(arg instanceof Symbol)) { logArgs.push(arg); } } return logArgs; }; var lastLoggingTime = getUnixTime(); // node_modules/lib0/logging.js var _browserStyleMap = { [BOLD]: create5("font-weight", "bold"), [UNBOLD]: create5("font-weight", "normal"), [BLUE]: create5("color", "blue"), [GREEN]: create5("color", "green"), [GREY]: create5("color", "grey"), [RED]: create5("color", "red"), [PURPLE]: create5("color", "purple"), [ORANGE]: create5("color", "orange"), // not well supported in chrome when debugging node with inspector - TODO: deprecate [UNCOLOR]: create5("color", "black") }; var computeBrowserLoggingArgs = (args2) => { if (args2.length === 1 && args2[0]?.constructor === Function) { args2 = /** @type {Array<string|Symbol|Object|number>} */ /** @type {[function]} */ args2[0](); } const strBuilder = []; const styles = []; const currentStyle = create(); let logArgs = []; let i = 0; for (; i < args2.length; i++) { const arg = args2[i]; const style = _browserStyleMap[arg]; if (style !== void 0) { currentStyle.set(style.left, style.right); } else { if (arg === void 0) { break; } if (arg.constructor === String || arg.constructor === Number) { const style2 = mapToStyleString(currentStyle); if (i > 0 || style2.length > 0) { strBuilder.push("%c" + arg); styles.push(style2); } else { strBuilder.push(arg); } } else { break; } } } if (i > 0) { logArgs = styles; logArgs.unshift(strBuilder.join("")); } for (; i < args2.length; i++) { const arg = args2[i]; if (!(arg instanceof Symbol)) { logArgs.push(arg); } } return logArgs; }; var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; var print = (...args2) => { console.log(...computeLoggingArgs(args2)); vconsoles.forEach((vc) => vc.print(args2)); }; var warn = (...args2) => { console.warn(...computeLoggingArgs(args2)); args2.unshift(ORANGE); vconsoles.forEach((vc) => vc.print(args2)); }; var vconsoles = create2(); // node_modules/lib0/iterator.js var createIterator = (next) => ({ /** * @return {IterableIterator<T>} */ [Symbol.iterator]() { return this; }, // @ts-ignore next }); var iteratorFilter = (iterator, filter) => createIterator(() => { let res; do { res = iterator.next(); } while (!res.done && !filter(res.value)); return res; }); var iteratorMap = (iterator, fmap) => createIterator(() => { const { done, value } = iterator.next(); return { done, value: done ? void 0 : fmap(value) }; }); // node_modules/yjs/dist/yjs.mjs var AbstractConnector = class extends ObservableV2 { /** * @param {Doc} ydoc * @param {any} awareness */ constructor(ydoc, awareness) { super(); this.doc = ydoc; this.awareness = awareness; } }; var DeleteItem = class { /** * @param {number} clock * @param {number} len */ constructor(clock, len) { this.clock = clock; this.len = len; } }; var DeleteSet = class { constructor() { this.clients = /* @__PURE__ */ new Map(); } }; var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { const structs = ( /** @type {Array<GC|Item>} */ transaction.doc.store.clients.get(clientid) ); if (structs != null) { const lastStruct = structs[structs.length - 1]; const clockState = lastStruct.id.clock + lastStruct.length; for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) { iterateStructs(transaction, structs, del.clock, del.len, f); } } }); var findIndexDS = (dis, clock) => { let left = 0; let right = dis.length - 1; while (left <= right) { const midindex = floor((left + right) / 2); const mid = dis[midindex]; const midclock = mid.clock; if (midclock <= clock) { if (clock < midclock + mid.len) { return midindex; } left = midindex + 1; } else { right = midindex - 1; } } return null; }; var isDeleted = (ds, id2) => { const dis = ds.clients.get(id2.client); return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; }; var sortAndMergeDeleteSet = (ds) => { ds.clients.forEach((dels) => { dels.sort((a, b) => a.clock - b.clock); let i, j; for (i = 1, j = 1; i < dels.length; i++) { const left = dels[j - 1]; const right = dels[i]; if (left.clock + left.len >= right.clock) { left.len = max(left.len, right.clock + right.len - left.clock); } else { if (j < i) { dels[j] = right; } j++; } } dels.length = j; }); }; var mergeDeleteSets = (dss) => { const merged = new DeleteSet(); for (let dssI = 0; dssI < dss.length; dssI++) { dss[dssI].clients.forEach((delsLeft, client) => { if (!merged.clients.has(client)) { const dels = delsLeft.slice(); for (let i = dssI + 1; i < dss.length; i++) { appendTo(dels, dss[i].clients.get(client) || []); } merged.clients.set(client, dels); } }); } sortAndMergeDeleteSet(merged); return merged; }; var addToDeleteSet = (ds, client, clock, length3) => { setIfUndefined(ds.clients, client, () => ( /** @type {Array<DeleteItem>} */ [] )).push(new DeleteItem(clock, length3)); }; var createDeleteSet = () => new DeleteSet(); var createDeleteSetFromStructStore = (ss) => { const ds = createDeleteSet(); ss.clients.forEach((structs, client) => { const dsitems = []; for (let i = 0; i < structs.length; i++) { const struct = structs[i]; if (struct.deleted) { const clock = struct.id.clock; let len = struct.length; if (i + 1 < structs.length) { for (let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1]) { len += next.length; } } dsitems.push(new DeleteItem(clock, len)); } } if (dsitems.length > 0) { ds.clients.set(client, dsitems); } }); return ds; }; var writeDeleteSet = (encoder, ds) => { writeVarUint(encoder.restEncoder, ds.clients.size); from(ds.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, dsitems]) => { encoder.resetDsCurVal(); writeVarUint(encoder.restEncoder, client); const len = dsitems.length; writeVarUint(encoder.restEncoder, len); for (let i = 0; i < len; i++) { const item = dsitems[i]; encoder.writeDsClock(item.clock); encoder.writeDsLen(item.len); } }); }; var readDeleteSet = (decoder) => { const ds = new DeleteSet(); const numClients = readVarUint(decoder.restDecoder); for (let i = 0; i < numClients; i++) { decoder.resetDsCurVal(); const client = readVarUint(decoder.restDecoder); const numberOfDeletes = readVarUint(decoder.restDecoder); if (numberOfDeletes > 0) { const dsField = setIfUndefined(ds.clients, client, () => ( /** @type {Array<DeleteItem>} */ [] )); for (let i2 = 0; i2 < numberOfDeletes; i2++) { dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); } } } return ds; }; var readAndApplyDeleteSet = (decoder, transaction, store) => { const unappliedDS = new DeleteSet(); const numClients = readVarUint(decoder.restDecoder); for (let i = 0; i < numClients; i++) { decoder.resetDsCurVal(); const client = readVarUint(decoder.restDecoder); const numberOfDeletes = readVarUint(decoder.restDecoder); const structs = store.clients.get(client) || []; const state = getState(store, client); for (let i2 = 0; i2 < numberOfDeletes; i2++) { const clock = decoder.readDsClock(); const clockEnd = clock + decoder.readDsLen(); if (clock < state) { if (state < clockEnd) { addToDeleteSet(unappliedDS, client, state, clockEnd - state); } let index = findIndexSS(structs, clock); let struct = structs[index]; if (!struct.deleted && struct.id.clock < clock) { structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); index++; } while (index < structs.length) { struct = structs[index++]; if (struct.id.clock < clockEnd) { if (!struct.deleted) { if (clockEnd < struct.id.clock + struct.length) { structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); } struct.delete(transaction); } } else { break; } } } else { addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); } } } if (unappliedDS.clients.size > 0) { const ds = new UpdateEncoderV2(); writeVarUint(ds.restEncoder, 0); writeDeleteSet(ds, unappliedDS); return ds.toUint8Array(); } return null; }; var equalDeleteSets = (ds1, ds2) => { if (ds1.clients.size !== ds2.clients.size) return false; for (const [client, deleteItems1] of ds1.clients.entries()) { const deleteItems2 = ( /** @type {Array<import('../internals.js').DeleteItem>} */ ds2.clients.get(client) ); if (deleteItems2 === void 0 || deleteItems1.length !== deleteItems2.length) return false; for (let i = 0; i < deleteItems1.length; i++) { const di1 = deleteItems1[i]; const di2 = deleteItems2[i]; if (di1.clock !== di2.clock || di1.len !== di2.len) { return false; } } } return true; }; var generateNewClientId = uint32; var Doc = class _Doc extends ObservableV2 { /** * @param {DocOpts} opts configuration */ constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { super(); this.gc = gc; this.gcFilter = gcFilter; this.clientID = generateNewClientId(); this.guid = guid; this.collectionid = collectionid; this.share = /* @__PURE__ */ new Map(); this.store = new StructStore(); this._transaction = null; this._transactionCleanups = []; this.subdocs = /* @__PURE__ */ new Set(); this._item = null; this.shouldLoad = shouldLoad; this.autoLoad = autoLoad; this.meta = meta; this.isLoaded = false; this.isSynced = false; this.isDestroyed = false; this.whenLoaded = create4((resolve) => { this.on("load", () => { this.isLoaded = true; resolve(this); }); }); const provideSyncedPromise = () => create4((resolve) => { const eventHandler = (isSynced) => { if (isSynced === void 0 || isSynced === true) { this.off("sync", eventHandler); resolve(); } }; this.on("sync", eventHandler); }); this.on("sync", (isSynced) => { if (isSynced === false && this.isSynced) { this.whenSynced = provideSyncedPromise(); } this.isSynced = isSynced === void 0 || isSynced === true; if (this.isSynced && !this.isLoaded) { this.emit("load", [this]); } }); this.whenSynced = provideSyncedPromise(); } /** * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). * * `load()` might be used in the future to request any provider to load the most current data. * * It is safe to call `load()` multiple times. */ load() { const item = this._item; if (item !== null && !this.shouldLoad) { transact( /** @type {any} */ item.parent.doc, (transaction) => { transaction.subdocsLoaded.add(this); }, null, true ); } this.shouldLoad = true; } getSubdocs() { return this.subdocs; } getSubdocGuids() { return new Set(from(this.subdocs).map((doc2) => doc2.guid)); } /** * Changes that happen inside of a transaction are bundled. This means that * the observer fires _after_ the transaction is finished and that all changes * that happened inside of the transaction are sent as one message to the * other peers. * * @template T * @param {function(Transaction):T} f The function that should be executed as a transaction * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin * @return T * * @public */ transact(f, origin2 = null) { return transact(this, f, origin2); } /** * Define a shared data type. * * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result * and do not overwrite each other. I.e. * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` * * After this method is called, the type is also available on `ydoc.share.get(name)`. * * *Best Practices:* * 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 {typeof AbstractType<any>} Type * @example * const ydoc = new Y.Doc(..) * const appState = { * document: ydoc.getText('document') * comments: ydoc.getArray('comments') * } * * @param {string} name * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor * * @public */ get(name, TypeConstructor = ( /** @type {any} */ AbstractType )) { const type = setIfUndefined(this.share, name, () => { const t = new TypeConstructor(); t._integrate(this, null); return t; }); const Constr = type.constructor; if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { if (Constr === AbstractType) { const t = new TypeConstructor(); t._map = type._map; type._map.forEach( /** @param {Item?} n */ (n) => { for (; n !== null; n = n.left) { n.parent = t; } } ); t._start = type._start; for (let n = t._start; n !== null; n = n.right) { n.parent = t; } t._length = type._length; this.share.set(name, t); t._integrate(this, null); return ( /** @type {InstanceType<Type>} */ t ); } else { throw new Error(`Type with the name ${name} has already been defined with a different constructor`); } } return ( /** @type {InstanceType<Type>} */ type ); } /** * @template T * @param {string} [name] * @return {YArray<T>} * * @public */ getArray(name = "") { return ( /** @type {YArray<T>} */ this.get(name, YArray) ); } /** * @param {string} [name] * @return {YText} * * @public */ getText(name = "") { return this.get(name, YText); } /** * @template T * @param {string} [name] * @return {YMap<T>} * * @public */ getMap(name = "") { return ( /** @type {YMap<T>} */ this.get(name, YMap) ); } /** * @param {string} [name] * @return {YXmlElement} * * @public */ getXmlElement(name = "") { return ( /** @type {YXmlElement<{[key:string]:string}>} */ this.get(name, YXmlElement) ); } /** * @param {string} [name] * @return {YXmlFragment} * * @public */ getXmlFragment(name = "") { return this.get(name, YXmlFragment); } /** * Converts the entire document into a js object, recursively traversing each yjs type * Doesn't log types that have not been defined (using ydoc.getType(..)). * * @deprecated Do not use this method and rather call toJSON directly on the shared types. * * @return {Object<string, any>} */ toJSON() { const doc2 = {}; this.share.forEach((value, key) => { doc2[key] = value.toJSON(); }); return doc2; } /** * Emit `destroy` event and unregister all event handlers. */ destroy() { this.isDestroyed = true; from(this.subdocs).forEach((subdoc) => subdoc.destroy()); const item = this._item; if (item !== null) { this._item = null; const content = ( /** @type {ContentDoc} */ item.content ); content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); content.doc._item = item; transact( /** @type {any} */ item.parent.doc, (transaction) => { const doc2 = content.doc; if (!item.deleted) { transaction.subdocsAdded.add(doc2); } transaction.subdocsRemoved.add(this); }, null, true ); } this.emit("destroyed", [true]); this.emit("destroy", [this]); super.destroy(); } }; var DSDecoderV1 = class { /** * @param {decoding.Decoder} decoder */ constructor(decoder) { this.restDecoder = decoder; } resetDsCurVal() { } /** * @return {number} */ readDsClock() { return readVarUint(this.restDecoder); } /** * @return {number} */ readDsLen() { return readVarUint(this.restDecoder); } }; var UpdateDecoderV1 = class extends DSDecoderV1 { /** * @return {ID} */ readLeftID() { return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); } /** * @return {ID} */ readRightID() { return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); } /** * Read the next client id. * Use this in favor of readID whenever possible to reduce the number of objects created. */ readClient() { return readVarUint(this.restDecoder); } /** * @return {number} info An unsigned 8-bit integer */ readInfo() { return readUint8(this.restDecoder); } /** * @return {string} */ readString() { return readVarString(this.restDecoder); } /** * @return {boolean} isKey */ readParentInfo() { return readVarUint(this.restDecoder) === 1; } /** * @return {number} info An unsigned 8-bit integer */ readTypeRef() { return readVarUint(this.restDecoder); } /** * Write len of a struct - well suited for Opt RLE encoder. * * @return {number} len */ readLen() { return readVarUint(this.restDecoder); } /** * @return {any} */ readAny() { return readAny(this.restDecoder); } /** * @return {Uint8Array} */ readBuf() { return copyUint8Array(readVarUint8Array(this.restDecoder)); } /** * Legacy implementation uses JSON parse. We use any-decoding in v2. * * @return {any} */ readJSON() { return JSON.parse(readVarString(this.restDecoder)); } /** * @return {string} */ readKey() { return readVarString(this.restDecoder); } }; var DSDecoderV2 = class { /** * @param {decoding.Decoder} decoder */ constructor(decoder) { this.dsCurrVal = 0; this.restDecoder = decoder; } resetDsCurVal() { this.dsCurrVal = 0; } /** * @return {number} */ readDsClock() { this.dsCurrVal += readVarUint(this.restDecoder); return this.dsCurrVal; } /** * @return {number} */ readDsLen() { const diff = readVarUint(this.restDecoder) + 1; this.dsCurrVal += diff; return diff; } }; var UpdateDecoderV2 = class extends DSDecoderV2 { /** * @param {decoding.Decoder} decoder */ constructor(decoder) { super(decoder); this.keys = []; readVarUint(decoder); this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); } /** * @return {ID} */ readLeftID() { return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); } /** * @return {ID} */ readRightID() { return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); } /** * Read the next client id. * Use this in favor of readID whenever possible to reduce the number of objects created. */ readClient() { return this.clientDecoder.read(); } /** * @return {number} info An unsigned 8-bit integer */ readInfo() { return ( /** @type {number} */ this.infoDecoder.read() ); } /** * @return {string} */ readString() { return this.stringDecoder.read(); } /** * @return {boolean} */ readParentInfo() { return this.parentInfoDecoder.read() === 1; } /** * @return {number} An unsigned 8-bit integer */ readTypeRef() { return this.typeRefDecoder.read(); } /** * Write len of a struct - well suited for Opt RLE encoder. * * @return {number} */ readLen() { return this.lenDecoder.read(); } /** * @return {any} */ readAny() { return readAny(this.restDecoder); } /** * @return {Uint8Array} */ readBuf() { return readVarUint8Array(this.restDecoder); } /** * This is mainly here for legacy purposes. * * Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder. * * @return {any} */ readJSON() { return readAny(this.restDecoder); } /** * @return {string} */ readKey() { const keyClock = this.keyClockDecoder.read(); if (keyClock < this.keys.length) { return this.keys[keyClock]; } else { const key = this.stringDecoder.read(); this.keys.push(key); return key; } } }; var DSEncoderV1 = class { constructor() { this.restEncoder = createEncoder(); } toUint8Array() { return toUint8Array(this.restEncoder); } resetDsCurVal() { } /** * @param {number} clock */ writeDsClock(clock) { writeVarUint(this.restEncoder, clock); } /** * @param {number} len */ writeDsLen(len) { writeVarUint(this.restEncoder, len); } }; var UpdateEncoderV1 = class extends DSEncoderV1 { /** * @param {ID} id */ writeLeftID(id2) { writeVarUint(this.restEncoder, id2.client); writeVarUint(this.restEncoder, id2.clock); } /** * @param {ID} id */ writeRightID(id2) { writeVarUint(this.restEncoder, id2.client); writeVarUint(this.restEncoder, id2.clock); } /** * Use writeClient and writeClock instead of writeID if possible. * @param {number} client */ writeClient(client) { writeVarUint(this.restEncoder, client); } /** * @param {number} info An unsigned 8-bit integer */ writeInfo(info) { writeUint8(this.restEncoder, info); } /** * @param {string} s */ writeString(s) { writeVarString(this.restEncoder, s); } /** * @param {boolean} isYKey */ writeParentInfo(isYKey) { writeVarUint(this.restEncoder, isYKey ? 1 : 0); } /** * @param {number} info An unsigned 8-bit integer */ writeTypeRef(info) { writeVarUint(this.restEncoder, info); } /** * Write len of a struct - well suited for Opt RLE encoder. * * @param {number} len */ writeLen(len) { writeVarUint(this.restEncoder, len); } /** * @param {any} any */ writeAny(any2) { writeAny(this.restEncoder, any2); } /** * @param {Uint8Array} buf */ writeBuf(buf) { writeVarUint8Array(this.restEncoder, buf); } /** * @param {any} embed */ writeJSON(embed) { writeVarString(this.restEncoder, JSON.stringify(embed)); } /** * @param {string} key */ writeKey(key) { writeVarString(this.restEncoder, key); } }; var DSEncoderV2 = class { constructor() { this.restEncoder = createEncoder(); this.dsCurrVal = 0; } toUint8Array() { return toUint8Array(this.restEncoder); } resetDsCurVal() { this.dsCurrVal = 0; } /** * @param {number} clock */ writeDsClock(clock) { const diff = clock - this.dsCurrVal; this.dsCurrVal = clock; writeVarUint(this.restEncoder, diff); } /** * @param {number} len */ writeDsLen(len) { if (len === 0) { unexpectedCase(); } writeVarUint(this.restEncoder, len - 1); this.dsCurrVal += len; } }; var UpdateEncoderV2 = class extends DSEncoderV2 { constructor() { super(); this.keyMap = /* @__PURE__ */ new Map(); this.keyClock = 0; this.keyClockEncoder = new IntDiffOptRleEncoder(); this.clientEncoder = new UintOptRleEncoder(); this.leftClockEncoder = new IntDiffOptRleEncoder(); this.rightClockEncoder = new IntDiffOptRleEncoder(); this.infoEncoder = new RleEncoder(writeUint8); this.stringEncoder = new StringEncoder(); this.parentInfoEncoder = new RleEncoder(writeUint8); this.typeRefEncoder = new UintOptRleEncoder(); this.lenEncoder = new UintOptRleEncoder(); } toUint8Array() { const encoder = createEncoder(); writeVarUint(encoder, 0); writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); writeUint8Array(encoder, toUint8Array(this.restEncoder)); return toUint8Array(encoder); } /** * @param {ID} id */ writeLeftID(id2) { this.clientEncoder.write(id2.client); this.leftClockEncoder.write(id2.clock); } /** * @param {ID} id */ writeRightID(id2) { this.clientEncoder.write(id2.client); this.rightClockEncoder.write(id2.clock); } /** * @param {number} client */ writeClient(client) { this.clientEncoder.write(client); } /** * @param {number} info An unsigned 8-bit integer */ writeInfo(info) { this.infoEncoder.write(info); } /** * @param {string} s */ writeString(s) { this.stringEncoder.write(s); } /** * @param {boolean} isYKey */ writeParentInfo(isYKey) { this.parentInfoEncoder.write(isYKey ? 1 : 0); } /** * @param {number} info An unsigned 8-bit integer */ writeTypeRef(info) { this.typeRefEncoder.write(info); } /** * Write len of a struct - well suited for Opt RLE encoder. * * @param {number} len */ writeLen(len) { this.lenEncoder.write(len); } /** * @param {any} any */ writeAny(any2) { writeAny(this.restEncoder, any2); } /** * @param {Uint8Array} buf */ writeBuf(buf) { writeVarUint8Array(this.restEncoder, buf); } /** * This is mainly here for legacy purposes. * * Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder. * * @param {any} embed */ writeJSON(embed) { writeAny(this.restEncoder, embed); } /** * Property keys are often reused. For example, in y-prosemirror the key `bold` might * occur very often. For a 3d application, the key `position` might occur very often. * * We cache these keys in a Map and refer to them via a unique number. * * @param {string} key */ writeKey(key) { const clock = this.keyMap.get(key); if (clock === void 0) { this.keyClockEncoder.write(this.keyClock++); this.stringEncoder.write(key); } else { this.keyClockEncoder.write(clock); } } }; var writeStructs = (encoder, structs, client, clock) => { clock = max(clock, structs[0].id.clock); const startNewStructs = findIndexSS(structs, clock); writeVarUint(encoder.restEncoder, structs.length - startNewStructs); encoder.writeClient(client); writeVarUint(encoder.restEncoder, clock); const firstStruct = structs[startNewStructs]; firstStruct.write(encoder, clock - firstStruct.id.clock); for (let i = startNewStructs + 1; i < structs.length; i++) { structs[i].write(encoder, 0); } }; var writeClientsStructs = (encoder, store, _sm) => { const sm = /* @__PURE__ */ new Map(); _sm.forEach((clock, client) => { if (getState(store, client) > clock) { sm.set(client, clock); } }); getStateVector(store).forEach((_clock, client) => { if (!_sm.has(client)) { sm.set(client, 0); } }); writeVarUint(encoder.restEncoder, sm.size); from(sm.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { writeStructs( encoder, /** @type {Array<GC|Item>} */ store.clients.get(client), client, clock ); }); }; var readClientsStructRefs = (decoder, doc2) => { const clientRefs = create(); const numOfStateUpdates = readVarUint(decoder.restDecoder); for (let i = 0; i < numOfStateUpdates; i++) { const numberOfStructs = readVarUint(decoder.restDecoder); const refs = new Array(numberOfStructs); const client = decoder.readClient(); let clock = readVarUint(decoder.restDecoder); clientRefs.set(client, { i: 0, refs }); for (let i2 = 0; i2 < numberOfStructs; i2++) { const info = decoder.readInfo(); switch (BITS5 & info) { case 0: { const len = decoder.readLen(); refs[i2] = new GC(createID(client, clock), len); clock += len; break; } case 10: { const len = readVarUint(decoder.restDecoder); refs[i2] = new Skip(createID(client, clock), len); clock += len; break; } default: { const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; const struct = new Item( createID(client, clock), null, // left (info & BIT8) === BIT8 ? decoder.readLeftID() : null, // origin null, // right (info & BIT7) === BIT7 ? decoder.readRightID() : null, // right origin cantCopyParentInfo ? decoder.readParentInfo() ? doc2.get(decoder.readString()) : decoder.readLeftID() : null, // parent cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, // parentSub readItemContent(decoder, info) // item content ); refs[i2] = struct; clock += struct.length; } } } } return clientRefs; }; var integrateStructs = (transaction, store, clientsStructRefs) => { const stack = []; let clientsStructRefsIds = from(clientsStructRefs.keys()).sort((a, b) => a - b); if (clientsStructRefsIds.length === 0) { return null; } const getNextStructTarget = () => { if (clientsStructRefsIds.length === 0) { return null; } let nextStructsTarget = ( /** @type {{i:number,refs:Array<GC|Item>}} */ clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) ); while (nextStructsTarget.refs.length === nextStructsTarget.i) { clientsStructRefsIds.pop(); if (clientsStructRefsIds.length > 0) { nextStructsTarget = /** @type {{i:number,refs:Array<GC|Item>}} */ clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); } else { return null; } } return nextStructsTarget; }; let curStructsTarget = getNextStructTarget(); if (curStructsTarget === null) { return null; } const restStructs = new StructStore(); const missingSV = /* @__PURE__ */ new Map(); const updateMissingSv = (client, clock) => { const mclock = missingSV.get(client); if (mclock == null || mclock > clock) { missingSV.set(client, clock); } }; let stackHead = ( /** @type {any} */ curStructsTarget.refs[ /** @type {any} */ curStructsTarget.i++ ] ); const state = /* @__PURE__ */ new Map(); const addStackToRestSS = () => { for (const item of stack) { const client = item.id.client; const inapplicableItems = clientsStructRefs.get(client); if (inapplicableItems) { inapplicableItems.i--; restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); clientsStructRefs.delete(client); inapplicableItems.i = 0; inapplicableItems.refs = []; } else { restStructs.clients.set(client, [item]); } clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); } stack.length = 0; }; while (true) { if (stackHead.constructor !== Skip) { const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store, stackHead.id.client)); const offset = localClock - stackHead.id.clock; if (offset < 0) { stack.push(stackHead); updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); addStackToRestSS(); } else { const missing = stackHead.getMissing(transaction, store); if (missing !== null) { stack.push(stackHead); const structRefs = clientsStructRefs.get( /** @type {number} */ missing ) || { refs: [], i: 0 }; if (structRefs.refs.length === structRefs.i) { updateMissingSv( /** @type {number} */ missing, getState(store, missing) ); addStackToRestSS(); } else { stackHead = structRefs.refs[structRefs.i++]; continue; } } else if (offset === 0 || offset < stackHead.length) { stackHead.integrate(transaction, offset); state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); } } } if (stack.length > 0) { stackHead = /** @type {GC|Item} */ stack.pop(); } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { stackHead = /** @type {GC|Item} */ curStructsTarget.refs[curStructsTarget.i++]; } else { curStructsTarget = getNextStructTarget(); if (curStructsTarget === null) { break; } else { stackHead = /** @type {GC|Item} */ curStructsTarget.refs[curStructsTarget.i++]; } } } if (restStructs.clients.size > 0) { const encoder = new UpdateEncoderV2(); writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); writeVarUint(encoder.restEncoder, 0); return { missing: missingSV, update: encoder.toUint8Array() }; } return null; }; var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { transaction.local = false; let retry = false; const doc2 = transaction.doc; const store = doc2.store; const ss = readClientsStructRefs(structDecoder, doc2); const restStructs = integrateStructs(transaction, store, ss); const pending = store.pendingStructs; if (pending) { for (const [client, clock] of pending.missing) { if (clock < getState(store, client)) { retry = true; break; } } if (restStructs) { for (const [client, clock] of restStructs.missing) { const mclock = pending.missing.get(client); if (mclock == null || mclock > clock) { pending.missing.set(client, clock); } } pending.update = mergeUpdatesV2([pending.update, restStructs.update]); } } else { store.pendingStructs = restStructs; } const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store); if (store.pendingDs) { const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store.pendingDs)); readVarUint(pendingDSUpdate.restDecoder); const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store); if (dsRest && dsRest2) { store.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); } else { store.pendingDs = dsRest || dsRest2; } } else { store.pendingDs = dsRest; } if (retry) { const update = ( /** @type {{update: Uint8Array}} */ store.pendingStructs.update ); store.pendingStructs = null; applyUpdateV2(transaction.doc, update); } }, transactionOrigin, false); var readUpdate = (decoder, ydoc, transactionOrigin) => readUpdateV2(decoder, ydoc, transactionOrigin, new UpdateDecoderV1(decoder)); var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { const decoder = createDecoder(update); readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); }; var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); var writeStateAsUpdate = (encoder, doc2, targetStateVector = /* @__PURE__ */ new Map()) => { writeClientsStructs(encoder, doc2.store, targetStateVector); writeDeleteSet(encoder, createDeleteSetFromStructStore(doc2.store)); }; var encodeStateAsUpdateV2 = (doc2, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { const targetStateVector = decodeStateVector(encodedTargetStateVector); writeStateAsUpdate(encoder, doc2, targetStateVector); const updates = [encoder.toUint8Array()]; if (doc2.store.pendingDs) { updates.push(doc2.store.pendingDs); } if (doc2.store.pendingStructs) { updates.push(diffUpdateV2(doc2.store.pendingStructs.update, encodedTargetStateVector)); } if (updates.length > 1) { if (encoder.constructor === UpdateEncoderV1) { return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); } else if (encoder.constructor === UpdateEncoderV2) { return mergeUpdatesV2(updates); } } return updates[0]; }; var encodeStateAsUpdate = (doc2, encodedTargetStateVector) => encodeStateAsUpdateV2(doc2, encodedTargetStateVector, new UpdateEncoderV1()); var readStateVector = (decoder) => { const ss = /* @__PURE__ */ new Map(); const ssLength = readVarUint(decoder.restDecoder); for (let i = 0; i < ssLength; i++) { const client = readVarUint(decoder.restDecoder); const clock = readVarUint(decoder.restDecoder); ss.set(client, clock); } return ss; }; var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); var writeStateVector = (encoder, sv) => { writeVarUint(encoder.restEncoder, sv.size); from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { writeVarUint(encoder.restEncoder, client); writeVarUint(encoder.restEncoder, clock); }); return encoder; }; var writeDocumentStateVector = (encoder, doc2) => writeStateVector(encoder, getStateVector(doc2.store)); var encodeStateVectorV2 = (doc2, encoder = new DSEncoderV2()) => { if (doc2 instanceof Map) { writeStateVector(encoder, doc2); } else { writeDocumentStateVector(encoder, doc2); } return encoder.toUint8Array(); }; var encodeStateVector = (doc2) => encodeStateVectorV2(doc2, new DSEncoderV1()); var EventHandler = class { constructor() { this.l = []; } }; var createEventHandler = () => new EventHandler(); var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); var removeEventHandlerListener = (eventHandler, f) => { const l = eventHandler.l; const len = l.length; eventHandler.l = l.filter((g) => f !== g); if (len === eventHandler.l.length) { console.error("[yjs] Tried to remove event handler that doesn't exist."); } }; var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); var ID = class { /** * @param {number} client client id * @param {number} clock unique per client id, continuous number */ constructor(client, clock) { this.client = client; this.clock = clock; } }; var compareIDs = (a, b) => a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock; var createID = (client, clock) => new ID(client, clock); var writeID = (encoder, id2) => { writeVarUint(encoder, id2.client); writeVarUint(encoder, id2.clock); }; var readID = (decoder) => createID(readVarUint(decoder), readVarUint(decoder)); var findRootTypeKey = (type) => { for (const [key, value] of type.doc.share.entries()) { if (value === type) { return key; } } throw unexpectedCase(); }; var isParentOf = (parent, child) => { while (child !== null) { if (child.parent === parent) { return true; } child = /** @type {AbstractType<any>} */ child.parent._item; } return false; }; var logType = (type) => { const res = []; let n = type._start; while (n) { res.push(n); n = n.right; } console.log("Children: ", res); console.log("Children content: ", res.filter((m) => !m.deleted).map((m) => m.content)); }; var PermanentUserData = class { /** * @param {Doc} doc * @param {YMap<any>} [storeType] */ constructor(doc2, storeType = doc2.getMap("users")) { const dss = /* @__PURE__ */ new Map(); this.yusers = storeType; this.doc = doc2; this.clients = /* @__PURE__ */ new Map(); this.dss = dss; const initUser = (user, userDescription) => { const ds = user.get("ds"); const ids = user.get("ids"); const addClientId = ( /** @param {number} clientid */ (clientid) => this.clients.set(clientid, userDescription) ); ds.observe( /** @param {YArrayEvent<any>} event */ (event) => { event.changes.added.forEach((item) => { item.content.getContent().forEach((encodedDs) => { if (encodedDs instanceof Uint8Array) { this.dss.set(userDescription, mergeDeleteSets([this.dss.get(userDescription) || createDeleteSet(), readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))])); } }); }); } ); this.dss.set(userDescription, mergeDeleteSets(ds.map((encodedDs) => readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))))); ids.observe( /** @param {YArrayEvent<any>} event */ (event) => event.changes.added.forEach((item) => item.content.getContent().forEach(addClientId)) ); ids.forEach(addClientId); }; storeType.observe((event) => { event.keysChanged.forEach( (userDescription) => initUser(storeType.get(userDescription), userDescription) ); }); storeType.forEach(initUser); } /** * @param {Doc} doc * @param {number} clientid * @param {string} userDescription * @param {Object} conf * @param {function(Transaction, DeleteSet):boolean} [conf.filter] */ setUserMapping(doc2, clientid, userDescription, { filter = () => true } = {}) { const users = this.yusers; let user = users.get(userDescription); if (!user) { user = new YMap(); user.set("ids", new YArray()); user.set("ds", new YArray()); users.set(userDescription, user); } user.get("ids").push([clientid]); users.observe((_event) => { setTimeout(() => { const userOverwrite = users.get(userDescription); if (userOverwrite !== user) { user = userOverwrite; this.clients.forEach((_userDescription, clientid2) => { if (userDescription === _userDescription) { user.get("ids").push([clientid2]); } }); const encoder = new DSEncoderV1(); const ds = this.dss.get(userDescription); if (ds) { writeDeleteSet(encoder, ds); user.get("ds").push([encoder.toUint8Array()]); } } }, 0); }); doc2.on( "afterTransaction", /** @param {Transaction} transaction */ (transaction) => { setTimeout(() => { const yds = user.get("ds"); const ds = transaction.deleteSet; if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) { const encoder = new DSEncoderV1(); writeDeleteSet(encoder, ds); yds.push([encoder.toUint8Array()]); } }); } ); } /** * @param {number} clientid * @return {any} */ getUserByClientId(clientid) { return this.clients.get(clientid) || null; } /** * @param {ID} id * @return {string | null} */ getUserByDeletedId(id2) { for (const [userDescription, ds] of this.dss.entries()) { if (isDeleted(ds, id2)) { return userDescription; } } return null; } }; var RelativePosition = class { /** * @param {ID|null} type * @param {string|null} tname * @param {ID|null} item * @param {number} assoc */ constructor(type, tname, item, assoc = 0) { this.type = type; this.tname = tname; this.item = item; this.assoc = assoc; } }; var relativePositionToJSON = (rpos) => { const json = {}; if (rpos.type) { json.type = rpos.type; } if (rpos.tname) { json.tname = rpos.tname; } if (rpos.item) { json.item = rpos.item; } if (rpos.assoc != null) { json.assoc = rpos.assoc; } return json; }; var createRelativePositionFromJSON = (json) => new RelativePosition(json.type == null ? null : createID(json.type.client, json.type.clock), json.tname ?? null, json.item == null ? null : createID(json.item.client, json.item.clock), json.assoc == null ? 0 : json.assoc); var AbsolutePosition = class { /** * @param {AbstractType<any>} type * @param {number} index * @param {number} [assoc] */ constructor(type, index, assoc = 0) { this.type = type; this.index = index; this.assoc = assoc; } }; var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); var createRelativePosition = (type, item, assoc) => { let typeid = null; let tname = null; if (type._item === null) { tname = findRootTypeKey(type); } else { typeid = createID(type._item.id.client, type._item.id.clock); } return new RelativePosition(typeid, tname, item, assoc); }; var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { let t = type._start; if (assoc < 0) { if (index === 0) { return createRelativePosition(type, null, assoc); } index--; } while (t !== null) { if (!t.deleted && t.countable) { if (t.length > index) { return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); } index -= t.length; } if (t.right === null && assoc < 0) { return createRelativePosition(type, t.lastId, assoc); } t = t.right; } return createRelativePosition(type, null, assoc); }; var writeRelativePosition = (encoder, rpos) => { const { type, tname, item, assoc } = rpos; if (item !== null) { writeVarUint(encoder, 0); writeID(encoder, item); } else if (tname !== null) { writeUint8(encoder, 1); writeVarString(encoder, tname); } else if (type !== null) { writeUint8(encoder, 2); writeID(encoder, type); } else { throw unexpectedCase(); } writeVarInt(encoder, assoc); return encoder; }; var encodeRelativePosition = (rpos) => { const encoder = createEncoder(); writeRelativePosition(encoder, rpos); return toUint8Array(encoder); }; var readRelativePosition = (decoder) => { let type = null; let tname = null; let itemID = null; switch (readVarUint(decoder)) { case 0: itemID = readID(decoder); break; case 1: tname = readVarString(decoder); break; case 2: { type = readID(decoder); } } const assoc = hasContent(decoder) ? readVarInt(decoder) : 0; return new RelativePosition(type, tname, itemID, assoc); }; var decodeRelativePosition = (uint8Array) => readRelativePosition(createDecoder(uint8Array)); var getItemWithOffset = (store, id2) => { const item = getItem(store, id2); const diff = id2.clock - item.id.clock; return { item, diff }; }; var createAbsolutePositionFromRelativePosition = (rpos, doc2, followUndoneDeletions = true) => { const store = doc2.store; const rightID = rpos.item; const typeID = rpos.type; const tname = rpos.tname; const assoc = rpos.assoc; let type = null; let index = 0; if (rightID !== null) { if (getState(store, rightID.client) <= rightID.clock) { return null; } const res = followUndoneDeletions ? followRedone(store, rightID) : getItemWithOffset(store, rightID); const right = res.item; if (!(right instanceof Item)) { return null; } type = /** @type {AbstractType<any>} */ right.parent; if (type._item === null || !type._item.deleted) { index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); let n = right.left; while (n !== null) { if (!n.deleted && n.countable) { index += n.length; } n = n.left; } } } else { if (tname !== null) { type = doc2.get(tname); } else if (typeID !== null) { if (getState(store, typeID.client) <= typeID.clock) { return null; } const { item } = followUndoneDeletions ? followRedone(store, typeID) : { item: getItem(store, typeID) }; if (item instanceof Item && item.content instanceof ContentType) { type = item.content.type; } else { return null; } } else { throw unexpectedCase(); } if (assoc >= 0) { index = type._length; } else { index = 0; } } return createAbsolutePosition(type, index, rpos.assoc); }; var compareRelativePositions = (a, b) => a === b || a !== null && b !== null && a.tname === b.tname && compareIDs(a.item, b.item) && compareIDs(a.type, b.type) && a.assoc === b.assoc; var Snapshot = class { /** * @param {DeleteSet} ds * @param {Map<number,number>} sv state map */ constructor(ds, sv) { this.ds = ds; this.sv = sv; } }; var equalSnapshots = (snap1, snap2) => { const ds1 = snap1.ds.clients; const ds2 = snap2.ds.clients; const sv1 = snap1.sv; const sv2 = snap2.sv; if (sv1.size !== sv2.size || ds1.size !== ds2.size) { return false; } for (const [key, value] of sv1.entries()) { if (sv2.get(key) !== value) { return false; } } for (const [client, dsitems1] of ds1.entries()) { const dsitems2 = ds2.get(client) || []; if (dsitems1.length !== dsitems2.length) { return false; } for (let i = 0; i < dsitems1.length; i++) { const dsitem1 = dsitems1[i]; const dsitem2 = dsitems2[i]; if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) { return false; } } } return true; }; var encodeSnapshotV2 = (snapshot2, encoder = new DSEncoderV2()) => { writeDeleteSet(encoder, snapshot2.ds); writeStateVector(encoder, snapshot2.sv); return encoder.toUint8Array(); }; var encodeSnapshot = (snapshot2) => encodeSnapshotV2(snapshot2, new DSEncoderV1()); var decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(createDecoder(buf))) => { return new Snapshot(readDeleteSet(decoder), readStateVector(decoder)); }; var decodeSnapshot = (buf) => decodeSnapshotV2(buf, new DSDecoderV1(createDecoder(buf))); var createSnapshot = (ds, sm) => new Snapshot(ds, sm); var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); var snapshot = (doc2) => createSnapshot(createDeleteSetFromStructStore(doc2.store), getStateVector(doc2.store)); var isVisible = (item, snapshot2) => snapshot2 === void 0 ? !item.deleted : snapshot2.sv.has(item.id.client) && (snapshot2.sv.get(item.id.client) || 0) > item.id.clock && !isDeleted(snapshot2.ds, item.id); var splitSnapshotAffectedStructs = (transaction, snapshot2) => { const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); const store = transaction.doc.store; if (!meta.has(snapshot2)) { snapshot2.sv.forEach((clock, client) => { if (clock < getState(store, client)) { getItemCleanStart(transaction, createID(client, clock)); } }); iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { }); meta.add(snapshot2); } }; var createDocFromSnapshot = (originDoc, snapshot2, newDoc = new Doc()) => { if (originDoc.gc) { throw new Error("Garbage-collection must be disabled in `originDoc`!"); } const { sv, ds } = snapshot2; const encoder = new UpdateEncoderV2(); originDoc.transact((transaction) => { let size2 = 0; sv.forEach((clock) => { if (clock > 0) { size2++; } }); writeVarUint(encoder.restEncoder, size2); for (const [client, clock] of sv) { if (clock === 0) { continue; } if (clock < getState(originDoc.store, client)) { getItemCleanStart(transaction, createID(client, clock)); } const structs = originDoc.store.clients.get(client) || []; const lastStructIndex = findIndexSS(structs, clock - 1); writeVarUint(encoder.restEncoder, lastStructIndex + 1); encoder.writeClient(client); writeVarUint(encoder.restEncoder, 0); for (let i = 0; i <= lastStructIndex; i++) { structs[i].write(encoder, 0); } } writeDeleteSet(encoder, ds); }); applyUpdateV2(newDoc, encoder.toUint8Array(), "snapshot"); return newDoc; }; var snapshotContainsUpdateV2 = (snapshot2, update, YDecoder = UpdateDecoderV2) => { const updateDecoder = new YDecoder(createDecoder(update)); const lazyDecoder = new LazyStructReader(updateDecoder, false); for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { if ((snapshot2.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) { return false; } } const mergedDS = mergeDeleteSets([snapshot2.ds, readDeleteSet(updateDecoder)]); return equalDeleteSets(snapshot2.ds, mergedDS); }; var snapshotContainsUpdate = (snapshot2, update) => snapshotContainsUpdateV2(snapshot2, update, UpdateDecoderV1); var StructStore = class { constructor() { this.clients = /* @__PURE__ */ new Map(); this.pendingStructs = null; this.pendingDs = null; } }; var getStateVector = (store) => { const sm = /* @__PURE__ */ new Map(); store.clients.forEach((structs, client) => { const struct = structs[structs.length - 1]; sm.set(client, struct.id.clock + struct.length); }); return sm; }; var getState = (store, client) => { const structs = store.clients.get(client); if (structs === void 0) { return 0; } const lastStruct = structs[structs.length - 1]; return lastStruct.id.clock + lastStruct.length; }; var addStruct = (store, struct) => { let structs = store.clients.get(struct.id.client); if (structs === void 0) { structs = []; store.clients.set(struct.id.client, structs); } else { const lastStruct = structs[structs.length - 1]; if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { throw unexpectedCase(); } } structs.push(struct); }; var findIndexSS = (structs, clock) => { let left = 0; let right = structs.length - 1; let mid = structs[right]; let midclock = mid.id.clock; if (midclock === clock) { return right; } let midindex = floor(clock / (midclock + mid.length - 1) * right); while (left <= right) { mid = structs[midindex]; midclock = mid.id.clock; if (midclock <= clock) { if (clock < midclock + mid.length) { return midindex; } left = midindex + 1; } else { right = midindex - 1; } midindex = floor((left + right) / 2); } throw unexpectedCase(); }; var find = (store, id2) => { const structs = store.clients.get(id2.client); return structs[findIndexSS(structs, id2.clock)]; }; var getItem = ( /** @type {function(StructStore,ID):Item} */ find ); var findIndexCleanStart = (transaction, structs, clock) => { const index = findIndexSS(structs, clock); const struct = structs[index]; if (struct.id.clock < clock && struct instanceof Item) { structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); return index + 1; } return index; }; var getItemCleanStart = (transaction, id2) => { const structs = ( /** @type {Array<Item>} */ transaction.doc.store.clients.get(id2.client) ); return structs[findIndexCleanStart(transaction, structs, id2.clock)]; }; var getItemCleanEnd = (transaction, store, id2) => { const structs = store.clients.get(id2.client); const index = findIndexSS(structs, id2.clock); const struct = structs[index]; if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); } return struct; }; var replaceStruct = (store, struct, newStruct) => { const structs = ( /** @type {Array<GC|Item>} */ store.clients.get(struct.id.client) ); structs[findIndexSS(structs, struct.id.clock)] = newStruct; }; var iterateStructs = (transaction, structs, clockStart, len, f) => { if (len === 0) { return; } const clockEnd = clockStart + len; let index = findIndexCleanStart(transaction, structs, clockStart); let struct; do { struct = structs[index++]; if (clockEnd < struct.id.clock + struct.length) { findIndexCleanStart(transaction, structs, clockEnd); } f(struct); } while (index < structs.length && structs[index].id.clock < clockEnd); }; var Transaction = class { /** * @param {Doc} doc * @param {any} origin * @param {boolean} local */ constructor(doc2, origin2, local) { this.doc = doc2; this.deleteSet = new DeleteSet(); this.beforeState = getStateVector(doc2.store); this.afterState = /* @__PURE__ */ new Map(); this.changed = /* @__PURE__ */ new Map(); this.changedParentTypes = /* @__PURE__ */ new Map(); this._mergeStructs = []; this.origin = origin2; this.meta = /* @__PURE__ */ new Map(); this.local = local; this.subdocsAdded = /* @__PURE__ */ new Set(); this.subdocsRemoved = /* @__PURE__ */ new Set(); this.subdocsLoaded = /* @__PURE__ */ new Set(); this._needFormattingCleanup = false; } }; var writeUpdateMessageFromTransaction = (encoder, transaction) => { if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { return false; } sortAndMergeDeleteSet(transaction.deleteSet); writeStructsFromTransaction(encoder, transaction); writeDeleteSet(encoder, transaction.deleteSet); return true; }; var addChangedTypeToTransaction = (transaction, type, parentSub) => { const item = type._item; if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { setIfUndefined(transaction.changed, type, create2).add(parentSub); } }; var tryToMergeWithLefts = (structs, pos) => { let right = structs[pos]; let left = structs[pos - 1]; let i = pos; for (; i > 0; right = left, left = structs[--i - 1]) { if (left.deleted === right.deleted && left.constructor === right.constructor) { if (left.mergeWith(right)) { if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ right.parent._map.get(right.parentSub) === right) { right.parent._map.set( right.parentSub, /** @type {Item} */ left ); } continue; } } break; } const merged = pos - i; if (merged) { structs.splice(pos + 1 - merged, merged); } return merged; }; var tryGcDeleteSet = (ds, store, gcFilter) => { for (const [client, deleteItems] of ds.clients.entries()) { const structs = ( /** @type {Array<GC|Item>} */ store.clients.get(client) ); for (let di = deleteItems.length - 1; di >= 0; di--) { const deleteItem = deleteItems[di]; const endDeleteItemClock = deleteItem.clock + deleteItem.len; for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { const struct2 = structs[si]; if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { break; } if (struct2 instanceof Item && struct2.deleted && !struct2.keep && gcFilter(struct2)) { struct2.gc(store, false); } } } } }; var tryMergeDeleteSet = (ds, store) => { ds.clients.forEach((deleteItems, client) => { const structs = ( /** @type {Array<GC|Item>} */ store.clients.get(client) ); for (let di = deleteItems.length - 1; di >= 0; di--) { const deleteItem = deleteItems[di]; const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { si -= 1 + tryToMergeWithLefts(structs, si); } } }); }; var tryGc = (ds, store, gcFilter) => { tryGcDeleteSet(ds, store, gcFilter); tryMergeDeleteSet(ds, store); }; var cleanupTransactions = (transactionCleanups, i) => { if (i < transactionCleanups.length) { const transaction = transactionCleanups[i]; const doc2 = transaction.doc; const store = doc2.store; const ds = transaction.deleteSet; const mergeStructs = transaction._mergeStructs; try { sortAndMergeDeleteSet(ds); transaction.afterState = getStateVector(transaction.doc.store); doc2.emit("beforeObserverCalls", [transaction, doc2]); const fs = []; transaction.changed.forEach( (subs, itemtype) => fs.push(() => { if (itemtype._item === null || !itemtype._item.deleted) { itemtype._callObserver(transaction, subs); } }) ); fs.push(() => { transaction.changedParentTypes.forEach((events, type) => { if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { events = events.filter( (event) => event.target._item === null || !event.target._item.deleted ); events.forEach((event) => { event.currentTarget = type; event._path = null; }); events.sort((event1, event2) => event1.path.length - event2.path.length); fs.push(() => { callEventHandlerListeners(type._dEH, events, transaction); }); } }); fs.push(() => doc2.emit("afterTransaction", [transaction, doc2])); fs.push(() => { if (transaction._needFormattingCleanup) { cleanupYTextAfterTransaction(transaction); } }); }); callAll(fs, []); } finally { if (doc2.gc) { tryGcDeleteSet(ds, store, doc2.gcFilter); } tryMergeDeleteSet(ds, store); transaction.afterState.forEach((clock, client) => { const beforeClock = transaction.beforeState.get(client) || 0; if (beforeClock !== clock) { const structs = ( /** @type {Array<GC|Item>} */ store.clients.get(client) ); const firstChangePos = max(findIndexSS(structs, beforeClock), 1); for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { i2 -= 1 + tryToMergeWithLefts(structs, i2); } } }); for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { const { client, clock } = mergeStructs[i2].id; const structs = ( /** @type {Array<GC|Item>} */ store.clients.get(client) ); const replacedStructPos = findIndexSS(structs, clock); if (replacedStructPos + 1 < structs.length) { if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { continue; } } if (replacedStructPos > 0) { tryToMergeWithLefts(structs, replacedStructPos); } } if (!transaction.local && transaction.afterState.get(doc2.clientID) !== transaction.beforeState.get(doc2.clientID)) { print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); doc2.clientID = generateNewClientId(); } doc2.emit("afterTransactionCleanup", [transaction, doc2]); if (doc2._observers.has("update")) { const encoder = new UpdateEncoderV1(); const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); if (hasContent2) { doc2.emit("update", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); } } if (doc2._observers.has("updateV2")) { const encoder = new UpdateEncoderV2(); const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); if (hasContent2) { doc2.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); } } const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { subdocsAdded.forEach((subdoc) => { subdoc.clientID = doc2.clientID; if (subdoc.collectionid == null) { subdoc.collectionid = doc2.collectionid; } doc2.subdocs.add(subdoc); }); subdocsRemoved.forEach((subdoc) => doc2.subdocs.delete(subdoc)); doc2.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc2, transaction]); subdocsRemoved.forEach((subdoc) => subdoc.destroy()); } if (transactionCleanups.length <= i + 1) { doc2._transactionCleanups = []; doc2.emit("afterAllTransactions", [doc2, transactionCleanups]); } else { cleanupTransactions(transactionCleanups, i + 1); } } } }; var transact = (doc2, f, origin2 = null, local = true) => { const transactionCleanups = doc2._transactionCleanups; let initialCall = false; let result = null; if (doc2._transaction === null) { initialCall = true; doc2._transaction = new Transaction(doc2, origin2, local); transactionCleanups.push(doc2._transaction); if (transactionCleanups.length === 1) { doc2.emit("beforeAllTransactions", [doc2]); } doc2.emit("beforeTransaction", [doc2._transaction, doc2]); } try { result = f(doc2._transaction); } finally { if (initialCall) { const finishCleanup = doc2._transaction === transactionCleanups[0]; doc2._transaction = null; if (finishCleanup) { cleanupTransactions(transactionCleanups, 0); } } } return result; }; var StackItem = class { /** * @param {DeleteSet} deletions * @param {DeleteSet} insertions */ constructor(deletions, insertions) { this.insertions = insertions; this.deletions = deletions; this.meta = /* @__PURE__ */ new Map(); } }; var clearUndoManagerStackItem = (tr, um, stackItem) => { iterateDeletedStructs(tr, stackItem.deletions, (item) => { if (item instanceof Item && um.scope.some((type) => type === tr.doc || isParentOf( /** @type {AbstractType<any>} */ type, item ))) { keepItem(item, false); } }); }; var popStackItem = (undoManager, stack, eventType) => { let _tr = null; const doc2 = undoManager.doc; const scope = undoManager.scope; transact(doc2, (transaction) => { while (stack.length > 0 && undoManager.currStackItem === null) { const store = doc2.store; const stackItem = ( /** @type {StackItem} */ stack.pop() ); const itemsToRedo = /* @__PURE__ */ new Set(); const itemsToDelete = []; let performedChange = false; iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { if (struct instanceof Item) { if (struct.redone !== null) { let { item, diff } = followRedone(store, struct.id); if (diff > 0) { item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); } struct = item; } if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( /** @type {AbstractType<any>} */ type, /** @type {Item} */ struct ))) { itemsToDelete.push(struct); } } }); iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { if (struct instanceof Item && scope.some((type) => type === transaction.doc || isParentOf( /** @type {AbstractType<any>} */ type, struct )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. !isDeleted(stackItem.insertions, struct.id)) { itemsToRedo.add(struct); } }); itemsToRedo.forEach((struct) => { performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange; }); for (let i = itemsToDelete.length - 1; i >= 0; i--) { const item = itemsToDelete[i]; if (undoManager.deleteFilter(item)) { item.delete(transaction); performedChange = true; } } undoManager.currStackItem = performedChange ? stackItem : null; } transaction.changed.forEach((subProps, type) => { if (subProps.has(null) && type._searchMarker) { type._searchMarker.length = 0; } }); _tr = transaction; }, undoManager); const res = undoManager.currStackItem; if (res != null) { const changedParentTypes = _tr.changedParentTypes; undoManager.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager }, undoManager]); undoManager.currStackItem = null; } return res; }; var UndoManager = class extends ObservableV2 { /** * @param {Doc|AbstractType<any>|Array<AbstractType<any>>} typeScope Limits the scope of the UndoManager. If this is set to a ydoc instance, all changes on that ydoc will be undone. If set to a specific type, only changes on that type or its children will be undone. Also accepts an array of types. * @param {UndoManagerOptions} options */ constructor(typeScope, { captureTimeout = 500, captureTransaction = (_tr) => true, deleteFilter = () => true, trackedOrigins = /* @__PURE__ */ new Set([null]), ignoreRemoteMapChanges = false, doc: doc2 = ( /** @type {Doc} */ isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc ) } = {}) { super(); this.scope = []; this.doc = doc2; this.addToScope(typeScope); this.deleteFilter = deleteFilter; trackedOrigins.add(this); this.trackedOrigins = trackedOrigins; this.captureTransaction = captureTransaction; this.undoStack = []; this.redoStack = []; this.undoing = false; this.redoing = false; this.currStackItem = null; this.lastChange = 0; this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; this.captureTimeout = captureTimeout; this.afterTransactionHandler = (transaction) => { if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( /** @type {AbstractType<any>} */ type ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { return; } const undoing = this.undoing; const redoing = this.redoing; const stack = undoing ? this.redoStack : this.undoStack; if (undoing) { this.stopCapturing(); } else if (!redoing) { this.clear(false, true); } const insertions = new DeleteSet(); transaction.afterState.forEach((endClock, client) => { const startClock = transaction.beforeState.get(client) || 0; const len = endClock - startClock; if (len > 0) { addToDeleteSet(insertions, client, startClock, len); } }); const now = getUnixTime(); let didAdd = false; if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { const lastOp = stack[stack.length - 1]; lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); } else { stack.push(new StackItem(transaction.deleteSet, insertions)); didAdd = true; } if (!undoing && !redoing) { this.lastChange = now; } iterateDeletedStructs( transaction, transaction.deleteSet, /** @param {Item|GC} item */ (item) => { if (item instanceof Item && this.scope.some((type) => type === transaction.doc || isParentOf( /** @type {AbstractType<any>} */ type, item ))) { keepItem(item, true); } } ); const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; if (didAdd) { this.emit("stack-item-added", changeEvent); } else { this.emit("stack-item-updated", changeEvent); } }; this.doc.on("afterTransaction", this.afterTransactionHandler); this.doc.on("destroy", () => { this.destroy(); }); } /** * Extend the scope. * * @param {Array<AbstractType<any> | Doc> | AbstractType<any> | Doc} ytypes */ addToScope(ytypes) { const tmpSet = new Set(this.scope); ytypes = isArray(ytypes) ? ytypes : [ytypes]; ytypes.forEach((ytype) => { if (!tmpSet.has(ytype)) { tmpSet.add(ytype); if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn("[yjs#509] Not same Y.Doc"); this.scope.push(ytype); } }); } /** * @param {any} origin */ addTrackedOrigin(origin2) { this.trackedOrigins.add(origin2); } /** * @param {any} origin */ removeTrackedOrigin(origin2) { this.trackedOrigins.delete(origin2); } clear(clearUndoStack = true, clearRedoStack = true) { if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { this.doc.transact((tr) => { if (clearUndoStack) { this.undoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); this.undoStack = []; } if (clearRedoStack) { this.redoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); this.redoStack = []; } this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); }); } } /** * UndoManager merges Undo-StackItem if they are created within time-gap * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next * StackItem won't be merged. * * * @example * // without stopCapturing * ytext.insert(0, 'a') * ytext.insert(1, 'b') * um.undo() * ytext.toString() // => '' (note that 'ab' was removed) * // with stopCapturing * ytext.insert(0, 'a') * um.stopCapturing() * ytext.insert(0, 'b') * um.undo() * ytext.toString() // => 'a' (note that only 'b' was removed) * */ stopCapturing() { this.lastChange = 0; } /** * Undo last changes on type. * * @return {StackItem?} Returns StackItem if a change was applied */ undo() { this.undoing = true; let res; try { res = popStackItem(this, this.undoStack, "undo"); } finally { this.undoing = false; } return res; } /** * Redo last undo operation. * * @return {StackItem?} Returns StackItem if a change was applied */ redo() { this.redoing = true; let res; try { res = popStackItem(this, this.redoStack, "redo"); } finally { this.redoing = false; } return res; } /** * Are undo steps available? * * @return {boolean} `true` if undo is possible */ canUndo() { return this.undoStack.length > 0; } /** * Are redo steps available? * * @return {boolean} `true` if redo is possible */ canRedo() { return this.redoStack.length > 0; } destroy() { this.trackedOrigins.delete(this); this.doc.off("afterTransaction", this.afterTransactionHandler); super.destroy(); } }; function* lazyStructReaderGenerator(decoder) { const numOfStateUpdates = readVarUint(decoder.restDecoder); for (let i = 0; i < numOfStateUpdates; i++) { const numberOfStructs = readVarUint(decoder.restDecoder); const client = decoder.readClient(); let clock = readVarUint(decoder.restDecoder); for (let i2 = 0; i2 < numberOfStructs; i2++) { const info = decoder.readInfo(); if (info === 10) { const len = readVarUint(decoder.restDecoder); yield new Skip(createID(client, clock), len); clock += len; } else if ((BITS5 & info) !== 0) { const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; const struct = new Item( createID(client, clock), null, // left (info & BIT8) === BIT8 ? decoder.readLeftID() : null, // origin null, // right (info & BIT7) === BIT7 ? decoder.readRightID() : null, // right origin // @ts-ignore Force writing a string here. cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, // parent cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, // parentSub readItemContent(decoder, info) // item content ); yield struct; clock += struct.length; } else { const len = decoder.readLen(); yield new GC(createID(client, clock), len); clock += len; } } } } var LazyStructReader = class { /** * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder * @param {boolean} filterSkips */ constructor(decoder, filterSkips) { this.gen = lazyStructReaderGenerator(decoder); this.curr = null; this.done = false; this.filterSkips = filterSkips; this.next(); } /** * @return {Item | GC | Skip |null} */ next() { do { this.curr = this.gen.next().value || null; } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); return this.curr; } }; var logUpdate = (update) => logUpdateV2(update, UpdateDecoderV1); var logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { const structs = []; const updateDecoder = new YDecoder(createDecoder(update)); const lazyDecoder = new LazyStructReader(updateDecoder, false); for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { structs.push(curr); } print("Structs: ", structs); const ds = readDeleteSet(updateDecoder); print("DeleteSet: ", ds); }; var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1); var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { const structs = []; const updateDecoder = new YDecoder(createDecoder(update)); const lazyDecoder = new LazyStructReader(updateDecoder, false); for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { structs.push(curr); } return { structs, ds: readDeleteSet(updateDecoder) }; }; var LazyStructWriter = class { /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder */ constructor(encoder) { this.currClient = 0; this.startClock = 0; this.written = 0; this.encoder = encoder; this.clientStructs = []; } }; var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); var encodeStateVectorFromUpdateV2 = (update, YEncoder = DSEncoderV2, YDecoder = UpdateDecoderV2) => { const encoder = new YEncoder(); const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); let curr = updateDecoder.curr; if (curr !== null) { let size2 = 0; let currClient = curr.id.client; let stopCounting = curr.id.clock !== 0; let currClock = stopCounting ? 0 : curr.id.clock + curr.length; for (; curr !== null; curr = updateDecoder.next()) { if (currClient !== curr.id.client) { if (currClock !== 0) { size2++; writeVarUint(encoder.restEncoder, currClient); writeVarUint(encoder.restEncoder, currClock); } currClient = curr.id.client; currClock = 0; stopCounting = curr.id.clock !== 0; } if (curr.constructor === Skip) { stopCounting = true; } if (!stopCounting) { currClock = curr.id.clock + curr.length; } } if (currClock !== 0) { size2++; writeVarUint(encoder.restEncoder, currClient); writeVarUint(encoder.restEncoder, currClock); } const enc = createEncoder(); writeVarUint(enc, size2); writeBinaryEncoder(enc, encoder.restEncoder); encoder.restEncoder = enc; return encoder.toUint8Array(); } else { writeVarUint(encoder.restEncoder, 0); return encoder.toUint8Array(); } }; var encodeStateVectorFromUpdate = (update) => encodeStateVectorFromUpdateV2(update, DSEncoderV1, UpdateDecoderV1); var parseUpdateMetaV2 = (update, YDecoder = UpdateDecoderV2) => { const from2 = /* @__PURE__ */ new Map(); const to = /* @__PURE__ */ new Map(); const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); let curr = updateDecoder.curr; if (curr !== null) { let currClient = curr.id.client; let currClock = curr.id.clock; from2.set(currClient, currClock); for (; curr !== null; curr = updateDecoder.next()) { if (currClient !== curr.id.client) { to.set(currClient, currClock); from2.set(curr.id.client, curr.id.clock); currClient = curr.id.client; } currClock = curr.id.clock + curr.length; } to.set(currClient, currClock); } return { from: from2, to }; }; var parseUpdateMeta = (update) => parseUpdateMetaV2(update, UpdateDecoderV1); var sliceStruct = (left, diff) => { if (left.constructor === GC) { const { client, clock } = left.id; return new GC(createID(client, clock + diff), left.length - diff); } else if (left.constructor === Skip) { const { client, clock } = left.id; return new Skip(createID(client, clock + diff), left.length - diff); } else { const leftItem = ( /** @type {Item} */ left ); const { client, clock } = leftItem.id; return new Item( createID(client, clock + diff), null, createID(client, clock + diff - 1), null, leftItem.rightOrigin, leftItem.parent, leftItem.parentSub, leftItem.content.splice(diff) ); } }; var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { if (updates.length === 1) { return updates[0]; } const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); let currWrite = null; const updateEncoder = new YEncoder(); const lazyStructEncoder = new LazyStructWriter(updateEncoder); while (true) { lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); lazyStructDecoders.sort( /** @type {function(any,any):number} */ (dec1, dec2) => { if (dec1.curr.id.client === dec2.curr.id.client) { const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; if (clockDiff === 0) { return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; } else { return clockDiff; } } else { return dec2.curr.id.client - dec1.curr.id.client; } } ); if (lazyStructDecoders.length === 0) { break; } const currDecoder = lazyStructDecoders[0]; const firstClient = ( /** @type {Item | GC} */ currDecoder.curr.id.client ); if (currWrite !== null) { let curr = ( /** @type {Item | GC | null} */ currDecoder.curr ); let iterated = false; while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { curr = currDecoder.next(); iterated = true; } if (curr === null || // current decoder is empty curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { continue; } if (firstClient !== currWrite.struct.id.client) { writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); currWrite = { struct: curr, offset: 0 }; currDecoder.next(); } else { if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { if (currWrite.struct.constructor === Skip) { currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; } else { writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); currWrite = { struct, offset: 0 }; } } else { const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; if (diff > 0) { if (currWrite.struct.constructor === Skip) { currWrite.struct.length -= diff; } else { curr = sliceStruct(curr, diff); } } if (!currWrite.struct.mergeWith( /** @type {any} */ curr )) { writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); currWrite = { struct: curr, offset: 0 }; currDecoder.next(); } } } } else { currWrite = { struct: ( /** @type {Item | GC} */ currDecoder.curr ), offset: 0 }; currDecoder.next(); } for (let next = currDecoder.curr; next !== null && next.id.client === firstClient && next.id.clock === currWrite.struct.id.clock + currWrite.struct.length && next.constructor !== Skip; next = currDecoder.next()) { writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); currWrite = { struct: next, offset: 0 }; } } if (currWrite !== null) { writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); currWrite = null; } finishLazyStructWriting(lazyStructEncoder); const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); const ds = mergeDeleteSets(dss); writeDeleteSet(updateEncoder, ds); return updateEncoder.toUint8Array(); }; var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { const state = decodeStateVector(sv); const encoder = new YEncoder(); const lazyStructWriter = new LazyStructWriter(encoder); const decoder = new YDecoder(createDecoder(update)); const reader = new LazyStructReader(decoder, false); while (reader.curr) { const curr = reader.curr; const currClient = curr.id.client; const svClock = state.get(currClient) || 0; if (reader.curr.constructor === Skip) { reader.next(); continue; } if (curr.id.clock + curr.length > svClock) { writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); reader.next(); while (reader.curr && reader.curr.id.client === currClient) { writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); reader.next(); } } else { while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { reader.next(); } } } finishLazyStructWriting(lazyStructWriter); const ds = readDeleteSet(decoder); writeDeleteSet(encoder, ds); return encoder.toUint8Array(); }; var diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1); var flushLazyStructWriter = (lazyWriter) => { if (lazyWriter.written > 0) { lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); lazyWriter.encoder.restEncoder = createEncoder(); lazyWriter.written = 0; } }; var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { flushLazyStructWriter(lazyWriter); } if (lazyWriter.written === 0) { lazyWriter.currClient = struct.id.client; lazyWriter.encoder.writeClient(struct.id.client); writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); } struct.write(lazyWriter.encoder, offset); lazyWriter.written++; }; var finishLazyStructWriting = (lazyWriter) => { flushLazyStructWriter(lazyWriter); const restEncoder = lazyWriter.encoder.restEncoder; writeVarUint(restEncoder, lazyWriter.clientStructs.length); for (let i = 0; i < lazyWriter.clientStructs.length; i++) { const partStructs = lazyWriter.clientStructs[i]; writeVarUint(restEncoder, partStructs.written); writeUint8Array(restEncoder, partStructs.restEncoder); } }; var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { const updateDecoder = new YDecoder(createDecoder(update)); const lazyDecoder = new LazyStructReader(updateDecoder, false); const updateEncoder = new YEncoder(); const lazyWriter = new LazyStructWriter(updateEncoder); for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); } finishLazyStructWriting(lazyWriter); const ds = readDeleteSet(updateDecoder); writeDeleteSet(updateEncoder, ds); return updateEncoder.toUint8Array(); }; var createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {}) => { let i = 0; const mapKeyCache = create(); const nodeNameCache = create(); const formattingKeyCache = create(); const formattingValueCache = create(); formattingValueCache.set(null, null); return (block) => { switch (block.constructor) { case GC: case Skip: return block; case Item: { const item = ( /** @type {Item} */ block ); const content = item.content; switch (content.constructor) { case ContentDeleted: break; case ContentType: { if (yxml) { const type = ( /** @type {ContentType} */ content.type ); if (type instanceof YXmlElement) { type.nodeName = setIfUndefined(nodeNameCache, type.nodeName, () => "node-" + i); } if (type instanceof YXmlHook) { type.hookName = setIfUndefined(nodeNameCache, type.hookName, () => "hook-" + i); } } break; } case ContentAny: { const c = ( /** @type {ContentAny} */ content ); c.arr = c.arr.map(() => i); break; } case ContentBinary: { const c = ( /** @type {ContentBinary} */ content ); c.content = new Uint8Array([i]); break; } case ContentDoc: { const c = ( /** @type {ContentDoc} */ content ); if (subdocs) { c.opts = {}; c.doc.guid = i + ""; } break; } case ContentEmbed: { const c = ( /** @type {ContentEmbed} */ content ); c.embed = {}; break; } case ContentFormat: { const c = ( /** @type {ContentFormat} */ content ); if (formatting) { c.key = setIfUndefined(formattingKeyCache, c.key, () => i + ""); c.value = setIfUndefined(formattingValueCache, c.value, () => ({ i })); } break; } case ContentJSON: { const c = ( /** @type {ContentJSON} */ content ); c.arr = c.arr.map(() => i); break; } case ContentString: { const c = ( /** @type {ContentString} */ content ); c.str = repeat(i % 10 + "", c.str.length); break; } default: unexpectedCase(); } if (item.parentSub) { item.parentSub = setIfUndefined(mapKeyCache, item.parentSub, () => i + ""); } i++; return block; } default: unexpectedCase(); } }; }; var obfuscateUpdate = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV1, UpdateEncoderV1); var obfuscateUpdateV2 = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV2, UpdateEncoderV2); var convertUpdateFormatV1ToV2 = (update) => convertUpdateFormat(update, id, UpdateDecoderV1, UpdateEncoderV2); var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); var errorComputeChanges = "You must not compute changes after the event-handler fired."; var YEvent = class { /** * @param {T} target The changed type. * @param {Transaction} transaction */ constructor(target, transaction) { this.target = target; this.currentTarget = target; this.transaction = transaction; this._changes = null; this._keys = null; this._delta = null; this._path = null; } /** * Computes the path from `y` to the changed type. * * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. * * The following property holds: * @example * let type = y * event.path.forEach(dir => { * type = type.get(dir) * }) * type === event.target // => true */ get path() { return this._path || (this._path = getPathTo(this.currentTarget, this.target)); } /** * Check if a struct is deleted by this event. * * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. * * @param {AbstractStruct} struct * @return {boolean} */ deletes(struct) { return isDeleted(this.transaction.deleteSet, struct.id); } /** * @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>} */ get keys() { if (this._keys === null) { if (this.transaction.doc._transactionCleanups.length === 0) { throw create3(errorComputeChanges); } const keys2 = /* @__PURE__ */ new Map(); const target = this.target; const changed = ( /** @type Set<string|null> */ this.transaction.changed.get(target) ); changed.forEach((key) => { if (key !== null) { const item = ( /** @type {Item} */ target._map.get(key) ); let action; let oldValue; if (this.adds(item)) { let prev = item.left; while (prev !== null && this.adds(prev)) { prev = prev.left; } if (this.deletes(item)) { if (prev !== null && this.deletes(prev)) { action = "delete"; oldValue = last(prev.content.getContent()); } else { return; } } else { if (prev !== null && this.deletes(prev)) { action = "update"; oldValue = last(prev.content.getContent()); } else { action = "add"; oldValue = void 0; } } } else { if (this.deletes(item)) { action = "delete"; oldValue = last( /** @type {Item} */ item.content.getContent() ); } else { return; } } keys2.set(key, { action, oldValue }); } }); this._keys = keys2; } return this._keys; } /** * This is a computed property. Note that this can only be safely computed during the * event call. Computing this property after other changes happened might result in * unexpected behavior (incorrect computation of deltas). A safe way to collect changes * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. * * @type {Array<{insert?: string | Array<any> | object | AbstractType<any>, retain?: number, delete?: number, attributes?: Object<string, any>}>} */ get delta() { return this.changes.delta; } /** * Check if a struct is added by this event. * * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. * * @param {AbstractStruct} struct * @return {boolean} */ adds(struct) { return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); } /** * This is a computed property. Note that this can only be safely computed during the * event call. Computing this property after other changes happened might result in * unexpected behavior (incorrect computation of deltas). A safe way to collect changes * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. * * @type {{added:Set<Item>,deleted:Set<Item>,keys:Map<string,{action:'add'|'update'|'delete',oldValue:any}>,delta:Array<{insert?:Array<any>|string, delete?:number, retain?:number}>}} */ get changes() { let changes = this._changes; if (changes === null) { if (this.transaction.doc._transactionCleanups.length === 0) { throw create3(errorComputeChanges); } const target = this.target; const added = create2(); const deleted = create2(); const delta = []; changes = { added, deleted, delta, keys: this.keys }; const changed = ( /** @type Set<string|null> */ this.transaction.changed.get(target) ); if (changed.has(null)) { let lastOp = null; const packOp = () => { if (lastOp) { delta.push(lastOp); } }; for (let item = target._start; item !== null; item = item.right) { if (item.deleted) { if (this.deletes(item) && !this.adds(item)) { if (lastOp === null || lastOp.delete === void 0) { packOp(); lastOp = { delete: 0 }; } lastOp.delete += item.length; deleted.add(item); } } else { if (this.adds(item)) { if (lastOp === null || lastOp.insert === void 0) { packOp(); lastOp = { insert: [] }; } lastOp.insert = lastOp.insert.concat(item.content.getContent()); added.add(item); } else { if (lastOp === null || lastOp.retain === void 0) { packOp(); lastOp = { retain: 0 }; } lastOp.retain += item.length; } } } if (lastOp !== null && lastOp.retain === void 0) { packOp(); } } this._changes = changes; } return ( /** @type {any} */ changes ); } }; var getPathTo = (parent, child) => { const path = []; while (child._item !== null && child !== parent) { if (child._item.parentSub !== null) { path.unshift(child._item.parentSub); } else { let i = 0; let c = ( /** @type {AbstractType<any>} */ child._item.parent._start ); while (c !== child._item && c !== null) { if (!c.deleted && c.countable) { i += c.length; } c = c.right; } path.unshift(i); } child = /** @type {AbstractType<any>} */ child._item.parent; } return path; }; var warnPrematureAccess = () => { warn("Invalid access: Add Yjs type to a document before reading data."); }; var maxSearchMarker = 80; var globalSearchMarkerTimestamp = 0; var ArraySearchMarker = class { /** * @param {Item} p * @param {number} index */ constructor(p, index) { p.marker = true; this.p = p; this.index = index; this.timestamp = globalSearchMarkerTimestamp++; } }; var refreshMarkerTimestamp = (marker) => { marker.timestamp = globalSearchMarkerTimestamp++; }; var overwriteMarker = (marker, p, index) => { marker.p.marker = false; marker.p = p; p.marker = true; marker.index = index; marker.timestamp = globalSearchMarkerTimestamp++; }; var markPosition = (searchMarker, p, index) => { if (searchMarker.length >= maxSearchMarker) { const marker = searchMarker.reduce((a, b) => a.timestamp < b.timestamp ? a : b); overwriteMarker(marker, p, index); return marker; } else { const pm = new ArraySearchMarker(p, index); searchMarker.push(pm); return pm; } }; var findMarker = (yarray, index) => { if (yarray._start === null || index === 0 || yarray._searchMarker === null) { return null; } const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b) => abs(index - a.index) < abs(index - b.index) ? a : b); let p = yarray._start; let pindex = 0; if (marker !== null) { p = marker.p; pindex = marker.index; refreshMarkerTimestamp(marker); } while (p.right !== null && pindex < index) { if (!p.deleted && p.countable) { if (index < pindex + p.length) { break; } pindex += p.length; } p = p.right; } while (p.left !== null && pindex > index) { p = p.left; if (!p.deleted && p.countable) { pindex -= p.length; } } while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { p = p.left; if (!p.deleted && p.countable) { pindex -= p.length; } } if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray<any>} */ p.parent.length / maxSearchMarker) { overwriteMarker(marker, p, pindex); return marker; } else { return markPosition(yarray._searchMarker, p, pindex); } }; var updateMarkerChanges = (searchMarker, index, len) => { for (let i = searchMarker.length - 1; i >= 0; i--) { const m = searchMarker[i]; if (len > 0) { let p = m.p; p.marker = false; while (p && (p.deleted || !p.countable)) { p = p.left; if (p && !p.deleted && p.countable) { m.index -= p.length; } } if (p === null || p.marker === true) { searchMarker.splice(i, 1); continue; } m.p = p; p.marker = true; } if (index < m.index || len > 0 && index === m.index) { m.index = max(index, m.index + len); } } }; var getTypeChildren = (t) => { t.doc ?? warnPrematureAccess(); let s = t._start; const arr = []; while (s) { arr.push(s); s = s.right; } return arr; }; var callTypeObservers = (type, transaction, event) => { const changedType = type; const changedParentTypes = transaction.changedParentTypes; while (true) { setIfUndefined(changedParentTypes, type, () => []).push(event); if (type._item === null) { break; } type = /** @type {AbstractType<any>} */ type._item.parent; } callEventHandlerListeners(changedType._eH, event, transaction); }; var AbstractType = class { constructor() { this._item = null; this._map = /* @__PURE__ */ new Map(); this._start = null; this.doc = null; this._length = 0; this._eH = createEventHandler(); this._dEH = createEventHandler(); this._searchMarker = null; } /** * @return {AbstractType<any>|null} */ get parent() { return this._item ? ( /** @type {AbstractType<any>} */ this._item.parent ) : null; } /** * Integrate this type into the Yjs instance. * * * Save this struct in the os * * This type is sent to other client * * Observer functions are fired * * @param {Doc} y The Yjs instance * @param {Item|null} item */ _integrate(y, item) { this.doc = y; this._item = item; } /** * @return {AbstractType<EventType>} */ _copy() { throw methodUnimplemented(); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {AbstractType<EventType>} */ clone() { throw methodUnimplemented(); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder */ _write(_encoder) { } /** * The first non-deleted item */ get _first() { let n = this._start; while (n !== null && n.deleted) { n = n.right; } return n; } /** * Creates YEvent and calls all type observers. * Must be implemented by each type. * * @param {Transaction} transaction * @param {Set<null|string>} _parentSubs Keys changed on this type. `null` if list was modified. */ _callObserver(transaction, _parentSubs) { if (!transaction.local && this._searchMarker) { this._searchMarker.length = 0; } } /** * Observe all events that are created on this type. * * @param {function(EventType, Transaction):void} f Observer function */ observe(f) { addEventHandlerListener(this._eH, f); } /** * Observe all events that are created by this type and its children. * * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function */ observeDeep(f) { addEventHandlerListener(this._dEH, f); } /** * Unregister an observer function. * * @param {function(EventType,Transaction):void} f Observer function */ unobserve(f) { removeEventHandlerListener(this._eH, f); } /** * Unregister an observer function. * * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function */ unobserveDeep(f) { removeEventHandlerListener(this._dEH, f); } /** * @abstract * @return {any} */ toJSON() { } }; var typeListSlice = (type, start, end) => { type.doc ?? warnPrematureAccess(); if (start < 0) { start = type._length + start; } if (end < 0) { end = type._length + end; } let len = end - start; const cs = []; let n = type._start; while (n !== null && len > 0) { if (n.countable && !n.deleted) { const c = n.content.getContent(); if (c.length <= start) { start -= c.length; } else { for (let i = start; i < c.length && len > 0; i++) { cs.push(c[i]); len--; } start = 0; } } n = n.right; } return cs; }; var typeListToArray = (type) => { type.doc ?? warnPrematureAccess(); const cs = []; let n = type._start; while (n !== null) { if (n.countable && !n.deleted) { const c = n.content.getContent(); for (let i = 0; i < c.length; i++) { cs.push(c[i]); } } n = n.right; } return cs; }; var typeListToArraySnapshot = (type, snapshot2) => { const cs = []; let n = type._start; while (n !== null) { if (n.countable && isVisible(n, snapshot2)) { const c = n.content.getContent(); for (let i = 0; i < c.length; i++) { cs.push(c[i]); } } n = n.right; } return cs; }; var typeListForEach = (type, f) => { let index = 0; let n = type._start; type.doc ?? warnPrematureAccess(); while (n !== null) { if (n.countable && !n.deleted) { const c = n.content.getContent(); for (let i = 0; i < c.length; i++) { f(c[i], index++, type); } } n = n.right; } }; var typeListMap = (type, f) => { const result = []; typeListForEach(type, (c, i) => { result.push(f(c, i, type)); }); return result; }; var typeListCreateIterator = (type) => { let n = type._start; let currentContent = null; let currentContentIndex = 0; return { [Symbol.iterator]() { return this; }, next: () => { if (currentContent === null) { while (n !== null && n.deleted) { n = n.right; } if (n === null) { return { done: true, value: void 0 }; } currentContent = n.content.getContent(); currentContentIndex = 0; n = n.right; } const value = currentContent[currentContentIndex++]; if (currentContent.length <= currentContentIndex) { currentContent = null; } return { done: false, value }; } }; }; var typeListGet = (type, index) => { type.doc ?? warnPrematureAccess(); const marker = findMarker(type, index); let n = type._start; if (marker !== null) { n = marker.p; index -= marker.index; } for (; n !== null; n = n.right) { if (!n.deleted && n.countable) { if (index < n.length) { return n.content.getContent()[index]; } index -= n.length; } } }; var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { let left = referenceItem; const doc2 = transaction.doc; const ownClientId = doc2.clientID; const store = doc2.store; const right = referenceItem === null ? parent._start : referenceItem.right; let jsonContent = []; const packJsonContent = () => { if (jsonContent.length > 0) { left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); left.integrate(transaction, 0); jsonContent = []; } }; content.forEach((c) => { if (c === null) { jsonContent.push(c); } else { switch (c.constructor) { case Number: case Object: case Boolean: case Array: case String: jsonContent.push(c); break; default: packJsonContent(); switch (c.constructor) { case Uint8Array: case ArrayBuffer: left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( /** @type {Uint8Array} */ c ))); left.integrate(transaction, 0); break; case Doc: left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( /** @type {Doc} */ c )); left.integrate(transaction, 0); break; default: if (c instanceof AbstractType) { left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); left.integrate(transaction, 0); } else { throw new Error("Unexpected content type in insert operation"); } } } } }); packJsonContent(); }; var lengthExceeded = () => create3("Length exceeded!"); var typeListInsertGenerics = (transaction, parent, index, content) => { if (index > parent._length) { throw lengthExceeded(); } if (index === 0) { if (parent._searchMarker) { updateMarkerChanges(parent._searchMarker, index, content.length); } return typeListInsertGenericsAfter(transaction, parent, null, content); } const startIndex = index; const marker = findMarker(parent, index); let n = parent._start; if (marker !== null) { n = marker.p; index -= marker.index; if (index === 0) { n = n.prev; index += n && n.countable && !n.deleted ? n.length : 0; } } for (; n !== null; n = n.right) { if (!n.deleted && n.countable) { if (index <= n.length) { if (index < n.length) { getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); } break; } index -= n.length; } } if (parent._searchMarker) { updateMarkerChanges(parent._searchMarker, startIndex, content.length); } return typeListInsertGenericsAfter(transaction, parent, n, content); }; var typeListPushGenerics = (transaction, parent, content) => { const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); let n = marker.p; if (n) { while (n.right) { n = n.right; } } return typeListInsertGenericsAfter(transaction, parent, n, content); }; var typeListDelete = (transaction, parent, index, length3) => { if (length3 === 0) { return; } const startIndex = index; const startLength = length3; const marker = findMarker(parent, index); let n = parent._start; if (marker !== null) { n = marker.p; index -= marker.index; } for (; n !== null && index > 0; n = n.right) { if (!n.deleted && n.countable) { if (index < n.length) { getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); } index -= n.length; } } while (length3 > 0 && n !== null) { if (!n.deleted) { if (length3 < n.length) { getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length3)); } n.delete(transaction); length3 -= n.length; } n = n.right; } if (length3 > 0) { throw lengthExceeded(); } if (parent._searchMarker) { updateMarkerChanges( parent._searchMarker, startIndex, -startLength + length3 /* in case we remove the above exception */ ); } }; var typeMapDelete = (transaction, parent, key) => { const c = parent._map.get(key); if (c !== void 0) { c.delete(transaction); } }; var typeMapSet = (transaction, parent, key, value) => { const left = parent._map.get(key) || null; const doc2 = transaction.doc; const ownClientId = doc2.clientID; let content; if (value == null) { content = new ContentAny([value]); } else { switch (value.constructor) { case Number: case Object: case Boolean: case Array: case String: case Date: case BigInt: content = new ContentAny([value]); break; case Uint8Array: content = new ContentBinary( /** @type {Uint8Array} */ value ); break; case Doc: content = new ContentDoc( /** @type {Doc} */ value ); break; default: if (value instanceof AbstractType) { content = new ContentType(value); } else { throw new Error("Unexpected content type"); } } } new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); }; var typeMapGet = (parent, key) => { parent.doc ?? warnPrematureAccess(); const val = parent._map.get(key); return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; }; var typeMapGetAll = (parent) => { const res = {}; parent.doc ?? warnPrematureAccess(); parent._map.forEach((value, key) => { if (!value.deleted) { res[key] = value.content.getContent()[value.length - 1]; } }); return res; }; var typeMapHas = (parent, key) => { parent.doc ?? warnPrematureAccess(); const val = parent._map.get(key); return val !== void 0 && !val.deleted; }; var typeMapGetSnapshot = (parent, key, snapshot2) => { let v = parent._map.get(key) || null; while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { v = v.left; } return v !== null && isVisible(v, snapshot2) ? v.content.getContent()[v.length - 1] : void 0; }; var typeMapGetAllSnapshot = (parent, snapshot2) => { const res = {}; parent._map.forEach((value, key) => { let v = value; while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { v = v.left; } if (v !== null && isVisible(v, snapshot2)) { res[key] = v.content.getContent()[v.length - 1]; } }); return res; }; var createMapIterator = (type) => { type.doc ?? warnPrematureAccess(); return iteratorFilter( type._map.entries(), /** @param {any} entry */ (entry) => !entry[1].deleted ); }; var YArrayEvent = class extends YEvent { }; var YArray = class _YArray extends AbstractType { constructor() { super(); this._prelimContent = []; this._searchMarker = []; } /** * Construct a new YArray containing the specified items. * @template {Object<string,any>|Array<any>|number|null|string|Uint8Array} T * @param {Array<T>} items * @return {YArray<T>} */ static from(items) { const a = new _YArray(); a.push(items); return a; } /** * Integrate this type into the Yjs instance. * * * Save this struct in the os * * This type is sent to other client * * Observer functions are fired * * @param {Doc} y The Yjs instance * @param {Item} item */ _integrate(y, item) { super._integrate(y, item); this.insert( 0, /** @type {Array<any>} */ this._prelimContent ); this._prelimContent = null; } /** * @return {YArray<T>} */ _copy() { return new _YArray(); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YArray<T>} */ clone() { const arr = new _YArray(); arr.insert(0, this.toArray().map( (el) => el instanceof AbstractType ? ( /** @type {typeof el} */ el.clone() ) : el )); return arr; } get length() { this.doc ?? warnPrematureAccess(); return this._length; } /** * Creates YArrayEvent and calls observers. * * @param {Transaction} transaction * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. */ _callObserver(transaction, parentSubs) { super._callObserver(transaction, parentSubs); callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); } /** * Inserts new content at an index. * * Important: This function expects an array of content. Not just a content * object. The reason for this "weirdness" is that inserting several elements * is very efficient when it is done as a single operation. * * @example * // Insert character 'a' at position 0 * yarray.insert(0, ['a']) * // Insert numbers 1, 2 at position 1 * yarray.insert(1, [1, 2]) * * @param {number} index The index to insert content at. * @param {Array<T>} content The array of content */ insert(index, content) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeListInsertGenerics( transaction, this, index, /** @type {any} */ content ); }); } else { this._prelimContent.splice(index, 0, ...content); } } /** * Appends content to this YArray. * * @param {Array<T>} content Array of content to append. * * @todo Use the following implementation in all types. */ push(content) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeListPushGenerics( transaction, this, /** @type {any} */ content ); }); } else { this._prelimContent.push(...content); } } /** * Prepends content to this YArray. * * @param {Array<T>} content Array of content to prepend. */ unshift(content) { this.insert(0, content); } /** * Deletes elements starting from an index. * * @param {number} index Index at which to start deleting elements * @param {number} length The number of elements to remove. Defaults to 1. */ delete(index, length3 = 1) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeListDelete(transaction, this, index, length3); }); } else { this._prelimContent.splice(index, length3); } } /** * Returns the i-th element from a YArray. * * @param {number} index The index of the element to return from the YArray * @return {T} */ get(index) { return typeListGet(this, index); } /** * Transforms this YArray to a JavaScript Array. * * @return {Array<T>} */ toArray() { return typeListToArray(this); } /** * Returns a portion of this YArray into a JavaScript Array selected * from start to end (end not included). * * @param {number} [start] * @param {number} [end] * @return {Array<T>} */ slice(start = 0, end = this.length) { return typeListSlice(this, start, end); } /** * Transforms this Shared Type to a JSON object. * * @return {Array<any>} */ toJSON() { return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); } /** * Returns an Array with the result of calling a provided function on every * element of this YArray. * * @template M * @param {function(T,number,YArray<T>):M} f Function that produces an element of the new Array * @return {Array<M>} A new array with each element being the result of the * callback function */ map(f) { return typeListMap( this, /** @type {any} */ f ); } /** * Executes a provided function once on every element of this YArray. * * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray. */ forEach(f) { typeListForEach(this, f); } /** * @return {IterableIterator<T>} */ [Symbol.iterator]() { return typeListCreateIterator(this); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder */ _write(encoder) { encoder.writeTypeRef(YArrayRefID); } }; var readYArray = (_decoder) => new YArray(); var YMapEvent = class extends YEvent { /** * @param {YMap<T>} ymap The YArray that changed. * @param {Transaction} transaction * @param {Set<any>} subs The keys that changed. */ constructor(ymap, transaction, subs) { super(ymap, transaction); this.keysChanged = subs; } }; var YMap = class _YMap extends AbstractType { /** * * @param {Iterable<readonly [string, any]>=} entries - an optional iterable to initialize the YMap */ constructor(entries) { super(); this._prelimContent = null; if (entries === void 0) { this._prelimContent = /* @__PURE__ */ new Map(); } else { this._prelimContent = new Map(entries); } } /** * Integrate this type into the Yjs instance. * * * Save this struct in the os * * This type is sent to other client * * Observer functions are fired * * @param {Doc} y The Yjs instance * @param {Item} item */ _integrate(y, item) { super._integrate(y, item); this._prelimContent.forEach((value, key) => { this.set(key, value); }); this._prelimContent = null; } /** * @return {YMap<MapType>} */ _copy() { return new _YMap(); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YMap<MapType>} */ clone() { const map2 = new _YMap(); this.forEach((value, key) => { map2.set(key, value instanceof AbstractType ? ( /** @type {typeof value} */ value.clone() ) : value); }); return map2; } /** * Creates YMapEvent and calls observers. * * @param {Transaction} transaction * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. */ _callObserver(transaction, parentSubs) { callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); } /** * Transforms this Shared Type to a JSON object. * * @return {Object<string,any>} */ toJSON() { this.doc ?? warnPrematureAccess(); const map2 = {}; this._map.forEach((item, key) => { if (!item.deleted) { const v = item.content.getContent()[item.length - 1]; map2[key] = v instanceof AbstractType ? v.toJSON() : v; } }); return map2; } /** * Returns the size of the YMap (count of key/value pairs) * * @return {number} */ get size() { return [...createMapIterator(this)].length; } /** * Returns the keys for each element in the YMap Type. * * @return {IterableIterator<string>} */ keys() { return iteratorMap( createMapIterator(this), /** @param {any} v */ (v) => v[0] ); } /** * Returns the values for each element in the YMap Type. * * @return {IterableIterator<MapType>} */ values() { return iteratorMap( createMapIterator(this), /** @param {any} v */ (v) => v[1].content.getContent()[v[1].length - 1] ); } /** * Returns an Iterator of [key, value] pairs * * @return {IterableIterator<[string, MapType]>} */ entries() { return iteratorMap( createMapIterator(this), /** @param {any} v */ (v) => ( /** @type {any} */ [v[0], v[1].content.getContent()[v[1].length - 1]] ) ); } /** * Executes a provided function on once on every key-value pair. * * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray. */ forEach(f) { this.doc ?? warnPrematureAccess(); this._map.forEach((item, key) => { if (!item.deleted) { f(item.content.getContent()[item.length - 1], key, this); } }); } /** * Returns an Iterator of [key, value] pairs * * @return {IterableIterator<[string, MapType]>} */ [Symbol.iterator]() { return this.entries(); } /** * Remove a specified element from this YMap. * * @param {string} key The key of the element to remove. */ delete(key) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeMapDelete(transaction, this, key); }); } else { this._prelimContent.delete(key); } } /** * Adds or updates an element with a specified key and value. * @template {MapType} VAL * * @param {string} key The key of the element to add to this YMap * @param {VAL} value The value of the element to add * @return {VAL} */ set(key, value) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeMapSet( transaction, this, key, /** @type {any} */ value ); }); } else { this._prelimContent.set(key, value); } return value; } /** * Returns a specified element from this YMap. * * @param {string} key * @return {MapType|undefined} */ get(key) { return ( /** @type {any} */ typeMapGet(this, key) ); } /** * Returns a boolean indicating whether the specified key exists or not. * * @param {string} key The key to test. * @return {boolean} */ has(key) { return typeMapHas(this, key); } /** * Removes all elements from this YMap. */ clear() { if (this.doc !== null) { transact(this.doc, (transaction) => { this.forEach(function(_value, key, map2) { typeMapDelete(transaction, map2, key); }); }); } else { this._prelimContent.clear(); } } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder */ _write(encoder) { encoder.writeTypeRef(YMapRefID); } }; var readYMap = (_decoder) => new YMap(); var equalAttrs = (a, b) => a === b || typeof a === "object" && typeof b === "object" && a && b && equalFlat(a, b); var ItemTextListPosition = class { /** * @param {Item|null} left * @param {Item|null} right * @param {number} index * @param {Map<string,any>} currentAttributes */ constructor(left, right, index, currentAttributes) { this.left = left; this.right = right; this.index = index; this.currentAttributes = currentAttributes; } /** * Only call this if you know that this.right is defined */ forward() { if (this.right === null) { unexpectedCase(); } switch (this.right.content.constructor) { case ContentFormat: if (!this.right.deleted) { updateCurrentAttributes( this.currentAttributes, /** @type {ContentFormat} */ this.right.content ); } break; default: if (!this.right.deleted) { this.index += this.right.length; } break; } this.left = this.right; this.right = this.right.right; } }; var findNextPosition = (transaction, pos, count) => { while (pos.right !== null && count > 0) { switch (pos.right.content.constructor) { case ContentFormat: if (!pos.right.deleted) { updateCurrentAttributes( pos.currentAttributes, /** @type {ContentFormat} */ pos.right.content ); } break; default: if (!pos.right.deleted) { if (count < pos.right.length) { getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); } pos.index += pos.right.length; count -= pos.right.length; } break; } pos.left = pos.right; pos.right = pos.right.right; } return pos; }; var findPosition = (transaction, parent, index, useSearchMarker) => { const currentAttributes = /* @__PURE__ */ new Map(); const marker = useSearchMarker ? findMarker(parent, index) : null; if (marker) { const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); return findNextPosition(transaction, pos, index - marker.index); } else { const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); return findNextPosition(transaction, pos, index); } }; var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( negatedAttributes.get( /** @type {ContentFormat} */ currPos.right.content.key ), /** @type {ContentFormat} */ currPos.right.content.value ))) { if (!currPos.right.deleted) { negatedAttributes.delete( /** @type {ContentFormat} */ currPos.right.content.key ); } currPos.forward(); } const doc2 = transaction.doc; const ownClientId = doc2.clientID; negatedAttributes.forEach((val, key) => { const left = currPos.left; const right = currPos.right; const nextFormat = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); nextFormat.integrate(transaction, 0); currPos.right = nextFormat; currPos.forward(); }); }; var updateCurrentAttributes = (currentAttributes, format) => { const { key, value } = format; if (value === null) { currentAttributes.delete(key); } else { currentAttributes.set(key, value); } }; var minimizeAttributeChanges = (currPos, attributes) => { while (true) { if (currPos.right === null) { break; } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( attributes[ /** @type {ContentFormat} */ currPos.right.content.key ] ?? null, /** @type {ContentFormat} */ currPos.right.content.value )) ; else { break; } currPos.forward(); } }; var insertAttributes = (transaction, parent, currPos, attributes) => { const doc2 = transaction.doc; const ownClientId = doc2.clientID; const negatedAttributes = /* @__PURE__ */ new Map(); for (const key in attributes) { const val = attributes[key]; const currentVal = currPos.currentAttributes.get(key) ?? null; if (!equalAttrs(currentVal, val)) { negatedAttributes.set(key, currentVal); const { left, right } = currPos; currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); currPos.right.integrate(transaction, 0); currPos.forward(); } } return negatedAttributes; }; var insertText = (transaction, parent, currPos, text2, attributes) => { currPos.currentAttributes.forEach((_val, key) => { if (attributes[key] === void 0) { attributes[key] = null; } }); const doc2 = transaction.doc; const ownClientId = doc2.clientID; minimizeAttributeChanges(currPos, attributes); const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); const content = text2.constructor === String ? new ContentString( /** @type {string} */ text2 ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); let { left, right, index } = currPos; if (parent._searchMarker) { updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); } right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); right.integrate(transaction, 0); currPos.right = right; currPos.index = index; currPos.forward(); insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); }; var formatText = (transaction, parent, currPos, length3, attributes) => { const doc2 = transaction.doc; const ownClientId = doc2.clientID; minimizeAttributeChanges(currPos, attributes); const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); iterationLoop: while (currPos.right !== null && (length3 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { if (!currPos.right.deleted) { switch (currPos.right.content.constructor) { case ContentFormat: { const { key, value } = ( /** @type {ContentFormat} */ currPos.right.content ); const attr = attributes[key]; if (attr !== void 0) { if (equalAttrs(attr, value)) { negatedAttributes.delete(key); } else { if (length3 === 0) { break iterationLoop; } negatedAttributes.set(key, value); } currPos.right.delete(transaction); } else { currPos.currentAttributes.set(key, value); } break; } default: if (length3 < currPos.right.length) { getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length3)); } length3 -= currPos.right.length; break; } } currPos.forward(); } if (length3 > 0) { let newlines = ""; for (; length3 > 0; length3--) { newlines += "\n"; } currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), currPos.left, currPos.left && currPos.left.lastId, currPos.right, currPos.right && currPos.right.id, parent, null, new ContentString(newlines)); currPos.right.integrate(transaction, 0); currPos.forward(); } insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); }; var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { let end = start; const endFormats = create(); while (end && (!end.countable || end.deleted)) { if (!end.deleted && end.content.constructor === ContentFormat) { const cf = ( /** @type {ContentFormat} */ end.content ); endFormats.set(cf.key, cf); } end = end.right; } let cleanups = 0; let reachedCurr = false; while (start !== end) { if (curr === start) { reachedCurr = true; } if (!start.deleted) { const content = start.content; switch (content.constructor) { case ContentFormat: { const { key, value } = ( /** @type {ContentFormat} */ content ); const startAttrValue = startAttributes.get(key) ?? null; if (endFormats.get(key) !== content || startAttrValue === value) { start.delete(transaction); cleanups++; if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { if (startAttrValue === null) { currAttributes.delete(key); } else { currAttributes.set(key, startAttrValue); } } } if (!reachedCurr && !start.deleted) { updateCurrentAttributes( currAttributes, /** @type {ContentFormat} */ content ); } break; } } } start = /** @type {Item} */ start.right; } return cleanups; }; var cleanupContextlessFormattingGap = (transaction, item) => { while (item && item.right && (item.right.deleted || !item.right.countable)) { item = item.right; } const attrs = /* @__PURE__ */ new Set(); while (item && (item.deleted || !item.countable)) { if (!item.deleted && item.content.constructor === ContentFormat) { const key = ( /** @type {ContentFormat} */ item.content.key ); if (attrs.has(key)) { item.delete(transaction); } else { attrs.add(key); } } item = item.left; } }; var cleanupYTextFormatting = (type) => { let res = 0; transact( /** @type {Doc} */ type.doc, (transaction) => { let start = ( /** @type {Item} */ type._start ); let end = type._start; let startAttributes = create(); const currentAttributes = copy(startAttributes); while (end) { if (end.deleted === false) { switch (end.content.constructor) { case ContentFormat: updateCurrentAttributes( currentAttributes, /** @type {ContentFormat} */ end.content ); break; default: res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); startAttributes = copy(currentAttributes); start = end; break; } } end = end.right; } } ); return res; }; var cleanupYTextAfterTransaction = (transaction) => { const needFullCleanup = /* @__PURE__ */ new Set(); const doc2 = transaction.doc; for (const [client, afterClock] of transaction.afterState.entries()) { const clock = transaction.beforeState.get(client) || 0; if (afterClock === clock) { continue; } iterateStructs( transaction, /** @type {Array<Item|GC>} */ doc2.store.clients.get(client), clock, afterClock, (item) => { if (!item.deleted && /** @type {Item} */ item.content.constructor === ContentFormat && item.constructor !== GC) { needFullCleanup.add( /** @type {any} */ item.parent ); } } ); } transact(doc2, (t) => { iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { if (item instanceof GC || !/** @type {YText} */ item.parent._hasFormatting || needFullCleanup.has( /** @type {YText} */ item.parent )) { return; } const parent = ( /** @type {YText} */ item.parent ); if (item.content.constructor === ContentFormat) { needFullCleanup.add(parent); } else { cleanupContextlessFormattingGap(t, item); } }); for (const yText of needFullCleanup) { cleanupYTextFormatting(yText); } }); }; var deleteText = (transaction, currPos, length3) => { const startLength = length3; const startAttrs = copy(currPos.currentAttributes); const start = currPos.right; while (length3 > 0 && currPos.right !== null) { if (currPos.right.deleted === false) { switch (currPos.right.content.constructor) { case ContentType: case ContentEmbed: case ContentString: if (length3 < currPos.right.length) { getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length3)); } length3 -= currPos.right.length; currPos.right.delete(transaction); break; } } currPos.forward(); } if (start) { cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); } const parent = ( /** @type {AbstractType<any>} */ /** @type {Item} */ (currPos.left || currPos.right).parent ); if (parent._searchMarker) { updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length3); } return currPos; }; var YTextEvent = class extends YEvent { /** * @param {YText} ytext * @param {Transaction} transaction * @param {Set<any>} subs The keys that changed */ constructor(ytext, transaction, subs) { super(ytext, transaction); this.childListChanged = false; this.keysChanged = /* @__PURE__ */ new Set(); subs.forEach((sub) => { if (sub === null) { this.childListChanged = true; } else { this.keysChanged.add(sub); } }); } /** * @type {{added:Set<Item>,deleted:Set<Item>,keys:Map<string,{action:'add'|'update'|'delete',oldValue:any}>,delta:Array<{insert?:Array<any>|string, delete?:number, retain?:number}>}} */ get changes() { if (this._changes === null) { const changes = { keys: this.keys, delta: this.delta, added: /* @__PURE__ */ new Set(), deleted: /* @__PURE__ */ new Set() }; this._changes = changes; } return ( /** @type {any} */ this._changes ); } /** * Compute the changes in the delta format. * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. * * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>} * * @public */ get delta() { if (this._delta === null) { const y = ( /** @type {Doc} */ this.target.doc ); const delta = []; transact(y, (transaction) => { const currentAttributes = /* @__PURE__ */ new Map(); const oldAttributes = /* @__PURE__ */ new Map(); let item = this.target._start; let action = null; const attributes = {}; let insert = ""; let retain = 0; let deleteLen = 0; const addOp = () => { if (action !== null) { let op = null; switch (action) { case "delete": if (deleteLen > 0) { op = { delete: deleteLen }; } deleteLen = 0; break; case "insert": if (typeof insert === "object" || insert.length > 0) { op = { insert }; if (currentAttributes.size > 0) { op.attributes = {}; currentAttributes.forEach((value, key) => { if (value !== null) { op.attributes[key] = value; } }); } } insert = ""; break; case "retain": if (retain > 0) { op = { retain }; if (!isEmpty(attributes)) { op.attributes = assign({}, attributes); } } retain = 0; break; } if (op) delta.push(op); action = null; } }; while (item !== null) { switch (item.content.constructor) { case ContentType: case ContentEmbed: if (this.adds(item)) { if (!this.deletes(item)) { addOp(); action = "insert"; insert = item.content.getContent()[0]; addOp(); } } else if (this.deletes(item)) { if (action !== "delete") { addOp(); action = "delete"; } deleteLen += 1; } else if (!item.deleted) { if (action !== "retain") { addOp(); action = "retain"; } retain += 1; } break; case ContentString: if (this.adds(item)) { if (!this.deletes(item)) { if (action !== "insert") { addOp(); action = "insert"; } insert += /** @type {ContentString} */ item.content.str; } } else if (this.deletes(item)) { if (action !== "delete") { addOp(); action = "delete"; } deleteLen += item.length; } else if (!item.deleted) { if (action !== "retain") { addOp(); action = "retain"; } retain += item.length; } break; case ContentFormat: { const { key, value } = ( /** @type {ContentFormat} */ item.content ); if (this.adds(item)) { if (!this.deletes(item)) { const curVal = currentAttributes.get(key) ?? null; if (!equalAttrs(curVal, value)) { if (action === "retain") { addOp(); } if (equalAttrs(value, oldAttributes.get(key) ?? null)) { delete attributes[key]; } else { attributes[key] = value; } } else if (value !== null) { item.delete(transaction); } } } else if (this.deletes(item)) { oldAttributes.set(key, value); const curVal = currentAttributes.get(key) ?? null; if (!equalAttrs(curVal, value)) { if (action === "retain") { addOp(); } attributes[key] = curVal; } } else if (!item.deleted) { oldAttributes.set(key, value); const attr = attributes[key]; if (attr !== void 0) { if (!equalAttrs(attr, value)) { if (action === "retain") { addOp(); } if (value === null) { delete attributes[key]; } else { attributes[key] = value; } } else if (attr !== null) { item.delete(transaction); } } } if (!item.deleted) { if (action === "insert") { addOp(); } updateCurrentAttributes( currentAttributes, /** @type {ContentFormat} */ item.content ); } break; } } item = item.right; } addOp(); while (delta.length > 0) { const lastOp = delta[delta.length - 1]; if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { delta.pop(); } else { break; } } }); this._delta = delta; } return ( /** @type {any} */ this._delta ); } }; var YText = class _YText extends AbstractType { /** * @param {String} [string] The initial value of the YText. */ constructor(string) { super(); this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; this._searchMarker = []; this._hasFormatting = false; } /** * Number of characters of this text type. * * @type {number} */ get length() { this.doc ?? warnPrematureAccess(); return this._length; } /** * @param {Doc} y * @param {Item} item */ _integrate(y, item) { super._integrate(y, item); try { this._pending.forEach((f) => f()); } catch (e) { console.error(e); } this._pending = null; } _copy() { return new _YText(); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YText} */ clone() { const text2 = new _YText(); text2.applyDelta(this.toDelta()); return text2; } /** * Creates YTextEvent and calls observers. * * @param {Transaction} transaction * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. */ _callObserver(transaction, parentSubs) { super._callObserver(transaction, parentSubs); const event = new YTextEvent(this, transaction, parentSubs); callTypeObservers(this, transaction, event); if (!transaction.local && this._hasFormatting) { transaction._needFormattingCleanup = true; } } /** * Returns the unformatted string representation of this YText type. * * @public */ toString() { this.doc ?? warnPrematureAccess(); let str = ""; let n = this._start; while (n !== null) { if (!n.deleted && n.countable && n.content.constructor === ContentString) { str += /** @type {ContentString} */ n.content.str; } n = n.right; } return str; } /** * Returns the unformatted string representation of this YText type. * * @return {string} * @public */ toJSON() { return this.toString(); } /** * Apply a {@link Delta} on this shared YText type. * * @param {Array<any>} delta The changes to apply on this element. * @param {object} opts * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. * * * @public */ applyDelta(delta, { sanitize = true } = {}) { if (this.doc !== null) { transact(this.doc, (transaction) => { const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); for (let i = 0; i < delta.length; i++) { const op = delta[i]; if (op.insert !== void 0) { const ins = !sanitize && typeof op.insert === "string" && i === delta.length - 1 && currPos.right === null && op.insert.slice(-1) === "\n" ? op.insert.slice(0, -1) : op.insert; if (typeof ins !== "string" || ins.length > 0) { insertText(transaction, this, currPos, ins, op.attributes || {}); } } else if (op.retain !== void 0) { formatText(transaction, this, currPos, op.retain, op.attributes || {}); } else if (op.delete !== void 0) { deleteText(transaction, currPos, op.delete); } } }); } else { this._pending.push(() => this.applyDelta(delta)); } } /** * Returns the Delta representation of this YText type. * * @param {Snapshot} [snapshot] * @param {Snapshot} [prevSnapshot] * @param {function('removed' | 'added', ID):any} [computeYChange] * @return {any} The Delta representation of this type. * * @public */ toDelta(snapshot2, prevSnapshot, computeYChange) { this.doc ?? warnPrematureAccess(); const ops = []; const currentAttributes = /* @__PURE__ */ new Map(); const doc2 = ( /** @type {Doc} */ this.doc ); let str = ""; let n = this._start; function packStr() { if (str.length > 0) { const attributes = {}; let addAttributes = false; currentAttributes.forEach((value, key) => { addAttributes = true; attributes[key] = value; }); const op = { insert: str }; if (addAttributes) { op.attributes = attributes; } ops.push(op); str = ""; } } const computeDelta = () => { while (n !== null) { if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { switch (n.content.constructor) { case ContentString: { const cur = currentAttributes.get("ychange"); if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { packStr(); currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); } } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { packStr(); currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); } } else if (cur !== void 0) { packStr(); currentAttributes.delete("ychange"); } str += /** @type {ContentString} */ n.content.str; break; } case ContentType: case ContentEmbed: { packStr(); const op = { insert: n.content.getContent()[0] }; if (currentAttributes.size > 0) { const attrs = ( /** @type {Object<string,any>} */ {} ); op.attributes = attrs; currentAttributes.forEach((value, key) => { attrs[key] = value; }); } ops.push(op); break; } case ContentFormat: if (isVisible(n, snapshot2)) { packStr(); updateCurrentAttributes( currentAttributes, /** @type {ContentFormat} */ n.content ); } break; } } n = n.right; } packStr(); }; if (snapshot2 || prevSnapshot) { transact(doc2, (transaction) => { if (snapshot2) { splitSnapshotAffectedStructs(transaction, snapshot2); } if (prevSnapshot) { splitSnapshotAffectedStructs(transaction, prevSnapshot); } computeDelta(); }, "cleanup"); } else { computeDelta(); } return ops; } /** * Insert text at a given index. * * @param {number} index The index at which to start inserting. * @param {String} text The text to insert at the specified position. * @param {TextAttributes} [attributes] Optionally define some formatting * information to apply on the inserted * Text. * @public */ insert(index, text2, attributes) { if (text2.length <= 0) { return; } const y = this.doc; if (y !== null) { transact(y, (transaction) => { const pos = findPosition(transaction, this, index, !attributes); if (!attributes) { attributes = {}; pos.currentAttributes.forEach((v, k) => { attributes[k] = v; }); } insertText(transaction, this, pos, text2, attributes); }); } else { this._pending.push(() => this.insert(index, text2, attributes)); } } /** * Inserts an embed at a index. * * @param {number} index The index to insert the embed at. * @param {Object | AbstractType<any>} embed The Object that represents the embed. * @param {TextAttributes} [attributes] Attribute information to apply on the * embed * * @public */ insertEmbed(index, embed, attributes) { const y = this.doc; if (y !== null) { transact(y, (transaction) => { const pos = findPosition(transaction, this, index, !attributes); insertText(transaction, this, pos, embed, attributes || {}); }); } else { this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); } } /** * Deletes text starting from an index. * * @param {number} index Index at which to start deleting. * @param {number} length The number of characters to remove. Defaults to 1. * * @public */ delete(index, length3) { if (length3 === 0) { return; } const y = this.doc; if (y !== null) { transact(y, (transaction) => { deleteText(transaction, findPosition(transaction, this, index, true), length3); }); } else { this._pending.push(() => this.delete(index, length3)); } } /** * Assigns properties to a range of text. * * @param {number} index The position where to start formatting. * @param {number} length The amount of characters to assign properties to. * @param {TextAttributes} attributes Attribute information to apply on the * text. * * @public */ format(index, length3, attributes) { if (length3 === 0) { return; } const y = this.doc; if (y !== null) { transact(y, (transaction) => { const pos = findPosition(transaction, this, index, false); if (pos.right === null) { return; } formatText(transaction, this, pos, length3, attributes); }); } else { this._pending.push(() => this.format(index, length3, attributes)); } } /** * Removes an attribute. * * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. * * @param {String} attributeName The attribute name that is to be removed. * * @public */ removeAttribute(attributeName) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeMapDelete(transaction, this, attributeName); }); } else { this._pending.push(() => this.removeAttribute(attributeName)); } } /** * Sets or updates an attribute. * * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. * * @param {String} attributeName The attribute name that is to be set. * @param {any} attributeValue The attribute value that is to be set. * * @public */ setAttribute(attributeName, attributeValue) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeMapSet(transaction, this, attributeName, attributeValue); }); } else { this._pending.push(() => this.setAttribute(attributeName, attributeValue)); } } /** * Returns an attribute value that belongs to the attribute name. * * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. * * @param {String} attributeName The attribute name that identifies the * queried value. * @return {any} The queried attribute value. * * @public */ getAttribute(attributeName) { return ( /** @type {any} */ typeMapGet(this, attributeName) ); } /** * Returns all attribute name/value pairs in a JSON Object. * * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. * * @return {Object<string, any>} A JSON Object that describes the attributes. * * @public */ getAttributes() { return typeMapGetAll(this); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder */ _write(encoder) { encoder.writeTypeRef(YTextRefID); } }; var readYText = (_decoder) => new YText(); var YXmlTreeWalker = class { /** * @param {YXmlFragment | YXmlElement} root * @param {function(AbstractType<any>):boolean} [f] */ constructor(root, f = () => true) { this._filter = f; this._root = root; this._currentNode = /** @type {Item} */ root._start; this._firstCall = true; root.doc ?? warnPrematureAccess(); } [Symbol.iterator]() { return this; } /** * Get the next node. * * @return {IteratorResult<YXmlElement|YXmlText|YXmlHook>} The next node. * * @public */ next() { let n = this._currentNode; let type = n && n.content && /** @type {any} */ n.content.type; if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { do { type = /** @type {any} */ n.content.type; if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { n = type._start; } else { while (n !== null) { const nxt = n.next; if (nxt !== null) { n = nxt; break; } else if (n.parent === this._root) { n = null; } else { n = /** @type {AbstractType<any>} */ n.parent._item; } } } } while (n !== null && (n.deleted || !this._filter( /** @type {ContentType} */ n.content.type ))); } this._firstCall = false; if (n === null) { return { value: void 0, done: true }; } this._currentNode = n; return { value: ( /** @type {any} */ n.content.type ), done: false }; } }; var YXmlFragment = class _YXmlFragment extends AbstractType { constructor() { super(); this._prelimContent = []; } /** * @type {YXmlElement|YXmlText|null} */ get firstChild() { const first = this._first; return first ? first.content.getContent()[0] : null; } /** * Integrate this type into the Yjs instance. * * * Save this struct in the os * * This type is sent to other client * * Observer functions are fired * * @param {Doc} y The Yjs instance * @param {Item} item */ _integrate(y, item) { super._integrate(y, item); this.insert( 0, /** @type {Array<any>} */ this._prelimContent ); this._prelimContent = null; } _copy() { return new _YXmlFragment(); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YXmlFragment} */ clone() { const el = new _YXmlFragment(); el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); return el; } get length() { this.doc ?? warnPrematureAccess(); return this._prelimContent === null ? this._length : this._prelimContent.length; } /** * Create a subtree of childNodes. * * @example * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') * for (let node in walker) { * // `node` is a div node * nop(node) * } * * @param {function(AbstractType<any>):boolean} filter Function that is called on each child element and * returns a Boolean indicating whether the child * is to be included in the subtree. * @return {YXmlTreeWalker} A subtree and a position within it. * * @public */ createTreeWalker(filter) { return new YXmlTreeWalker(this, filter); } /** * Returns the first YXmlElement that matches the query. * Similar to DOM's {@link querySelector}. * * Query support: * - tagname * TODO: * - id * - attribute * * @param {CSS_Selector} query The query on the children. * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. * * @public */ querySelector(query) { query = query.toUpperCase(); const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); const next = iterator.next(); if (next.done) { return null; } else { return next.value; } } /** * Returns all YXmlElements that match the query. * Similar to Dom's {@link querySelectorAll}. * * @todo Does not yet support all queries. Currently only query by tagName. * * @param {CSS_Selector} query The query on the children * @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query. * * @public */ querySelectorAll(query) { query = query.toUpperCase(); return from(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); } /** * Creates YXmlEvent and calls observers. * * @param {Transaction} transaction * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. */ _callObserver(transaction, parentSubs) { callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); } /** * Get the string representation of all the children of this YXmlFragment. * * @return {string} The string representation of all children. */ toString() { return typeListMap(this, (xml) => xml.toString()).join(""); } /** * @return {string} */ toJSON() { return this.toString(); } /** * Creates a Dom Element that mirrors this YXmlElement. * * @param {Document} [_document=document] The document object (you must define * this when calling this method in * nodejs) * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks * are presented in the DOM * @param {any} [binding] You should not set this property. This is * used if DomBinding wants to create a * association to the created DOM type. * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} * * @public */ toDOM(_document = document, hooks = {}, binding) { const fragment = _document.createDocumentFragment(); if (binding !== void 0) { binding._createAssociation(fragment, this); } typeListForEach(this, (xmlType) => { fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); }); return fragment; } /** * Inserts new content at an index. * * @example * // Insert character 'a' at position 0 * xml.insert(0, [new Y.XmlText('text')]) * * @param {number} index The index to insert content at * @param {Array<YXmlElement|YXmlText>} content The array of content */ insert(index, content) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeListInsertGenerics(transaction, this, index, content); }); } else { this._prelimContent.splice(index, 0, ...content); } } /** * Inserts new content at an index. * * @example * // Insert character 'a' at position 0 * xml.insert(0, [new Y.XmlText('text')]) * * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at * @param {Array<YXmlElement|YXmlText>} content The array of content */ insertAfter(ref, content) { if (this.doc !== null) { transact(this.doc, (transaction) => { const refItem = ref && ref instanceof AbstractType ? ref._item : ref; typeListInsertGenericsAfter(transaction, this, refItem, content); }); } else { const pc = ( /** @type {Array<any>} */ this._prelimContent ); const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; if (index === 0 && ref !== null) { throw create3("Reference item not found"); } pc.splice(index, 0, ...content); } } /** * Deletes elements starting from an index. * * @param {number} index Index at which to start deleting elements * @param {number} [length=1] The number of elements to remove. Defaults to 1. */ delete(index, length3 = 1) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeListDelete(transaction, this, index, length3); }); } else { this._prelimContent.splice(index, length3); } } /** * Transforms this YArray to a JavaScript Array. * * @return {Array<YXmlElement|YXmlText|YXmlHook>} */ toArray() { return typeListToArray(this); } /** * Appends content to this YArray. * * @param {Array<YXmlElement|YXmlText>} content Array of content to append. */ push(content) { this.insert(this.length, content); } /** * Prepends content to this YArray. * * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend. */ unshift(content) { this.insert(0, content); } /** * Returns the i-th element from a YArray. * * @param {number} index The index of the element to return from the YArray * @return {YXmlElement|YXmlText} */ get(index) { return typeListGet(this, index); } /** * Returns a portion of this YXmlFragment into a JavaScript Array selected * from start to end (end not included). * * @param {number} [start] * @param {number} [end] * @return {Array<YXmlElement|YXmlText>} */ slice(start = 0, end = this.length) { return typeListSlice(this, start, end); } /** * Executes a provided function on once on every child element. * * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. */ forEach(f) { typeListForEach(this, f); } /** * Transform the properties of this type to binary and write it to an * BinaryEncoder. * * This is called when this Item is sent to a remote peer. * * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. */ _write(encoder) { encoder.writeTypeRef(YXmlFragmentRefID); } }; var readYXmlFragment = (_decoder) => new YXmlFragment(); var YXmlElement = class _YXmlElement extends YXmlFragment { constructor(nodeName = "UNDEFINED") { super(); this.nodeName = nodeName; this._prelimAttrs = /* @__PURE__ */ new Map(); } /** * @type {YXmlElement|YXmlText|null} */ get nextSibling() { const n = this._item ? this._item.next : null; return n ? ( /** @type {YXmlElement|YXmlText} */ /** @type {ContentType} */ n.content.type ) : null; } /** * @type {YXmlElement|YXmlText|null} */ get prevSibling() { const n = this._item ? this._item.prev : null; return n ? ( /** @type {YXmlElement|YXmlText} */ /** @type {ContentType} */ n.content.type ) : null; } /** * Integrate this type into the Yjs instance. * * * Save this struct in the os * * This type is sent to other client * * Observer functions are fired * * @param {Doc} y The Yjs instance * @param {Item} item */ _integrate(y, item) { super._integrate(y, item); /** @type {Map<string, any>} */ this._prelimAttrs.forEach((value, key) => { this.setAttribute(key, value); }); this._prelimAttrs = null; } /** * Creates an Item with the same effect as this Item (without position effect) * * @return {YXmlElement} */ _copy() { return new _YXmlElement(this.nodeName); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YXmlElement<KV>} */ clone() { const el = new _YXmlElement(this.nodeName); const attrs = this.getAttributes(); forEach(attrs, (value, key) => { el.setAttribute( key, /** @type {any} */ value ); }); el.insert(0, this.toArray().map((v) => v instanceof AbstractType ? v.clone() : v)); return el; } /** * Returns the XML serialization of this YXmlElement. * The attributes are ordered by attribute-name, so you can easily use this * method to compare YXmlElements * * @return {string} The string representation of this type. * * @public */ toString() { const attrs = this.getAttributes(); const stringBuilder = []; const keys2 = []; for (const key in attrs) { keys2.push(key); } keys2.sort(); const keysLen = keys2.length; for (let i = 0; i < keysLen; i++) { const key = keys2[i]; stringBuilder.push(key + '="' + attrs[key] + '"'); } const nodeName = this.nodeName.toLocaleLowerCase(); const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; return `<${nodeName}${attrsString}>${super.toString()}</${nodeName}>`; } /** * Removes an attribute from this YXmlElement. * * @param {string} attributeName The attribute name that is to be removed. * * @public */ removeAttribute(attributeName) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeMapDelete(transaction, this, attributeName); }); } else { this._prelimAttrs.delete(attributeName); } } /** * Sets or updates an attribute. * * @template {keyof KV & string} KEY * * @param {KEY} attributeName The attribute name that is to be set. * @param {KV[KEY]} attributeValue The attribute value that is to be set. * * @public */ setAttribute(attributeName, attributeValue) { if (this.doc !== null) { transact(this.doc, (transaction) => { typeMapSet(transaction, this, attributeName, attributeValue); }); } else { this._prelimAttrs.set(attributeName, attributeValue); } } /** * Returns an attribute value that belongs to the attribute name. * * @template {keyof KV & string} KEY * * @param {KEY} attributeName The attribute name that identifies the * queried value. * @return {KV[KEY]|undefined} The queried attribute value. * * @public */ getAttribute(attributeName) { return ( /** @type {any} */ typeMapGet(this, attributeName) ); } /** * Returns whether an attribute exists * * @param {string} attributeName The attribute name to check for existence. * @return {boolean} whether the attribute exists. * * @public */ hasAttribute(attributeName) { return ( /** @type {any} */ typeMapHas(this, attributeName) ); } /** * Returns all attribute name/value pairs in a JSON Object. * * @param {Snapshot} [snapshot] * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes. * * @public */ getAttributes(snapshot2) { return ( /** @type {any} */ snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) ); } /** * Creates a Dom Element that mirrors this YXmlElement. * * @param {Document} [_document=document] The document object (you must define * this when calling this method in * nodejs) * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks * are presented in the DOM * @param {any} [binding] You should not set this property. This is * used if DomBinding wants to create a * association to the created DOM type. * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} * * @public */ toDOM(_document = document, hooks = {}, binding) { const dom = _document.createElement(this.nodeName); const attrs = this.getAttributes(); for (const key in attrs) { const value = attrs[key]; if (typeof value === "string") { dom.setAttribute(key, value); } } typeListForEach(this, (yxml) => { dom.appendChild(yxml.toDOM(_document, hooks, binding)); }); if (binding !== void 0) { binding._createAssociation(dom, this); } return dom; } /** * Transform the properties of this type to binary and write it to an * BinaryEncoder. * * This is called when this Item is sent to a remote peer. * * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. */ _write(encoder) { encoder.writeTypeRef(YXmlElementRefID); encoder.writeKey(this.nodeName); } }; var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); var YXmlEvent = class extends YEvent { /** * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the * child list changed. * @param {Transaction} transaction The transaction instance with which the * change was created. */ constructor(target, subs, transaction) { super(target, transaction); this.childListChanged = false; this.attributesChanged = /* @__PURE__ */ new Set(); subs.forEach((sub) => { if (sub === null) { this.childListChanged = true; } else { this.attributesChanged.add(sub); } }); } }; var YXmlHook = class _YXmlHook extends YMap { /** * @param {string} hookName nodeName of the Dom Node. */ constructor(hookName) { super(); this.hookName = hookName; } /** * Creates an Item with the same effect as this Item (without position effect) */ _copy() { return new _YXmlHook(this.hookName); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YXmlHook} */ clone() { const el = new _YXmlHook(this.hookName); this.forEach((value, key) => { el.set(key, value); }); return el; } /** * Creates a Dom Element that mirrors this YXmlElement. * * @param {Document} [_document=document] The document object (you must define * this when calling this method in * nodejs) * @param {Object.<string, any>} [hooks] Optional property to customize how hooks * are presented in the DOM * @param {any} [binding] You should not set this property. This is * used if DomBinding wants to create a * association to the created DOM type * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} * * @public */ toDOM(_document = document, hooks = {}, binding) { const hook = hooks[this.hookName]; let dom; if (hook !== void 0) { dom = hook.createDom(this); } else { dom = document.createElement(this.hookName); } dom.setAttribute("data-yjs-hook", this.hookName); if (binding !== void 0) { binding._createAssociation(dom, this); } return dom; } /** * Transform the properties of this type to binary and write it to an * BinaryEncoder. * * This is called when this Item is sent to a remote peer. * * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. */ _write(encoder) { encoder.writeTypeRef(YXmlHookRefID); encoder.writeKey(this.hookName); } }; var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); var YXmlText = class _YXmlText extends YText { /** * @type {YXmlElement|YXmlText|null} */ get nextSibling() { const n = this._item ? this._item.next : null; return n ? ( /** @type {YXmlElement|YXmlText} */ /** @type {ContentType} */ n.content.type ) : null; } /** * @type {YXmlElement|YXmlText|null} */ get prevSibling() { const n = this._item ? this._item.prev : null; return n ? ( /** @type {YXmlElement|YXmlText} */ /** @type {ContentType} */ n.content.type ) : null; } _copy() { return new _YXmlText(); } /** * Makes a copy of this data type that can be included somewhere else. * * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. * * @return {YXmlText} */ clone() { const text2 = new _YXmlText(); text2.applyDelta(this.toDelta()); return text2; } /** * Creates a Dom Element that mirrors this YXmlText. * * @param {Document} [_document=document] The document object (you must define * this when calling this method in * nodejs) * @param {Object<string, any>} [hooks] Optional property to customize how hooks * are presented in the DOM * @param {any} [binding] You should not set this property. This is * used if DomBinding wants to create a * association to the created DOM type. * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} * * @public */ toDOM(_document = document, hooks, binding) { const dom = _document.createTextNode(this.toString()); if (binding !== void 0) { binding._createAssociation(dom, this); } return dom; } toString() { return this.toDelta().map((delta) => { const nestedNodes = []; for (const nodeName in delta.attributes) { const attrs = []; for (const key in delta.attributes[nodeName]) { attrs.push({ key, value: delta.attributes[nodeName][key] }); } attrs.sort((a, b) => a.key < b.key ? -1 : 1); nestedNodes.push({ nodeName, attrs }); } nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1); let str = ""; for (let i = 0; i < nestedNodes.length; i++) { const node = nestedNodes[i]; str += `<${node.nodeName}`; for (let j = 0; j < node.attrs.length; j++) { const attr = node.attrs[j]; str += ` ${attr.key}="${attr.value}"`; } str += ">"; } str += delta.insert; for (let i = nestedNodes.length - 1; i >= 0; i--) { str += `</${nestedNodes[i].nodeName}>`; } return str; }).join(""); } /** * @return {string} */ toJSON() { return this.toString(); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder */ _write(encoder) { encoder.writeTypeRef(YXmlTextRefID); } }; var readYXmlText = (decoder) => new YXmlText(); var AbstractStruct = class { /** * @param {ID} id * @param {number} length */ constructor(id2, length3) { this.id = id2; this.length = length3; } /** * @type {boolean} */ get deleted() { throw methodUnimplemented(); } /** * Merge this struct with the item to the right. * This method is already assuming that `this.id.clock + this.length === this.id.clock`. * Also this method does *not* remove right from StructStore! * @param {AbstractStruct} right * @return {boolean} whether this merged with right */ mergeWith(right) { return false; } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. * @param {number} offset * @param {number} encodingRef */ write(encoder, offset, encodingRef) { throw methodUnimplemented(); } /** * @param {Transaction} transaction * @param {number} offset */ integrate(transaction, offset) { throw methodUnimplemented(); } }; var structGCRefNumber = 0; var GC = class extends AbstractStruct { get deleted() { return true; } delete() { } /** * @param {GC} right * @return {boolean} */ mergeWith(right) { if (this.constructor !== right.constructor) { return false; } this.length += right.length; return true; } /** * @param {Transaction} transaction * @param {number} offset */ integrate(transaction, offset) { if (offset > 0) { this.id.clock += offset; this.length -= offset; } addStruct(transaction.doc.store, this); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeInfo(structGCRefNumber); encoder.writeLen(this.length - offset); } /** * @param {Transaction} transaction * @param {StructStore} store * @return {null | number} */ getMissing(transaction, store) { return null; } }; var ContentBinary = class _ContentBinary { /** * @param {Uint8Array} content */ constructor(content) { this.content = content; } /** * @return {number} */ getLength() { return 1; } /** * @return {Array<any>} */ getContent() { return [this.content]; } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentBinary} */ copy() { return new _ContentBinary(this.content); } /** * @param {number} offset * @return {ContentBinary} */ splice(offset) { throw methodUnimplemented(); } /** * @param {ContentBinary} right * @return {boolean} */ mergeWith(right) { return false; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeBuf(this.content); } /** * @return {number} */ getRef() { return 3; } }; var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); var ContentDeleted = class _ContentDeleted { /** * @param {number} len */ constructor(len) { this.len = len; } /** * @return {number} */ getLength() { return this.len; } /** * @return {Array<any>} */ getContent() { return []; } /** * @return {boolean} */ isCountable() { return false; } /** * @return {ContentDeleted} */ copy() { return new _ContentDeleted(this.len); } /** * @param {number} offset * @return {ContentDeleted} */ splice(offset) { const right = new _ContentDeleted(this.len - offset); this.len = offset; return right; } /** * @param {ContentDeleted} right * @return {boolean} */ mergeWith(right) { this.len += right.len; return true; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); item.markDeleted(); } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeLen(this.len - offset); } /** * @return {number} */ getRef() { return 1; } }; var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); var ContentDoc = class _ContentDoc { /** * @param {Doc} doc */ constructor(doc2) { if (doc2._item) { console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); } this.doc = doc2; const opts = {}; this.opts = opts; if (!doc2.gc) { opts.gc = false; } if (doc2.autoLoad) { opts.autoLoad = true; } if (doc2.meta !== null) { opts.meta = doc2.meta; } } /** * @return {number} */ getLength() { return 1; } /** * @return {Array<any>} */ getContent() { return [this.doc]; } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentDoc} */ copy() { return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); } /** * @param {number} offset * @return {ContentDoc} */ splice(offset) { throw methodUnimplemented(); } /** * @param {ContentDoc} right * @return {boolean} */ mergeWith(right) { return false; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { this.doc._item = item; transaction.subdocsAdded.add(this.doc); if (this.doc.shouldLoad) { transaction.subdocsLoaded.add(this.doc); } } /** * @param {Transaction} transaction */ delete(transaction) { if (transaction.subdocsAdded.has(this.doc)) { transaction.subdocsAdded.delete(this.doc); } else { transaction.subdocsRemoved.add(this.doc); } } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeString(this.doc.guid); encoder.writeAny(this.opts); } /** * @return {number} */ getRef() { return 9; } }; var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); var ContentEmbed = class _ContentEmbed { /** * @param {Object} embed */ constructor(embed) { this.embed = embed; } /** * @return {number} */ getLength() { return 1; } /** * @return {Array<any>} */ getContent() { return [this.embed]; } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentEmbed} */ copy() { return new _ContentEmbed(this.embed); } /** * @param {number} offset * @return {ContentEmbed} */ splice(offset) { throw methodUnimplemented(); } /** * @param {ContentEmbed} right * @return {boolean} */ mergeWith(right) { return false; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeJSON(this.embed); } /** * @return {number} */ getRef() { return 5; } }; var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); var ContentFormat = class _ContentFormat { /** * @param {string} key * @param {Object} value */ constructor(key, value) { this.key = key; this.value = value; } /** * @return {number} */ getLength() { return 1; } /** * @return {Array<any>} */ getContent() { return []; } /** * @return {boolean} */ isCountable() { return false; } /** * @return {ContentFormat} */ copy() { return new _ContentFormat(this.key, this.value); } /** * @param {number} _offset * @return {ContentFormat} */ splice(_offset) { throw methodUnimplemented(); } /** * @param {ContentFormat} _right * @return {boolean} */ mergeWith(_right) { return false; } /** * @param {Transaction} _transaction * @param {Item} item */ integrate(_transaction, item) { const p = ( /** @type {YText} */ item.parent ); p._searchMarker = null; p._hasFormatting = true; } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeKey(this.key); encoder.writeJSON(this.value); } /** * @return {number} */ getRef() { return 6; } }; var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); var ContentJSON = class _ContentJSON { /** * @param {Array<any>} arr */ constructor(arr) { this.arr = arr; } /** * @return {number} */ getLength() { return this.arr.length; } /** * @return {Array<any>} */ getContent() { return this.arr; } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentJSON} */ copy() { return new _ContentJSON(this.arr); } /** * @param {number} offset * @return {ContentJSON} */ splice(offset) { const right = new _ContentJSON(this.arr.slice(offset)); this.arr = this.arr.slice(0, offset); return right; } /** * @param {ContentJSON} right * @return {boolean} */ mergeWith(right) { this.arr = this.arr.concat(right.arr); return true; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { const len = this.arr.length; encoder.writeLen(len - offset); for (let i = offset; i < len; i++) { const c = this.arr[i]; encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); } } /** * @return {number} */ getRef() { return 2; } }; var readContentJSON = (decoder) => { const len = decoder.readLen(); const cs = []; for (let i = 0; i < len; i++) { const c = decoder.readString(); if (c === "undefined") { cs.push(void 0); } else { cs.push(JSON.parse(c)); } } return new ContentJSON(cs); }; var isDevMode = getVariable("node_env") === "development"; var ContentAny = class _ContentAny { /** * @param {Array<any>} arr */ constructor(arr) { this.arr = arr; isDevMode && deepFreeze(arr); } /** * @return {number} */ getLength() { return this.arr.length; } /** * @return {Array<any>} */ getContent() { return this.arr; } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentAny} */ copy() { return new _ContentAny(this.arr); } /** * @param {number} offset * @return {ContentAny} */ splice(offset) { const right = new _ContentAny(this.arr.slice(offset)); this.arr = this.arr.slice(0, offset); return right; } /** * @param {ContentAny} right * @return {boolean} */ mergeWith(right) { this.arr = this.arr.concat(right.arr); return true; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { const len = this.arr.length; encoder.writeLen(len - offset); for (let i = offset; i < len; i++) { const c = this.arr[i]; encoder.writeAny(c); } } /** * @return {number} */ getRef() { return 8; } }; var readContentAny = (decoder) => { const len = decoder.readLen(); const cs = []; for (let i = 0; i < len; i++) { cs.push(decoder.readAny()); } return new ContentAny(cs); }; var ContentString = class _ContentString { /** * @param {string} str */ constructor(str) { this.str = str; } /** * @return {number} */ getLength() { return this.str.length; } /** * @return {Array<any>} */ getContent() { return this.str.split(""); } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentString} */ copy() { return new _ContentString(this.str); } /** * @param {number} offset * @return {ContentString} */ splice(offset) { const right = new _ContentString(this.str.slice(offset)); this.str = this.str.slice(0, offset); const firstCharCode = this.str.charCodeAt(offset - 1); if (firstCharCode >= 55296 && firstCharCode <= 56319) { this.str = this.str.slice(0, offset - 1) + "\uFFFD"; right.str = "\uFFFD" + right.str.slice(1); } return right; } /** * @param {ContentString} right * @return {boolean} */ mergeWith(right) { this.str += right.str; return true; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { } /** * @param {Transaction} transaction */ delete(transaction) { } /** * @param {StructStore} store */ gc(store) { } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); } /** * @return {number} */ getRef() { return 4; } }; var readContentString = (decoder) => new ContentString(decoder.readString()); var typeRefs = [ readYArray, readYMap, readYText, readYXmlElement, readYXmlFragment, readYXmlHook, readYXmlText ]; var YArrayRefID = 0; var YMapRefID = 1; var YTextRefID = 2; var YXmlElementRefID = 3; var YXmlFragmentRefID = 4; var YXmlHookRefID = 5; var YXmlTextRefID = 6; var ContentType = class _ContentType { /** * @param {AbstractType<any>} type */ constructor(type) { this.type = type; } /** * @return {number} */ getLength() { return 1; } /** * @return {Array<any>} */ getContent() { return [this.type]; } /** * @return {boolean} */ isCountable() { return true; } /** * @return {ContentType} */ copy() { return new _ContentType(this.type._copy()); } /** * @param {number} offset * @return {ContentType} */ splice(offset) { throw methodUnimplemented(); } /** * @param {ContentType} right * @return {boolean} */ mergeWith(right) { return false; } /** * @param {Transaction} transaction * @param {Item} item */ integrate(transaction, item) { this.type._integrate(transaction.doc, item); } /** * @param {Transaction} transaction */ delete(transaction) { let item = this.type._start; while (item !== null) { if (!item.deleted) { item.delete(transaction); } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { transaction._mergeStructs.push(item); } item = item.right; } this.type._map.forEach((item2) => { if (!item2.deleted) { item2.delete(transaction); } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { transaction._mergeStructs.push(item2); } }); transaction.changed.delete(this.type); } /** * @param {StructStore} store */ gc(store) { let item = this.type._start; while (item !== null) { item.gc(store, true); item = item.right; } this.type._start = null; this.type._map.forEach( /** @param {Item | null} item */ (item2) => { while (item2 !== null) { item2.gc(store, true); item2 = item2.left; } } ); this.type._map = /* @__PURE__ */ new Map(); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { this.type._write(encoder); } /** * @return {number} */ getRef() { return 7; } }; var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); var followRedone = (store, id2) => { let nextID = id2; let diff = 0; let item; do { if (diff > 0) { nextID = createID(nextID.client, nextID.clock + diff); } item = getItem(store, nextID); diff = nextID.clock - item.id.clock; nextID = item.redone; } while (nextID !== null && item instanceof Item); return { item, diff }; }; var keepItem = (item, keep) => { while (item !== null && item.keep !== keep) { item.keep = keep; item = /** @type {AbstractType<any>} */ item.parent._item; } }; var splitItem = (transaction, leftItem, diff) => { const { client, clock } = leftItem.id; const rightItem = new Item( createID(client, clock + diff), leftItem, createID(client, clock + diff - 1), leftItem.right, leftItem.rightOrigin, leftItem.parent, leftItem.parentSub, leftItem.content.splice(diff) ); if (leftItem.deleted) { rightItem.markDeleted(); } if (leftItem.keep) { rightItem.keep = true; } if (leftItem.redone !== null) { rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); } leftItem.right = rightItem; if (rightItem.right !== null) { rightItem.right.left = rightItem; } transaction._mergeStructs.push(rightItem); if (rightItem.parentSub !== null && rightItem.right === null) { rightItem.parent._map.set(rightItem.parentSub, rightItem); } leftItem.length = diff; return rightItem; }; var isDeletedByUndoStack = (stack, id2) => some( stack, /** @param {StackItem} s */ (s) => isDeleted(s.deletions, id2) ); var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { const doc2 = transaction.doc; const store = doc2.store; const ownClientID = doc2.clientID; const redone = item.redone; if (redone !== null) { return getItemCleanStart(transaction, redone); } let parentItem = ( /** @type {AbstractType<any>} */ item.parent._item ); let left = null; let right; if (parentItem !== null && parentItem.deleted === true) { if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { return null; } while (parentItem.redone !== null) { parentItem = getItemCleanStart(transaction, parentItem.redone); } } const parentType = parentItem === null ? ( /** @type {AbstractType<any>} */ item.parent ) : ( /** @type {ContentType} */ parentItem.content.type ); if (item.parentSub === null) { left = item.left; right = item; while (left !== null) { let leftTrace = left; while (leftTrace !== null && /** @type {AbstractType<any>} */ leftTrace.parent._item !== parentItem) { leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); } if (leftTrace !== null && /** @type {AbstractType<any>} */ leftTrace.parent._item === parentItem) { left = leftTrace; break; } left = left.left; } while (right !== null) { let rightTrace = right; while (rightTrace !== null && /** @type {AbstractType<any>} */ rightTrace.parent._item !== parentItem) { rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); } if (rightTrace !== null && /** @type {AbstractType<any>} */ rightTrace.parent._item === parentItem) { right = rightTrace; break; } right = right.right; } } else { right = null; if (item.right && !ignoreRemoteMapChanges) { left = item; while (left !== null && left.right !== null && (left.right.redone || isDeleted(itemsToDelete, left.right.id) || isDeletedByUndoStack(um.undoStack, left.right.id) || isDeletedByUndoStack(um.redoStack, left.right.id))) { left = left.right; while (left.redone) left = getItemCleanStart(transaction, left.redone); } if (left && left.right !== null) { return null; } } else { left = parentType._map.get(item.parentSub) || null; } } const nextClock = getState(store, ownClientID); const nextId = createID(ownClientID, nextClock); const redoneItem = new Item( nextId, left, left && left.lastId, right, right && right.id, parentType, item.parentSub, item.content.copy() ); item.redone = nextId; keepItem(redoneItem, true); redoneItem.integrate(transaction, 0); return redoneItem; }; var Item = class _Item extends AbstractStruct { /** * @param {ID} id * @param {Item | null} left * @param {ID | null} origin * @param {Item | null} right * @param {ID | null} rightOrigin * @param {AbstractType<any>|ID|null} parent Is a type if integrated, is null if it is possible to copy parent from left or right, is ID before integration to search for it. * @param {string | null} parentSub * @param {AbstractContent} content */ constructor(id2, left, origin2, right, rightOrigin, parent, parentSub, content) { super(id2, content.getLength()); this.origin = origin2; this.left = left; this.right = right; this.rightOrigin = rightOrigin; this.parent = parent; this.parentSub = parentSub; this.redone = null; this.content = content; this.info = this.content.isCountable() ? BIT2 : 0; } /** * This is used to mark the item as an indexed fast-search marker * * @type {boolean} */ set marker(isMarked) { if ((this.info & BIT4) > 0 !== isMarked) { this.info ^= BIT4; } } get marker() { return (this.info & BIT4) > 0; } /** * If true, do not garbage collect this Item. */ get keep() { return (this.info & BIT1) > 0; } set keep(doKeep) { if (this.keep !== doKeep) { this.info ^= BIT1; } } get countable() { return (this.info & BIT2) > 0; } /** * Whether this item was deleted or not. * @type {Boolean} */ get deleted() { return (this.info & BIT3) > 0; } set deleted(doDelete) { if (this.deleted !== doDelete) { this.info ^= BIT3; } } markDeleted() { this.info |= BIT3; } /** * Return the creator clientID of the missing op or define missing items and return null. * * @param {Transaction} transaction * @param {StructStore} store * @return {null | number} */ getMissing(transaction, store) { if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store, this.origin.client)) { return this.origin.client; } if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store, this.rightOrigin.client)) { return this.rightOrigin.client; } if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store, this.parent.client)) { return this.parent.client; } if (this.origin) { this.left = getItemCleanEnd(transaction, store, this.origin); this.origin = this.left.lastId; } if (this.rightOrigin) { this.right = getItemCleanStart(transaction, this.rightOrigin); this.rightOrigin = this.right.id; } if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { this.parent = null; } else if (!this.parent) { if (this.left && this.left.constructor === _Item) { this.parent = this.left.parent; this.parentSub = this.left.parentSub; } else if (this.right && this.right.constructor === _Item) { this.parent = this.right.parent; this.parentSub = this.right.parentSub; } } else if (this.parent.constructor === ID) { const parentItem = getItem(store, this.parent); if (parentItem.constructor === GC) { this.parent = null; } else { this.parent = /** @type {ContentType} */ parentItem.content.type; } } return null; } /** * @param {Transaction} transaction * @param {number} offset */ integrate(transaction, offset) { if (offset > 0) { this.id.clock += offset; this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); this.origin = this.left.lastId; this.content = this.content.splice(offset); this.length -= offset; } if (this.parent) { if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { let left = this.left; let o; if (left !== null) { o = left.right; } else if (this.parentSub !== null) { o = /** @type {AbstractType<any>} */ this.parent._map.get(this.parentSub) || null; while (o !== null && o.left !== null) { o = o.left; } } else { o = /** @type {AbstractType<any>} */ this.parent._start; } const conflictingItems = /* @__PURE__ */ new Set(); const itemsBeforeOrigin = /* @__PURE__ */ new Set(); while (o !== null && o !== this.right) { itemsBeforeOrigin.add(o); conflictingItems.add(o); if (compareIDs(this.origin, o.origin)) { if (o.id.client < this.id.client) { left = o; conflictingItems.clear(); } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { break; } } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { left = o; conflictingItems.clear(); } } else { break; } o = o.right; } this.left = left; } if (this.left !== null) { const right = this.left.right; this.right = right; this.left.right = this; } else { let r; if (this.parentSub !== null) { r = /** @type {AbstractType<any>} */ this.parent._map.get(this.parentSub) || null; while (r !== null && r.left !== null) { r = r.left; } } else { r = /** @type {AbstractType<any>} */ this.parent._start; this.parent._start = this; } this.right = r; } if (this.right !== null) { this.right.left = this; } else if (this.parentSub !== null) { this.parent._map.set(this.parentSub, this); if (this.left !== null) { this.left.delete(transaction); } } if (this.parentSub === null && this.countable && !this.deleted) { this.parent._length += this.length; } addStruct(transaction.doc.store, this); this.content.integrate(transaction, this); addChangedTypeToTransaction( transaction, /** @type {AbstractType<any>} */ this.parent, this.parentSub ); if ( /** @type {AbstractType<any>} */ this.parent._item !== null && /** @type {AbstractType<any>} */ this.parent._item.deleted || this.parentSub !== null && this.right !== null ) { this.delete(transaction); } } else { new GC(this.id, this.length).integrate(transaction, 0); } } /** * Returns the next non-deleted item */ get next() { let n = this.right; while (n !== null && n.deleted) { n = n.right; } return n; } /** * Returns the previous non-deleted item */ get prev() { let n = this.left; while (n !== null && n.deleted) { n = n.left; } return n; } /** * Computes the last content address of this Item. */ get lastId() { return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); } /** * Try to merge two items * * @param {Item} right * @return {boolean} */ mergeWith(right) { if (this.constructor === right.constructor && compareIDs(right.origin, this.lastId) && this.right === right && compareIDs(this.rightOrigin, right.rightOrigin) && this.id.client === right.id.client && this.id.clock + this.length === right.id.clock && this.deleted === right.deleted && this.redone === null && right.redone === null && this.content.constructor === right.content.constructor && this.content.mergeWith(right.content)) { const searchMarker = ( /** @type {AbstractType<any>} */ this.parent._searchMarker ); if (searchMarker) { searchMarker.forEach((marker) => { if (marker.p === right) { marker.p = this; if (!this.deleted && this.countable) { marker.index -= this.length; } } }); } if (right.keep) { this.keep = true; } this.right = right.right; if (this.right !== null) { this.right.left = this; } this.length += right.length; return true; } return false; } /** * Mark this Item as deleted. * * @param {Transaction} transaction */ delete(transaction) { if (!this.deleted) { const parent = ( /** @type {AbstractType<any>} */ this.parent ); if (this.countable && this.parentSub === null) { parent._length -= this.length; } this.markDeleted(); addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); addChangedTypeToTransaction(transaction, parent, this.parentSub); this.content.delete(transaction); } } /** * @param {StructStore} store * @param {boolean} parentGCd */ gc(store, parentGCd) { if (!this.deleted) { throw unexpectedCase(); } this.content.gc(store); if (parentGCd) { replaceStruct(store, this, new GC(this.id, this.length)); } else { this.content = new ContentDeleted(this.length); } } /** * Transform the properties of this type to binary and write it to an * BinaryEncoder. * * This is called when this Item is sent to a remote peer. * * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. * @param {number} offset */ write(encoder, offset) { const origin2 = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; const rightOrigin = this.rightOrigin; const parentSub = this.parentSub; const info = this.content.getRef() & BITS5 | (origin2 === null ? 0 : BIT8) | // origin is defined (rightOrigin === null ? 0 : BIT7) | // right origin is defined (parentSub === null ? 0 : BIT6); encoder.writeInfo(info); if (origin2 !== null) { encoder.writeLeftID(origin2); } if (rightOrigin !== null) { encoder.writeRightID(rightOrigin); } if (origin2 === null && rightOrigin === null) { const parent = ( /** @type {AbstractType<any>} */ this.parent ); if (parent._item !== void 0) { const parentItem = parent._item; if (parentItem === null) { const ykey = findRootTypeKey(parent); encoder.writeParentInfo(true); encoder.writeString(ykey); } else { encoder.writeParentInfo(false); encoder.writeLeftID(parentItem.id); } } else if (parent.constructor === String) { encoder.writeParentInfo(true); encoder.writeString(parent); } else if (parent.constructor === ID) { encoder.writeParentInfo(false); encoder.writeLeftID(parent); } else { unexpectedCase(); } if (parentSub !== null) { encoder.writeString(parentSub); } } this.content.write(encoder, offset); } }; var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); var contentRefs = [ () => { unexpectedCase(); }, // GC is not ItemContent readContentDeleted, // 1 readContentJSON, // 2 readContentBinary, // 3 readContentString, // 4 readContentEmbed, // 5 readContentFormat, // 6 readContentType, // 7 readContentAny, // 8 readContentDoc, // 9 () => { unexpectedCase(); } // 10 - Skip is not ItemContent ]; var structSkipRefNumber = 10; var Skip = class extends AbstractStruct { get deleted() { return true; } delete() { } /** * @param {Skip} right * @return {boolean} */ mergeWith(right) { if (this.constructor !== right.constructor) { return false; } this.length += right.length; return true; } /** * @param {Transaction} transaction * @param {number} offset */ integrate(transaction, offset) { unexpectedCase(); } /** * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder * @param {number} offset */ write(encoder, offset) { encoder.writeInfo(structSkipRefNumber); writeVarUint(encoder.restEncoder, this.length - offset); } /** * @param {Transaction} transaction * @param {StructStore} store * @return {null | number} */ getMissing(transaction, store) { return null; } }; var glo = ( /** @type {any} */ typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} ); var importIdentifier = "__ $YJS$ __"; if (glo[importIdentifier] === true) { console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); } glo[importIdentifier] = true; // packages/sync/node_modules/y-protocols/awareness.js var outdatedTimeout = 3e4; var Awareness = class extends Observable { /** * @param {Y.Doc} doc */ constructor(doc2) { super(); this.doc = doc2; this.clientID = doc2.clientID; this.states = /* @__PURE__ */ new Map(); this.meta = /* @__PURE__ */ new Map(); this._checkInterval = /** @type {any} */ setInterval(() => { const now = getUnixTime(); if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ this.meta.get(this.clientID).lastUpdated) { this.setLocalState(this.getLocalState()); } const remove = []; this.meta.forEach((meta, clientid) => { if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { remove.push(clientid); } }); if (remove.length > 0) { removeAwarenessStates(this, remove, "timeout"); } }, floor(outdatedTimeout / 10)); doc2.on("destroy", () => { this.destroy(); }); this.setLocalState({}); } destroy() { this.emit("destroy", [this]); this.setLocalState(null); super.destroy(); clearInterval(this._checkInterval); } /** * @return {Object<string,any>|null} */ getLocalState() { return this.states.get(this.clientID) || null; } /** * @param {Object<string,any>|null} state */ setLocalState(state) { const clientID = this.clientID; const currLocalMeta = this.meta.get(clientID); const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; const prevState = this.states.get(clientID); if (state === null) { this.states.delete(clientID); } else { this.states.set(clientID, state); } this.meta.set(clientID, { clock, lastUpdated: getUnixTime() }); const added = []; const updated = []; const filteredUpdated = []; const removed = []; if (state === null) { removed.push(clientID); } else if (prevState == null) { if (state != null) { added.push(clientID); } } else { updated.push(clientID); if (!equalityDeep(prevState, state)) { filteredUpdated.push(clientID); } } if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); } this.emit("update", [{ added, updated, removed }, "local"]); } /** * @param {string} field * @param {any} value */ setLocalStateField(field, value) { const state = this.getLocalState(); if (state !== null) { this.setLocalState({ ...state, [field]: value }); } } /** * @return {Map<number,Object<string,any>>} */ getStates() { return this.states; } }; var removeAwarenessStates = (awareness, clients, origin2) => { const removed = []; for (let i = 0; i < clients.length; i++) { const clientID = clients[i]; if (awareness.states.has(clientID)) { awareness.states.delete(clientID); if (clientID === awareness.clientID) { const curMeta = ( /** @type {MetaClientState} */ awareness.meta.get(clientID) ); awareness.meta.set(clientID, { clock: curMeta.clock + 1, lastUpdated: getUnixTime() }); } removed.push(clientID); } } if (removed.length > 0) { awareness.emit("change", [{ added: [], updated: [], removed }, origin2]); awareness.emit("update", [{ added: [], updated: [], removed }, origin2]); } }; // packages/sync/build-module/config.mjs var CRDT_DOC_VERSION = 1; var CRDT_DOC_META_PERSISTENCE_KEY = "fromPersistence"; var CRDT_RECORD_MAP_KEY = "document"; var CRDT_STATE_MAP_KEY = "state"; var CRDT_STATE_MAP_SAVED_AT_KEY = "savedAt"; var CRDT_STATE_MAP_SAVED_BY_KEY = "savedBy"; var CRDT_STATE_MAP_VERSION_KEY = "version"; var LOCAL_EDITOR_ORIGIN = "gutenberg"; var LOCAL_SYNC_MANAGER_ORIGIN = "syncManager"; var LOCAL_UNDO_IGNORED_ORIGIN = "gutenberg-undo-ignored"; // packages/sync/build-module/errors.mjs var ConnectionErrorCode = /* @__PURE__ */ ((ConnectionErrorCode2) => { ConnectionErrorCode2["AUTHENTICATION_FAILED"] = "authentication-failed"; ConnectionErrorCode2["CONNECTION_EXPIRED"] = "connection-expired"; ConnectionErrorCode2["CONNECTION_LIMIT_EXCEEDED"] = "connection-limit-exceeded"; ConnectionErrorCode2["DOCUMENT_SIZE_LIMIT_EXCEEDED"] = "document-size-limit-exceeded"; ConnectionErrorCode2["UNKNOWN_ERROR"] = "unknown-error"; return ConnectionErrorCode2; })(ConnectionErrorCode || {}); var ConnectionError = class extends Error { constructor(code = "unknown-error", message) { super(message); this.code = code; this.name = "ConnectionError"; } }; // packages/sync/build-module/lock-unlock.mjs var import_private_apis = __toESM(require_private_apis(), 1); var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", "@wordpress/sync" ); // packages/sync/build-module/performance.mjs function logPerformanceTiming(fn) { return function(...args2) { const start = performance.now(); const result = fn.apply(this, args2); const end = performance.now(); console.log( `[SyncManager][performance]: ${fn.name} took ${(end - start).toFixed(2)} ms` ); return result; }; } function passThru(fn) { return ((...args2) => fn(...args2)); } function yieldToEventLoop(fn) { return function(...args2) { setTimeout(() => { fn.apply(this, args2); }, 0); }; } // packages/sync/build-module/providers/index.mjs var import_hooks3 = __toESM(require_hooks(), 1); // packages/sync/build-module/providers/http-polling/polling-manager.mjs var import_hooks2 = __toESM(require_hooks(), 1); // packages/sync/node_modules/y-protocols/sync.js var messageYjsSyncStep1 = 0; var messageYjsSyncStep2 = 1; var messageYjsUpdate = 2; var writeSyncStep1 = (encoder, doc2) => { writeVarUint(encoder, messageYjsSyncStep1); const sv = encodeStateVector(doc2); writeVarUint8Array(encoder, sv); }; var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { writeVarUint(encoder, messageYjsSyncStep2); writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); }; var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { try { applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); } catch (error) { if (errorHandler != null) errorHandler( /** @type {Error} */ error ); console.error("Caught error while handling a Yjs update", error); } }; var readUpdate2 = readSyncStep2; var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { const messageType = readVarUint(decoder); switch (messageType) { case messageYjsSyncStep1: readSyncStep1(decoder, encoder, doc2); break; case messageYjsSyncStep2: readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); break; case messageYjsUpdate: readUpdate2(decoder, doc2, transactionOrigin, errorHandler); break; default: throw new Error("Unknown message type"); } return messageType; }; // packages/sync/build-module/providers/http-polling/config.mjs var import_hooks = __toESM(require_hooks(), 1); var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; var MAX_ERROR_BACKOFF_IN_MS = 30 * 1e3; var MAX_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; var POLLING_INTERVAL_IN_MS = (0, import_hooks.applyFilters)( "sync.pollingManager.pollingInterval", 4e3 // 4 seconds ); var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = (0, import_hooks.applyFilters)( "sync.pollingManager.pollingIntervalWithCollaborators", 1e3 // 1 second ); var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; // packages/sync/build-module/providers/http-polling/types.mjs var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { SyncUpdateType2["COMPACTION"] = "compaction"; SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; SyncUpdateType2["UPDATE"] = "update"; return SyncUpdateType2; })(SyncUpdateType || {}); // packages/sync/build-module/providers/http-polling/utils.mjs var import_api_fetch = __toESM(require_api_fetch(), 1); var SYNC_API_PATH = "/wp-sync/v1/updates"; function uint8ArrayToBase64(data) { let binary = ""; const len = data.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(data[i]); } return globalThis.btoa(binary); } function base64ToUint8Array(base64) { const binaryString = globalThis.atob(base64); const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes; } function createSyncUpdate(data, type) { return { data: uint8ArrayToBase64(data), type }; } function createUpdateQueue(initial = [], paused = true) { let isPaused = paused; const updates = [...initial]; return { add(update) { updates.push(update); }, addBulk(bulkUpdates) { if (0 === bulkUpdates.length) { return; } updates.push(...bulkUpdates); }, clear() { updates.splice(0, updates.length); }, get() { if (isPaused) { return []; } return updates.splice(0, updates.length); }, pause() { isPaused = true; }, restore(restoredUpdates) { const filtered = restoredUpdates.filter( (u) => u.type !== SyncUpdateType.COMPACTION ); if (0 === filtered.length) { return; } updates.unshift(...filtered); }, resume() { isPaused = false; }, size() { return updates.length; } }; } async function postSyncUpdate(payload) { const response = await (0, import_api_fetch.default)({ body: JSON.stringify(payload), headers: { "Content-Type": "application/json" }, method: "POST", parse: false, path: SYNC_API_PATH }); if (!response.ok) { throw new Error( `Sync update failed with status ${response.status}` ); } return await response.json(); } function postSyncUpdateNonBlocking(payload) { if (payload.rooms.length === 0) { return; } (0, import_api_fetch.default)({ body: JSON.stringify(payload), headers: { "Content-Type": "application/json" }, keepalive: true, method: "POST", parse: false, path: SYNC_API_PATH }).catch(() => { }); } function intValueOrDefault(value, defaultValue) { const intValue = parseInt(String(value), 10); return isNaN(intValue) ? defaultValue : intValue; } // packages/sync/build-module/providers/http-polling/polling-manager.mjs var POLLING_MANAGER_ORIGIN = "polling-manager"; var roomStates = /* @__PURE__ */ new Map(); function createDeprecatedCompactionUpdate(updates) { const mergeable = updates.filter( (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( u.type ) ).map((u) => base64ToUint8Array(u.data)); return createSyncUpdate( mergeUpdatesV2(mergeable), SyncUpdateType.COMPACTION ); } function createSyncStep1Update(doc2) { const encoder = createEncoder(); writeSyncStep1(encoder, doc2); return createSyncUpdate( toUint8Array(encoder), SyncUpdateType.SYNC_STEP_1 ); } function createSyncStep2Update(doc2, step1) { const decoder = createDecoder(step1); const encoder = createEncoder(); readSyncMessage( decoder, encoder, doc2, POLLING_MANAGER_ORIGIN ); return createSyncUpdate( toUint8Array(encoder), SyncUpdateType.SYNC_STEP_2 ); } function processAwarenessUpdate(state, awareness) { const currentStates = awareness.getStates(); const added = /* @__PURE__ */ new Set(); const updated = /* @__PURE__ */ new Set(); const removed = new Set( Array.from(currentStates.keys()).filter( (clientId) => !state[clientId] ) ); Object.entries(state).forEach(([clientIdString, awarenessState]) => { const clientId = Number(clientIdString); if (clientId === awareness.clientID) { return; } if (null === awarenessState) { currentStates.delete(clientId); removed.add(clientId); return; } if (!currentStates.has(clientId)) { currentStates.set(clientId, awarenessState); added.add(clientId); return; } const currentState = currentStates.get(clientId); if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { currentStates.set(clientId, awarenessState); updated.add(clientId); } }); if (added.size + updated.size > 0) { awareness.emit("change", [ { added: Array.from(added), updated: Array.from(updated), // Left blank on purpose, as the removal of clients is handled in the if condition below. removed: [] } ]); } if (removed.size > 0) { removeAwarenessStates( awareness, Array.from(removed), POLLING_MANAGER_ORIGIN ); } } function processDocUpdate(update, doc2, onSync) { const data = base64ToUint8Array(update.data); switch (update.type) { case SyncUpdateType.SYNC_STEP_1: { return createSyncStep2Update(doc2, data); } case SyncUpdateType.SYNC_STEP_2: { const decoder = createDecoder(data); const encoder = createEncoder(); readSyncMessage( decoder, encoder, doc2, POLLING_MANAGER_ORIGIN ); onSync(); return; } case SyncUpdateType.COMPACTION: case SyncUpdateType.UPDATE: { applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); } } } function checkConnectionLimit(awareness, roomState) { if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { return false; } hasCheckedConnectionLimit = true; const maxClientsPerRoom = (0, import_hooks2.applyFilters)( "sync.pollingProvider.maxClientsPerRoom", DEFAULT_CLIENT_LIMIT_PER_ROOM, roomState.room ); const clientCount = Object.keys(awareness).length; const validatedLimit = intValueOrDefault( maxClientsPerRoom, DEFAULT_CLIENT_LIMIT_PER_ROOM ); if (clientCount > validatedLimit) { roomState.log("Connection limit exceeded", { clientCount, maxClientsPerRoom: validatedLimit, room: roomState.room }); return true; } return false; } var areListenersRegistered = false; var hasCheckedConnectionLimit = false; var hasCollaborators = false; var isActiveBrowser = "visible" === document.visibilityState; var isPolling = false; var isUnloadPending = false; var pollInterval = POLLING_INTERVAL_IN_MS; var pollingTimeoutId = null; function handleBeforeUnload() { isUnloadPending = true; } function handlePageHide() { const rooms = Array.from(roomStates.entries()).map( ([room, state]) => ({ after: 0, awareness: null, client_id: state.clientId, room, updates: [] }) ); postSyncUpdateNonBlocking({ rooms }); } function handleVisibilityChange() { const wasActive = isActiveBrowser; isActiveBrowser = document.visibilityState === "visible"; if (isActiveBrowser && !wasActive) { if (pollingTimeoutId) { clearTimeout(pollingTimeoutId); pollingTimeoutId = null; poll(); } } } function poll() { isPolling = true; pollingTimeoutId = null; async function start() { if (0 === roomStates.size) { isPolling = false; return; } isUnloadPending = false; roomStates.forEach((state) => { state.onStatusChange({ status: "connecting" }); }); const payload = { rooms: Array.from(roomStates.entries()).map( ([room, state]) => ({ after: state.endCursor ?? 0, awareness: state.localAwarenessState, client_id: state.clientId, room, updates: state.updateQueue.get() }) ) }; try { const { rooms } = await postSyncUpdate(payload); roomStates.forEach((state) => { state.onStatusChange({ status: "connected" }); }); hasCollaborators = false; rooms.forEach((room) => { if (!roomStates.has(room.room)) { return; } const roomState = roomStates.get(room.room); roomState.endCursor = room.end_cursor; if (checkConnectionLimit(room.awareness, roomState)) { roomState.onStatusChange({ status: "disconnected", error: new ConnectionError( ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, "Connection limit exceeded" ) }); unregisterRoom(room.room); return; } roomState.processAwarenessUpdate(room.awareness); if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { hasCollaborators = true; roomStates.forEach((state) => { state.updateQueue.resume(); }); } const responseUpdates = []; for (const update of room.updates) { try { const response = roomState.processDocUpdate(update); if (response) { responseUpdates.push(response); } } catch (error) { roomState.log( "Failed to apply sync update", { error, update }, "error", true // force ); } } roomState.updateQueue.addBulk(responseUpdates); if (room.should_compact) { roomState.log("Server requested compaction update"); roomState.updateQueue.clear(); roomState.updateQueue.add( roomState.createCompactionUpdate() ); } else if (room.compaction_request) { roomState.log("Server requested (old) compaction update"); roomState.updateQueue.add( createDeprecatedCompactionUpdate( room.compaction_request ) ); } }); if (isActiveBrowser && hasCollaborators) { pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; } else if (isActiveBrowser) { pollInterval = POLLING_INTERVAL_IN_MS; } else { pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; } } catch (error) { pollInterval = Math.min( pollInterval * 2, MAX_ERROR_BACKOFF_IN_MS ); for (const room of payload.rooms) { if (!roomStates.has(room.room)) { continue; } const state = roomStates.get(room.room); if (room.updates.length > 0 && state.endCursor > 0) { state.updateQueue.clear(); state.updateQueue.add(state.createCompactionUpdate()); } else if (room.updates.length > 0) { state.updateQueue.restore(room.updates); } state.log( "Error posting sync update, will retry with backoff", { error, nextPoll: pollInterval }, "error", true // force ); } if (!isUnloadPending) { roomStates.forEach((state) => { state.onStatusChange({ status: "disconnected", canManuallyRetry: true, willAutoRetryInMs: pollInterval }); }); } } pollingTimeoutId = setTimeout(poll, pollInterval); } void start(); } function registerRoom({ room, doc: doc2, awareness, log, onSync, onStatusChange }) { if (roomStates.has(room)) { return; } const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); const isPrimaryRoom = 0 === roomStates.size; function onAwarenessUpdate() { roomState.localAwarenessState = awareness.getLocalState() ?? {}; } function onDocUpdate(update, origin2) { if (POLLING_MANAGER_ORIGIN === origin2) { return; } if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { const state = roomStates.get(room); if (!state) { return; } state.log("Document size limit exceeded", { maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, updateSizeInBytes: update.byteLength }); state.onStatusChange({ status: "disconnected", error: new ConnectionError( ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, "Document size limit exceeded" ) }); unregisterRoom(room); } updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); } function unregister() { doc2.off("updateV2", onDocUpdate); awareness.off("change", onAwarenessUpdate); updateQueue.clear(); } const roomState = { clientId: doc2.clientID, createCompactionUpdate: () => createSyncUpdate( encodeStateAsUpdateV2(doc2), SyncUpdateType.COMPACTION ), endCursor: 0, isPrimaryRoom, localAwarenessState: awareness.getLocalState() ?? {}, log, onStatusChange, processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), processDocUpdate: (update) => processDocUpdate(update, doc2, onSync), room, unregister, updateQueue }; doc2.on("updateV2", onDocUpdate); awareness.on("change", onAwarenessUpdate); roomStates.set(room, roomState); if (!areListenersRegistered) { window.addEventListener("beforeunload", handleBeforeUnload); window.addEventListener("pagehide", handlePageHide); document.addEventListener("visibilitychange", handleVisibilityChange); areListenersRegistered = true; } if (!isPolling) { poll(); } } function unregisterRoom(room) { const state = roomStates.get(room); if (state) { const rooms = [ { after: 0, awareness: null, client_id: state.clientId, room, updates: [] } ]; postSyncUpdateNonBlocking({ rooms }); state.unregister(); roomStates.delete(room); } if (0 === roomStates.size && areListenersRegistered) { window.removeEventListener("beforeunload", handleBeforeUnload); window.removeEventListener("pagehide", handlePageHide); document.removeEventListener( "visibilitychange", handleVisibilityChange ); areListenersRegistered = false; hasCheckedConnectionLimit = false; } } function retryNow() { pollInterval = POLLING_INTERVAL_IN_MS * 2; if (pollingTimeoutId) { clearTimeout(pollingTimeoutId); pollingTimeoutId = null; poll(); } } var pollingManager = { registerRoom, retryNow, unregisterRoom }; // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs var HttpPollingProvider = class extends ObservableV2 { constructor(options) { super(); this.options = options; this.log("Initializing", { room: options.room }); this.awareness = options.awareness ?? new Awareness(options.ydoc); this.connect(); } awareness; status = "disconnected"; synced = false; /** * Connect to the endpoint and initialize sync. */ connect() { this.log("Connecting"); pollingManager.registerRoom({ room: this.options.room, doc: this.options.ydoc, awareness: this.awareness, log: this.log, onStatusChange: this.emitStatus, onSync: this.onSync }); } /** * Destroy the provider and cleanup resources. */ destroy() { this.disconnect(); super.destroy(); } /** * Disconnect the provider and allow reconnection later. */ disconnect() { this.log("Disconnecting"); pollingManager.unregisterRoom(this.options.room); this.emitStatus({ status: "disconnected" }); } /** * Emit connection status, passing the full object through so that * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. * * @param connectionStatus The connection status object */ emitStatus = (connectionStatus) => { const { status } = connectionStatus; const error = status === "disconnected" ? connectionStatus.error : void 0; if (this.status === status && !error) { return; } if (status === "connecting" && this.status !== "disconnected") { return; } this.log("Status change", { status, error }); this.status = status; this.emit("status", [connectionStatus]); }; /** * Log debug messages if debugging is enabled. * * @param message The debug message * @param debug Additional debug information * @param errorLevel The console method to use for logging * @param force Whether to force logging regardless of debug setting */ log = (message, debug = {}, errorLevel = "log", force = false) => { if (!this.options.debug && !force) { return; } const logFn = console[errorLevel] || console.log; logFn(`[${this.constructor.name}]: ${message}`, { room: this.options.room, ...debug }); }; /** * Handle synchronization events from the polling manager. */ onSync = () => { if (!this.synced) { this.synced = true; this.log("Synced"); } }; }; function createHttpPollingProvider() { return async ({ awareness, objectType, objectId, ydoc }) => { const room = objectId ? `${objectType}:${objectId}` : objectType; const provider = new HttpPollingProvider({ awareness, // debug: true, room, ydoc }); return { destroy: () => provider.destroy(), // Adapter: ObservableV2.on is compatible with ProviderOn // The callback receives data as the first parameter on: (event, callback) => { provider.on(event, callback); } }; }; } // packages/sync/build-module/providers/index.mjs var providerCreators = null; function getDefaultProviderCreators() { return [createHttpPollingProvider()]; } function isProviderCreator(creator) { return "function" === typeof creator; } function getProviderCreators() { if (providerCreators) { return providerCreators; } if (!window._wpCollaborationEnabled) { return []; } const filteredProviderCreators = (0, import_hooks3.applyFilters)( "sync.providers", getDefaultProviderCreators() ); if (!Array.isArray(filteredProviderCreators)) { providerCreators = []; return providerCreators; } providerCreators = filteredProviderCreators.filter(isProviderCreator); return providerCreators; } // packages/sync/build-module/y-utilities/y-multidoc-undomanager.mjs var popStackItem2 = (mum, type) => { const stack = type === "undo" ? mum.undoStack : mum.redoStack; while (stack.length > 0) { const um = ( /** @type {Y.UndoManager} */ stack.pop() ); const prevUmStack = type === "undo" ? um.undoStack : um.redoStack; const stackItem = ( /** @type {any} */ prevUmStack.pop() ); let actionPerformed = false; if (type === "undo") { um.undoStack = [stackItem]; actionPerformed = um.undo() !== null; um.undoStack = prevUmStack; } else { um.redoStack = [stackItem]; actionPerformed = um.redo() !== null; um.redoStack = prevUmStack; } if (actionPerformed) { return stackItem; } } return null; }; var YMultiDocUndoManager = class extends Observable { /** * @param {Y.AbstractType<any>|Array<Y.AbstractType<any>>} typeScope Accepts either a single type, or an array of types * @param {ConstructorParameters<typeof Y.UndoManager>[1]} opts */ constructor(typeScope = [], opts = {}) { super(); this.docs = /* @__PURE__ */ new Map(); this.trackedOrigins = opts.trackedOrigins || /* @__PURE__ */ new Set([null]); opts.trackedOrigins = this.trackedOrigins; this._defaultOpts = opts; this.undoStack = []; this.redoStack = []; this.addToScope(typeScope); } /** * @param {Array<Y.AbstractType<any>> | Y.AbstractType<any>} ytypes */ addToScope(ytypes) { ytypes = isArray(ytypes) ? ytypes : [ytypes]; ytypes.forEach((ytype) => { const ydoc = ( /** @type {Y.Doc} */ ytype.doc ); const um = setIfUndefined(this.docs, ydoc, () => { const um2 = new UndoManager([ytype], this._defaultOpts); um2.on( "stack-cleared", /** @param {any} opts */ ({ undoStackCleared, redoStackCleared }) => { this.clear(undoStackCleared, redoStackCleared); } ); ydoc.on("destroy", () => { this.docs.delete(ydoc); this.undoStack = this.undoStack.filter( (um3) => um3.doc !== ydoc ); this.redoStack = this.redoStack.filter( (um3) => um3.doc !== ydoc ); }); um2.on( "stack-item-added", /** @param {any} change */ (change) => { const stack = change.type === "undo" ? this.undoStack : this.redoStack; stack.push(um2); this.emit("stack-item-added", [ { ...change, ydoc }, this ]); } ); um2.on( "stack-item-updated", /** @param {any} change */ (change) => { this.emit("stack-item-updated", [ { ...change, ydoc }, this ]); } ); um2.on( "stack-item-popped", /** @param {any} change */ (change) => { this.emit("stack-item-popped", [ { ...change, ydoc }, this ]); } ); return um2; }); if (um.scope.every((yt) => yt !== ytype)) { um.scope.push(ytype); } }); } /** * @param {any} origin */ /* c8 ignore next 3 */ addTrackedOrigin(origin2) { this.trackedOrigins.add(origin2); } /** * @param {any} origin */ /* c8 ignore next 3 */ removeTrackedOrigin(origin2) { this.trackedOrigins.delete(origin2); } /** * Undo last changes on type. * * @return {any?} Returns StackItem if a change was applied */ undo() { return popStackItem2(this, "undo"); } /** * Redo last undo operation. * * @return {any?} Returns StackItem if a change was applied */ redo() { return popStackItem2(this, "redo"); } clear(clearUndoStack = true, clearRedoStack = true) { if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { this.docs.forEach((um) => { clearUndoStack && (this.undoStack = []); clearRedoStack && (this.redoStack = []); um.clear(clearUndoStack, clearRedoStack); }); this.emit("stack-cleared", [ { undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack } ]); } } /* c8 ignore next 5 */ stopCapturing() { this.docs.forEach((um) => { um.stopCapturing(); }); } /** * Are undo steps available? * * @return {boolean} `true` if undo is possible */ canUndo() { return this.undoStack.length > 0; } /** * Are redo steps available? * * @return {boolean} `true` if redo is possible */ canRedo() { return this.redoStack.length > 0; } destroy() { this.docs.forEach((um) => um.destroy()); super.destroy(); } }; // packages/sync/build-module/undo-manager.mjs function createUndoManager() { const yUndoManager = new YMultiDocUndoManager([], { // Throttle undo/redo captures after 500ms of inactivity. // 500 was selected from subjective local UX testing, shorter timeouts // may cause mid-word undo stack items. captureTimeout: 500, // Ensure that we only scope the undo/redo to the current editor. // The yjs document's clientID is added once it's available. trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) }); return { /** * Record changes into the history. * Since Yjs automatically tracks changes, this method translates the WordPress * HistoryRecord format into Yjs operations. * * @param _record A record of changes to record. * @param _isStaged Whether to immediately create an undo point or not. */ addRecord(_record, _isStaged = false) { }, /** * Add a Yjs map to the scope of the undo manager. * * @param {Y.Map< any >} ymap The Yjs map to add to the scope. * @param handlers * @param handlers.addUndoMeta * @param handlers.restoreUndoMeta */ addToScope(ymap, handlers) { if (ymap.doc === null) { return; } const ydoc = ymap.doc; yUndoManager.addToScope(ymap); const { addUndoMeta, restoreUndoMeta } = handlers; yUndoManager.on("stack-item-added", (event) => { addUndoMeta(ydoc, event.stackItem.meta); }); yUndoManager.on("stack-item-popped", (event) => { restoreUndoMeta(ydoc, event.stackItem.meta); }); }, /** * Undo the last recorded changes. * */ undo() { if (!yUndoManager.canUndo()) { return; } yUndoManager.undo(); return []; }, /** * Redo the last undone changes. */ redo() { if (!yUndoManager.canRedo()) { return; } yUndoManager.redo(); return []; }, /** * Check if there are changes that can be undone. * * @return {boolean} Whether there are changes to undo. */ hasUndo() { return yUndoManager.canUndo(); }, /** * Check if there are changes that can be redone. * * @return {boolean} Whether there are changes to redo. */ hasRedo() { return yUndoManager.canRedo(); }, /** * Stop capturing changes into the current undo item. * The next change will create a new undo item. */ stopCapturing() { yUndoManager.stopCapturing(); } }; } // packages/sync/build-module/utils.mjs function createYjsDoc(documentMeta = {}) { const metaMap = new Map( Object.entries(documentMeta) ); return new Doc({ meta: metaMap }); } function initializeYjsDoc(ydoc) { const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); } function markEntityAsSaved(ydoc) { const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); } function pseudoRandomID() { return Math.floor(Math.random() * 1e9); } function serializeCrdtDoc(crdtDoc) { return JSON.stringify({ document: toBase64(encodeStateAsUpdateV2(crdtDoc)), updateId: pseudoRandomID() // helps with debugging }); } function deserializeCrdtDoc(serializedCrdtDoc) { try { const { document: document2 } = JSON.parse(serializedCrdtDoc); const docMeta = { [CRDT_DOC_META_PERSISTENCE_KEY]: true }; const ydoc = createYjsDoc(docMeta); const yupdate = fromBase64(document2); applyUpdateV2(ydoc, yupdate); ydoc.clientID = pseudoRandomID(); return ydoc; } catch (e) { return null; } } // packages/sync/build-module/manager.mjs function getEntityId(objectType, objectId) { return `${objectType}_${objectId}`; } function createSyncManager(debug = false) { const debugWrap = debug ? logPerformanceTiming : passThru; const collectionStates = /* @__PURE__ */ new Map(); const entityStates = /* @__PURE__ */ new Map(); let undoManager; function log(component, message, entityId, context = {}) { if (!debug) { return; } console.log(`[SyncManager][${component}]: ${message}`, { ...context, entityId }); } async function loadEntity(syncConfig, objectType, objectId, record, handlers) { const providerCreators2 = getProviderCreators(); const entityId = getEntityId(objectType, objectId); if (0 === providerCreators2.length) { log("loadEntity", "no providers, skipping", entityId); return; } if (entityStates.has(entityId)) { log("loadEntity", "already loaded", entityId); return; } log("loadEntity", "loading", entityId); handlers = { addUndoMeta: debugWrap(handlers.addUndoMeta), editRecord: debugWrap(handlers.editRecord), getEditedRecord: debugWrap(handlers.getEditedRecord), onStatusChange: debugWrap(handlers.onStatusChange), persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), refetchRecord: debugWrap(handlers.refetchRecord), restoreUndoMeta: debugWrap(handlers.restoreUndoMeta) }; const ydoc = createYjsDoc({ objectType }); const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); const now = Date.now(); const unload = () => { log("loadEntity", "unloading", entityId); providerResults.forEach((result) => result.destroy()); handlers.onStatusChange(null); recordMap.unobserveDeep(onRecordUpdate); stateMap.unobserve(onStateMapUpdate); ydoc.destroy(); entityStates.delete(entityId); }; const awareness = syncConfig.createAwareness?.(ydoc, objectId); const onRecordUpdate = (_events, transaction) => { if (transaction.local && !(transaction.origin instanceof UndoManager)) { return; } void internal.updateEntityRecord(objectType, objectId); }; const onStateMapUpdate = (event, transaction) => { if (transaction.local) { return; } event.keysChanged.forEach((key) => { switch (key) { case CRDT_STATE_MAP_SAVED_AT_KEY: const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); if ("number" === typeof newValue && newValue > now) { log("loadEntity", "refetching record", entityId); void handlers.refetchRecord().catch(() => { }); } break; } }); }; if (!undoManager) { undoManager = createUndoManager(); } const { addUndoMeta, restoreUndoMeta } = handlers; undoManager.addToScope(recordMap, { addUndoMeta, restoreUndoMeta }); const entityState = { awareness, handlers, objectId, objectType, syncConfig, unload, ydoc }; entityStates.set(entityId, entityState); log("loadEntity", "connecting", entityId); const providerResults = await Promise.all( providerCreators2.map(async (create7) => { const provider = await create7({ objectType, objectId, ydoc, awareness }); provider.on("status", handlers.onStatusChange); return provider; }) ); recordMap.observeDeep(onRecordUpdate); stateMap.observe(onStateMapUpdate); initializeYjsDoc(ydoc); internal.applyPersistedCrdtDoc(objectType, objectId, record); } async function loadCollection(syncConfig, objectType, handlers) { const providerCreators2 = getProviderCreators(); const entityId = getEntityId(objectType, null); if (0 === providerCreators2.length) { log("loadCollection", "no providers, skipping", entityId); return; } if (collectionStates.has(objectType)) { log("loadCollection", "already loaded", entityId); return; } log("loadCollection", "loading", entityId); const ydoc = createYjsDoc({ collection: true, objectType }); const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); const now = Date.now(); const unload = () => { log("loadCollection", "unloading", entityId); providerResults.forEach((result) => result.destroy()); handlers.onStatusChange(null); stateMap.unobserve(onStateMapUpdate); ydoc.destroy(); collectionStates.delete(objectType); }; const onStateMapUpdate = (event, transaction) => { if (transaction.local) { return; } event.keysChanged.forEach((key) => { switch (key) { case CRDT_STATE_MAP_SAVED_AT_KEY: const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); if ("number" === typeof newValue && newValue > now) { void handlers.refetchRecords().catch(() => { }); } break; } }); }; const awareness = syncConfig.createAwareness?.(ydoc); const collectionState = { awareness, handlers, syncConfig, unload, ydoc }; collectionStates.set(objectType, collectionState); log("loadCollection", "connecting", entityId); const providerResults = await Promise.all( providerCreators2.map(async (create7) => { const provider = await create7({ awareness, objectType, objectId: null, ydoc }); provider.on("status", handlers.onStatusChange); return provider; }) ); stateMap.observe(onStateMapUpdate); initializeYjsDoc(ydoc); } function unloadEntity(objectType, objectId) { const entityId = getEntityId(objectType, objectId); log("unloadEntity", "unloading", entityId); entityStates.get(entityId)?.unload(); updateCRDTDoc(objectType, null, {}, origin, { isSave: true }); } function getAwareness(objectType, objectId) { const entityId = getEntityId(objectType, objectId); const entityState = entityStates.get(entityId); if (!entityState || !entityState.awareness) { return void 0; } return entityState.awareness; } function _applyPersistedCrdtDoc(objectType, objectId, record) { const entityId = getEntityId(objectType, objectId); const entityState = entityStates.get(entityId); if (!entityState) { log("applyPersistedCrdtDoc", "no entity state", entityId); return; } const { handlers, syncConfig: { applyChangesToCRDTDoc, getChangesFromCRDTDoc, getPersistedCRDTDoc }, ydoc: targetDoc } = entityState; const serialized = getPersistedCRDTDoc?.(record); const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; if (!tempDoc) { log("applyPersistedCrdtDoc", "no persisted doc", entityId); targetDoc.transact(() => { applyChangesToCRDTDoc(targetDoc, record); handlers.persistCRDTDoc(); }, LOCAL_SYNC_MANAGER_ORIGIN); return; } const update = encodeStateAsUpdateV2(tempDoc); applyUpdateV2(targetDoc, update); const invalidations = getChangesFromCRDTDoc(tempDoc, record); const invalidatedKeys = Object.keys(invalidations); tempDoc.destroy(); if (0 === invalidatedKeys.length) { log("applyPersistedCrdtDoc", "valid persisted doc", entityId); return; } log("applyPersistedCrdtDoc", "invalidated keys", entityId, { invalidatedKeys }); const changes = invalidatedKeys.reduce( (acc, key) => Object.assign(acc, { [key]: record[key] }), {} ); targetDoc.transact(() => { applyChangesToCRDTDoc(targetDoc, changes); handlers.persistCRDTDoc(); }, LOCAL_SYNC_MANAGER_ORIGIN); } function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { const { isSave = false, isNewUndoLevel = false } = options; const entityId = getEntityId(objectType, objectId); const entityState = entityStates.get(entityId); const collectionState = collectionStates.get(objectType); if (entityState) { const { syncConfig, ydoc } = entityState; if (isNewUndoLevel && undoManager) { undoManager.stopCapturing?.(); } ydoc.transact(() => { log("updateCRDTDoc", "applying changes", entityId, { changedKeys: Object.keys(changes) }); syncConfig.applyChangesToCRDTDoc(ydoc, changes); if (isSave) { markEntityAsSaved(ydoc); } }, origin2); } if (collectionState && isSave) { collectionState.ydoc.transact(() => { markEntityAsSaved(collectionState.ydoc); }, origin2); } } async function _updateEntityRecord(objectType, objectId) { const entityId = getEntityId(objectType, objectId); const entityState = entityStates.get(entityId); if (!entityState) { log("updateEntityRecord", "no entity state", entityId); return; } const { handlers, syncConfig, ydoc } = entityState; const changes = syncConfig.getChangesFromCRDTDoc( ydoc, await handlers.getEditedRecord() ); const changedKeys = Object.keys(changes); if (0 === changedKeys.length) { return; } log("updateEntityRecord", "changes", entityId, { changedKeys }); handlers.editRecord(changes); } async function createPersistedCRDTDoc(objectType, objectId) { const entityId = getEntityId(objectType, objectId); const entityState = entityStates.get(entityId); if (!entityState?.ydoc) { return null; } await new Promise((resolve) => setTimeout(resolve, 0)); return serializeCrdtDoc(entityState.ydoc); } const internal = { applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), updateEntityRecord: debugWrap(_updateEntityRecord) }; return { createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), getAwareness, load: debugWrap(loadEntity), loadCollection: debugWrap(loadCollection), // Use getter to ensure we always return the current value of `undoManager`. get undoManager() { return undoManager; }, unload: debugWrap(unloadEntity), update: debugWrap(yieldToEventLoop(updateCRDTDoc)) }; } // packages/sync/node_modules/diff/libesm/diff/base.js var Diff = class { diff(oldStr, newStr, options = {}) { let callback; if (typeof options === "function") { callback = options; options = {}; } else if ("callback" in options) { callback = options.callback; } const oldString = this.castInput(oldStr, options); const newString = this.castInput(newStr, options); const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); const newTokens = this.removeEmpty(this.tokenize(newString, options)); return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); } diffWithOptionsObj(oldTokens, newTokens, options, callback) { var _a; const done = (value) => { value = this.postProcess(value, options); if (callback) { setTimeout(function() { callback(value); }, 0); return void 0; } else { return value; } }; const newLen = newTokens.length, oldLen = oldTokens.length; let editLength = 1; let maxEditLength = newLen + oldLen; if (options.maxEditLength != null) { maxEditLength = Math.min(maxEditLength, options.maxEditLength); } const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; const abortAfterTimestamp = Date.now() + maxExecutionTime; const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); } let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; const execEditLength = () => { for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { let basePath; const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; if (removePath) { bestPath[diagonalPath - 1] = void 0; } let canAdd = false; if (addPath) { const addPathNewPos = addPath.oldPos - diagonalPath; canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; } const canRemove = removePath && removePath.oldPos + 1 < oldLen; if (!canAdd && !canRemove) { bestPath[diagonalPath] = void 0; continue; } if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { basePath = this.addToPath(addPath, true, false, 0, options); } else { basePath = this.addToPath(removePath, false, true, 1, options); } newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; } else { bestPath[diagonalPath] = basePath; if (basePath.oldPos + 1 >= oldLen) { maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); } if (newPos + 1 >= newLen) { minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); } } } editLength++; }; if (callback) { (function exec() { setTimeout(function() { if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { return callback(void 0); } if (!execEditLength()) { exec(); } }, 0); })(); } else { while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { const ret = execEditLength(); if (ret) { return ret; } } } } addToPath(path, added, removed, oldPosInc, options) { const last2 = path.lastComponent; if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { return { oldPos: path.oldPos + oldPosInc, lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } }; } else { return { oldPos: path.oldPos + oldPosInc, lastComponent: { count: 1, added, removed, previousComponent: last2 } }; } } extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { const newLen = newTokens.length, oldLen = oldTokens.length; let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { newPos++; oldPos++; commonCount++; if (options.oneChangePerToken) { basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; } } if (commonCount && !options.oneChangePerToken) { basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; } basePath.oldPos = oldPos; return newPos; } equals(left, right, options) { if (options.comparator) { return options.comparator(left, right); } else { return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); } } removeEmpty(array) { const ret = []; for (let i = 0; i < array.length; i++) { if (array[i]) { ret.push(array[i]); } } return ret; } // eslint-disable-next-line @typescript-eslint/no-unused-vars castInput(value, options) { return value; } // eslint-disable-next-line @typescript-eslint/no-unused-vars tokenize(value, options) { return Array.from(value); } join(chars) { return chars.join(""); } postProcess(changeObjects, options) { return changeObjects; } get useLongestToken() { return false; } buildValues(lastComponent, newTokens, oldTokens) { const components = []; let nextComponent; while (lastComponent) { components.push(lastComponent); nextComponent = lastComponent.previousComponent; delete lastComponent.previousComponent; lastComponent = nextComponent; } components.reverse(); const componentLen = components.length; let componentPos = 0, newPos = 0, oldPos = 0; for (; componentPos < componentLen; componentPos++) { const component = components[componentPos]; if (!component.removed) { if (!component.added && this.useLongestToken) { let value = newTokens.slice(newPos, newPos + component.count); value = value.map(function(value2, i) { const oldValue = oldTokens[oldPos + i]; return oldValue.length > value2.length ? oldValue : value2; }); component.value = this.join(value); } else { component.value = this.join(newTokens.slice(newPos, newPos + component.count)); } newPos += component.count; if (!component.added) { oldPos += component.count; } } else { component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); oldPos += component.count; } } return components; } }; // packages/sync/node_modules/diff/libesm/diff/character.js var CharacterDiff = class extends Diff { }; var characterDiff = new CharacterDiff(); function diffChars(oldStr, newStr, options) { return characterDiff.diff(oldStr, newStr, options); } // packages/sync/node_modules/diff/libesm/diff/line.js var LineDiff = class extends Diff { constructor() { super(...arguments); this.tokenize = tokenize; } equals(left, right, options) { if (options.ignoreWhitespace) { if (!options.newlineIsToken || !left.includes("\n")) { left = left.trim(); } if (!options.newlineIsToken || !right.includes("\n")) { right = right.trim(); } } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { if (left.endsWith("\n")) { left = left.slice(0, -1); } if (right.endsWith("\n")) { right = right.slice(0, -1); } } return super.equals(left, right, options); } }; var lineDiff = new LineDiff(); function diffLines(oldStr, newStr, options) { return lineDiff.diff(oldStr, newStr, options); } function tokenize(value, options) { if (options.stripTrailingCr) { value = value.replace(/\r\n/g, "\n"); } const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); if (!linesAndNewlines[linesAndNewlines.length - 1]) { linesAndNewlines.pop(); } for (let i = 0; i < linesAndNewlines.length; i++) { const line = linesAndNewlines[i]; if (i % 2 && !options.newlineIsToken) { retLines[retLines.length - 1] += line; } else { retLines.push(line); } } return retLines; } // packages/sync/build-module/quill-delta/Delta.mjs var import_es62 = __toESM(require_es6(), 1); // packages/sync/build-module/quill-delta/AttributeMap.mjs var import_es6 = __toESM(require_es6(), 1); function cloneDeep(value) { return JSON.parse(JSON.stringify(value)); } var AttributeMap; ((AttributeMap2) => { function compose(a = {}, b = {}, keepNull = false) { if (typeof a !== "object") { a = {}; } if (typeof b !== "object") { b = {}; } let attributes = cloneDeep(b); if (!keepNull) { attributes = Object.keys(attributes).reduce( (copy2, key) => { if (attributes[key] !== null || attributes[key] !== void 0) { copy2[key] = attributes[key]; } return copy2; }, {} ); } for (const key in a) { if (a[key] !== void 0 && b[key] === void 0) { attributes[key] = a[key]; } } return Object.keys(attributes).length > 0 ? attributes : void 0; } AttributeMap2.compose = compose; function diff(a = {}, b = {}) { if (typeof a !== "object") { a = {}; } if (typeof b !== "object") { b = {}; } const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { if (!(0, import_es6.default)(a[key], b[key])) { attrs[key] = b[key] === void 0 ? null : b[key]; } return attrs; }, {}); return Object.keys(attributes).length > 0 ? attributes : void 0; } AttributeMap2.diff = diff; function invert(attr = {}, base = {}) { attr = attr || {}; const baseInverted = Object.keys(base).reduce( (memo, key) => { if (base[key] !== attr[key] && attr[key] !== void 0) { memo[key] = base[key]; } return memo; }, {} ); return Object.keys(attr).reduce((memo, key) => { if (attr[key] !== base[key] && base[key] === void 0) { memo[key] = null; } return memo; }, baseInverted); } AttributeMap2.invert = invert; function transform(a, b, priority = false) { if (typeof a !== "object") { return b; } if (typeof b !== "object") { return void 0; } if (!priority) { return b; } const attributes = Object.keys(b).reduce( (attrs, key) => { if (a[key] === void 0) { attrs[key] = b[key]; } return attrs; }, {} ); return Object.keys(attributes).length > 0 ? attributes : void 0; } AttributeMap2.transform = transform; })(AttributeMap || (AttributeMap = {})); var AttributeMap_default = AttributeMap; // packages/sync/build-module/quill-delta/Op.mjs var Op; ((Op2) => { function length3(op) { if (typeof op.delete === "number") { return op.delete; } else if (typeof op.retain === "number") { return op.retain; } else if (typeof op.retain === "object" && op.retain !== null) { return 1; } return typeof op.insert === "string" ? op.insert.length : 1; } Op2.length = length3; })(Op || (Op = {})); var Op_default = Op; // packages/sync/build-module/quill-delta/OpIterator.mjs var Iterator = class { ops; index; offset; constructor(ops) { this.ops = ops; this.index = 0; this.offset = 0; } hasNext() { return this.peekLength() < Infinity; } next(length3) { if (!length3) { length3 = Infinity; } const nextOp = this.ops[this.index]; if (nextOp) { const offset = this.offset; const opLength = Op_default.length(nextOp); if (length3 >= opLength - offset) { length3 = opLength - offset; this.index += 1; this.offset = 0; } else { this.offset += length3; } if (typeof nextOp.delete === "number") { return { delete: length3 }; } const retOp = {}; if (nextOp.attributes) { retOp.attributes = nextOp.attributes; } if (typeof nextOp.retain === "number") { retOp.retain = length3; } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { retOp.retain = nextOp.retain; } else if (typeof nextOp.insert === "string") { retOp.insert = nextOp.insert.substr(offset, length3); } else { retOp.insert = nextOp.insert; } return retOp; } return { retain: Infinity }; } peek() { return this.ops[this.index]; } peekLength() { if (this.ops[this.index]) { return Op_default.length(this.ops[this.index]) - this.offset; } return Infinity; } peekType() { const op = this.ops[this.index]; if (op) { if (typeof op.delete === "number") { return "delete"; } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { return "retain"; } return "insert"; } return "retain"; } rest() { if (!this.hasNext()) { return []; } else if (this.offset === 0) { return this.ops.slice(this.index); } const offset = this.offset; const index = this.index; const next = this.next(); const rest = this.ops.slice(this.index); this.offset = offset; this.index = index; return [next].concat(rest); } }; // packages/sync/build-module/quill-delta/Delta.mjs function cloneDeep2(value) { return JSON.parse(JSON.stringify(value)); } var NULL_CHARACTER = String.fromCharCode(0); var STRING_TOO_LARGE_THRESHOLD = 1e4; function normalizeChangeCounts(changes) { return changes.map((change) => ({ ...change, count: change.value.length })); } var getEmbedTypeAndData = (a, b) => { if (typeof a !== "object" || a === null) { throw new Error(`cannot retain a ${typeof a}`); } if (typeof b !== "object" || b === null) { throw new Error(`cannot retain a ${typeof b}`); } const embedType = Object.keys(a)[0]; if (!embedType || embedType !== Object.keys(b)[0]) { throw new Error( `embed types not matched: ${embedType} != ${Object.keys(b)[0]}` ); } return [embedType, a[embedType], b[embedType]]; }; var Delta = class _Delta { static Op = Op_default; static OpIterator = Iterator; static AttributeMap = AttributeMap_default; static handlers = {}; static registerEmbed(embedType, handler) { this.handlers[embedType] = handler; } static unregisterEmbed(embedType) { delete this.handlers[embedType]; } static getHandler(embedType) { const handler = this.handlers[embedType]; if (!handler) { throw new Error(`no handlers for embed type "${embedType}"`); } return handler; } ops; constructor(ops) { if (Array.isArray(ops)) { this.ops = ops; } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { this.ops = ops.ops; } else { this.ops = []; } } insert(arg, attributes) { const newOp = {}; if (typeof arg === "string" && arg.length === 0) { return this; } newOp.insert = arg; if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { newOp.attributes = attributes; } return this.push(newOp); } delete(length3) { if (length3 <= 0) { return this; } return this.push({ delete: length3 }); } retain(length3, attributes) { if (typeof length3 === "number" && length3 <= 0) { return this; } const newOp = { retain: length3 }; if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { newOp.attributes = attributes; } return this.push(newOp); } push(newOp) { let index = this.ops.length; let lastOp = this.ops[index - 1]; newOp = cloneDeep2(newOp); if (typeof lastOp === "object") { if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { this.ops[index - 1] = { delete: lastOp.delete + newOp.delete }; return this; } if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { index -= 1; lastOp = this.ops[index - 1]; if (typeof lastOp !== "object") { this.ops.unshift(newOp); return this; } } if ((0, import_es62.default)(newOp.attributes, lastOp.attributes)) { if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { this.ops[index - 1] = { insert: lastOp.insert + newOp.insert }; if (typeof newOp.attributes === "object") { this.ops[index - 1].attributes = newOp.attributes; } return this; } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { this.ops[index - 1] = { retain: lastOp.retain + newOp.retain }; if (typeof newOp.attributes === "object") { this.ops[index - 1].attributes = newOp.attributes; } return this; } } } if (index === this.ops.length) { this.ops.push(newOp); } else { this.ops.splice(index, 0, newOp); } return this; } chop() { const lastOp = this.ops[this.ops.length - 1]; if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { this.ops.pop(); } return this; } filter(predicate) { return this.ops.filter(predicate); } forEach(predicate) { this.ops.forEach(predicate); } map(predicate) { return this.ops.map(predicate); } partition(predicate) { const passed = []; const failed = []; this.forEach((op) => { const target = predicate(op) ? passed : failed; target.push(op); }); return [passed, failed]; } reduce(predicate, initialValue) { return this.ops.reduce(predicate, initialValue); } changeLength() { return this.reduce((length3, elem) => { if (elem.insert) { return length3 + Op_default.length(elem); } else if (elem.delete) { return length3 - elem.delete; } return length3; }, 0); } length() { return this.reduce((length3, elem) => { return length3 + Op_default.length(elem); }, 0); } slice(start = 0, end = Infinity) { const ops = []; const iter = new Iterator(this.ops); let index = 0; while (index < end && iter.hasNext()) { let nextOp; if (index < start) { nextOp = iter.next(start - index); } else { nextOp = iter.next(end - index); ops.push(nextOp); } index += Op_default.length(nextOp); } return new _Delta(ops); } compose(other) { const thisIter = new Iterator(this.ops); const otherIter = new Iterator(other.ops); const ops = []; const firstOther = otherIter.peek(); if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { let firstLeft = firstOther.retain; while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { firstLeft -= thisIter.peekLength(); ops.push(thisIter.next()); } if (firstOther.retain - firstLeft > 0) { otherIter.next(firstOther.retain - firstLeft); } } const delta = new _Delta(ops); while (thisIter.hasNext() || otherIter.hasNext()) { if (otherIter.peekType() === "insert") { delta.push(otherIter.next()); } else if (thisIter.peekType() === "delete") { delta.push(thisIter.next()); } else { const length3 = Math.min( thisIter.peekLength(), otherIter.peekLength() ); const thisOp = thisIter.next(length3); const otherOp = otherIter.next(length3); if (otherOp.retain) { const newOp = {}; if (typeof thisOp.retain === "number") { newOp.retain = typeof otherOp.retain === "number" ? length3 : otherOp.retain; } else if (typeof otherOp.retain === "number") { if (thisOp.retain === null || thisOp.retain === void 0) { newOp.insert = thisOp.insert; } else { newOp.retain = thisOp.retain; } } else { const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; const [embedType, thisData, otherData] = getEmbedTypeAndData( thisOp[action], otherOp.retain ); const handler = _Delta.getHandler(embedType); newOp[action] = { [embedType]: handler.compose( thisData, otherData, action === "retain" ) }; } const attributes = AttributeMap_default.compose( thisOp.attributes, otherOp.attributes, typeof thisOp.retain === "number" ); if (attributes) { newOp.attributes = attributes; } delta.push(newOp); if (!otherIter.hasNext() && (0, import_es62.default)(delta.ops[delta.ops.length - 1], newOp)) { const rest = new _Delta(thisIter.rest()); return delta.concat(rest).chop(); } } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { delta.push(otherOp); } } } return delta.chop(); } concat(other) { const delta = new _Delta(this.ops.slice()); if (other.ops.length > 0) { delta.push(other.ops[0]); delta.ops = delta.ops.concat(other.ops.slice(1)); } return delta; } diff(other) { if (this.ops === other.ops) { return new _Delta(); } const strings = this.deltasToStrings(other); const diffResult = normalizeChangeCounts( diffChars(strings[0], strings[1]) ); const thisIter = new Iterator(this.ops); const otherIter = new Iterator(other.ops); const retDelta = this.convertChangesToDelta( diffResult, thisIter, otherIter ); return retDelta.chop(); } eachLine(predicate, newline = "\n") { const iter = new Iterator(this.ops); let line = new _Delta(); let i = 0; while (iter.hasNext()) { if (iter.peekType() !== "insert") { return; } const thisOp = iter.peek(); const start = Op_default.length(thisOp) - iter.peekLength(); const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; if (index < 0) { line.push(iter.next()); } else if (index > 0) { line.push(iter.next(index)); } else { if (predicate(line, iter.next(1).attributes || {}, i) === false) { return; } i += 1; line = new _Delta(); } } if (line.length() > 0) { predicate(line, {}, i); } } invert(base) { const inverted = new _Delta(); this.reduce((baseIndex, op) => { if (op.insert) { inverted.delete(Op_default.length(op)); } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { inverted.retain(op.retain); return baseIndex + op.retain; } else if (op.delete || typeof op.retain === "number") { const length3 = op.delete || op.retain; const slice = base.slice(baseIndex, baseIndex + length3); slice.forEach((baseOp) => { if (op.delete) { inverted.push(baseOp); } else if (op.retain && op.attributes) { inverted.retain( Op_default.length(baseOp), AttributeMap_default.invert( op.attributes, baseOp.attributes ) ); } }); return baseIndex + length3; } else if (typeof op.retain === "object" && op.retain !== null) { const slice = base.slice(baseIndex, baseIndex + 1); const baseOp = new Iterator(slice.ops).next(); const [embedType, opData, baseOpData] = getEmbedTypeAndData( op.retain, baseOp.insert ); const handler = _Delta.getHandler(embedType); inverted.retain( { [embedType]: handler.invert(opData, baseOpData) }, AttributeMap_default.invert(op.attributes, baseOp.attributes) ); return baseIndex + 1; } return baseIndex; }, 0); return inverted.chop(); } transform(arg, priority = false) { priority = !!priority; if (typeof arg === "number") { return this.transformPosition(arg, priority); } const other = arg; const thisIter = new Iterator(this.ops); const otherIter = new Iterator(other.ops); const delta = new _Delta(); while (thisIter.hasNext() || otherIter.hasNext()) { if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { delta.retain(Op_default.length(thisIter.next())); } else if (otherIter.peekType() === "insert") { delta.push(otherIter.next()); } else { const length3 = Math.min( thisIter.peekLength(), otherIter.peekLength() ); const thisOp = thisIter.next(length3); const otherOp = otherIter.next(length3); if (thisOp.delete) { continue; } else if (otherOp.delete) { delta.push(otherOp); } else { const thisData = thisOp.retain; const otherData = otherOp.retain; let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length3; if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { const embedType = Object.keys(thisData)[0]; if (embedType === Object.keys(otherData)[0]) { const handler = _Delta.getHandler(embedType); if (handler) { transformedData = { [embedType]: handler.transform( thisData[embedType], otherData[embedType], priority ) }; } } } delta.retain( transformedData, AttributeMap_default.transform( thisOp.attributes, otherOp.attributes, priority ) ); } } } return delta.chop(); } transformPosition(index, priority = false) { priority = !!priority; const thisIter = new Iterator(this.ops); let offset = 0; while (thisIter.hasNext() && offset <= index) { const length3 = thisIter.peekLength(); const nextType = thisIter.peekType(); thisIter.next(); if (nextType === "delete") { index -= Math.min(length3, index - offset); continue; } else if (nextType === "insert" && (offset < index || !priority)) { index += length3; } offset += length3; } return index; } /** * Given a Delta and a cursor position, do a diff and attempt to adjust * the diff to place insertions or deletions at the cursor position. * * @param other - The other Delta to diff against. * @param cursorAfterChange - The cursor position index after the change. * @return A Delta that attempts to place insertions or deletions at the cursor position. */ diffWithCursor(other, cursorAfterChange) { if (this.ops === other.ops) { return new _Delta(); } const strings = this.deltasToStrings(other); const maxStringLength = Math.max( ...strings.map((str) => str.length) ); if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { const diffResult = normalizeChangeCounts( diffLines(strings[0], strings[1]) ); const thisIterLarge = new Iterator(this.ops); const otherIterLarge = new Iterator(other.ops); return this.convertChangesToDelta( diffResult, thisIterLarge, otherIterLarge ).chop(); } else if (cursorAfterChange === null) { return this.diff(other); } let diffs = normalizeChangeCounts( diffChars(strings[0], strings[1]) ); let lastDiffPosition = 0; const adjustedDiffs = []; for (let i = 0; i < diffs.length; i++) { const diff = diffs[i]; const segmentStart = lastDiffPosition; const segmentEnd = lastDiffPosition + (diff.count ?? 0); const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; const isUnchangedSegment = !diff.added && !diff.removed; const isRemovalSegment = diff.removed && !diff.added; const nextDiff = diffs[i + 1]; const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { const movedSegments = this.tryMoveInsertionToCursor( diff, nextDiff, cursorAfterChange, segmentStart ); if (movedSegments) { adjustedDiffs.push(...movedSegments); i++; lastDiffPosition = segmentEnd; continue; } } if (isRemovalSegment) { const movedSegments = this.tryMoveDeletionToCursor( diff, adjustedDiffs, cursorAfterChange, lastDiffPosition ); if (movedSegments) { adjustedDiffs.pop(); adjustedDiffs.push(...movedSegments); lastDiffPosition += diff.count ?? 0; continue; } } adjustedDiffs.push(diff); if (!diff.added) { lastDiffPosition += diff.count ?? 0; } } diffs = adjustedDiffs; const thisIter = new Iterator(this.ops); const otherIter = new Iterator(other.ops); const retDelta = this.convertChangesToDelta( diffs, thisIter, otherIter ); return retDelta.chop(); } /** * Try to move an insertion operation from after an unchanged segment to the cursor position within it. * This is a "look-ahead" strategy. * * @param diff - The current unchanged diff segment. * @param nextDiff - The next diff segment (expected to be an insertion). * @param cursorAfterChange - The cursor position after the change. * @param segmentStart - The start position of the current segment. * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. */ tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { const nextDiffInsert = nextDiff.value; const insertLength = nextDiffInsert.length; const insertOffset = cursorAfterChange - segmentStart - insertLength; const textAtCursor = diff.value.substring( insertOffset, insertOffset + nextDiffInsert.length ); const isInsertMoveable = textAtCursor === nextDiffInsert; if (!isInsertMoveable) { return null; } const beforeCursor = diff.value.substring(0, insertOffset); const afterCursor = diff.value.substring(insertOffset); const result = []; if (beforeCursor.length > 0) { result.push({ value: beforeCursor, count: beforeCursor.length, added: false, removed: false }); } result.push(nextDiff); if (afterCursor.length > 0) { result.push({ value: afterCursor, count: afterCursor.length, added: false, removed: false }); } return result; } /** * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. * This is a "look-back" strategy. * * @param diff - The current deletion diff segment. * @param adjustedDiffs - The array of previously processed diff segments. * @param cursorAfterChange - The cursor position after the change. * @param lastDiffPosition - The position in the document up to (but not including) the current diff. * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. */ tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; if (!prevDiff || prevDiff.added || prevDiff.removed) { return null; } const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); const prevSegmentEnd = lastDiffPosition; if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { return null; } const deletedChars = diff.value; const deleteOffset = cursorAfterChange - prevSegmentStart; const textAtCursor = prevDiff.value.substring( deleteOffset, deleteOffset + deletedChars.length ); const canBePlacedHere = textAtCursor === deletedChars; if (!canBePlacedHere) { return null; } const beforeCursor = prevDiff.value.substring(0, deleteOffset); const atAndAfterCursor = prevDiff.value.substring(deleteOffset); const deletionLength = diff.count ?? 0; const afterDeletion = atAndAfterCursor.substring(deletionLength); const result = []; if (beforeCursor.length > 0) { result.push({ value: beforeCursor, count: beforeCursor.length, added: false, removed: false }); } result.push(diff); if (afterDeletion.length > 0) { result.push({ value: afterDeletion, count: afterDeletion.length, added: false, removed: false }); } return result; } /** * Convert two Deltas to string representations for diffing. * * @param other - The other Delta to convert. * @return A tuple of [thisString, otherString]. */ deltasToStrings(other) { return [this, other].map((delta) => { return delta.map((op) => { if (op.insert !== null || op.insert !== void 0) { return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; } const prep = delta === other ? "on" : "with"; throw new Error( "diff() called " + prep + " non-document" ); }).join(""); }); } /** * Process diff changes and convert them to Delta operations. * * @param changes - The array of changes from the diff algorithm. * @param thisIter - Iterator for this Delta's operations. * @param otherIter - Iterator for the other Delta's operations. * @return A Delta containing the processed diff operations. */ convertChangesToDelta(changes, thisIter, otherIter) { const retDelta = new _Delta(); changes.forEach((component) => { let length3 = component.count ?? 0; while (length3 > 0) { let opLength = 0; if (component.added) { opLength = Math.min(otherIter.peekLength(), length3); retDelta.push(otherIter.next(opLength)); } else if (component.removed) { opLength = Math.min(length3, thisIter.peekLength()); thisIter.next(opLength); retDelta.delete(opLength); } else { opLength = Math.min( thisIter.peekLength(), otherIter.peekLength(), length3 ); const thisOp = thisIter.next(opLength); const otherOp = otherIter.next(opLength); if ((0, import_es62.default)(thisOp.insert, otherOp.insert)) { retDelta.retain( opLength, AttributeMap_default.diff( thisOp.attributes, otherOp.attributes ) ); } else { retDelta.push(otherOp).delete(opLength); } } length3 -= opLength; } }); return retDelta; } }; var Delta_default = Delta; // packages/sync/build-module/private-apis.mjs var privateApis = {}; lock(privateApis, { ConnectionErrorCode, createSyncManager, Delta: Delta_default, CRDT_DOC_META_PERSISTENCE_KEY, CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_UNDO_IGNORED_ORIGIN, retrySyncConnection: () => pollingManager.retryNow() }); // packages/sync/build-module/index.mjs var YJS_VERSION = "13"; return __toCommonJS(index_exports); })();
Save
Cancel