| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 "use strict"; 2 var wp; 3 (wp ||= {}).sync = (() => { 4 var __create = Object.create; 5 var __defProp = Object.defineProperty; 6 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 7 var __getOwnPropNames = Object.getOwnPropertyNames; 8 var __getProtoOf = Object.getPrototypeOf; 9 var __hasOwnProp = Object.prototype.hasOwnProperty; 10 var __commonJS = (cb, mod) => function __require() { 11 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 12 }; 13 var __export = (target, all2) => { 14 for (var name in all2) 15 __defProp(target, name, { get: all2[name], enumerable: true }); 16 }; 17 var __copyProps = (to, from2, except, desc) => { 18 if (from2 && typeof from2 === "object" || typeof from2 === "function") { 19 for (let key of __getOwnPropNames(from2)) 20 if (!__hasOwnProp.call(to, key) && key !== except) 21 __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable }); 22 } 23 return to; 24 }; 25 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 26 // If the importer is in node compatibility mode or this is not an ESM 27 // file that has been converted to a CommonJS file using a Babel- 28 // compatible transform (i.e. "__esModule" has not been set), then set 29 // "default" to the CommonJS "module.exports" for node compatibility. 30 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 31 mod 32 )); 33 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 34 35 // package-external:@wordpress/private-apis 36 var require_private_apis = __commonJS({ 37 "package-external:@wordpress/private-apis"(exports, module) { 38 module.exports = window.wp.privateApis; 39 } 40 }); 41 42 // package-external:@wordpress/hooks 43 var require_hooks = __commonJS({ 44 "package-external:@wordpress/hooks"(exports, module) { 45 module.exports = window.wp.hooks; 46 } 47 }); 48 49 // package-external:@wordpress/api-fetch 50 var require_api_fetch = __commonJS({ 51 "package-external:@wordpress/api-fetch"(exports, module) { 52 module.exports = window.wp.apiFetch; 53 } 54 }); 55 56 // node_modules/fast-deep-equal/es6/index.js 57 var require_es6 = __commonJS({ 58 "node_modules/fast-deep-equal/es6/index.js"(exports, module) { 59 "use strict"; 60 module.exports = function equal(a, b) { 61 if (a === b) return true; 62 if (a && b && typeof a == "object" && typeof b == "object") { 63 if (a.constructor !== b.constructor) return false; 64 var length3, i, keys2; 65 if (Array.isArray(a)) { 66 length3 = a.length; 67 if (length3 != b.length) return false; 68 for (i = length3; i-- !== 0; ) 69 if (!equal(a[i], b[i])) return false; 70 return true; 71 } 72 if (a instanceof Map && b instanceof Map) { 73 if (a.size !== b.size) return false; 74 for (i of a.entries()) 75 if (!b.has(i[0])) return false; 76 for (i of a.entries()) 77 if (!equal(i[1], b.get(i[0]))) return false; 78 return true; 79 } 80 if (a instanceof Set && b instanceof Set) { 81 if (a.size !== b.size) return false; 82 for (i of a.entries()) 83 if (!b.has(i[0])) return false; 84 return true; 85 } 86 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 87 length3 = a.length; 88 if (length3 != b.length) return false; 89 for (i = length3; i-- !== 0; ) 90 if (a[i] !== b[i]) return false; 91 return true; 92 } 93 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 94 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 95 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 96 keys2 = Object.keys(a); 97 length3 = keys2.length; 98 if (length3 !== Object.keys(b).length) return false; 99 for (i = length3; i-- !== 0; ) 100 if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false; 101 for (i = length3; i-- !== 0; ) { 102 var key = keys2[i]; 103 if (!equal(a[key], b[key])) return false; 104 } 105 return true; 106 } 107 return a !== a && b !== b; 108 }; 109 } 110 }); 111 112 // packages/sync/build-module/index.mjs 113 var index_exports = {}; 114 __export(index_exports, { 115 Awareness: () => Awareness, 116 Y: () => yjs_exports, 117 YJS_VERSION: () => YJS_VERSION, 118 privateApis: () => privateApis 119 }); 120 121 // node_modules/yjs/dist/yjs.mjs 122 var yjs_exports = {}; 123 __export(yjs_exports, { 124 AbsolutePosition: () => AbsolutePosition, 125 AbstractConnector: () => AbstractConnector, 126 AbstractStruct: () => AbstractStruct, 127 AbstractType: () => AbstractType, 128 Array: () => YArray, 129 ContentAny: () => ContentAny, 130 ContentBinary: () => ContentBinary, 131 ContentDeleted: () => ContentDeleted, 132 ContentDoc: () => ContentDoc, 133 ContentEmbed: () => ContentEmbed, 134 ContentFormat: () => ContentFormat, 135 ContentJSON: () => ContentJSON, 136 ContentString: () => ContentString, 137 ContentType: () => ContentType, 138 Doc: () => Doc, 139 GC: () => GC, 140 ID: () => ID, 141 Item: () => Item, 142 Map: () => YMap, 143 PermanentUserData: () => PermanentUserData, 144 RelativePosition: () => RelativePosition, 145 Skip: () => Skip, 146 Snapshot: () => Snapshot, 147 Text: () => YText, 148 Transaction: () => Transaction, 149 UndoManager: () => UndoManager, 150 UpdateDecoderV1: () => UpdateDecoderV1, 151 UpdateDecoderV2: () => UpdateDecoderV2, 152 UpdateEncoderV1: () => UpdateEncoderV1, 153 UpdateEncoderV2: () => UpdateEncoderV2, 154 XmlElement: () => YXmlElement, 155 XmlFragment: () => YXmlFragment, 156 XmlHook: () => YXmlHook, 157 XmlText: () => YXmlText, 158 YArrayEvent: () => YArrayEvent, 159 YEvent: () => YEvent, 160 YMapEvent: () => YMapEvent, 161 YTextEvent: () => YTextEvent, 162 YXmlEvent: () => YXmlEvent, 163 applyUpdate: () => applyUpdate, 164 applyUpdateV2: () => applyUpdateV2, 165 cleanupYTextFormatting: () => cleanupYTextFormatting, 166 compareIDs: () => compareIDs, 167 compareRelativePositions: () => compareRelativePositions, 168 convertUpdateFormatV1ToV2: () => convertUpdateFormatV1ToV2, 169 convertUpdateFormatV2ToV1: () => convertUpdateFormatV2ToV1, 170 createAbsolutePositionFromRelativePosition: () => createAbsolutePositionFromRelativePosition, 171 createDeleteSet: () => createDeleteSet, 172 createDeleteSetFromStructStore: () => createDeleteSetFromStructStore, 173 createDocFromSnapshot: () => createDocFromSnapshot, 174 createID: () => createID, 175 createRelativePositionFromJSON: () => createRelativePositionFromJSON, 176 createRelativePositionFromTypeIndex: () => createRelativePositionFromTypeIndex, 177 createSnapshot: () => createSnapshot, 178 decodeRelativePosition: () => decodeRelativePosition, 179 decodeSnapshot: () => decodeSnapshot, 180 decodeSnapshotV2: () => decodeSnapshotV2, 181 decodeStateVector: () => decodeStateVector, 182 decodeUpdate: () => decodeUpdate, 183 decodeUpdateV2: () => decodeUpdateV2, 184 diffUpdate: () => diffUpdate, 185 diffUpdateV2: () => diffUpdateV2, 186 emptySnapshot: () => emptySnapshot, 187 encodeRelativePosition: () => encodeRelativePosition, 188 encodeSnapshot: () => encodeSnapshot, 189 encodeSnapshotV2: () => encodeSnapshotV2, 190 encodeStateAsUpdate: () => encodeStateAsUpdate, 191 encodeStateAsUpdateV2: () => encodeStateAsUpdateV2, 192 encodeStateVector: () => encodeStateVector, 193 encodeStateVectorFromUpdate: () => encodeStateVectorFromUpdate, 194 encodeStateVectorFromUpdateV2: () => encodeStateVectorFromUpdateV2, 195 equalDeleteSets: () => equalDeleteSets, 196 equalSnapshots: () => equalSnapshots, 197 findIndexSS: () => findIndexSS, 198 findRootTypeKey: () => findRootTypeKey, 199 getItem: () => getItem, 200 getItemCleanEnd: () => getItemCleanEnd, 201 getItemCleanStart: () => getItemCleanStart, 202 getState: () => getState, 203 getTypeChildren: () => getTypeChildren, 204 isDeleted: () => isDeleted, 205 isParentOf: () => isParentOf, 206 iterateDeletedStructs: () => iterateDeletedStructs, 207 logType: () => logType, 208 logUpdate: () => logUpdate, 209 logUpdateV2: () => logUpdateV2, 210 mergeDeleteSets: () => mergeDeleteSets, 211 mergeUpdates: () => mergeUpdates, 212 mergeUpdatesV2: () => mergeUpdatesV2, 213 obfuscateUpdate: () => obfuscateUpdate, 214 obfuscateUpdateV2: () => obfuscateUpdateV2, 215 parseUpdateMeta: () => parseUpdateMeta, 216 parseUpdateMetaV2: () => parseUpdateMetaV2, 217 readUpdate: () => readUpdate, 218 readUpdateV2: () => readUpdateV2, 219 relativePositionToJSON: () => relativePositionToJSON, 220 snapshot: () => snapshot, 221 snapshotContainsUpdate: () => snapshotContainsUpdate, 222 transact: () => transact, 223 tryGc: () => tryGc, 224 typeListToArraySnapshot: () => typeListToArraySnapshot, 225 typeMapGetAllSnapshot: () => typeMapGetAllSnapshot, 226 typeMapGetSnapshot: () => typeMapGetSnapshot 227 }); 228 229 // node_modules/lib0/map.js 230 var create = () => /* @__PURE__ */ new Map(); 231 var copy = (m) => { 232 const r = create(); 233 m.forEach((v, k) => { 234 r.set(k, v); 235 }); 236 return r; 237 }; 238 var setIfUndefined = (map2, key, createT) => { 239 let set = map2.get(key); 240 if (set === void 0) { 241 map2.set(key, set = createT()); 242 } 243 return set; 244 }; 245 var map = (m, f) => { 246 const res = []; 247 for (const [key, value] of m) { 248 res.push(f(value, key)); 249 } 250 return res; 251 }; 252 var any = (m, f) => { 253 for (const [key, value] of m) { 254 if (f(value, key)) { 255 return true; 256 } 257 } 258 return false; 259 }; 260 261 // node_modules/lib0/set.js 262 var create2 = () => /* @__PURE__ */ new Set(); 263 264 // node_modules/lib0/array.js 265 var last = (arr) => arr[arr.length - 1]; 266 var appendTo = (dest, src) => { 267 for (let i = 0; i < src.length; i++) { 268 dest.push(src[i]); 269 } 270 }; 271 var from = Array.from; 272 var some = (arr, f) => { 273 for (let i = 0; i < arr.length; i++) { 274 if (f(arr[i], i, arr)) { 275 return true; 276 } 277 } 278 return false; 279 }; 280 var unfold = (len, f) => { 281 const array = new Array(len); 282 for (let i = 0; i < len; i++) { 283 array[i] = f(i, array); 284 } 285 return array; 286 }; 287 var isArray = Array.isArray; 288 289 // node_modules/lib0/observable.js 290 var ObservableV2 = class { 291 constructor() { 292 this._observers = create(); 293 } 294 /** 295 * @template {keyof EVENTS & string} NAME 296 * @param {NAME} name 297 * @param {EVENTS[NAME]} f 298 */ 299 on(name, f) { 300 setIfUndefined( 301 this._observers, 302 /** @type {string} */ 303 name, 304 create2 305 ).add(f); 306 return f; 307 } 308 /** 309 * @template {keyof EVENTS & string} NAME 310 * @param {NAME} name 311 * @param {EVENTS[NAME]} f 312 */ 313 once(name, f) { 314 const _f = (...args2) => { 315 this.off( 316 name, 317 /** @type {any} */ 318 _f 319 ); 320 f(...args2); 321 }; 322 this.on( 323 name, 324 /** @type {any} */ 325 _f 326 ); 327 } 328 /** 329 * @template {keyof EVENTS & string} NAME 330 * @param {NAME} name 331 * @param {EVENTS[NAME]} f 332 */ 333 off(name, f) { 334 const observers = this._observers.get(name); 335 if (observers !== void 0) { 336 observers.delete(f); 337 if (observers.size === 0) { 338 this._observers.delete(name); 339 } 340 } 341 } 342 /** 343 * Emit a named event. All registered event listeners that listen to the 344 * specified name will receive the event. 345 * 346 * @todo This should catch exceptions 347 * 348 * @template {keyof EVENTS & string} NAME 349 * @param {NAME} name The event name. 350 * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. 351 */ 352 emit(name, args2) { 353 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 354 } 355 destroy() { 356 this._observers = create(); 357 } 358 }; 359 var Observable = class { 360 constructor() { 361 this._observers = create(); 362 } 363 /** 364 * @param {N} name 365 * @param {function} f 366 */ 367 on(name, f) { 368 setIfUndefined(this._observers, name, create2).add(f); 369 } 370 /** 371 * @param {N} name 372 * @param {function} f 373 */ 374 once(name, f) { 375 const _f = (...args2) => { 376 this.off(name, _f); 377 f(...args2); 378 }; 379 this.on(name, _f); 380 } 381 /** 382 * @param {N} name 383 * @param {function} f 384 */ 385 off(name, f) { 386 const observers = this._observers.get(name); 387 if (observers !== void 0) { 388 observers.delete(f); 389 if (observers.size === 0) { 390 this._observers.delete(name); 391 } 392 } 393 } 394 /** 395 * Emit a named event. All registered event listeners that listen to the 396 * specified name will receive the event. 397 * 398 * @todo This should catch exceptions 399 * 400 * @param {N} name The event name. 401 * @param {Array<any>} args The arguments that are applied to the event listener. 402 */ 403 emit(name, args2) { 404 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 405 } 406 destroy() { 407 this._observers = create(); 408 } 409 }; 410 411 // node_modules/lib0/math.js 412 var floor = Math.floor; 413 var abs = Math.abs; 414 var min = (a, b) => a < b ? a : b; 415 var max = (a, b) => a > b ? a : b; 416 var isNaN2 = Number.isNaN; 417 var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; 418 419 // node_modules/lib0/binary.js 420 var BIT1 = 1; 421 var BIT2 = 2; 422 var BIT3 = 4; 423 var BIT4 = 8; 424 var BIT6 = 32; 425 var BIT7 = 64; 426 var BIT8 = 128; 427 var BIT18 = 1 << 17; 428 var BIT19 = 1 << 18; 429 var BIT20 = 1 << 19; 430 var BIT21 = 1 << 20; 431 var BIT22 = 1 << 21; 432 var BIT23 = 1 << 22; 433 var BIT24 = 1 << 23; 434 var BIT25 = 1 << 24; 435 var BIT26 = 1 << 25; 436 var BIT27 = 1 << 26; 437 var BIT28 = 1 << 27; 438 var BIT29 = 1 << 28; 439 var BIT30 = 1 << 29; 440 var BIT31 = 1 << 30; 441 var BIT32 = 1 << 31; 442 var BITS5 = 31; 443 var BITS6 = 63; 444 var BITS7 = 127; 445 var BITS17 = BIT18 - 1; 446 var BITS18 = BIT19 - 1; 447 var BITS19 = BIT20 - 1; 448 var BITS20 = BIT21 - 1; 449 var BITS21 = BIT22 - 1; 450 var BITS22 = BIT23 - 1; 451 var BITS23 = BIT24 - 1; 452 var BITS24 = BIT25 - 1; 453 var BITS25 = BIT26 - 1; 454 var BITS26 = BIT27 - 1; 455 var BITS27 = BIT28 - 1; 456 var BITS28 = BIT29 - 1; 457 var BITS29 = BIT30 - 1; 458 var BITS30 = BIT31 - 1; 459 var BITS31 = 2147483647; 460 461 // node_modules/lib0/number.js 462 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; 463 var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; 464 var LOWEST_INT32 = 1 << 31; 465 var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); 466 var isNaN3 = Number.isNaN; 467 var parseInt2 = Number.parseInt; 468 469 // node_modules/lib0/string.js 470 var fromCharCode = String.fromCharCode; 471 var fromCodePoint = String.fromCodePoint; 472 var MAX_UTF16_CHARACTER = fromCharCode(65535); 473 var toLowerCase = (s) => s.toLowerCase(); 474 var trimLeftRegex = /^\s*/g; 475 var trimLeft = (s) => s.replace(trimLeftRegex, ""); 476 var fromCamelCaseRegex = /([A-Z])/g; 477 var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match) => `$separator}$toLowerCase(match)}`)); 478 var _encodeUtf8Polyfill = (str) => { 479 const encodedString = unescape(encodeURIComponent(str)); 480 const len = encodedString.length; 481 const buf = new Uint8Array(len); 482 for (let i = 0; i < len; i++) { 483 buf[i] = /** @type {number} */ 484 encodedString.codePointAt(i); 485 } 486 return buf; 487 }; 488 var utf8TextEncoder = ( 489 /** @type {TextEncoder} */ 490 typeof TextEncoder !== "undefined" ? new TextEncoder() : null 491 ); 492 var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); 493 var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; 494 var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); 495 if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { 496 utf8TextDecoder = null; 497 } 498 var repeat = (source, n) => unfold(n, () => source).join(""); 499 500 // node_modules/lib0/encoding.js 501 var Encoder = class { 502 constructor() { 503 this.cpos = 0; 504 this.cbuf = new Uint8Array(100); 505 this.bufs = []; 506 } 507 }; 508 var createEncoder = () => new Encoder(); 509 var length = (encoder) => { 510 let len = encoder.cpos; 511 for (let i = 0; i < encoder.bufs.length; i++) { 512 len += encoder.bufs[i].length; 513 } 514 return len; 515 }; 516 var toUint8Array = (encoder) => { 517 const uint8arr = new Uint8Array(length(encoder)); 518 let curPos = 0; 519 for (let i = 0; i < encoder.bufs.length; i++) { 520 const d = encoder.bufs[i]; 521 uint8arr.set(d, curPos); 522 curPos += d.length; 523 } 524 uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); 525 return uint8arr; 526 }; 527 var verifyLen = (encoder, len) => { 528 const bufferLen = encoder.cbuf.length; 529 if (bufferLen - encoder.cpos < len) { 530 encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); 531 encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); 532 encoder.cpos = 0; 533 } 534 }; 535 var write = (encoder, num) => { 536 const bufferLen = encoder.cbuf.length; 537 if (encoder.cpos === bufferLen) { 538 encoder.bufs.push(encoder.cbuf); 539 encoder.cbuf = new Uint8Array(bufferLen * 2); 540 encoder.cpos = 0; 541 } 542 encoder.cbuf[encoder.cpos++] = num; 543 }; 544 var writeUint8 = write; 545 var writeVarUint = (encoder, num) => { 546 while (num > BITS7) { 547 write(encoder, BIT8 | BITS7 & num); 548 num = floor(num / 128); 549 } 550 write(encoder, BITS7 & num); 551 }; 552 var writeVarInt = (encoder, num) => { 553 const isNegative = isNegativeZero(num); 554 if (isNegative) { 555 num = -num; 556 } 557 write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); 558 num = floor(num / 64); 559 while (num > 0) { 560 write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); 561 num = floor(num / 128); 562 } 563 }; 564 var _strBuffer = new Uint8Array(3e4); 565 var _maxStrBSize = _strBuffer.length / 3; 566 var _writeVarStringNative = (encoder, str) => { 567 if (str.length < _maxStrBSize) { 568 const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; 569 writeVarUint(encoder, written); 570 for (let i = 0; i < written; i++) { 571 write(encoder, _strBuffer[i]); 572 } 573 } else { 574 writeVarUint8Array(encoder, encodeUtf8(str)); 575 } 576 }; 577 var _writeVarStringPolyfill = (encoder, str) => { 578 const encodedString = unescape(encodeURIComponent(str)); 579 const len = encodedString.length; 580 writeVarUint(encoder, len); 581 for (let i = 0; i < len; i++) { 582 write( 583 encoder, 584 /** @type {number} */ 585 encodedString.codePointAt(i) 586 ); 587 } 588 }; 589 var writeVarString = utf8TextEncoder && /** @type {any} */ 590 utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; 591 var writeBinaryEncoder = (encoder, append2) => writeUint8Array(encoder, toUint8Array(append2)); 592 var writeUint8Array = (encoder, uint8Array) => { 593 const bufferLen = encoder.cbuf.length; 594 const cpos = encoder.cpos; 595 const leftCopyLen = min(bufferLen - cpos, uint8Array.length); 596 const rightCopyLen = uint8Array.length - leftCopyLen; 597 encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); 598 encoder.cpos += leftCopyLen; 599 if (rightCopyLen > 0) { 600 encoder.bufs.push(encoder.cbuf); 601 encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); 602 encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); 603 encoder.cpos = rightCopyLen; 604 } 605 }; 606 var writeVarUint8Array = (encoder, uint8Array) => { 607 writeVarUint(encoder, uint8Array.byteLength); 608 writeUint8Array(encoder, uint8Array); 609 }; 610 var writeOnDataView = (encoder, len) => { 611 verifyLen(encoder, len); 612 const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); 613 encoder.cpos += len; 614 return dview; 615 }; 616 var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); 617 var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); 618 var writeBigInt64 = (encoder, num) => ( 619 /** @type {any} */ 620 writeOnDataView(encoder, 8).setBigInt64(0, num, false) 621 ); 622 var floatTestBed = new DataView(new ArrayBuffer(4)); 623 var isFloat32 = (num) => { 624 floatTestBed.setFloat32(0, num); 625 return floatTestBed.getFloat32(0) === num; 626 }; 627 var writeAny = (encoder, data) => { 628 switch (typeof data) { 629 case "string": 630 write(encoder, 119); 631 writeVarString(encoder, data); 632 break; 633 case "number": 634 if (isInteger(data) && abs(data) <= BITS31) { 635 write(encoder, 125); 636 writeVarInt(encoder, data); 637 } else if (isFloat32(data)) { 638 write(encoder, 124); 639 writeFloat32(encoder, data); 640 } else { 641 write(encoder, 123); 642 writeFloat64(encoder, data); 643 } 644 break; 645 case "bigint": 646 write(encoder, 122); 647 writeBigInt64(encoder, data); 648 break; 649 case "object": 650 if (data === null) { 651 write(encoder, 126); 652 } else if (isArray(data)) { 653 write(encoder, 117); 654 writeVarUint(encoder, data.length); 655 for (let i = 0; i < data.length; i++) { 656 writeAny(encoder, data[i]); 657 } 658 } else if (data instanceof Uint8Array) { 659 write(encoder, 116); 660 writeVarUint8Array(encoder, data); 661 } else { 662 write(encoder, 118); 663 const keys2 = Object.keys(data); 664 writeVarUint(encoder, keys2.length); 665 for (let i = 0; i < keys2.length; i++) { 666 const key = keys2[i]; 667 writeVarString(encoder, key); 668 writeAny(encoder, data[key]); 669 } 670 } 671 break; 672 case "boolean": 673 write(encoder, data ? 120 : 121); 674 break; 675 default: 676 write(encoder, 127); 677 } 678 }; 679 var RleEncoder = class extends Encoder { 680 /** 681 * @param {function(Encoder, T):void} writer 682 */ 683 constructor(writer) { 684 super(); 685 this.w = writer; 686 this.s = null; 687 this.count = 0; 688 } 689 /** 690 * @param {T} v 691 */ 692 write(v) { 693 if (this.s === v) { 694 this.count++; 695 } else { 696 if (this.count > 0) { 697 writeVarUint(this, this.count - 1); 698 } 699 this.count = 1; 700 this.w(this, v); 701 this.s = v; 702 } 703 } 704 }; 705 var flushUintOptRleEncoder = (encoder) => { 706 if (encoder.count > 0) { 707 writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); 708 if (encoder.count > 1) { 709 writeVarUint(encoder.encoder, encoder.count - 2); 710 } 711 } 712 }; 713 var UintOptRleEncoder = class { 714 constructor() { 715 this.encoder = new Encoder(); 716 this.s = 0; 717 this.count = 0; 718 } 719 /** 720 * @param {number} v 721 */ 722 write(v) { 723 if (this.s === v) { 724 this.count++; 725 } else { 726 flushUintOptRleEncoder(this); 727 this.count = 1; 728 this.s = v; 729 } 730 } 731 /** 732 * Flush the encoded state and transform this to a Uint8Array. 733 * 734 * Note that this should only be called once. 735 */ 736 toUint8Array() { 737 flushUintOptRleEncoder(this); 738 return toUint8Array(this.encoder); 739 } 740 }; 741 var flushIntDiffOptRleEncoder = (encoder) => { 742 if (encoder.count > 0) { 743 const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); 744 writeVarInt(encoder.encoder, encodedDiff); 745 if (encoder.count > 1) { 746 writeVarUint(encoder.encoder, encoder.count - 2); 747 } 748 } 749 }; 750 var IntDiffOptRleEncoder = class { 751 constructor() { 752 this.encoder = new Encoder(); 753 this.s = 0; 754 this.count = 0; 755 this.diff = 0; 756 } 757 /** 758 * @param {number} v 759 */ 760 write(v) { 761 if (this.diff === v - this.s) { 762 this.s = v; 763 this.count++; 764 } else { 765 flushIntDiffOptRleEncoder(this); 766 this.count = 1; 767 this.diff = v - this.s; 768 this.s = v; 769 } 770 } 771 /** 772 * Flush the encoded state and transform this to a Uint8Array. 773 * 774 * Note that this should only be called once. 775 */ 776 toUint8Array() { 777 flushIntDiffOptRleEncoder(this); 778 return toUint8Array(this.encoder); 779 } 780 }; 781 var StringEncoder = class { 782 constructor() { 783 this.sarr = []; 784 this.s = ""; 785 this.lensE = new UintOptRleEncoder(); 786 } 787 /** 788 * @param {string} string 789 */ 790 write(string) { 791 this.s += string; 792 if (this.s.length > 19) { 793 this.sarr.push(this.s); 794 this.s = ""; 795 } 796 this.lensE.write(string.length); 797 } 798 toUint8Array() { 799 const encoder = new Encoder(); 800 this.sarr.push(this.s); 801 this.s = ""; 802 writeVarString(encoder, this.sarr.join("")); 803 writeUint8Array(encoder, this.lensE.toUint8Array()); 804 return toUint8Array(encoder); 805 } 806 }; 807 808 // node_modules/lib0/error.js 809 var create3 = (s) => new Error(s); 810 var methodUnimplemented = () => { 811 throw create3("Method unimplemented"); 812 }; 813 var unexpectedCase = () => { 814 throw create3("Unexpected case"); 815 }; 816 817 // node_modules/lib0/decoding.js 818 var errorUnexpectedEndOfArray = create3("Unexpected end of array"); 819 var errorIntegerOutOfRange = create3("Integer out of Range"); 820 var Decoder = class { 821 /** 822 * @param {Uint8Array} uint8Array Binary data to decode 823 */ 824 constructor(uint8Array) { 825 this.arr = uint8Array; 826 this.pos = 0; 827 } 828 }; 829 var createDecoder = (uint8Array) => new Decoder(uint8Array); 830 var hasContent = (decoder) => decoder.pos !== decoder.arr.length; 831 var readUint8Array = (decoder, len) => { 832 const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); 833 decoder.pos += len; 834 return view; 835 }; 836 var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); 837 var readUint8 = (decoder) => decoder.arr[decoder.pos++]; 838 var readVarUint = (decoder) => { 839 let num = 0; 840 let mult = 1; 841 const len = decoder.arr.length; 842 while (decoder.pos < len) { 843 const r = decoder.arr[decoder.pos++]; 844 num = num + (r & BITS7) * mult; 845 mult *= 128; 846 if (r < BIT8) { 847 return num; 848 } 849 if (num > MAX_SAFE_INTEGER) { 850 throw errorIntegerOutOfRange; 851 } 852 } 853 throw errorUnexpectedEndOfArray; 854 }; 855 var readVarInt = (decoder) => { 856 let r = decoder.arr[decoder.pos++]; 857 let num = r & BITS6; 858 let mult = 64; 859 const sign = (r & BIT7) > 0 ? -1 : 1; 860 if ((r & BIT8) === 0) { 861 return sign * num; 862 } 863 const len = decoder.arr.length; 864 while (decoder.pos < len) { 865 r = decoder.arr[decoder.pos++]; 866 num = num + (r & BITS7) * mult; 867 mult *= 128; 868 if (r < BIT8) { 869 return sign * num; 870 } 871 if (num > MAX_SAFE_INTEGER) { 872 throw errorIntegerOutOfRange; 873 } 874 } 875 throw errorUnexpectedEndOfArray; 876 }; 877 var _readVarStringPolyfill = (decoder) => { 878 let remainingLen = readVarUint(decoder); 879 if (remainingLen === 0) { 880 return ""; 881 } else { 882 let encodedString = String.fromCodePoint(readUint8(decoder)); 883 if (--remainingLen < 100) { 884 while (remainingLen--) { 885 encodedString += String.fromCodePoint(readUint8(decoder)); 886 } 887 } else { 888 while (remainingLen > 0) { 889 const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; 890 const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); 891 decoder.pos += nextLen; 892 encodedString += String.fromCodePoint.apply( 893 null, 894 /** @type {any} */ 895 bytes 896 ); 897 remainingLen -= nextLen; 898 } 899 } 900 return decodeURIComponent(escape(encodedString)); 901 } 902 }; 903 var _readVarStringNative = (decoder) => ( 904 /** @type any */ 905 utf8TextDecoder.decode(readVarUint8Array(decoder)) 906 ); 907 var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; 908 var readFromDataView = (decoder, len) => { 909 const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); 910 decoder.pos += len; 911 return dv; 912 }; 913 var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); 914 var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); 915 var readBigInt64 = (decoder) => ( 916 /** @type {any} */ 917 readFromDataView(decoder, 8).getBigInt64(0, false) 918 ); 919 var readAnyLookupTable = [ 920 (decoder) => void 0, 921 // CASE 127: undefined 922 (decoder) => null, 923 // CASE 126: null 924 readVarInt, 925 // CASE 125: integer 926 readFloat32, 927 // CASE 124: float32 928 readFloat64, 929 // CASE 123: float64 930 readBigInt64, 931 // CASE 122: bigint 932 (decoder) => false, 933 // CASE 121: boolean (false) 934 (decoder) => true, 935 // CASE 120: boolean (true) 936 readVarString, 937 // CASE 119: string 938 (decoder) => { 939 const len = readVarUint(decoder); 940 const obj = {}; 941 for (let i = 0; i < len; i++) { 942 const key = readVarString(decoder); 943 obj[key] = readAny(decoder); 944 } 945 return obj; 946 }, 947 (decoder) => { 948 const len = readVarUint(decoder); 949 const arr = []; 950 for (let i = 0; i < len; i++) { 951 arr.push(readAny(decoder)); 952 } 953 return arr; 954 }, 955 readVarUint8Array 956 // CASE 116: Uint8Array 957 ]; 958 var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); 959 var RleDecoder = class extends Decoder { 960 /** 961 * @param {Uint8Array} uint8Array 962 * @param {function(Decoder):T} reader 963 */ 964 constructor(uint8Array, reader) { 965 super(uint8Array); 966 this.reader = reader; 967 this.s = null; 968 this.count = 0; 969 } 970 read() { 971 if (this.count === 0) { 972 this.s = this.reader(this); 973 if (hasContent(this)) { 974 this.count = readVarUint(this) + 1; 975 } else { 976 this.count = -1; 977 } 978 } 979 this.count--; 980 return ( 981 /** @type {T} */ 982 this.s 983 ); 984 } 985 }; 986 var UintOptRleDecoder = class extends Decoder { 987 /** 988 * @param {Uint8Array} uint8Array 989 */ 990 constructor(uint8Array) { 991 super(uint8Array); 992 this.s = 0; 993 this.count = 0; 994 } 995 read() { 996 if (this.count === 0) { 997 this.s = readVarInt(this); 998 const isNegative = isNegativeZero(this.s); 999 this.count = 1; 1000 if (isNegative) { 1001 this.s = -this.s; 1002 this.count = readVarUint(this) + 2; 1003 } 1004 } 1005 this.count--; 1006 return ( 1007 /** @type {number} */ 1008 this.s 1009 ); 1010 } 1011 }; 1012 var IntDiffOptRleDecoder = class extends Decoder { 1013 /** 1014 * @param {Uint8Array} uint8Array 1015 */ 1016 constructor(uint8Array) { 1017 super(uint8Array); 1018 this.s = 0; 1019 this.count = 0; 1020 this.diff = 0; 1021 } 1022 /** 1023 * @return {number} 1024 */ 1025 read() { 1026 if (this.count === 0) { 1027 const diff = readVarInt(this); 1028 const hasCount = diff & 1; 1029 this.diff = floor(diff / 2); 1030 this.count = 1; 1031 if (hasCount) { 1032 this.count = readVarUint(this) + 2; 1033 } 1034 } 1035 this.s += this.diff; 1036 this.count--; 1037 return this.s; 1038 } 1039 }; 1040 var StringDecoder = class { 1041 /** 1042 * @param {Uint8Array} uint8Array 1043 */ 1044 constructor(uint8Array) { 1045 this.decoder = new UintOptRleDecoder(uint8Array); 1046 this.str = readVarString(this.decoder); 1047 this.spos = 0; 1048 } 1049 /** 1050 * @return {string} 1051 */ 1052 read() { 1053 const end = this.spos + this.decoder.read(); 1054 const res = this.str.slice(this.spos, end); 1055 this.spos = end; 1056 return res; 1057 } 1058 }; 1059 1060 // node_modules/lib0/webcrypto.js 1061 var subtle = crypto.subtle; 1062 var getRandomValues = crypto.getRandomValues.bind(crypto); 1063 1064 // node_modules/lib0/random.js 1065 var uint32 = () => getRandomValues(new Uint32Array(1))[0]; 1066 var uuidv4Template = "10000000-1000-4000-8000" + -1e11; 1067 var uuidv4 = () => uuidv4Template.replace( 1068 /[018]/g, 1069 /** @param {number} c */ 1070 (c) => (c ^ uint32() & 15 >> c / 4).toString(16) 1071 ); 1072 1073 // node_modules/lib0/time.js 1074 var getUnixTime = Date.now; 1075 1076 // node_modules/lib0/promise.js 1077 var create4 = (f) => ( 1078 /** @type {Promise<T>} */ 1079 new Promise(f) 1080 ); 1081 var all = Promise.all.bind(Promise); 1082 1083 // node_modules/lib0/conditions.js 1084 var undefinedToNull = (v) => v === void 0 ? null : v; 1085 1086 // node_modules/lib0/storage.js 1087 var VarStoragePolyfill = class { 1088 constructor() { 1089 this.map = /* @__PURE__ */ new Map(); 1090 } 1091 /** 1092 * @param {string} key 1093 * @param {any} newValue 1094 */ 1095 setItem(key, newValue) { 1096 this.map.set(key, newValue); 1097 } 1098 /** 1099 * @param {string} key 1100 */ 1101 getItem(key) { 1102 return this.map.get(key); 1103 } 1104 }; 1105 var _localStorage = new VarStoragePolyfill(); 1106 var usePolyfill = true; 1107 try { 1108 if (typeof localStorage !== "undefined" && localStorage) { 1109 _localStorage = localStorage; 1110 usePolyfill = false; 1111 } 1112 } catch (e) { 1113 } 1114 var varStorage = _localStorage; 1115 1116 // node_modules/lib0/object.js 1117 var assign = Object.assign; 1118 var keys = Object.keys; 1119 var forEach = (obj, f) => { 1120 for (const key in obj) { 1121 f(obj[key], key); 1122 } 1123 }; 1124 var length2 = (obj) => keys(obj).length; 1125 var size = (obj) => keys(obj).length; 1126 var isEmpty = (obj) => { 1127 for (const _k in obj) { 1128 return false; 1129 } 1130 return true; 1131 }; 1132 var every = (obj, f) => { 1133 for (const key in obj) { 1134 if (!f(obj[key], key)) { 1135 return false; 1136 } 1137 } 1138 return true; 1139 }; 1140 var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); 1141 var equalFlat = (a, b) => a === b || size(a) === size(b) && every(a, (val, key) => (val !== void 0 || hasProperty(b, key)) && b[key] === val); 1142 var freeze = Object.freeze; 1143 var deepFreeze = (o) => { 1144 for (const key in o) { 1145 const c = o[key]; 1146 if (typeof c === "object" || typeof c === "function") { 1147 deepFreeze(o[key]); 1148 } 1149 } 1150 return freeze(o); 1151 }; 1152 1153 // node_modules/lib0/function.js 1154 var callAll = (fs, args2, i = 0) => { 1155 try { 1156 for (; i < fs.length; i++) { 1157 fs[i](...args2); 1158 } 1159 } finally { 1160 if (i < fs.length) { 1161 callAll(fs, args2, i + 1); 1162 } 1163 } 1164 }; 1165 var id = (a) => a; 1166 var equalityStrict = (a, b) => a === b; 1167 var equalityDeep = (a, b) => { 1168 if (a == null || b == null) { 1169 return equalityStrict(a, b); 1170 } 1171 if (a.constructor !== b.constructor) { 1172 return false; 1173 } 1174 if (a === b) { 1175 return true; 1176 } 1177 switch (a.constructor) { 1178 case ArrayBuffer: 1179 a = new Uint8Array(a); 1180 b = new Uint8Array(b); 1181 // eslint-disable-next-line no-fallthrough 1182 case Uint8Array: { 1183 if (a.byteLength !== b.byteLength) { 1184 return false; 1185 } 1186 for (let i = 0; i < a.length; i++) { 1187 if (a[i] !== b[i]) { 1188 return false; 1189 } 1190 } 1191 break; 1192 } 1193 case Set: { 1194 if (a.size !== b.size) { 1195 return false; 1196 } 1197 for (const value of a) { 1198 if (!b.has(value)) { 1199 return false; 1200 } 1201 } 1202 break; 1203 } 1204 case Map: { 1205 if (a.size !== b.size) { 1206 return false; 1207 } 1208 for (const key of a.keys()) { 1209 if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) { 1210 return false; 1211 } 1212 } 1213 break; 1214 } 1215 case Object: 1216 if (length2(a) !== length2(b)) { 1217 return false; 1218 } 1219 for (const key in a) { 1220 if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) { 1221 return false; 1222 } 1223 } 1224 break; 1225 case Array: 1226 if (a.length !== b.length) { 1227 return false; 1228 } 1229 for (let i = 0; i < a.length; i++) { 1230 if (!equalityDeep(a[i], b[i])) { 1231 return false; 1232 } 1233 } 1234 break; 1235 default: 1236 return false; 1237 } 1238 return true; 1239 }; 1240 var isOneOf = (value, options) => options.includes(value); 1241 1242 // node_modules/lib0/environment.js 1243 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]"; 1244 var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; 1245 var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; 1246 var params; 1247 var args = []; 1248 var computeParams = () => { 1249 if (params === void 0) { 1250 if (isNode) { 1251 params = create(); 1252 const pargs = process.argv; 1253 let currParamName = null; 1254 for (let i = 0; i < pargs.length; i++) { 1255 const parg = pargs[i]; 1256 if (parg[0] === "-") { 1257 if (currParamName !== null) { 1258 params.set(currParamName, ""); 1259 } 1260 currParamName = parg; 1261 } else { 1262 if (currParamName !== null) { 1263 params.set(currParamName, parg); 1264 currParamName = null; 1265 } else { 1266 args.push(parg); 1267 } 1268 } 1269 } 1270 if (currParamName !== null) { 1271 params.set(currParamName, ""); 1272 } 1273 } else if (typeof location === "object") { 1274 params = create(); 1275 (location.search || "?").slice(1).split("&").forEach((kv) => { 1276 if (kv.length !== 0) { 1277 const [key, value] = kv.split("="); 1278 params.set(`--$fromCamelCase(key, "-")}`, value); 1279 params.set(`-$fromCamelCase(key, "-")}`, value); 1280 } 1281 }); 1282 } else { 1283 params = create(); 1284 } 1285 } 1286 return params; 1287 }; 1288 var hasParam = (name) => computeParams().has(name); 1289 var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); 1290 var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; 1291 var production = hasConf("production"); 1292 var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); 1293 var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors 1294 !hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); 1295 1296 // node_modules/lib0/buffer.js 1297 var createUint8ArrayFromLen = (len) => new Uint8Array(len); 1298 var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length3) => new Uint8Array(buffer, byteOffset, length3); 1299 var toBase64Browser = (bytes) => { 1300 let s = ""; 1301 for (let i = 0; i < bytes.byteLength; i++) { 1302 s += fromCharCode(bytes[i]); 1303 } 1304 return btoa(s); 1305 }; 1306 var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); 1307 var fromBase64Browser = (s) => { 1308 const a = atob(s); 1309 const bytes = createUint8ArrayFromLen(a.length); 1310 for (let i = 0; i < a.length; i++) { 1311 bytes[i] = a.charCodeAt(i); 1312 } 1313 return bytes; 1314 }; 1315 var fromBase64Node = (s) => { 1316 const buf = Buffer.from(s, "base64"); 1317 return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); 1318 }; 1319 var toBase64 = isBrowser ? toBase64Browser : toBase64Node; 1320 var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; 1321 var copyUint8Array = (uint8Array) => { 1322 const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); 1323 newBuf.set(uint8Array); 1324 return newBuf; 1325 }; 1326 1327 // node_modules/lib0/pair.js 1328 var Pair = class { 1329 /** 1330 * @param {L} left 1331 * @param {R} right 1332 */ 1333 constructor(left, right) { 1334 this.left = left; 1335 this.right = right; 1336 } 1337 }; 1338 var create5 = (left, right) => new Pair(left, right); 1339 1340 // node_modules/lib0/dom.js 1341 var doc = ( 1342 /** @type {Document} */ 1343 typeof document !== "undefined" ? document : {} 1344 ); 1345 var domParser = ( 1346 /** @type {DOMParser} */ 1347 typeof DOMParser !== "undefined" ? new DOMParser() : null 1348 ); 1349 var mapToStyleString = (m) => map(m, (value, key) => `$key}:$value};`).join(""); 1350 var ELEMENT_NODE = doc.ELEMENT_NODE; 1351 var TEXT_NODE = doc.TEXT_NODE; 1352 var CDATA_SECTION_NODE = doc.CDATA_SECTION_NODE; 1353 var COMMENT_NODE = doc.COMMENT_NODE; 1354 var DOCUMENT_NODE = doc.DOCUMENT_NODE; 1355 var DOCUMENT_TYPE_NODE = doc.DOCUMENT_TYPE_NODE; 1356 var DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE; 1357 1358 // node_modules/lib0/symbol.js 1359 var create6 = Symbol; 1360 1361 // node_modules/lib0/logging.common.js 1362 var BOLD = create6(); 1363 var UNBOLD = create6(); 1364 var BLUE = create6(); 1365 var GREY = create6(); 1366 var GREEN = create6(); 1367 var RED = create6(); 1368 var PURPLE = create6(); 1369 var ORANGE = create6(); 1370 var UNCOLOR = create6(); 1371 var computeNoColorLoggingArgs = (args2) => { 1372 if (args2.length === 1 && args2[0]?.constructor === Function) { 1373 args2 = /** @type {Array<string|Symbol|Object|number>} */ 1374 /** @type {[function]} */ 1375 args2[0](); 1376 } 1377 const strBuilder = []; 1378 const logArgs = []; 1379 let i = 0; 1380 for (; i < args2.length; i++) { 1381 const arg = args2[i]; 1382 if (arg === void 0) { 1383 break; 1384 } else if (arg.constructor === String || arg.constructor === Number) { 1385 strBuilder.push(arg); 1386 } else if (arg.constructor === Object) { 1387 break; 1388 } 1389 } 1390 if (i > 0) { 1391 logArgs.push(strBuilder.join("")); 1392 } 1393 for (; i < args2.length; i++) { 1394 const arg = args2[i]; 1395 if (!(arg instanceof Symbol)) { 1396 logArgs.push(arg); 1397 } 1398 } 1399 return logArgs; 1400 }; 1401 var lastLoggingTime = getUnixTime(); 1402 1403 // node_modules/lib0/logging.js 1404 var _browserStyleMap = { 1405 [BOLD]: create5("font-weight", "bold"), 1406 [UNBOLD]: create5("font-weight", "normal"), 1407 [BLUE]: create5("color", "blue"), 1408 [GREEN]: create5("color", "green"), 1409 [GREY]: create5("color", "grey"), 1410 [RED]: create5("color", "red"), 1411 [PURPLE]: create5("color", "purple"), 1412 [ORANGE]: create5("color", "orange"), 1413 // not well supported in chrome when debugging node with inspector - TODO: deprecate 1414 [UNCOLOR]: create5("color", "black") 1415 }; 1416 var computeBrowserLoggingArgs = (args2) => { 1417 if (args2.length === 1 && args2[0]?.constructor === Function) { 1418 args2 = /** @type {Array<string|Symbol|Object|number>} */ 1419 /** @type {[function]} */ 1420 args2[0](); 1421 } 1422 const strBuilder = []; 1423 const styles = []; 1424 const currentStyle = create(); 1425 let logArgs = []; 1426 let i = 0; 1427 for (; i < args2.length; i++) { 1428 const arg = args2[i]; 1429 const style = _browserStyleMap[arg]; 1430 if (style !== void 0) { 1431 currentStyle.set(style.left, style.right); 1432 } else { 1433 if (arg === void 0) { 1434 break; 1435 } 1436 if (arg.constructor === String || arg.constructor === Number) { 1437 const style2 = mapToStyleString(currentStyle); 1438 if (i > 0 || style2.length > 0) { 1439 strBuilder.push("%c" + arg); 1440 styles.push(style2); 1441 } else { 1442 strBuilder.push(arg); 1443 } 1444 } else { 1445 break; 1446 } 1447 } 1448 } 1449 if (i > 0) { 1450 logArgs = styles; 1451 logArgs.unshift(strBuilder.join("")); 1452 } 1453 for (; i < args2.length; i++) { 1454 const arg = args2[i]; 1455 if (!(arg instanceof Symbol)) { 1456 logArgs.push(arg); 1457 } 1458 } 1459 return logArgs; 1460 }; 1461 var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; 1462 var print = (...args2) => { 1463 console.log(...computeLoggingArgs(args2)); 1464 vconsoles.forEach((vc) => vc.print(args2)); 1465 }; 1466 var warn = (...args2) => { 1467 console.warn(...computeLoggingArgs(args2)); 1468 args2.unshift(ORANGE); 1469 vconsoles.forEach((vc) => vc.print(args2)); 1470 }; 1471 var vconsoles = create2(); 1472 1473 // node_modules/lib0/iterator.js 1474 var createIterator = (next) => ({ 1475 /** 1476 * @return {IterableIterator<T>} 1477 */ 1478 [Symbol.iterator]() { 1479 return this; 1480 }, 1481 // @ts-ignore 1482 next 1483 }); 1484 var iteratorFilter = (iterator, filter) => createIterator(() => { 1485 let res; 1486 do { 1487 res = iterator.next(); 1488 } while (!res.done && !filter(res.value)); 1489 return res; 1490 }); 1491 var iteratorMap = (iterator, fmap) => createIterator(() => { 1492 const { done, value } = iterator.next(); 1493 return { done, value: done ? void 0 : fmap(value) }; 1494 }); 1495 1496 // node_modules/yjs/dist/yjs.mjs 1497 var AbstractConnector = class extends ObservableV2 { 1498 /** 1499 * @param {Doc} ydoc 1500 * @param {any} awareness 1501 */ 1502 constructor(ydoc, awareness) { 1503 super(); 1504 this.doc = ydoc; 1505 this.awareness = awareness; 1506 } 1507 }; 1508 var DeleteItem = class { 1509 /** 1510 * @param {number} clock 1511 * @param {number} len 1512 */ 1513 constructor(clock, len) { 1514 this.clock = clock; 1515 this.len = len; 1516 } 1517 }; 1518 var DeleteSet = class { 1519 constructor() { 1520 this.clients = /* @__PURE__ */ new Map(); 1521 } 1522 }; 1523 var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { 1524 const structs = ( 1525 /** @type {Array<GC|Item>} */ 1526 transaction.doc.store.clients.get(clientid) 1527 ); 1528 if (structs != null) { 1529 const lastStruct = structs[structs.length - 1]; 1530 const clockState = lastStruct.id.clock + lastStruct.length; 1531 for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) { 1532 iterateStructs(transaction, structs, del.clock, del.len, f); 1533 } 1534 } 1535 }); 1536 var findIndexDS = (dis, clock) => { 1537 let left = 0; 1538 let right = dis.length - 1; 1539 while (left <= right) { 1540 const midindex = floor((left + right) / 2); 1541 const mid = dis[midindex]; 1542 const midclock = mid.clock; 1543 if (midclock <= clock) { 1544 if (clock < midclock + mid.len) { 1545 return midindex; 1546 } 1547 left = midindex + 1; 1548 } else { 1549 right = midindex - 1; 1550 } 1551 } 1552 return null; 1553 }; 1554 var isDeleted = (ds, id2) => { 1555 const dis = ds.clients.get(id2.client); 1556 return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; 1557 }; 1558 var sortAndMergeDeleteSet = (ds) => { 1559 ds.clients.forEach((dels) => { 1560 dels.sort((a, b) => a.clock - b.clock); 1561 let i, j; 1562 for (i = 1, j = 1; i < dels.length; i++) { 1563 const left = dels[j - 1]; 1564 const right = dels[i]; 1565 if (left.clock + left.len >= right.clock) { 1566 left.len = max(left.len, right.clock + right.len - left.clock); 1567 } else { 1568 if (j < i) { 1569 dels[j] = right; 1570 } 1571 j++; 1572 } 1573 } 1574 dels.length = j; 1575 }); 1576 }; 1577 var mergeDeleteSets = (dss) => { 1578 const merged = new DeleteSet(); 1579 for (let dssI = 0; dssI < dss.length; dssI++) { 1580 dss[dssI].clients.forEach((delsLeft, client) => { 1581 if (!merged.clients.has(client)) { 1582 const dels = delsLeft.slice(); 1583 for (let i = dssI + 1; i < dss.length; i++) { 1584 appendTo(dels, dss[i].clients.get(client) || []); 1585 } 1586 merged.clients.set(client, dels); 1587 } 1588 }); 1589 } 1590 sortAndMergeDeleteSet(merged); 1591 return merged; 1592 }; 1593 var addToDeleteSet = (ds, client, clock, length3) => { 1594 setIfUndefined(ds.clients, client, () => ( 1595 /** @type {Array<DeleteItem>} */ 1596 [] 1597 )).push(new DeleteItem(clock, length3)); 1598 }; 1599 var createDeleteSet = () => new DeleteSet(); 1600 var createDeleteSetFromStructStore = (ss) => { 1601 const ds = createDeleteSet(); 1602 ss.clients.forEach((structs, client) => { 1603 const dsitems = []; 1604 for (let i = 0; i < structs.length; i++) { 1605 const struct = structs[i]; 1606 if (struct.deleted) { 1607 const clock = struct.id.clock; 1608 let len = struct.length; 1609 if (i + 1 < structs.length) { 1610 for (let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1]) { 1611 len += next.length; 1612 } 1613 } 1614 dsitems.push(new DeleteItem(clock, len)); 1615 } 1616 } 1617 if (dsitems.length > 0) { 1618 ds.clients.set(client, dsitems); 1619 } 1620 }); 1621 return ds; 1622 }; 1623 var writeDeleteSet = (encoder, ds) => { 1624 writeVarUint(encoder.restEncoder, ds.clients.size); 1625 from(ds.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, dsitems]) => { 1626 encoder.resetDsCurVal(); 1627 writeVarUint(encoder.restEncoder, client); 1628 const len = dsitems.length; 1629 writeVarUint(encoder.restEncoder, len); 1630 for (let i = 0; i < len; i++) { 1631 const item = dsitems[i]; 1632 encoder.writeDsClock(item.clock); 1633 encoder.writeDsLen(item.len); 1634 } 1635 }); 1636 }; 1637 var readDeleteSet = (decoder) => { 1638 const ds = new DeleteSet(); 1639 const numClients = readVarUint(decoder.restDecoder); 1640 for (let i = 0; i < numClients; i++) { 1641 decoder.resetDsCurVal(); 1642 const client = readVarUint(decoder.restDecoder); 1643 const numberOfDeletes = readVarUint(decoder.restDecoder); 1644 if (numberOfDeletes > 0) { 1645 const dsField = setIfUndefined(ds.clients, client, () => ( 1646 /** @type {Array<DeleteItem>} */ 1647 [] 1648 )); 1649 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 1650 dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); 1651 } 1652 } 1653 } 1654 return ds; 1655 }; 1656 var readAndApplyDeleteSet = (decoder, transaction, store) => { 1657 const unappliedDS = new DeleteSet(); 1658 const numClients = readVarUint(decoder.restDecoder); 1659 for (let i = 0; i < numClients; i++) { 1660 decoder.resetDsCurVal(); 1661 const client = readVarUint(decoder.restDecoder); 1662 const numberOfDeletes = readVarUint(decoder.restDecoder); 1663 const structs = store.clients.get(client) || []; 1664 const state = getState(store, client); 1665 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 1666 const clock = decoder.readDsClock(); 1667 const clockEnd = clock + decoder.readDsLen(); 1668 if (clock < state) { 1669 if (state < clockEnd) { 1670 addToDeleteSet(unappliedDS, client, state, clockEnd - state); 1671 } 1672 let index = findIndexSS(structs, clock); 1673 let struct = structs[index]; 1674 if (!struct.deleted && struct.id.clock < clock) { 1675 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 1676 index++; 1677 } 1678 while (index < structs.length) { 1679 struct = structs[index++]; 1680 if (struct.id.clock < clockEnd) { 1681 if (!struct.deleted) { 1682 if (clockEnd < struct.id.clock + struct.length) { 1683 structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); 1684 } 1685 struct.delete(transaction); 1686 } 1687 } else { 1688 break; 1689 } 1690 } 1691 } else { 1692 addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); 1693 } 1694 } 1695 } 1696 if (unappliedDS.clients.size > 0) { 1697 const ds = new UpdateEncoderV2(); 1698 writeVarUint(ds.restEncoder, 0); 1699 writeDeleteSet(ds, unappliedDS); 1700 return ds.toUint8Array(); 1701 } 1702 return null; 1703 }; 1704 var equalDeleteSets = (ds1, ds2) => { 1705 if (ds1.clients.size !== ds2.clients.size) return false; 1706 for (const [client, deleteItems1] of ds1.clients.entries()) { 1707 const deleteItems2 = ( 1708 /** @type {Array<import('../internals.js').DeleteItem>} */ 1709 ds2.clients.get(client) 1710 ); 1711 if (deleteItems2 === void 0 || deleteItems1.length !== deleteItems2.length) return false; 1712 for (let i = 0; i < deleteItems1.length; i++) { 1713 const di1 = deleteItems1[i]; 1714 const di2 = deleteItems2[i]; 1715 if (di1.clock !== di2.clock || di1.len !== di2.len) { 1716 return false; 1717 } 1718 } 1719 } 1720 return true; 1721 }; 1722 var generateNewClientId = uint32; 1723 var Doc = class _Doc extends ObservableV2 { 1724 /** 1725 * @param {DocOpts} opts configuration 1726 */ 1727 constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { 1728 super(); 1729 this.gc = gc; 1730 this.gcFilter = gcFilter; 1731 this.clientID = generateNewClientId(); 1732 this.guid = guid; 1733 this.collectionid = collectionid; 1734 this.share = /* @__PURE__ */ new Map(); 1735 this.store = new StructStore(); 1736 this._transaction = null; 1737 this._transactionCleanups = []; 1738 this.subdocs = /* @__PURE__ */ new Set(); 1739 this._item = null; 1740 this.shouldLoad = shouldLoad; 1741 this.autoLoad = autoLoad; 1742 this.meta = meta; 1743 this.isLoaded = false; 1744 this.isSynced = false; 1745 this.isDestroyed = false; 1746 this.whenLoaded = create4((resolve) => { 1747 this.on("load", () => { 1748 this.isLoaded = true; 1749 resolve(this); 1750 }); 1751 }); 1752 const provideSyncedPromise = () => create4((resolve) => { 1753 const eventHandler = (isSynced) => { 1754 if (isSynced === void 0 || isSynced === true) { 1755 this.off("sync", eventHandler); 1756 resolve(); 1757 } 1758 }; 1759 this.on("sync", eventHandler); 1760 }); 1761 this.on("sync", (isSynced) => { 1762 if (isSynced === false && this.isSynced) { 1763 this.whenSynced = provideSyncedPromise(); 1764 } 1765 this.isSynced = isSynced === void 0 || isSynced === true; 1766 if (this.isSynced && !this.isLoaded) { 1767 this.emit("load", [this]); 1768 } 1769 }); 1770 this.whenSynced = provideSyncedPromise(); 1771 } 1772 /** 1773 * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). 1774 * 1775 * `load()` might be used in the future to request any provider to load the most current data. 1776 * 1777 * It is safe to call `load()` multiple times. 1778 */ 1779 load() { 1780 const item = this._item; 1781 if (item !== null && !this.shouldLoad) { 1782 transact( 1783 /** @type {any} */ 1784 item.parent.doc, 1785 (transaction) => { 1786 transaction.subdocsLoaded.add(this); 1787 }, 1788 null, 1789 true 1790 ); 1791 } 1792 this.shouldLoad = true; 1793 } 1794 getSubdocs() { 1795 return this.subdocs; 1796 } 1797 getSubdocGuids() { 1798 return new Set(from(this.subdocs).map((doc2) => doc2.guid)); 1799 } 1800 /** 1801 * Changes that happen inside of a transaction are bundled. This means that 1802 * the observer fires _after_ the transaction is finished and that all changes 1803 * that happened inside of the transaction are sent as one message to the 1804 * other peers. 1805 * 1806 * @template T 1807 * @param {function(Transaction):T} f The function that should be executed as a transaction 1808 * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin 1809 * @return T 1810 * 1811 * @public 1812 */ 1813 transact(f, origin2 = null) { 1814 return transact(this, f, origin2); 1815 } 1816 /** 1817 * Define a shared data type. 1818 * 1819 * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result 1820 * and do not overwrite each other. I.e. 1821 * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` 1822 * 1823 * After this method is called, the type is also available on `ydoc.share.get(name)`. 1824 * 1825 * *Best Practices:* 1826 * Define all types right after the Y.Doc instance is created and store them in a separate object. 1827 * Also use the typed methods `getText(name)`, `getArray(name)`, .. 1828 * 1829 * @template {typeof AbstractType<any>} Type 1830 * @example 1831 * const ydoc = new Y.Doc(..) 1832 * const appState = { 1833 * document: ydoc.getText('document') 1834 * comments: ydoc.getArray('comments') 1835 * } 1836 * 1837 * @param {string} name 1838 * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... 1839 * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor 1840 * 1841 * @public 1842 */ 1843 get(name, TypeConstructor = ( 1844 /** @type {any} */ 1845 AbstractType 1846 )) { 1847 const type = setIfUndefined(this.share, name, () => { 1848 const t = new TypeConstructor(); 1849 t._integrate(this, null); 1850 return t; 1851 }); 1852 const Constr = type.constructor; 1853 if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { 1854 if (Constr === AbstractType) { 1855 const t = new TypeConstructor(); 1856 t._map = type._map; 1857 type._map.forEach( 1858 /** @param {Item?} n */ 1859 (n) => { 1860 for (; n !== null; n = n.left) { 1861 n.parent = t; 1862 } 1863 } 1864 ); 1865 t._start = type._start; 1866 for (let n = t._start; n !== null; n = n.right) { 1867 n.parent = t; 1868 } 1869 t._length = type._length; 1870 this.share.set(name, t); 1871 t._integrate(this, null); 1872 return ( 1873 /** @type {InstanceType<Type>} */ 1874 t 1875 ); 1876 } else { 1877 throw new Error(`Type with the name $name} has already been defined with a different constructor`); 1878 } 1879 } 1880 return ( 1881 /** @type {InstanceType<Type>} */ 1882 type 1883 ); 1884 } 1885 /** 1886 * @template T 1887 * @param {string} [name] 1888 * @return {YArray<T>} 1889 * 1890 * @public 1891 */ 1892 getArray(name = "") { 1893 return ( 1894 /** @type {YArray<T>} */ 1895 this.get(name, YArray) 1896 ); 1897 } 1898 /** 1899 * @param {string} [name] 1900 * @return {YText} 1901 * 1902 * @public 1903 */ 1904 getText(name = "") { 1905 return this.get(name, YText); 1906 } 1907 /** 1908 * @template T 1909 * @param {string} [name] 1910 * @return {YMap<T>} 1911 * 1912 * @public 1913 */ 1914 getMap(name = "") { 1915 return ( 1916 /** @type {YMap<T>} */ 1917 this.get(name, YMap) 1918 ); 1919 } 1920 /** 1921 * @param {string} [name] 1922 * @return {YXmlElement} 1923 * 1924 * @public 1925 */ 1926 getXmlElement(name = "") { 1927 return ( 1928 /** @type {YXmlElement<{[key:string]:string}>} */ 1929 this.get(name, YXmlElement) 1930 ); 1931 } 1932 /** 1933 * @param {string} [name] 1934 * @return {YXmlFragment} 1935 * 1936 * @public 1937 */ 1938 getXmlFragment(name = "") { 1939 return this.get(name, YXmlFragment); 1940 } 1941 /** 1942 * Converts the entire document into a js object, recursively traversing each yjs type 1943 * Doesn't log types that have not been defined (using ydoc.getType(..)). 1944 * 1945 * @deprecated Do not use this method and rather call toJSON directly on the shared types. 1946 * 1947 * @return {Object<string, any>} 1948 */ 1949 toJSON() { 1950 const doc2 = {}; 1951 this.share.forEach((value, key) => { 1952 doc2[key] = value.toJSON(); 1953 }); 1954 return doc2; 1955 } 1956 /** 1957 * Emit `destroy` event and unregister all event handlers. 1958 */ 1959 destroy() { 1960 this.isDestroyed = true; 1961 from(this.subdocs).forEach((subdoc) => subdoc.destroy()); 1962 const item = this._item; 1963 if (item !== null) { 1964 this._item = null; 1965 const content = ( 1966 /** @type {ContentDoc} */ 1967 item.content 1968 ); 1969 content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); 1970 content.doc._item = item; 1971 transact( 1972 /** @type {any} */ 1973 item.parent.doc, 1974 (transaction) => { 1975 const doc2 = content.doc; 1976 if (!item.deleted) { 1977 transaction.subdocsAdded.add(doc2); 1978 } 1979 transaction.subdocsRemoved.add(this); 1980 }, 1981 null, 1982 true 1983 ); 1984 } 1985 this.emit("destroyed", [true]); 1986 this.emit("destroy", [this]); 1987 super.destroy(); 1988 } 1989 }; 1990 var DSDecoderV1 = class { 1991 /** 1992 * @param {decoding.Decoder} decoder 1993 */ 1994 constructor(decoder) { 1995 this.restDecoder = decoder; 1996 } 1997 resetDsCurVal() { 1998 } 1999 /** 2000 * @return {number} 2001 */ 2002 readDsClock() { 2003 return readVarUint(this.restDecoder); 2004 } 2005 /** 2006 * @return {number} 2007 */ 2008 readDsLen() { 2009 return readVarUint(this.restDecoder); 2010 } 2011 }; 2012 var UpdateDecoderV1 = class extends DSDecoderV1 { 2013 /** 2014 * @return {ID} 2015 */ 2016 readLeftID() { 2017 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2018 } 2019 /** 2020 * @return {ID} 2021 */ 2022 readRightID() { 2023 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2024 } 2025 /** 2026 * Read the next client id. 2027 * Use this in favor of readID whenever possible to reduce the number of objects created. 2028 */ 2029 readClient() { 2030 return readVarUint(this.restDecoder); 2031 } 2032 /** 2033 * @return {number} info An unsigned 8-bit integer 2034 */ 2035 readInfo() { 2036 return readUint8(this.restDecoder); 2037 } 2038 /** 2039 * @return {string} 2040 */ 2041 readString() { 2042 return readVarString(this.restDecoder); 2043 } 2044 /** 2045 * @return {boolean} isKey 2046 */ 2047 readParentInfo() { 2048 return readVarUint(this.restDecoder) === 1; 2049 } 2050 /** 2051 * @return {number} info An unsigned 8-bit integer 2052 */ 2053 readTypeRef() { 2054 return readVarUint(this.restDecoder); 2055 } 2056 /** 2057 * Write len of a struct - well suited for Opt RLE encoder. 2058 * 2059 * @return {number} len 2060 */ 2061 readLen() { 2062 return readVarUint(this.restDecoder); 2063 } 2064 /** 2065 * @return {any} 2066 */ 2067 readAny() { 2068 return readAny(this.restDecoder); 2069 } 2070 /** 2071 * @return {Uint8Array} 2072 */ 2073 readBuf() { 2074 return copyUint8Array(readVarUint8Array(this.restDecoder)); 2075 } 2076 /** 2077 * Legacy implementation uses JSON parse. We use any-decoding in v2. 2078 * 2079 * @return {any} 2080 */ 2081 readJSON() { 2082 return JSON.parse(readVarString(this.restDecoder)); 2083 } 2084 /** 2085 * @return {string} 2086 */ 2087 readKey() { 2088 return readVarString(this.restDecoder); 2089 } 2090 }; 2091 var DSDecoderV2 = class { 2092 /** 2093 * @param {decoding.Decoder} decoder 2094 */ 2095 constructor(decoder) { 2096 this.dsCurrVal = 0; 2097 this.restDecoder = decoder; 2098 } 2099 resetDsCurVal() { 2100 this.dsCurrVal = 0; 2101 } 2102 /** 2103 * @return {number} 2104 */ 2105 readDsClock() { 2106 this.dsCurrVal += readVarUint(this.restDecoder); 2107 return this.dsCurrVal; 2108 } 2109 /** 2110 * @return {number} 2111 */ 2112 readDsLen() { 2113 const diff = readVarUint(this.restDecoder) + 1; 2114 this.dsCurrVal += diff; 2115 return diff; 2116 } 2117 }; 2118 var UpdateDecoderV2 = class extends DSDecoderV2 { 2119 /** 2120 * @param {decoding.Decoder} decoder 2121 */ 2122 constructor(decoder) { 2123 super(decoder); 2124 this.keys = []; 2125 readVarUint(decoder); 2126 this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2127 this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2128 this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2129 this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2130 this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2131 this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); 2132 this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2133 this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2134 this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2135 } 2136 /** 2137 * @return {ID} 2138 */ 2139 readLeftID() { 2140 return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); 2141 } 2142 /** 2143 * @return {ID} 2144 */ 2145 readRightID() { 2146 return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); 2147 } 2148 /** 2149 * Read the next client id. 2150 * Use this in favor of readID whenever possible to reduce the number of objects created. 2151 */ 2152 readClient() { 2153 return this.clientDecoder.read(); 2154 } 2155 /** 2156 * @return {number} info An unsigned 8-bit integer 2157 */ 2158 readInfo() { 2159 return ( 2160 /** @type {number} */ 2161 this.infoDecoder.read() 2162 ); 2163 } 2164 /** 2165 * @return {string} 2166 */ 2167 readString() { 2168 return this.stringDecoder.read(); 2169 } 2170 /** 2171 * @return {boolean} 2172 */ 2173 readParentInfo() { 2174 return this.parentInfoDecoder.read() === 1; 2175 } 2176 /** 2177 * @return {number} An unsigned 8-bit integer 2178 */ 2179 readTypeRef() { 2180 return this.typeRefDecoder.read(); 2181 } 2182 /** 2183 * Write len of a struct - well suited for Opt RLE encoder. 2184 * 2185 * @return {number} 2186 */ 2187 readLen() { 2188 return this.lenDecoder.read(); 2189 } 2190 /** 2191 * @return {any} 2192 */ 2193 readAny() { 2194 return readAny(this.restDecoder); 2195 } 2196 /** 2197 * @return {Uint8Array} 2198 */ 2199 readBuf() { 2200 return readVarUint8Array(this.restDecoder); 2201 } 2202 /** 2203 * This is mainly here for legacy purposes. 2204 * 2205 * 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. 2206 * 2207 * @return {any} 2208 */ 2209 readJSON() { 2210 return readAny(this.restDecoder); 2211 } 2212 /** 2213 * @return {string} 2214 */ 2215 readKey() { 2216 const keyClock = this.keyClockDecoder.read(); 2217 if (keyClock < this.keys.length) { 2218 return this.keys[keyClock]; 2219 } else { 2220 const key = this.stringDecoder.read(); 2221 this.keys.push(key); 2222 return key; 2223 } 2224 } 2225 }; 2226 var DSEncoderV1 = class { 2227 constructor() { 2228 this.restEncoder = createEncoder(); 2229 } 2230 toUint8Array() { 2231 return toUint8Array(this.restEncoder); 2232 } 2233 resetDsCurVal() { 2234 } 2235 /** 2236 * @param {number} clock 2237 */ 2238 writeDsClock(clock) { 2239 writeVarUint(this.restEncoder, clock); 2240 } 2241 /** 2242 * @param {number} len 2243 */ 2244 writeDsLen(len) { 2245 writeVarUint(this.restEncoder, len); 2246 } 2247 }; 2248 var UpdateEncoderV1 = class extends DSEncoderV1 { 2249 /** 2250 * @param {ID} id 2251 */ 2252 writeLeftID(id2) { 2253 writeVarUint(this.restEncoder, id2.client); 2254 writeVarUint(this.restEncoder, id2.clock); 2255 } 2256 /** 2257 * @param {ID} id 2258 */ 2259 writeRightID(id2) { 2260 writeVarUint(this.restEncoder, id2.client); 2261 writeVarUint(this.restEncoder, id2.clock); 2262 } 2263 /** 2264 * Use writeClient and writeClock instead of writeID if possible. 2265 * @param {number} client 2266 */ 2267 writeClient(client) { 2268 writeVarUint(this.restEncoder, client); 2269 } 2270 /** 2271 * @param {number} info An unsigned 8-bit integer 2272 */ 2273 writeInfo(info) { 2274 writeUint8(this.restEncoder, info); 2275 } 2276 /** 2277 * @param {string} s 2278 */ 2279 writeString(s) { 2280 writeVarString(this.restEncoder, s); 2281 } 2282 /** 2283 * @param {boolean} isYKey 2284 */ 2285 writeParentInfo(isYKey) { 2286 writeVarUint(this.restEncoder, isYKey ? 1 : 0); 2287 } 2288 /** 2289 * @param {number} info An unsigned 8-bit integer 2290 */ 2291 writeTypeRef(info) { 2292 writeVarUint(this.restEncoder, info); 2293 } 2294 /** 2295 * Write len of a struct - well suited for Opt RLE encoder. 2296 * 2297 * @param {number} len 2298 */ 2299 writeLen(len) { 2300 writeVarUint(this.restEncoder, len); 2301 } 2302 /** 2303 * @param {any} any 2304 */ 2305 writeAny(any2) { 2306 writeAny(this.restEncoder, any2); 2307 } 2308 /** 2309 * @param {Uint8Array} buf 2310 */ 2311 writeBuf(buf) { 2312 writeVarUint8Array(this.restEncoder, buf); 2313 } 2314 /** 2315 * @param {any} embed 2316 */ 2317 writeJSON(embed) { 2318 writeVarString(this.restEncoder, JSON.stringify(embed)); 2319 } 2320 /** 2321 * @param {string} key 2322 */ 2323 writeKey(key) { 2324 writeVarString(this.restEncoder, key); 2325 } 2326 }; 2327 var DSEncoderV2 = class { 2328 constructor() { 2329 this.restEncoder = createEncoder(); 2330 this.dsCurrVal = 0; 2331 } 2332 toUint8Array() { 2333 return toUint8Array(this.restEncoder); 2334 } 2335 resetDsCurVal() { 2336 this.dsCurrVal = 0; 2337 } 2338 /** 2339 * @param {number} clock 2340 */ 2341 writeDsClock(clock) { 2342 const diff = clock - this.dsCurrVal; 2343 this.dsCurrVal = clock; 2344 writeVarUint(this.restEncoder, diff); 2345 } 2346 /** 2347 * @param {number} len 2348 */ 2349 writeDsLen(len) { 2350 if (len === 0) { 2351 unexpectedCase(); 2352 } 2353 writeVarUint(this.restEncoder, len - 1); 2354 this.dsCurrVal += len; 2355 } 2356 }; 2357 var UpdateEncoderV2 = class extends DSEncoderV2 { 2358 constructor() { 2359 super(); 2360 this.keyMap = /* @__PURE__ */ new Map(); 2361 this.keyClock = 0; 2362 this.keyClockEncoder = new IntDiffOptRleEncoder(); 2363 this.clientEncoder = new UintOptRleEncoder(); 2364 this.leftClockEncoder = new IntDiffOptRleEncoder(); 2365 this.rightClockEncoder = new IntDiffOptRleEncoder(); 2366 this.infoEncoder = new RleEncoder(writeUint8); 2367 this.stringEncoder = new StringEncoder(); 2368 this.parentInfoEncoder = new RleEncoder(writeUint8); 2369 this.typeRefEncoder = new UintOptRleEncoder(); 2370 this.lenEncoder = new UintOptRleEncoder(); 2371 } 2372 toUint8Array() { 2373 const encoder = createEncoder(); 2374 writeVarUint(encoder, 0); 2375 writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); 2376 writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); 2377 writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); 2378 writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); 2379 writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); 2380 writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); 2381 writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); 2382 writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); 2383 writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); 2384 writeUint8Array(encoder, toUint8Array(this.restEncoder)); 2385 return toUint8Array(encoder); 2386 } 2387 /** 2388 * @param {ID} id 2389 */ 2390 writeLeftID(id2) { 2391 this.clientEncoder.write(id2.client); 2392 this.leftClockEncoder.write(id2.clock); 2393 } 2394 /** 2395 * @param {ID} id 2396 */ 2397 writeRightID(id2) { 2398 this.clientEncoder.write(id2.client); 2399 this.rightClockEncoder.write(id2.clock); 2400 } 2401 /** 2402 * @param {number} client 2403 */ 2404 writeClient(client) { 2405 this.clientEncoder.write(client); 2406 } 2407 /** 2408 * @param {number} info An unsigned 8-bit integer 2409 */ 2410 writeInfo(info) { 2411 this.infoEncoder.write(info); 2412 } 2413 /** 2414 * @param {string} s 2415 */ 2416 writeString(s) { 2417 this.stringEncoder.write(s); 2418 } 2419 /** 2420 * @param {boolean} isYKey 2421 */ 2422 writeParentInfo(isYKey) { 2423 this.parentInfoEncoder.write(isYKey ? 1 : 0); 2424 } 2425 /** 2426 * @param {number} info An unsigned 8-bit integer 2427 */ 2428 writeTypeRef(info) { 2429 this.typeRefEncoder.write(info); 2430 } 2431 /** 2432 * Write len of a struct - well suited for Opt RLE encoder. 2433 * 2434 * @param {number} len 2435 */ 2436 writeLen(len) { 2437 this.lenEncoder.write(len); 2438 } 2439 /** 2440 * @param {any} any 2441 */ 2442 writeAny(any2) { 2443 writeAny(this.restEncoder, any2); 2444 } 2445 /** 2446 * @param {Uint8Array} buf 2447 */ 2448 writeBuf(buf) { 2449 writeVarUint8Array(this.restEncoder, buf); 2450 } 2451 /** 2452 * This is mainly here for legacy purposes. 2453 * 2454 * 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. 2455 * 2456 * @param {any} embed 2457 */ 2458 writeJSON(embed) { 2459 writeAny(this.restEncoder, embed); 2460 } 2461 /** 2462 * Property keys are often reused. For example, in y-prosemirror the key `bold` might 2463 * occur very often. For a 3d application, the key `position` might occur very often. 2464 * 2465 * We cache these keys in a Map and refer to them via a unique number. 2466 * 2467 * @param {string} key 2468 */ 2469 writeKey(key) { 2470 const clock = this.keyMap.get(key); 2471 if (clock === void 0) { 2472 this.keyClockEncoder.write(this.keyClock++); 2473 this.stringEncoder.write(key); 2474 } else { 2475 this.keyClockEncoder.write(clock); 2476 } 2477 } 2478 }; 2479 var writeStructs = (encoder, structs, client, clock) => { 2480 clock = max(clock, structs[0].id.clock); 2481 const startNewStructs = findIndexSS(structs, clock); 2482 writeVarUint(encoder.restEncoder, structs.length - startNewStructs); 2483 encoder.writeClient(client); 2484 writeVarUint(encoder.restEncoder, clock); 2485 const firstStruct = structs[startNewStructs]; 2486 firstStruct.write(encoder, clock - firstStruct.id.clock); 2487 for (let i = startNewStructs + 1; i < structs.length; i++) { 2488 structs[i].write(encoder, 0); 2489 } 2490 }; 2491 var writeClientsStructs = (encoder, store, _sm) => { 2492 const sm = /* @__PURE__ */ new Map(); 2493 _sm.forEach((clock, client) => { 2494 if (getState(store, client) > clock) { 2495 sm.set(client, clock); 2496 } 2497 }); 2498 getStateVector(store).forEach((_clock, client) => { 2499 if (!_sm.has(client)) { 2500 sm.set(client, 0); 2501 } 2502 }); 2503 writeVarUint(encoder.restEncoder, sm.size); 2504 from(sm.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 2505 writeStructs( 2506 encoder, 2507 /** @type {Array<GC|Item>} */ 2508 store.clients.get(client), 2509 client, 2510 clock 2511 ); 2512 }); 2513 }; 2514 var readClientsStructRefs = (decoder, doc2) => { 2515 const clientRefs = create(); 2516 const numOfStateUpdates = readVarUint(decoder.restDecoder); 2517 for (let i = 0; i < numOfStateUpdates; i++) { 2518 const numberOfStructs = readVarUint(decoder.restDecoder); 2519 const refs = new Array(numberOfStructs); 2520 const client = decoder.readClient(); 2521 let clock = readVarUint(decoder.restDecoder); 2522 clientRefs.set(client, { i: 0, refs }); 2523 for (let i2 = 0; i2 < numberOfStructs; i2++) { 2524 const info = decoder.readInfo(); 2525 switch (BITS5 & info) { 2526 case 0: { 2527 const len = decoder.readLen(); 2528 refs[i2] = new GC(createID(client, clock), len); 2529 clock += len; 2530 break; 2531 } 2532 case 10: { 2533 const len = readVarUint(decoder.restDecoder); 2534 refs[i2] = new Skip(createID(client, clock), len); 2535 clock += len; 2536 break; 2537 } 2538 default: { 2539 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 2540 const struct = new Item( 2541 createID(client, clock), 2542 null, 2543 // left 2544 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 2545 // origin 2546 null, 2547 // right 2548 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 2549 // right origin 2550 cantCopyParentInfo ? decoder.readParentInfo() ? doc2.get(decoder.readString()) : decoder.readLeftID() : null, 2551 // parent 2552 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 2553 // parentSub 2554 readItemContent(decoder, info) 2555 // item content 2556 ); 2557 refs[i2] = struct; 2558 clock += struct.length; 2559 } 2560 } 2561 } 2562 } 2563 return clientRefs; 2564 }; 2565 var integrateStructs = (transaction, store, clientsStructRefs) => { 2566 const stack = []; 2567 let clientsStructRefsIds = from(clientsStructRefs.keys()).sort((a, b) => a - b); 2568 if (clientsStructRefsIds.length === 0) { 2569 return null; 2570 } 2571 const getNextStructTarget = () => { 2572 if (clientsStructRefsIds.length === 0) { 2573 return null; 2574 } 2575 let nextStructsTarget = ( 2576 /** @type {{i:number,refs:Array<GC|Item>}} */ 2577 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) 2578 ); 2579 while (nextStructsTarget.refs.length === nextStructsTarget.i) { 2580 clientsStructRefsIds.pop(); 2581 if (clientsStructRefsIds.length > 0) { 2582 nextStructsTarget = /** @type {{i:number,refs:Array<GC|Item>}} */ 2583 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); 2584 } else { 2585 return null; 2586 } 2587 } 2588 return nextStructsTarget; 2589 }; 2590 let curStructsTarget = getNextStructTarget(); 2591 if (curStructsTarget === null) { 2592 return null; 2593 } 2594 const restStructs = new StructStore(); 2595 const missingSV = /* @__PURE__ */ new Map(); 2596 const updateMissingSv = (client, clock) => { 2597 const mclock = missingSV.get(client); 2598 if (mclock == null || mclock > clock) { 2599 missingSV.set(client, clock); 2600 } 2601 }; 2602 let stackHead = ( 2603 /** @type {any} */ 2604 curStructsTarget.refs[ 2605 /** @type {any} */ 2606 curStructsTarget.i++ 2607 ] 2608 ); 2609 const state = /* @__PURE__ */ new Map(); 2610 const addStackToRestSS = () => { 2611 for (const item of stack) { 2612 const client = item.id.client; 2613 const inapplicableItems = clientsStructRefs.get(client); 2614 if (inapplicableItems) { 2615 inapplicableItems.i--; 2616 restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); 2617 clientsStructRefs.delete(client); 2618 inapplicableItems.i = 0; 2619 inapplicableItems.refs = []; 2620 } else { 2621 restStructs.clients.set(client, [item]); 2622 } 2623 clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); 2624 } 2625 stack.length = 0; 2626 }; 2627 while (true) { 2628 if (stackHead.constructor !== Skip) { 2629 const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store, stackHead.id.client)); 2630 const offset = localClock - stackHead.id.clock; 2631 if (offset < 0) { 2632 stack.push(stackHead); 2633 updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); 2634 addStackToRestSS(); 2635 } else { 2636 const missing = stackHead.getMissing(transaction, store); 2637 if (missing !== null) { 2638 stack.push(stackHead); 2639 const structRefs = clientsStructRefs.get( 2640 /** @type {number} */ 2641 missing 2642 ) || { refs: [], i: 0 }; 2643 if (structRefs.refs.length === structRefs.i) { 2644 updateMissingSv( 2645 /** @type {number} */ 2646 missing, 2647 getState(store, missing) 2648 ); 2649 addStackToRestSS(); 2650 } else { 2651 stackHead = structRefs.refs[structRefs.i++]; 2652 continue; 2653 } 2654 } else if (offset === 0 || offset < stackHead.length) { 2655 stackHead.integrate(transaction, offset); 2656 state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); 2657 } 2658 } 2659 } 2660 if (stack.length > 0) { 2661 stackHead = /** @type {GC|Item} */ 2662 stack.pop(); 2663 } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { 2664 stackHead = /** @type {GC|Item} */ 2665 curStructsTarget.refs[curStructsTarget.i++]; 2666 } else { 2667 curStructsTarget = getNextStructTarget(); 2668 if (curStructsTarget === null) { 2669 break; 2670 } else { 2671 stackHead = /** @type {GC|Item} */ 2672 curStructsTarget.refs[curStructsTarget.i++]; 2673 } 2674 } 2675 } 2676 if (restStructs.clients.size > 0) { 2677 const encoder = new UpdateEncoderV2(); 2678 writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); 2679 writeVarUint(encoder.restEncoder, 0); 2680 return { missing: missingSV, update: encoder.toUint8Array() }; 2681 } 2682 return null; 2683 }; 2684 var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); 2685 var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { 2686 transaction.local = false; 2687 let retry = false; 2688 const doc2 = transaction.doc; 2689 const store = doc2.store; 2690 const ss = readClientsStructRefs(structDecoder, doc2); 2691 const restStructs = integrateStructs(transaction, store, ss); 2692 const pending = store.pendingStructs; 2693 if (pending) { 2694 for (const [client, clock] of pending.missing) { 2695 if (clock < getState(store, client)) { 2696 retry = true; 2697 break; 2698 } 2699 } 2700 if (restStructs) { 2701 for (const [client, clock] of restStructs.missing) { 2702 const mclock = pending.missing.get(client); 2703 if (mclock == null || mclock > clock) { 2704 pending.missing.set(client, clock); 2705 } 2706 } 2707 pending.update = mergeUpdatesV2([pending.update, restStructs.update]); 2708 } 2709 } else { 2710 store.pendingStructs = restStructs; 2711 } 2712 const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store); 2713 if (store.pendingDs) { 2714 const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store.pendingDs)); 2715 readVarUint(pendingDSUpdate.restDecoder); 2716 const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store); 2717 if (dsRest && dsRest2) { 2718 store.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); 2719 } else { 2720 store.pendingDs = dsRest || dsRest2; 2721 } 2722 } else { 2723 store.pendingDs = dsRest; 2724 } 2725 if (retry) { 2726 const update = ( 2727 /** @type {{update: Uint8Array}} */ 2728 store.pendingStructs.update 2729 ); 2730 store.pendingStructs = null; 2731 applyUpdateV2(transaction.doc, update); 2732 } 2733 }, transactionOrigin, false); 2734 var readUpdate = (decoder, ydoc, transactionOrigin) => readUpdateV2(decoder, ydoc, transactionOrigin, new UpdateDecoderV1(decoder)); 2735 var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { 2736 const decoder = createDecoder(update); 2737 readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); 2738 }; 2739 var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); 2740 var writeStateAsUpdate = (encoder, doc2, targetStateVector = /* @__PURE__ */ new Map()) => { 2741 writeClientsStructs(encoder, doc2.store, targetStateVector); 2742 writeDeleteSet(encoder, createDeleteSetFromStructStore(doc2.store)); 2743 }; 2744 var encodeStateAsUpdateV2 = (doc2, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { 2745 const targetStateVector = decodeStateVector(encodedTargetStateVector); 2746 writeStateAsUpdate(encoder, doc2, targetStateVector); 2747 const updates = [encoder.toUint8Array()]; 2748 if (doc2.store.pendingDs) { 2749 updates.push(doc2.store.pendingDs); 2750 } 2751 if (doc2.store.pendingStructs) { 2752 updates.push(diffUpdateV2(doc2.store.pendingStructs.update, encodedTargetStateVector)); 2753 } 2754 if (updates.length > 1) { 2755 if (encoder.constructor === UpdateEncoderV1) { 2756 return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); 2757 } else if (encoder.constructor === UpdateEncoderV2) { 2758 return mergeUpdatesV2(updates); 2759 } 2760 } 2761 return updates[0]; 2762 }; 2763 var encodeStateAsUpdate = (doc2, encodedTargetStateVector) => encodeStateAsUpdateV2(doc2, encodedTargetStateVector, new UpdateEncoderV1()); 2764 var readStateVector = (decoder) => { 2765 const ss = /* @__PURE__ */ new Map(); 2766 const ssLength = readVarUint(decoder.restDecoder); 2767 for (let i = 0; i < ssLength; i++) { 2768 const client = readVarUint(decoder.restDecoder); 2769 const clock = readVarUint(decoder.restDecoder); 2770 ss.set(client, clock); 2771 } 2772 return ss; 2773 }; 2774 var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); 2775 var writeStateVector = (encoder, sv) => { 2776 writeVarUint(encoder.restEncoder, sv.size); 2777 from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 2778 writeVarUint(encoder.restEncoder, client); 2779 writeVarUint(encoder.restEncoder, clock); 2780 }); 2781 return encoder; 2782 }; 2783 var writeDocumentStateVector = (encoder, doc2) => writeStateVector(encoder, getStateVector(doc2.store)); 2784 var encodeStateVectorV2 = (doc2, encoder = new DSEncoderV2()) => { 2785 if (doc2 instanceof Map) { 2786 writeStateVector(encoder, doc2); 2787 } else { 2788 writeDocumentStateVector(encoder, doc2); 2789 } 2790 return encoder.toUint8Array(); 2791 }; 2792 var encodeStateVector = (doc2) => encodeStateVectorV2(doc2, new DSEncoderV1()); 2793 var EventHandler = class { 2794 constructor() { 2795 this.l = []; 2796 } 2797 }; 2798 var createEventHandler = () => new EventHandler(); 2799 var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); 2800 var removeEventHandlerListener = (eventHandler, f) => { 2801 const l = eventHandler.l; 2802 const len = l.length; 2803 eventHandler.l = l.filter((g) => f !== g); 2804 if (len === eventHandler.l.length) { 2805 console.error("[yjs] Tried to remove event handler that doesn't exist."); 2806 } 2807 }; 2808 var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); 2809 var ID = class { 2810 /** 2811 * @param {number} client client id 2812 * @param {number} clock unique per client id, continuous number 2813 */ 2814 constructor(client, clock) { 2815 this.client = client; 2816 this.clock = clock; 2817 } 2818 }; 2819 var compareIDs = (a, b) => a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock; 2820 var createID = (client, clock) => new ID(client, clock); 2821 var writeID = (encoder, id2) => { 2822 writeVarUint(encoder, id2.client); 2823 writeVarUint(encoder, id2.clock); 2824 }; 2825 var readID = (decoder) => createID(readVarUint(decoder), readVarUint(decoder)); 2826 var findRootTypeKey = (type) => { 2827 for (const [key, value] of type.doc.share.entries()) { 2828 if (value === type) { 2829 return key; 2830 } 2831 } 2832 throw unexpectedCase(); 2833 }; 2834 var isParentOf = (parent, child) => { 2835 while (child !== null) { 2836 if (child.parent === parent) { 2837 return true; 2838 } 2839 child = /** @type {AbstractType<any>} */ 2840 child.parent._item; 2841 } 2842 return false; 2843 }; 2844 var logType = (type) => { 2845 const res = []; 2846 let n = type._start; 2847 while (n) { 2848 res.push(n); 2849 n = n.right; 2850 } 2851 console.log("Children: ", res); 2852 console.log("Children content: ", res.filter((m) => !m.deleted).map((m) => m.content)); 2853 }; 2854 var PermanentUserData = class { 2855 /** 2856 * @param {Doc} doc 2857 * @param {YMap<any>} [storeType] 2858 */ 2859 constructor(doc2, storeType = doc2.getMap("users")) { 2860 const dss = /* @__PURE__ */ new Map(); 2861 this.yusers = storeType; 2862 this.doc = doc2; 2863 this.clients = /* @__PURE__ */ new Map(); 2864 this.dss = dss; 2865 const initUser = (user, userDescription) => { 2866 const ds = user.get("ds"); 2867 const ids = user.get("ids"); 2868 const addClientId = ( 2869 /** @param {number} clientid */ 2870 (clientid) => this.clients.set(clientid, userDescription) 2871 ); 2872 ds.observe( 2873 /** @param {YArrayEvent<any>} event */ 2874 (event) => { 2875 event.changes.added.forEach((item) => { 2876 item.content.getContent().forEach((encodedDs) => { 2877 if (encodedDs instanceof Uint8Array) { 2878 this.dss.set(userDescription, mergeDeleteSets([this.dss.get(userDescription) || createDeleteSet(), readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))])); 2879 } 2880 }); 2881 }); 2882 } 2883 ); 2884 this.dss.set(userDescription, mergeDeleteSets(ds.map((encodedDs) => readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))))); 2885 ids.observe( 2886 /** @param {YArrayEvent<any>} event */ 2887 (event) => event.changes.added.forEach((item) => item.content.getContent().forEach(addClientId)) 2888 ); 2889 ids.forEach(addClientId); 2890 }; 2891 storeType.observe((event) => { 2892 event.keysChanged.forEach( 2893 (userDescription) => initUser(storeType.get(userDescription), userDescription) 2894 ); 2895 }); 2896 storeType.forEach(initUser); 2897 } 2898 /** 2899 * @param {Doc} doc 2900 * @param {number} clientid 2901 * @param {string} userDescription 2902 * @param {Object} conf 2903 * @param {function(Transaction, DeleteSet):boolean} [conf.filter] 2904 */ 2905 setUserMapping(doc2, clientid, userDescription, { filter = () => true } = {}) { 2906 const users = this.yusers; 2907 let user = users.get(userDescription); 2908 if (!user) { 2909 user = new YMap(); 2910 user.set("ids", new YArray()); 2911 user.set("ds", new YArray()); 2912 users.set(userDescription, user); 2913 } 2914 user.get("ids").push([clientid]); 2915 users.observe((_event) => { 2916 setTimeout(() => { 2917 const userOverwrite = users.get(userDescription); 2918 if (userOverwrite !== user) { 2919 user = userOverwrite; 2920 this.clients.forEach((_userDescription, clientid2) => { 2921 if (userDescription === _userDescription) { 2922 user.get("ids").push([clientid2]); 2923 } 2924 }); 2925 const encoder = new DSEncoderV1(); 2926 const ds = this.dss.get(userDescription); 2927 if (ds) { 2928 writeDeleteSet(encoder, ds); 2929 user.get("ds").push([encoder.toUint8Array()]); 2930 } 2931 } 2932 }, 0); 2933 }); 2934 doc2.on( 2935 "afterTransaction", 2936 /** @param {Transaction} transaction */ 2937 (transaction) => { 2938 setTimeout(() => { 2939 const yds = user.get("ds"); 2940 const ds = transaction.deleteSet; 2941 if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) { 2942 const encoder = new DSEncoderV1(); 2943 writeDeleteSet(encoder, ds); 2944 yds.push([encoder.toUint8Array()]); 2945 } 2946 }); 2947 } 2948 ); 2949 } 2950 /** 2951 * @param {number} clientid 2952 * @return {any} 2953 */ 2954 getUserByClientId(clientid) { 2955 return this.clients.get(clientid) || null; 2956 } 2957 /** 2958 * @param {ID} id 2959 * @return {string | null} 2960 */ 2961 getUserByDeletedId(id2) { 2962 for (const [userDescription, ds] of this.dss.entries()) { 2963 if (isDeleted(ds, id2)) { 2964 return userDescription; 2965 } 2966 } 2967 return null; 2968 } 2969 }; 2970 var RelativePosition = class { 2971 /** 2972 * @param {ID|null} type 2973 * @param {string|null} tname 2974 * @param {ID|null} item 2975 * @param {number} assoc 2976 */ 2977 constructor(type, tname, item, assoc = 0) { 2978 this.type = type; 2979 this.tname = tname; 2980 this.item = item; 2981 this.assoc = assoc; 2982 } 2983 }; 2984 var relativePositionToJSON = (rpos) => { 2985 const json = {}; 2986 if (rpos.type) { 2987 json.type = rpos.type; 2988 } 2989 if (rpos.tname) { 2990 json.tname = rpos.tname; 2991 } 2992 if (rpos.item) { 2993 json.item = rpos.item; 2994 } 2995 if (rpos.assoc != null) { 2996 json.assoc = rpos.assoc; 2997 } 2998 return json; 2999 }; 3000 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); 3001 var AbsolutePosition = class { 3002 /** 3003 * @param {AbstractType<any>} type 3004 * @param {number} index 3005 * @param {number} [assoc] 3006 */ 3007 constructor(type, index, assoc = 0) { 3008 this.type = type; 3009 this.index = index; 3010 this.assoc = assoc; 3011 } 3012 }; 3013 var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); 3014 var createRelativePosition = (type, item, assoc) => { 3015 let typeid = null; 3016 let tname = null; 3017 if (type._item === null) { 3018 tname = findRootTypeKey(type); 3019 } else { 3020 typeid = createID(type._item.id.client, type._item.id.clock); 3021 } 3022 return new RelativePosition(typeid, tname, item, assoc); 3023 }; 3024 var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { 3025 let t = type._start; 3026 if (assoc < 0) { 3027 if (index === 0) { 3028 return createRelativePosition(type, null, assoc); 3029 } 3030 index--; 3031 } 3032 while (t !== null) { 3033 if (!t.deleted && t.countable) { 3034 if (t.length > index) { 3035 return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); 3036 } 3037 index -= t.length; 3038 } 3039 if (t.right === null && assoc < 0) { 3040 return createRelativePosition(type, t.lastId, assoc); 3041 } 3042 t = t.right; 3043 } 3044 return createRelativePosition(type, null, assoc); 3045 }; 3046 var writeRelativePosition = (encoder, rpos) => { 3047 const { type, tname, item, assoc } = rpos; 3048 if (item !== null) { 3049 writeVarUint(encoder, 0); 3050 writeID(encoder, item); 3051 } else if (tname !== null) { 3052 writeUint8(encoder, 1); 3053 writeVarString(encoder, tname); 3054 } else if (type !== null) { 3055 writeUint8(encoder, 2); 3056 writeID(encoder, type); 3057 } else { 3058 throw unexpectedCase(); 3059 } 3060 writeVarInt(encoder, assoc); 3061 return encoder; 3062 }; 3063 var encodeRelativePosition = (rpos) => { 3064 const encoder = createEncoder(); 3065 writeRelativePosition(encoder, rpos); 3066 return toUint8Array(encoder); 3067 }; 3068 var readRelativePosition = (decoder) => { 3069 let type = null; 3070 let tname = null; 3071 let itemID = null; 3072 switch (readVarUint(decoder)) { 3073 case 0: 3074 itemID = readID(decoder); 3075 break; 3076 case 1: 3077 tname = readVarString(decoder); 3078 break; 3079 case 2: { 3080 type = readID(decoder); 3081 } 3082 } 3083 const assoc = hasContent(decoder) ? readVarInt(decoder) : 0; 3084 return new RelativePosition(type, tname, itemID, assoc); 3085 }; 3086 var decodeRelativePosition = (uint8Array) => readRelativePosition(createDecoder(uint8Array)); 3087 var getItemWithOffset = (store, id2) => { 3088 const item = getItem(store, id2); 3089 const diff = id2.clock - item.id.clock; 3090 return { 3091 item, 3092 diff 3093 }; 3094 }; 3095 var createAbsolutePositionFromRelativePosition = (rpos, doc2, followUndoneDeletions = true) => { 3096 const store = doc2.store; 3097 const rightID = rpos.item; 3098 const typeID = rpos.type; 3099 const tname = rpos.tname; 3100 const assoc = rpos.assoc; 3101 let type = null; 3102 let index = 0; 3103 if (rightID !== null) { 3104 if (getState(store, rightID.client) <= rightID.clock) { 3105 return null; 3106 } 3107 const res = followUndoneDeletions ? followRedone(store, rightID) : getItemWithOffset(store, rightID); 3108 const right = res.item; 3109 if (!(right instanceof Item)) { 3110 return null; 3111 } 3112 type = /** @type {AbstractType<any>} */ 3113 right.parent; 3114 if (type._item === null || !type._item.deleted) { 3115 index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); 3116 let n = right.left; 3117 while (n !== null) { 3118 if (!n.deleted && n.countable) { 3119 index += n.length; 3120 } 3121 n = n.left; 3122 } 3123 } 3124 } else { 3125 if (tname !== null) { 3126 type = doc2.get(tname); 3127 } else if (typeID !== null) { 3128 if (getState(store, typeID.client) <= typeID.clock) { 3129 return null; 3130 } 3131 const { item } = followUndoneDeletions ? followRedone(store, typeID) : { item: getItem(store, typeID) }; 3132 if (item instanceof Item && item.content instanceof ContentType) { 3133 type = item.content.type; 3134 } else { 3135 return null; 3136 } 3137 } else { 3138 throw unexpectedCase(); 3139 } 3140 if (assoc >= 0) { 3141 index = type._length; 3142 } else { 3143 index = 0; 3144 } 3145 } 3146 return createAbsolutePosition(type, index, rpos.assoc); 3147 }; 3148 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; 3149 var Snapshot = class { 3150 /** 3151 * @param {DeleteSet} ds 3152 * @param {Map<number,number>} sv state map 3153 */ 3154 constructor(ds, sv) { 3155 this.ds = ds; 3156 this.sv = sv; 3157 } 3158 }; 3159 var equalSnapshots = (snap1, snap2) => { 3160 const ds1 = snap1.ds.clients; 3161 const ds2 = snap2.ds.clients; 3162 const sv1 = snap1.sv; 3163 const sv2 = snap2.sv; 3164 if (sv1.size !== sv2.size || ds1.size !== ds2.size) { 3165 return false; 3166 } 3167 for (const [key, value] of sv1.entries()) { 3168 if (sv2.get(key) !== value) { 3169 return false; 3170 } 3171 } 3172 for (const [client, dsitems1] of ds1.entries()) { 3173 const dsitems2 = ds2.get(client) || []; 3174 if (dsitems1.length !== dsitems2.length) { 3175 return false; 3176 } 3177 for (let i = 0; i < dsitems1.length; i++) { 3178 const dsitem1 = dsitems1[i]; 3179 const dsitem2 = dsitems2[i]; 3180 if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) { 3181 return false; 3182 } 3183 } 3184 } 3185 return true; 3186 }; 3187 var encodeSnapshotV2 = (snapshot2, encoder = new DSEncoderV2()) => { 3188 writeDeleteSet(encoder, snapshot2.ds); 3189 writeStateVector(encoder, snapshot2.sv); 3190 return encoder.toUint8Array(); 3191 }; 3192 var encodeSnapshot = (snapshot2) => encodeSnapshotV2(snapshot2, new DSEncoderV1()); 3193 var decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(createDecoder(buf))) => { 3194 return new Snapshot(readDeleteSet(decoder), readStateVector(decoder)); 3195 }; 3196 var decodeSnapshot = (buf) => decodeSnapshotV2(buf, new DSDecoderV1(createDecoder(buf))); 3197 var createSnapshot = (ds, sm) => new Snapshot(ds, sm); 3198 var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); 3199 var snapshot = (doc2) => createSnapshot(createDeleteSetFromStructStore(doc2.store), getStateVector(doc2.store)); 3200 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); 3201 var splitSnapshotAffectedStructs = (transaction, snapshot2) => { 3202 const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); 3203 const store = transaction.doc.store; 3204 if (!meta.has(snapshot2)) { 3205 snapshot2.sv.forEach((clock, client) => { 3206 if (clock < getState(store, client)) { 3207 getItemCleanStart(transaction, createID(client, clock)); 3208 } 3209 }); 3210 iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { 3211 }); 3212 meta.add(snapshot2); 3213 } 3214 }; 3215 var createDocFromSnapshot = (originDoc, snapshot2, newDoc = new Doc()) => { 3216 if (originDoc.gc) { 3217 throw new Error("Garbage-collection must be disabled in `originDoc`!"); 3218 } 3219 const { sv, ds } = snapshot2; 3220 const encoder = new UpdateEncoderV2(); 3221 originDoc.transact((transaction) => { 3222 let size2 = 0; 3223 sv.forEach((clock) => { 3224 if (clock > 0) { 3225 size2++; 3226 } 3227 }); 3228 writeVarUint(encoder.restEncoder, size2); 3229 for (const [client, clock] of sv) { 3230 if (clock === 0) { 3231 continue; 3232 } 3233 if (clock < getState(originDoc.store, client)) { 3234 getItemCleanStart(transaction, createID(client, clock)); 3235 } 3236 const structs = originDoc.store.clients.get(client) || []; 3237 const lastStructIndex = findIndexSS(structs, clock - 1); 3238 writeVarUint(encoder.restEncoder, lastStructIndex + 1); 3239 encoder.writeClient(client); 3240 writeVarUint(encoder.restEncoder, 0); 3241 for (let i = 0; i <= lastStructIndex; i++) { 3242 structs[i].write(encoder, 0); 3243 } 3244 } 3245 writeDeleteSet(encoder, ds); 3246 }); 3247 applyUpdateV2(newDoc, encoder.toUint8Array(), "snapshot"); 3248 return newDoc; 3249 }; 3250 var snapshotContainsUpdateV2 = (snapshot2, update, YDecoder = UpdateDecoderV2) => { 3251 const updateDecoder = new YDecoder(createDecoder(update)); 3252 const lazyDecoder = new LazyStructReader(updateDecoder, false); 3253 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 3254 if ((snapshot2.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) { 3255 return false; 3256 } 3257 } 3258 const mergedDS = mergeDeleteSets([snapshot2.ds, readDeleteSet(updateDecoder)]); 3259 return equalDeleteSets(snapshot2.ds, mergedDS); 3260 }; 3261 var snapshotContainsUpdate = (snapshot2, update) => snapshotContainsUpdateV2(snapshot2, update, UpdateDecoderV1); 3262 var StructStore = class { 3263 constructor() { 3264 this.clients = /* @__PURE__ */ new Map(); 3265 this.pendingStructs = null; 3266 this.pendingDs = null; 3267 } 3268 }; 3269 var getStateVector = (store) => { 3270 const sm = /* @__PURE__ */ new Map(); 3271 store.clients.forEach((structs, client) => { 3272 const struct = structs[structs.length - 1]; 3273 sm.set(client, struct.id.clock + struct.length); 3274 }); 3275 return sm; 3276 }; 3277 var getState = (store, client) => { 3278 const structs = store.clients.get(client); 3279 if (structs === void 0) { 3280 return 0; 3281 } 3282 const lastStruct = structs[structs.length - 1]; 3283 return lastStruct.id.clock + lastStruct.length; 3284 }; 3285 var addStruct = (store, struct) => { 3286 let structs = store.clients.get(struct.id.client); 3287 if (structs === void 0) { 3288 structs = []; 3289 store.clients.set(struct.id.client, structs); 3290 } else { 3291 const lastStruct = structs[structs.length - 1]; 3292 if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { 3293 throw unexpectedCase(); 3294 } 3295 } 3296 structs.push(struct); 3297 }; 3298 var findIndexSS = (structs, clock) => { 3299 let left = 0; 3300 let right = structs.length - 1; 3301 let mid = structs[right]; 3302 let midclock = mid.id.clock; 3303 if (midclock === clock) { 3304 return right; 3305 } 3306 let midindex = floor(clock / (midclock + mid.length - 1) * right); 3307 while (left <= right) { 3308 mid = structs[midindex]; 3309 midclock = mid.id.clock; 3310 if (midclock <= clock) { 3311 if (clock < midclock + mid.length) { 3312 return midindex; 3313 } 3314 left = midindex + 1; 3315 } else { 3316 right = midindex - 1; 3317 } 3318 midindex = floor((left + right) / 2); 3319 } 3320 throw unexpectedCase(); 3321 }; 3322 var find = (store, id2) => { 3323 const structs = store.clients.get(id2.client); 3324 return structs[findIndexSS(structs, id2.clock)]; 3325 }; 3326 var getItem = ( 3327 /** @type {function(StructStore,ID):Item} */ 3328 find 3329 ); 3330 var findIndexCleanStart = (transaction, structs, clock) => { 3331 const index = findIndexSS(structs, clock); 3332 const struct = structs[index]; 3333 if (struct.id.clock < clock && struct instanceof Item) { 3334 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 3335 return index + 1; 3336 } 3337 return index; 3338 }; 3339 var getItemCleanStart = (transaction, id2) => { 3340 const structs = ( 3341 /** @type {Array<Item>} */ 3342 transaction.doc.store.clients.get(id2.client) 3343 ); 3344 return structs[findIndexCleanStart(transaction, structs, id2.clock)]; 3345 }; 3346 var getItemCleanEnd = (transaction, store, id2) => { 3347 const structs = store.clients.get(id2.client); 3348 const index = findIndexSS(structs, id2.clock); 3349 const struct = structs[index]; 3350 if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { 3351 structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); 3352 } 3353 return struct; 3354 }; 3355 var replaceStruct = (store, struct, newStruct) => { 3356 const structs = ( 3357 /** @type {Array<GC|Item>} */ 3358 store.clients.get(struct.id.client) 3359 ); 3360 structs[findIndexSS(structs, struct.id.clock)] = newStruct; 3361 }; 3362 var iterateStructs = (transaction, structs, clockStart, len, f) => { 3363 if (len === 0) { 3364 return; 3365 } 3366 const clockEnd = clockStart + len; 3367 let index = findIndexCleanStart(transaction, structs, clockStart); 3368 let struct; 3369 do { 3370 struct = structs[index++]; 3371 if (clockEnd < struct.id.clock + struct.length) { 3372 findIndexCleanStart(transaction, structs, clockEnd); 3373 } 3374 f(struct); 3375 } while (index < structs.length && structs[index].id.clock < clockEnd); 3376 }; 3377 var Transaction = class { 3378 /** 3379 * @param {Doc} doc 3380 * @param {any} origin 3381 * @param {boolean} local 3382 */ 3383 constructor(doc2, origin2, local) { 3384 this.doc = doc2; 3385 this.deleteSet = new DeleteSet(); 3386 this.beforeState = getStateVector(doc2.store); 3387 this.afterState = /* @__PURE__ */ new Map(); 3388 this.changed = /* @__PURE__ */ new Map(); 3389 this.changedParentTypes = /* @__PURE__ */ new Map(); 3390 this._mergeStructs = []; 3391 this.origin = origin2; 3392 this.meta = /* @__PURE__ */ new Map(); 3393 this.local = local; 3394 this.subdocsAdded = /* @__PURE__ */ new Set(); 3395 this.subdocsRemoved = /* @__PURE__ */ new Set(); 3396 this.subdocsLoaded = /* @__PURE__ */ new Set(); 3397 this._needFormattingCleanup = false; 3398 } 3399 }; 3400 var writeUpdateMessageFromTransaction = (encoder, transaction) => { 3401 if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { 3402 return false; 3403 } 3404 sortAndMergeDeleteSet(transaction.deleteSet); 3405 writeStructsFromTransaction(encoder, transaction); 3406 writeDeleteSet(encoder, transaction.deleteSet); 3407 return true; 3408 }; 3409 var addChangedTypeToTransaction = (transaction, type, parentSub) => { 3410 const item = type._item; 3411 if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { 3412 setIfUndefined(transaction.changed, type, create2).add(parentSub); 3413 } 3414 }; 3415 var tryToMergeWithLefts = (structs, pos) => { 3416 let right = structs[pos]; 3417 let left = structs[pos - 1]; 3418 let i = pos; 3419 for (; i > 0; right = left, left = structs[--i - 1]) { 3420 if (left.deleted === right.deleted && left.constructor === right.constructor) { 3421 if (left.mergeWith(right)) { 3422 if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ 3423 right.parent._map.get(right.parentSub) === right) { 3424 right.parent._map.set( 3425 right.parentSub, 3426 /** @type {Item} */ 3427 left 3428 ); 3429 } 3430 continue; 3431 } 3432 } 3433 break; 3434 } 3435 const merged = pos - i; 3436 if (merged) { 3437 structs.splice(pos + 1 - merged, merged); 3438 } 3439 return merged; 3440 }; 3441 var tryGcDeleteSet = (ds, store, gcFilter) => { 3442 for (const [client, deleteItems] of ds.clients.entries()) { 3443 const structs = ( 3444 /** @type {Array<GC|Item>} */ 3445 store.clients.get(client) 3446 ); 3447 for (let di = deleteItems.length - 1; di >= 0; di--) { 3448 const deleteItem = deleteItems[di]; 3449 const endDeleteItemClock = deleteItem.clock + deleteItem.len; 3450 for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { 3451 const struct2 = structs[si]; 3452 if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { 3453 break; 3454 } 3455 if (struct2 instanceof Item && struct2.deleted && !struct2.keep && gcFilter(struct2)) { 3456 struct2.gc(store, false); 3457 } 3458 } 3459 } 3460 } 3461 }; 3462 var tryMergeDeleteSet = (ds, store) => { 3463 ds.clients.forEach((deleteItems, client) => { 3464 const structs = ( 3465 /** @type {Array<GC|Item>} */ 3466 store.clients.get(client) 3467 ); 3468 for (let di = deleteItems.length - 1; di >= 0; di--) { 3469 const deleteItem = deleteItems[di]; 3470 const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); 3471 for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { 3472 si -= 1 + tryToMergeWithLefts(structs, si); 3473 } 3474 } 3475 }); 3476 }; 3477 var tryGc = (ds, store, gcFilter) => { 3478 tryGcDeleteSet(ds, store, gcFilter); 3479 tryMergeDeleteSet(ds, store); 3480 }; 3481 var cleanupTransactions = (transactionCleanups, i) => { 3482 if (i < transactionCleanups.length) { 3483 const transaction = transactionCleanups[i]; 3484 const doc2 = transaction.doc; 3485 const store = doc2.store; 3486 const ds = transaction.deleteSet; 3487 const mergeStructs = transaction._mergeStructs; 3488 try { 3489 sortAndMergeDeleteSet(ds); 3490 transaction.afterState = getStateVector(transaction.doc.store); 3491 doc2.emit("beforeObserverCalls", [transaction, doc2]); 3492 const fs = []; 3493 transaction.changed.forEach( 3494 (subs, itemtype) => fs.push(() => { 3495 if (itemtype._item === null || !itemtype._item.deleted) { 3496 itemtype._callObserver(transaction, subs); 3497 } 3498 }) 3499 ); 3500 fs.push(() => { 3501 transaction.changedParentTypes.forEach((events, type) => { 3502 if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { 3503 events = events.filter( 3504 (event) => event.target._item === null || !event.target._item.deleted 3505 ); 3506 events.forEach((event) => { 3507 event.currentTarget = type; 3508 event._path = null; 3509 }); 3510 events.sort((event1, event2) => event1.path.length - event2.path.length); 3511 fs.push(() => { 3512 callEventHandlerListeners(type._dEH, events, transaction); 3513 }); 3514 } 3515 }); 3516 fs.push(() => doc2.emit("afterTransaction", [transaction, doc2])); 3517 fs.push(() => { 3518 if (transaction._needFormattingCleanup) { 3519 cleanupYTextAfterTransaction(transaction); 3520 } 3521 }); 3522 }); 3523 callAll(fs, []); 3524 } finally { 3525 if (doc2.gc) { 3526 tryGcDeleteSet(ds, store, doc2.gcFilter); 3527 } 3528 tryMergeDeleteSet(ds, store); 3529 transaction.afterState.forEach((clock, client) => { 3530 const beforeClock = transaction.beforeState.get(client) || 0; 3531 if (beforeClock !== clock) { 3532 const structs = ( 3533 /** @type {Array<GC|Item>} */ 3534 store.clients.get(client) 3535 ); 3536 const firstChangePos = max(findIndexSS(structs, beforeClock), 1); 3537 for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { 3538 i2 -= 1 + tryToMergeWithLefts(structs, i2); 3539 } 3540 } 3541 }); 3542 for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { 3543 const { client, clock } = mergeStructs[i2].id; 3544 const structs = ( 3545 /** @type {Array<GC|Item>} */ 3546 store.clients.get(client) 3547 ); 3548 const replacedStructPos = findIndexSS(structs, clock); 3549 if (replacedStructPos + 1 < structs.length) { 3550 if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { 3551 continue; 3552 } 3553 } 3554 if (replacedStructPos > 0) { 3555 tryToMergeWithLefts(structs, replacedStructPos); 3556 } 3557 } 3558 if (!transaction.local && transaction.afterState.get(doc2.clientID) !== transaction.beforeState.get(doc2.clientID)) { 3559 print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); 3560 doc2.clientID = generateNewClientId(); 3561 } 3562 doc2.emit("afterTransactionCleanup", [transaction, doc2]); 3563 if (doc2._observers.has("update")) { 3564 const encoder = new UpdateEncoderV1(); 3565 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 3566 if (hasContent2) { 3567 doc2.emit("update", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 3568 } 3569 } 3570 if (doc2._observers.has("updateV2")) { 3571 const encoder = new UpdateEncoderV2(); 3572 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 3573 if (hasContent2) { 3574 doc2.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 3575 } 3576 } 3577 const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; 3578 if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { 3579 subdocsAdded.forEach((subdoc) => { 3580 subdoc.clientID = doc2.clientID; 3581 if (subdoc.collectionid == null) { 3582 subdoc.collectionid = doc2.collectionid; 3583 } 3584 doc2.subdocs.add(subdoc); 3585 }); 3586 subdocsRemoved.forEach((subdoc) => doc2.subdocs.delete(subdoc)); 3587 doc2.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc2, transaction]); 3588 subdocsRemoved.forEach((subdoc) => subdoc.destroy()); 3589 } 3590 if (transactionCleanups.length <= i + 1) { 3591 doc2._transactionCleanups = []; 3592 doc2.emit("afterAllTransactions", [doc2, transactionCleanups]); 3593 } else { 3594 cleanupTransactions(transactionCleanups, i + 1); 3595 } 3596 } 3597 } 3598 }; 3599 var transact = (doc2, f, origin2 = null, local = true) => { 3600 const transactionCleanups = doc2._transactionCleanups; 3601 let initialCall = false; 3602 let result = null; 3603 if (doc2._transaction === null) { 3604 initialCall = true; 3605 doc2._transaction = new Transaction(doc2, origin2, local); 3606 transactionCleanups.push(doc2._transaction); 3607 if (transactionCleanups.length === 1) { 3608 doc2.emit("beforeAllTransactions", [doc2]); 3609 } 3610 doc2.emit("beforeTransaction", [doc2._transaction, doc2]); 3611 } 3612 try { 3613 result = f(doc2._transaction); 3614 } finally { 3615 if (initialCall) { 3616 const finishCleanup = doc2._transaction === transactionCleanups[0]; 3617 doc2._transaction = null; 3618 if (finishCleanup) { 3619 cleanupTransactions(transactionCleanups, 0); 3620 } 3621 } 3622 } 3623 return result; 3624 }; 3625 var StackItem = class { 3626 /** 3627 * @param {DeleteSet} deletions 3628 * @param {DeleteSet} insertions 3629 */ 3630 constructor(deletions, insertions) { 3631 this.insertions = insertions; 3632 this.deletions = deletions; 3633 this.meta = /* @__PURE__ */ new Map(); 3634 } 3635 }; 3636 var clearUndoManagerStackItem = (tr, um, stackItem) => { 3637 iterateDeletedStructs(tr, stackItem.deletions, (item) => { 3638 if (item instanceof Item && um.scope.some((type) => type === tr.doc || isParentOf( 3639 /** @type {AbstractType<any>} */ 3640 type, 3641 item 3642 ))) { 3643 keepItem(item, false); 3644 } 3645 }); 3646 }; 3647 var popStackItem = (undoManager, stack, eventType) => { 3648 let _tr = null; 3649 const doc2 = undoManager.doc; 3650 const scope = undoManager.scope; 3651 transact(doc2, (transaction) => { 3652 while (stack.length > 0 && undoManager.currStackItem === null) { 3653 const store = doc2.store; 3654 const stackItem = ( 3655 /** @type {StackItem} */ 3656 stack.pop() 3657 ); 3658 const itemsToRedo = /* @__PURE__ */ new Set(); 3659 const itemsToDelete = []; 3660 let performedChange = false; 3661 iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { 3662 if (struct instanceof Item) { 3663 if (struct.redone !== null) { 3664 let { item, diff } = followRedone(store, struct.id); 3665 if (diff > 0) { 3666 item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); 3667 } 3668 struct = item; 3669 } 3670 if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( 3671 /** @type {AbstractType<any>} */ 3672 type, 3673 /** @type {Item} */ 3674 struct 3675 ))) { 3676 itemsToDelete.push(struct); 3677 } 3678 } 3679 }); 3680 iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { 3681 if (struct instanceof Item && scope.some((type) => type === transaction.doc || isParentOf( 3682 /** @type {AbstractType<any>} */ 3683 type, 3684 struct 3685 )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. 3686 !isDeleted(stackItem.insertions, struct.id)) { 3687 itemsToRedo.add(struct); 3688 } 3689 }); 3690 itemsToRedo.forEach((struct) => { 3691 performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange; 3692 }); 3693 for (let i = itemsToDelete.length - 1; i >= 0; i--) { 3694 const item = itemsToDelete[i]; 3695 if (undoManager.deleteFilter(item)) { 3696 item.delete(transaction); 3697 performedChange = true; 3698 } 3699 } 3700 undoManager.currStackItem = performedChange ? stackItem : null; 3701 } 3702 transaction.changed.forEach((subProps, type) => { 3703 if (subProps.has(null) && type._searchMarker) { 3704 type._searchMarker.length = 0; 3705 } 3706 }); 3707 _tr = transaction; 3708 }, undoManager); 3709 const res = undoManager.currStackItem; 3710 if (res != null) { 3711 const changedParentTypes = _tr.changedParentTypes; 3712 undoManager.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager }, undoManager]); 3713 undoManager.currStackItem = null; 3714 } 3715 return res; 3716 }; 3717 var UndoManager = class extends ObservableV2 { 3718 /** 3719 * @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. 3720 * @param {UndoManagerOptions} options 3721 */ 3722 constructor(typeScope, { 3723 captureTimeout = 500, 3724 captureTransaction = (_tr) => true, 3725 deleteFilter = () => true, 3726 trackedOrigins = /* @__PURE__ */ new Set([null]), 3727 ignoreRemoteMapChanges = false, 3728 doc: doc2 = ( 3729 /** @type {Doc} */ 3730 isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc 3731 ) 3732 } = {}) { 3733 super(); 3734 this.scope = []; 3735 this.doc = doc2; 3736 this.addToScope(typeScope); 3737 this.deleteFilter = deleteFilter; 3738 trackedOrigins.add(this); 3739 this.trackedOrigins = trackedOrigins; 3740 this.captureTransaction = captureTransaction; 3741 this.undoStack = []; 3742 this.redoStack = []; 3743 this.undoing = false; 3744 this.redoing = false; 3745 this.currStackItem = null; 3746 this.lastChange = 0; 3747 this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; 3748 this.captureTimeout = captureTimeout; 3749 this.afterTransactionHandler = (transaction) => { 3750 if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( 3751 /** @type {AbstractType<any>} */ 3752 type 3753 ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { 3754 return; 3755 } 3756 const undoing = this.undoing; 3757 const redoing = this.redoing; 3758 const stack = undoing ? this.redoStack : this.undoStack; 3759 if (undoing) { 3760 this.stopCapturing(); 3761 } else if (!redoing) { 3762 this.clear(false, true); 3763 } 3764 const insertions = new DeleteSet(); 3765 transaction.afterState.forEach((endClock, client) => { 3766 const startClock = transaction.beforeState.get(client) || 0; 3767 const len = endClock - startClock; 3768 if (len > 0) { 3769 addToDeleteSet(insertions, client, startClock, len); 3770 } 3771 }); 3772 const now = getUnixTime(); 3773 let didAdd = false; 3774 if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { 3775 const lastOp = stack[stack.length - 1]; 3776 lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); 3777 lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); 3778 } else { 3779 stack.push(new StackItem(transaction.deleteSet, insertions)); 3780 didAdd = true; 3781 } 3782 if (!undoing && !redoing) { 3783 this.lastChange = now; 3784 } 3785 iterateDeletedStructs( 3786 transaction, 3787 transaction.deleteSet, 3788 /** @param {Item|GC} item */ 3789 (item) => { 3790 if (item instanceof Item && this.scope.some((type) => type === transaction.doc || isParentOf( 3791 /** @type {AbstractType<any>} */ 3792 type, 3793 item 3794 ))) { 3795 keepItem(item, true); 3796 } 3797 } 3798 ); 3799 const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; 3800 if (didAdd) { 3801 this.emit("stack-item-added", changeEvent); 3802 } else { 3803 this.emit("stack-item-updated", changeEvent); 3804 } 3805 }; 3806 this.doc.on("afterTransaction", this.afterTransactionHandler); 3807 this.doc.on("destroy", () => { 3808 this.destroy(); 3809 }); 3810 } 3811 /** 3812 * Extend the scope. 3813 * 3814 * @param {Array<AbstractType<any> | Doc> | AbstractType<any> | Doc} ytypes 3815 */ 3816 addToScope(ytypes) { 3817 const tmpSet = new Set(this.scope); 3818 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 3819 ytypes.forEach((ytype) => { 3820 if (!tmpSet.has(ytype)) { 3821 tmpSet.add(ytype); 3822 if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn("[yjs#509] Not same Y.Doc"); 3823 this.scope.push(ytype); 3824 } 3825 }); 3826 } 3827 /** 3828 * @param {any} origin 3829 */ 3830 addTrackedOrigin(origin2) { 3831 this.trackedOrigins.add(origin2); 3832 } 3833 /** 3834 * @param {any} origin 3835 */ 3836 removeTrackedOrigin(origin2) { 3837 this.trackedOrigins.delete(origin2); 3838 } 3839 clear(clearUndoStack = true, clearRedoStack = true) { 3840 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 3841 this.doc.transact((tr) => { 3842 if (clearUndoStack) { 3843 this.undoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 3844 this.undoStack = []; 3845 } 3846 if (clearRedoStack) { 3847 this.redoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 3848 this.redoStack = []; 3849 } 3850 this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); 3851 }); 3852 } 3853 } 3854 /** 3855 * UndoManager merges Undo-StackItem if they are created within time-gap 3856 * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next 3857 * StackItem won't be merged. 3858 * 3859 * 3860 * @example 3861 * // without stopCapturing 3862 * ytext.insert(0, 'a') 3863 * ytext.insert(1, 'b') 3864 * um.undo() 3865 * ytext.toString() // => '' (note that 'ab' was removed) 3866 * // with stopCapturing 3867 * ytext.insert(0, 'a') 3868 * um.stopCapturing() 3869 * ytext.insert(0, 'b') 3870 * um.undo() 3871 * ytext.toString() // => 'a' (note that only 'b' was removed) 3872 * 3873 */ 3874 stopCapturing() { 3875 this.lastChange = 0; 3876 } 3877 /** 3878 * Undo last changes on type. 3879 * 3880 * @return {StackItem?} Returns StackItem if a change was applied 3881 */ 3882 undo() { 3883 this.undoing = true; 3884 let res; 3885 try { 3886 res = popStackItem(this, this.undoStack, "undo"); 3887 } finally { 3888 this.undoing = false; 3889 } 3890 return res; 3891 } 3892 /** 3893 * Redo last undo operation. 3894 * 3895 * @return {StackItem?} Returns StackItem if a change was applied 3896 */ 3897 redo() { 3898 this.redoing = true; 3899 let res; 3900 try { 3901 res = popStackItem(this, this.redoStack, "redo"); 3902 } finally { 3903 this.redoing = false; 3904 } 3905 return res; 3906 } 3907 /** 3908 * Are undo steps available? 3909 * 3910 * @return {boolean} `true` if undo is possible 3911 */ 3912 canUndo() { 3913 return this.undoStack.length > 0; 3914 } 3915 /** 3916 * Are redo steps available? 3917 * 3918 * @return {boolean} `true` if redo is possible 3919 */ 3920 canRedo() { 3921 return this.redoStack.length > 0; 3922 } 3923 destroy() { 3924 this.trackedOrigins.delete(this); 3925 this.doc.off("afterTransaction", this.afterTransactionHandler); 3926 super.destroy(); 3927 } 3928 }; 3929 function* lazyStructReaderGenerator(decoder) { 3930 const numOfStateUpdates = readVarUint(decoder.restDecoder); 3931 for (let i = 0; i < numOfStateUpdates; i++) { 3932 const numberOfStructs = readVarUint(decoder.restDecoder); 3933 const client = decoder.readClient(); 3934 let clock = readVarUint(decoder.restDecoder); 3935 for (let i2 = 0; i2 < numberOfStructs; i2++) { 3936 const info = decoder.readInfo(); 3937 if (info === 10) { 3938 const len = readVarUint(decoder.restDecoder); 3939 yield new Skip(createID(client, clock), len); 3940 clock += len; 3941 } else if ((BITS5 & info) !== 0) { 3942 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 3943 const struct = new Item( 3944 createID(client, clock), 3945 null, 3946 // left 3947 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 3948 // origin 3949 null, 3950 // right 3951 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 3952 // right origin 3953 // @ts-ignore Force writing a string here. 3954 cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, 3955 // parent 3956 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 3957 // parentSub 3958 readItemContent(decoder, info) 3959 // item content 3960 ); 3961 yield struct; 3962 clock += struct.length; 3963 } else { 3964 const len = decoder.readLen(); 3965 yield new GC(createID(client, clock), len); 3966 clock += len; 3967 } 3968 } 3969 } 3970 } 3971 var LazyStructReader = class { 3972 /** 3973 * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder 3974 * @param {boolean} filterSkips 3975 */ 3976 constructor(decoder, filterSkips) { 3977 this.gen = lazyStructReaderGenerator(decoder); 3978 this.curr = null; 3979 this.done = false; 3980 this.filterSkips = filterSkips; 3981 this.next(); 3982 } 3983 /** 3984 * @return {Item | GC | Skip |null} 3985 */ 3986 next() { 3987 do { 3988 this.curr = this.gen.next().value || null; 3989 } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); 3990 return this.curr; 3991 } 3992 }; 3993 var logUpdate = (update) => logUpdateV2(update, UpdateDecoderV1); 3994 var logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 3995 const structs = []; 3996 const updateDecoder = new YDecoder(createDecoder(update)); 3997 const lazyDecoder = new LazyStructReader(updateDecoder, false); 3998 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 3999 structs.push(curr); 4000 } 4001 print("Structs: ", structs); 4002 const ds = readDeleteSet(updateDecoder); 4003 print("DeleteSet: ", ds); 4004 }; 4005 var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1); 4006 var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4007 const structs = []; 4008 const updateDecoder = new YDecoder(createDecoder(update)); 4009 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4010 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4011 structs.push(curr); 4012 } 4013 return { 4014 structs, 4015 ds: readDeleteSet(updateDecoder) 4016 }; 4017 }; 4018 var LazyStructWriter = class { 4019 /** 4020 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 4021 */ 4022 constructor(encoder) { 4023 this.currClient = 0; 4024 this.startClock = 0; 4025 this.written = 0; 4026 this.encoder = encoder; 4027 this.clientStructs = []; 4028 } 4029 }; 4030 var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); 4031 var encodeStateVectorFromUpdateV2 = (update, YEncoder = DSEncoderV2, YDecoder = UpdateDecoderV2) => { 4032 const encoder = new YEncoder(); 4033 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4034 let curr = updateDecoder.curr; 4035 if (curr !== null) { 4036 let size2 = 0; 4037 let currClient = curr.id.client; 4038 let stopCounting = curr.id.clock !== 0; 4039 let currClock = stopCounting ? 0 : curr.id.clock + curr.length; 4040 for (; curr !== null; curr = updateDecoder.next()) { 4041 if (currClient !== curr.id.client) { 4042 if (currClock !== 0) { 4043 size2++; 4044 writeVarUint(encoder.restEncoder, currClient); 4045 writeVarUint(encoder.restEncoder, currClock); 4046 } 4047 currClient = curr.id.client; 4048 currClock = 0; 4049 stopCounting = curr.id.clock !== 0; 4050 } 4051 if (curr.constructor === Skip) { 4052 stopCounting = true; 4053 } 4054 if (!stopCounting) { 4055 currClock = curr.id.clock + curr.length; 4056 } 4057 } 4058 if (currClock !== 0) { 4059 size2++; 4060 writeVarUint(encoder.restEncoder, currClient); 4061 writeVarUint(encoder.restEncoder, currClock); 4062 } 4063 const enc = createEncoder(); 4064 writeVarUint(enc, size2); 4065 writeBinaryEncoder(enc, encoder.restEncoder); 4066 encoder.restEncoder = enc; 4067 return encoder.toUint8Array(); 4068 } else { 4069 writeVarUint(encoder.restEncoder, 0); 4070 return encoder.toUint8Array(); 4071 } 4072 }; 4073 var encodeStateVectorFromUpdate = (update) => encodeStateVectorFromUpdateV2(update, DSEncoderV1, UpdateDecoderV1); 4074 var parseUpdateMetaV2 = (update, YDecoder = UpdateDecoderV2) => { 4075 const from2 = /* @__PURE__ */ new Map(); 4076 const to = /* @__PURE__ */ new Map(); 4077 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4078 let curr = updateDecoder.curr; 4079 if (curr !== null) { 4080 let currClient = curr.id.client; 4081 let currClock = curr.id.clock; 4082 from2.set(currClient, currClock); 4083 for (; curr !== null; curr = updateDecoder.next()) { 4084 if (currClient !== curr.id.client) { 4085 to.set(currClient, currClock); 4086 from2.set(curr.id.client, curr.id.clock); 4087 currClient = curr.id.client; 4088 } 4089 currClock = curr.id.clock + curr.length; 4090 } 4091 to.set(currClient, currClock); 4092 } 4093 return { from: from2, to }; 4094 }; 4095 var parseUpdateMeta = (update) => parseUpdateMetaV2(update, UpdateDecoderV1); 4096 var sliceStruct = (left, diff) => { 4097 if (left.constructor === GC) { 4098 const { client, clock } = left.id; 4099 return new GC(createID(client, clock + diff), left.length - diff); 4100 } else if (left.constructor === Skip) { 4101 const { client, clock } = left.id; 4102 return new Skip(createID(client, clock + diff), left.length - diff); 4103 } else { 4104 const leftItem = ( 4105 /** @type {Item} */ 4106 left 4107 ); 4108 const { client, clock } = leftItem.id; 4109 return new Item( 4110 createID(client, clock + diff), 4111 null, 4112 createID(client, clock + diff - 1), 4113 null, 4114 leftItem.rightOrigin, 4115 leftItem.parent, 4116 leftItem.parentSub, 4117 leftItem.content.splice(diff) 4118 ); 4119 } 4120 }; 4121 var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4122 if (updates.length === 1) { 4123 return updates[0]; 4124 } 4125 const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); 4126 let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); 4127 let currWrite = null; 4128 const updateEncoder = new YEncoder(); 4129 const lazyStructEncoder = new LazyStructWriter(updateEncoder); 4130 while (true) { 4131 lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); 4132 lazyStructDecoders.sort( 4133 /** @type {function(any,any):number} */ 4134 (dec1, dec2) => { 4135 if (dec1.curr.id.client === dec2.curr.id.client) { 4136 const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; 4137 if (clockDiff === 0) { 4138 return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; 4139 } else { 4140 return clockDiff; 4141 } 4142 } else { 4143 return dec2.curr.id.client - dec1.curr.id.client; 4144 } 4145 } 4146 ); 4147 if (lazyStructDecoders.length === 0) { 4148 break; 4149 } 4150 const currDecoder = lazyStructDecoders[0]; 4151 const firstClient = ( 4152 /** @type {Item | GC} */ 4153 currDecoder.curr.id.client 4154 ); 4155 if (currWrite !== null) { 4156 let curr = ( 4157 /** @type {Item | GC | null} */ 4158 currDecoder.curr 4159 ); 4160 let iterated = false; 4161 while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { 4162 curr = currDecoder.next(); 4163 iterated = true; 4164 } 4165 if (curr === null || // current decoder is empty 4166 curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` 4167 iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { 4168 continue; 4169 } 4170 if (firstClient !== currWrite.struct.id.client) { 4171 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4172 currWrite = { struct: curr, offset: 0 }; 4173 currDecoder.next(); 4174 } else { 4175 if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { 4176 if (currWrite.struct.constructor === Skip) { 4177 currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; 4178 } else { 4179 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4180 const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; 4181 const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); 4182 currWrite = { struct, offset: 0 }; 4183 } 4184 } else { 4185 const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; 4186 if (diff > 0) { 4187 if (currWrite.struct.constructor === Skip) { 4188 currWrite.struct.length -= diff; 4189 } else { 4190 curr = sliceStruct(curr, diff); 4191 } 4192 } 4193 if (!currWrite.struct.mergeWith( 4194 /** @type {any} */ 4195 curr 4196 )) { 4197 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4198 currWrite = { struct: curr, offset: 0 }; 4199 currDecoder.next(); 4200 } 4201 } 4202 } 4203 } else { 4204 currWrite = { struct: ( 4205 /** @type {Item | GC} */ 4206 currDecoder.curr 4207 ), offset: 0 }; 4208 currDecoder.next(); 4209 } 4210 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()) { 4211 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4212 currWrite = { struct: next, offset: 0 }; 4213 } 4214 } 4215 if (currWrite !== null) { 4216 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4217 currWrite = null; 4218 } 4219 finishLazyStructWriting(lazyStructEncoder); 4220 const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); 4221 const ds = mergeDeleteSets(dss); 4222 writeDeleteSet(updateEncoder, ds); 4223 return updateEncoder.toUint8Array(); 4224 }; 4225 var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4226 const state = decodeStateVector(sv); 4227 const encoder = new YEncoder(); 4228 const lazyStructWriter = new LazyStructWriter(encoder); 4229 const decoder = new YDecoder(createDecoder(update)); 4230 const reader = new LazyStructReader(decoder, false); 4231 while (reader.curr) { 4232 const curr = reader.curr; 4233 const currClient = curr.id.client; 4234 const svClock = state.get(currClient) || 0; 4235 if (reader.curr.constructor === Skip) { 4236 reader.next(); 4237 continue; 4238 } 4239 if (curr.id.clock + curr.length > svClock) { 4240 writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); 4241 reader.next(); 4242 while (reader.curr && reader.curr.id.client === currClient) { 4243 writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); 4244 reader.next(); 4245 } 4246 } else { 4247 while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { 4248 reader.next(); 4249 } 4250 } 4251 } 4252 finishLazyStructWriting(lazyStructWriter); 4253 const ds = readDeleteSet(decoder); 4254 writeDeleteSet(encoder, ds); 4255 return encoder.toUint8Array(); 4256 }; 4257 var diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1); 4258 var flushLazyStructWriter = (lazyWriter) => { 4259 if (lazyWriter.written > 0) { 4260 lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); 4261 lazyWriter.encoder.restEncoder = createEncoder(); 4262 lazyWriter.written = 0; 4263 } 4264 }; 4265 var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { 4266 if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { 4267 flushLazyStructWriter(lazyWriter); 4268 } 4269 if (lazyWriter.written === 0) { 4270 lazyWriter.currClient = struct.id.client; 4271 lazyWriter.encoder.writeClient(struct.id.client); 4272 writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); 4273 } 4274 struct.write(lazyWriter.encoder, offset); 4275 lazyWriter.written++; 4276 }; 4277 var finishLazyStructWriting = (lazyWriter) => { 4278 flushLazyStructWriter(lazyWriter); 4279 const restEncoder = lazyWriter.encoder.restEncoder; 4280 writeVarUint(restEncoder, lazyWriter.clientStructs.length); 4281 for (let i = 0; i < lazyWriter.clientStructs.length; i++) { 4282 const partStructs = lazyWriter.clientStructs[i]; 4283 writeVarUint(restEncoder, partStructs.written); 4284 writeUint8Array(restEncoder, partStructs.restEncoder); 4285 } 4286 }; 4287 var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { 4288 const updateDecoder = new YDecoder(createDecoder(update)); 4289 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4290 const updateEncoder = new YEncoder(); 4291 const lazyWriter = new LazyStructWriter(updateEncoder); 4292 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4293 writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); 4294 } 4295 finishLazyStructWriting(lazyWriter); 4296 const ds = readDeleteSet(updateDecoder); 4297 writeDeleteSet(updateEncoder, ds); 4298 return updateEncoder.toUint8Array(); 4299 }; 4300 var createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {}) => { 4301 let i = 0; 4302 const mapKeyCache = create(); 4303 const nodeNameCache = create(); 4304 const formattingKeyCache = create(); 4305 const formattingValueCache = create(); 4306 formattingValueCache.set(null, null); 4307 return (block) => { 4308 switch (block.constructor) { 4309 case GC: 4310 case Skip: 4311 return block; 4312 case Item: { 4313 const item = ( 4314 /** @type {Item} */ 4315 block 4316 ); 4317 const content = item.content; 4318 switch (content.constructor) { 4319 case ContentDeleted: 4320 break; 4321 case ContentType: { 4322 if (yxml) { 4323 const type = ( 4324 /** @type {ContentType} */ 4325 content.type 4326 ); 4327 if (type instanceof YXmlElement) { 4328 type.nodeName = setIfUndefined(nodeNameCache, type.nodeName, () => "node-" + i); 4329 } 4330 if (type instanceof YXmlHook) { 4331 type.hookName = setIfUndefined(nodeNameCache, type.hookName, () => "hook-" + i); 4332 } 4333 } 4334 break; 4335 } 4336 case ContentAny: { 4337 const c = ( 4338 /** @type {ContentAny} */ 4339 content 4340 ); 4341 c.arr = c.arr.map(() => i); 4342 break; 4343 } 4344 case ContentBinary: { 4345 const c = ( 4346 /** @type {ContentBinary} */ 4347 content 4348 ); 4349 c.content = new Uint8Array([i]); 4350 break; 4351 } 4352 case ContentDoc: { 4353 const c = ( 4354 /** @type {ContentDoc} */ 4355 content 4356 ); 4357 if (subdocs) { 4358 c.opts = {}; 4359 c.doc.guid = i + ""; 4360 } 4361 break; 4362 } 4363 case ContentEmbed: { 4364 const c = ( 4365 /** @type {ContentEmbed} */ 4366 content 4367 ); 4368 c.embed = {}; 4369 break; 4370 } 4371 case ContentFormat: { 4372 const c = ( 4373 /** @type {ContentFormat} */ 4374 content 4375 ); 4376 if (formatting) { 4377 c.key = setIfUndefined(formattingKeyCache, c.key, () => i + ""); 4378 c.value = setIfUndefined(formattingValueCache, c.value, () => ({ i })); 4379 } 4380 break; 4381 } 4382 case ContentJSON: { 4383 const c = ( 4384 /** @type {ContentJSON} */ 4385 content 4386 ); 4387 c.arr = c.arr.map(() => i); 4388 break; 4389 } 4390 case ContentString: { 4391 const c = ( 4392 /** @type {ContentString} */ 4393 content 4394 ); 4395 c.str = repeat(i % 10 + "", c.str.length); 4396 break; 4397 } 4398 default: 4399 unexpectedCase(); 4400 } 4401 if (item.parentSub) { 4402 item.parentSub = setIfUndefined(mapKeyCache, item.parentSub, () => i + ""); 4403 } 4404 i++; 4405 return block; 4406 } 4407 default: 4408 unexpectedCase(); 4409 } 4410 }; 4411 }; 4412 var obfuscateUpdate = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV1, UpdateEncoderV1); 4413 var obfuscateUpdateV2 = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV2, UpdateEncoderV2); 4414 var convertUpdateFormatV1ToV2 = (update) => convertUpdateFormat(update, id, UpdateDecoderV1, UpdateEncoderV2); 4415 var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); 4416 var errorComputeChanges = "You must not compute changes after the event-handler fired."; 4417 var YEvent = class { 4418 /** 4419 * @param {T} target The changed type. 4420 * @param {Transaction} transaction 4421 */ 4422 constructor(target, transaction) { 4423 this.target = target; 4424 this.currentTarget = target; 4425 this.transaction = transaction; 4426 this._changes = null; 4427 this._keys = null; 4428 this._delta = null; 4429 this._path = null; 4430 } 4431 /** 4432 * Computes the path from `y` to the changed type. 4433 * 4434 * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. 4435 * 4436 * The following property holds: 4437 * @example 4438 * let type = y 4439 * event.path.forEach(dir => { 4440 * type = type.get(dir) 4441 * }) 4442 * type === event.target // => true 4443 */ 4444 get path() { 4445 return this._path || (this._path = getPathTo(this.currentTarget, this.target)); 4446 } 4447 /** 4448 * Check if a struct is deleted by this event. 4449 * 4450 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 4451 * 4452 * @param {AbstractStruct} struct 4453 * @return {boolean} 4454 */ 4455 deletes(struct) { 4456 return isDeleted(this.transaction.deleteSet, struct.id); 4457 } 4458 /** 4459 * @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>} 4460 */ 4461 get keys() { 4462 if (this._keys === null) { 4463 if (this.transaction.doc._transactionCleanups.length === 0) { 4464 throw create3(errorComputeChanges); 4465 } 4466 const keys2 = /* @__PURE__ */ new Map(); 4467 const target = this.target; 4468 const changed = ( 4469 /** @type Set<string|null> */ 4470 this.transaction.changed.get(target) 4471 ); 4472 changed.forEach((key) => { 4473 if (key !== null) { 4474 const item = ( 4475 /** @type {Item} */ 4476 target._map.get(key) 4477 ); 4478 let action; 4479 let oldValue; 4480 if (this.adds(item)) { 4481 let prev = item.left; 4482 while (prev !== null && this.adds(prev)) { 4483 prev = prev.left; 4484 } 4485 if (this.deletes(item)) { 4486 if (prev !== null && this.deletes(prev)) { 4487 action = "delete"; 4488 oldValue = last(prev.content.getContent()); 4489 } else { 4490 return; 4491 } 4492 } else { 4493 if (prev !== null && this.deletes(prev)) { 4494 action = "update"; 4495 oldValue = last(prev.content.getContent()); 4496 } else { 4497 action = "add"; 4498 oldValue = void 0; 4499 } 4500 } 4501 } else { 4502 if (this.deletes(item)) { 4503 action = "delete"; 4504 oldValue = last( 4505 /** @type {Item} */ 4506 item.content.getContent() 4507 ); 4508 } else { 4509 return; 4510 } 4511 } 4512 keys2.set(key, { action, oldValue }); 4513 } 4514 }); 4515 this._keys = keys2; 4516 } 4517 return this._keys; 4518 } 4519 /** 4520 * This is a computed property. Note that this can only be safely computed during the 4521 * event call. Computing this property after other changes happened might result in 4522 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 4523 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 4524 * 4525 * @type {Array<{insert?: string | Array<any> | object | AbstractType<any>, retain?: number, delete?: number, attributes?: Object<string, any>}>} 4526 */ 4527 get delta() { 4528 return this.changes.delta; 4529 } 4530 /** 4531 * Check if a struct is added by this event. 4532 * 4533 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 4534 * 4535 * @param {AbstractStruct} struct 4536 * @return {boolean} 4537 */ 4538 adds(struct) { 4539 return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); 4540 } 4541 /** 4542 * This is a computed property. Note that this can only be safely computed during the 4543 * event call. Computing this property after other changes happened might result in 4544 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 4545 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 4546 * 4547 * @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}>}} 4548 */ 4549 get changes() { 4550 let changes = this._changes; 4551 if (changes === null) { 4552 if (this.transaction.doc._transactionCleanups.length === 0) { 4553 throw create3(errorComputeChanges); 4554 } 4555 const target = this.target; 4556 const added = create2(); 4557 const deleted = create2(); 4558 const delta = []; 4559 changes = { 4560 added, 4561 deleted, 4562 delta, 4563 keys: this.keys 4564 }; 4565 const changed = ( 4566 /** @type Set<string|null> */ 4567 this.transaction.changed.get(target) 4568 ); 4569 if (changed.has(null)) { 4570 let lastOp = null; 4571 const packOp = () => { 4572 if (lastOp) { 4573 delta.push(lastOp); 4574 } 4575 }; 4576 for (let item = target._start; item !== null; item = item.right) { 4577 if (item.deleted) { 4578 if (this.deletes(item) && !this.adds(item)) { 4579 if (lastOp === null || lastOp.delete === void 0) { 4580 packOp(); 4581 lastOp = { delete: 0 }; 4582 } 4583 lastOp.delete += item.length; 4584 deleted.add(item); 4585 } 4586 } else { 4587 if (this.adds(item)) { 4588 if (lastOp === null || lastOp.insert === void 0) { 4589 packOp(); 4590 lastOp = { insert: [] }; 4591 } 4592 lastOp.insert = lastOp.insert.concat(item.content.getContent()); 4593 added.add(item); 4594 } else { 4595 if (lastOp === null || lastOp.retain === void 0) { 4596 packOp(); 4597 lastOp = { retain: 0 }; 4598 } 4599 lastOp.retain += item.length; 4600 } 4601 } 4602 } 4603 if (lastOp !== null && lastOp.retain === void 0) { 4604 packOp(); 4605 } 4606 } 4607 this._changes = changes; 4608 } 4609 return ( 4610 /** @type {any} */ 4611 changes 4612 ); 4613 } 4614 }; 4615 var getPathTo = (parent, child) => { 4616 const path = []; 4617 while (child._item !== null && child !== parent) { 4618 if (child._item.parentSub !== null) { 4619 path.unshift(child._item.parentSub); 4620 } else { 4621 let i = 0; 4622 let c = ( 4623 /** @type {AbstractType<any>} */ 4624 child._item.parent._start 4625 ); 4626 while (c !== child._item && c !== null) { 4627 if (!c.deleted && c.countable) { 4628 i += c.length; 4629 } 4630 c = c.right; 4631 } 4632 path.unshift(i); 4633 } 4634 child = /** @type {AbstractType<any>} */ 4635 child._item.parent; 4636 } 4637 return path; 4638 }; 4639 var warnPrematureAccess = () => { 4640 warn("Invalid access: Add Yjs type to a document before reading data."); 4641 }; 4642 var maxSearchMarker = 80; 4643 var globalSearchMarkerTimestamp = 0; 4644 var ArraySearchMarker = class { 4645 /** 4646 * @param {Item} p 4647 * @param {number} index 4648 */ 4649 constructor(p, index) { 4650 p.marker = true; 4651 this.p = p; 4652 this.index = index; 4653 this.timestamp = globalSearchMarkerTimestamp++; 4654 } 4655 }; 4656 var refreshMarkerTimestamp = (marker) => { 4657 marker.timestamp = globalSearchMarkerTimestamp++; 4658 }; 4659 var overwriteMarker = (marker, p, index) => { 4660 marker.p.marker = false; 4661 marker.p = p; 4662 p.marker = true; 4663 marker.index = index; 4664 marker.timestamp = globalSearchMarkerTimestamp++; 4665 }; 4666 var markPosition = (searchMarker, p, index) => { 4667 if (searchMarker.length >= maxSearchMarker) { 4668 const marker = searchMarker.reduce((a, b) => a.timestamp < b.timestamp ? a : b); 4669 overwriteMarker(marker, p, index); 4670 return marker; 4671 } else { 4672 const pm = new ArraySearchMarker(p, index); 4673 searchMarker.push(pm); 4674 return pm; 4675 } 4676 }; 4677 var findMarker = (yarray, index) => { 4678 if (yarray._start === null || index === 0 || yarray._searchMarker === null) { 4679 return null; 4680 } 4681 const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b) => abs(index - a.index) < abs(index - b.index) ? a : b); 4682 let p = yarray._start; 4683 let pindex = 0; 4684 if (marker !== null) { 4685 p = marker.p; 4686 pindex = marker.index; 4687 refreshMarkerTimestamp(marker); 4688 } 4689 while (p.right !== null && pindex < index) { 4690 if (!p.deleted && p.countable) { 4691 if (index < pindex + p.length) { 4692 break; 4693 } 4694 pindex += p.length; 4695 } 4696 p = p.right; 4697 } 4698 while (p.left !== null && pindex > index) { 4699 p = p.left; 4700 if (!p.deleted && p.countable) { 4701 pindex -= p.length; 4702 } 4703 } 4704 while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { 4705 p = p.left; 4706 if (!p.deleted && p.countable) { 4707 pindex -= p.length; 4708 } 4709 } 4710 if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray<any>} */ 4711 p.parent.length / maxSearchMarker) { 4712 overwriteMarker(marker, p, pindex); 4713 return marker; 4714 } else { 4715 return markPosition(yarray._searchMarker, p, pindex); 4716 } 4717 }; 4718 var updateMarkerChanges = (searchMarker, index, len) => { 4719 for (let i = searchMarker.length - 1; i >= 0; i--) { 4720 const m = searchMarker[i]; 4721 if (len > 0) { 4722 let p = m.p; 4723 p.marker = false; 4724 while (p && (p.deleted || !p.countable)) { 4725 p = p.left; 4726 if (p && !p.deleted && p.countable) { 4727 m.index -= p.length; 4728 } 4729 } 4730 if (p === null || p.marker === true) { 4731 searchMarker.splice(i, 1); 4732 continue; 4733 } 4734 m.p = p; 4735 p.marker = true; 4736 } 4737 if (index < m.index || len > 0 && index === m.index) { 4738 m.index = max(index, m.index + len); 4739 } 4740 } 4741 }; 4742 var getTypeChildren = (t) => { 4743 t.doc ?? warnPrematureAccess(); 4744 let s = t._start; 4745 const arr = []; 4746 while (s) { 4747 arr.push(s); 4748 s = s.right; 4749 } 4750 return arr; 4751 }; 4752 var callTypeObservers = (type, transaction, event) => { 4753 const changedType = type; 4754 const changedParentTypes = transaction.changedParentTypes; 4755 while (true) { 4756 setIfUndefined(changedParentTypes, type, () => []).push(event); 4757 if (type._item === null) { 4758 break; 4759 } 4760 type = /** @type {AbstractType<any>} */ 4761 type._item.parent; 4762 } 4763 callEventHandlerListeners(changedType._eH, event, transaction); 4764 }; 4765 var AbstractType = class { 4766 constructor() { 4767 this._item = null; 4768 this._map = /* @__PURE__ */ new Map(); 4769 this._start = null; 4770 this.doc = null; 4771 this._length = 0; 4772 this._eH = createEventHandler(); 4773 this._dEH = createEventHandler(); 4774 this._searchMarker = null; 4775 } 4776 /** 4777 * @return {AbstractType<any>|null} 4778 */ 4779 get parent() { 4780 return this._item ? ( 4781 /** @type {AbstractType<any>} */ 4782 this._item.parent 4783 ) : null; 4784 } 4785 /** 4786 * Integrate this type into the Yjs instance. 4787 * 4788 * * Save this struct in the os 4789 * * This type is sent to other client 4790 * * Observer functions are fired 4791 * 4792 * @param {Doc} y The Yjs instance 4793 * @param {Item|null} item 4794 */ 4795 _integrate(y, item) { 4796 this.doc = y; 4797 this._item = item; 4798 } 4799 /** 4800 * @return {AbstractType<EventType>} 4801 */ 4802 _copy() { 4803 throw methodUnimplemented(); 4804 } 4805 /** 4806 * Makes a copy of this data type that can be included somewhere else. 4807 * 4808 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 4809 * 4810 * @return {AbstractType<EventType>} 4811 */ 4812 clone() { 4813 throw methodUnimplemented(); 4814 } 4815 /** 4816 * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder 4817 */ 4818 _write(_encoder) { 4819 } 4820 /** 4821 * The first non-deleted item 4822 */ 4823 get _first() { 4824 let n = this._start; 4825 while (n !== null && n.deleted) { 4826 n = n.right; 4827 } 4828 return n; 4829 } 4830 /** 4831 * Creates YEvent and calls all type observers. 4832 * Must be implemented by each type. 4833 * 4834 * @param {Transaction} transaction 4835 * @param {Set<null|string>} _parentSubs Keys changed on this type. `null` if list was modified. 4836 */ 4837 _callObserver(transaction, _parentSubs) { 4838 if (!transaction.local && this._searchMarker) { 4839 this._searchMarker.length = 0; 4840 } 4841 } 4842 /** 4843 * Observe all events that are created on this type. 4844 * 4845 * @param {function(EventType, Transaction):void} f Observer function 4846 */ 4847 observe(f) { 4848 addEventHandlerListener(this._eH, f); 4849 } 4850 /** 4851 * Observe all events that are created by this type and its children. 4852 * 4853 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 4854 */ 4855 observeDeep(f) { 4856 addEventHandlerListener(this._dEH, f); 4857 } 4858 /** 4859 * Unregister an observer function. 4860 * 4861 * @param {function(EventType,Transaction):void} f Observer function 4862 */ 4863 unobserve(f) { 4864 removeEventHandlerListener(this._eH, f); 4865 } 4866 /** 4867 * Unregister an observer function. 4868 * 4869 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 4870 */ 4871 unobserveDeep(f) { 4872 removeEventHandlerListener(this._dEH, f); 4873 } 4874 /** 4875 * @abstract 4876 * @return {any} 4877 */ 4878 toJSON() { 4879 } 4880 }; 4881 var typeListSlice = (type, start, end) => { 4882 type.doc ?? warnPrematureAccess(); 4883 if (start < 0) { 4884 start = type._length + start; 4885 } 4886 if (end < 0) { 4887 end = type._length + end; 4888 } 4889 let len = end - start; 4890 const cs = []; 4891 let n = type._start; 4892 while (n !== null && len > 0) { 4893 if (n.countable && !n.deleted) { 4894 const c = n.content.getContent(); 4895 if (c.length <= start) { 4896 start -= c.length; 4897 } else { 4898 for (let i = start; i < c.length && len > 0; i++) { 4899 cs.push(c[i]); 4900 len--; 4901 } 4902 start = 0; 4903 } 4904 } 4905 n = n.right; 4906 } 4907 return cs; 4908 }; 4909 var typeListToArray = (type) => { 4910 type.doc ?? warnPrematureAccess(); 4911 const cs = []; 4912 let n = type._start; 4913 while (n !== null) { 4914 if (n.countable && !n.deleted) { 4915 const c = n.content.getContent(); 4916 for (let i = 0; i < c.length; i++) { 4917 cs.push(c[i]); 4918 } 4919 } 4920 n = n.right; 4921 } 4922 return cs; 4923 }; 4924 var typeListToArraySnapshot = (type, snapshot2) => { 4925 const cs = []; 4926 let n = type._start; 4927 while (n !== null) { 4928 if (n.countable && isVisible(n, snapshot2)) { 4929 const c = n.content.getContent(); 4930 for (let i = 0; i < c.length; i++) { 4931 cs.push(c[i]); 4932 } 4933 } 4934 n = n.right; 4935 } 4936 return cs; 4937 }; 4938 var typeListForEach = (type, f) => { 4939 let index = 0; 4940 let n = type._start; 4941 type.doc ?? warnPrematureAccess(); 4942 while (n !== null) { 4943 if (n.countable && !n.deleted) { 4944 const c = n.content.getContent(); 4945 for (let i = 0; i < c.length; i++) { 4946 f(c[i], index++, type); 4947 } 4948 } 4949 n = n.right; 4950 } 4951 }; 4952 var typeListMap = (type, f) => { 4953 const result = []; 4954 typeListForEach(type, (c, i) => { 4955 result.push(f(c, i, type)); 4956 }); 4957 return result; 4958 }; 4959 var typeListCreateIterator = (type) => { 4960 let n = type._start; 4961 let currentContent = null; 4962 let currentContentIndex = 0; 4963 return { 4964 [Symbol.iterator]() { 4965 return this; 4966 }, 4967 next: () => { 4968 if (currentContent === null) { 4969 while (n !== null && n.deleted) { 4970 n = n.right; 4971 } 4972 if (n === null) { 4973 return { 4974 done: true, 4975 value: void 0 4976 }; 4977 } 4978 currentContent = n.content.getContent(); 4979 currentContentIndex = 0; 4980 n = n.right; 4981 } 4982 const value = currentContent[currentContentIndex++]; 4983 if (currentContent.length <= currentContentIndex) { 4984 currentContent = null; 4985 } 4986 return { 4987 done: false, 4988 value 4989 }; 4990 } 4991 }; 4992 }; 4993 var typeListGet = (type, index) => { 4994 type.doc ?? warnPrematureAccess(); 4995 const marker = findMarker(type, index); 4996 let n = type._start; 4997 if (marker !== null) { 4998 n = marker.p; 4999 index -= marker.index; 5000 } 5001 for (; n !== null; n = n.right) { 5002 if (!n.deleted && n.countable) { 5003 if (index < n.length) { 5004 return n.content.getContent()[index]; 5005 } 5006 index -= n.length; 5007 } 5008 } 5009 }; 5010 var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { 5011 let left = referenceItem; 5012 const doc2 = transaction.doc; 5013 const ownClientId = doc2.clientID; 5014 const store = doc2.store; 5015 const right = referenceItem === null ? parent._start : referenceItem.right; 5016 let jsonContent = []; 5017 const packJsonContent = () => { 5018 if (jsonContent.length > 0) { 5019 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); 5020 left.integrate(transaction, 0); 5021 jsonContent = []; 5022 } 5023 }; 5024 content.forEach((c) => { 5025 if (c === null) { 5026 jsonContent.push(c); 5027 } else { 5028 switch (c.constructor) { 5029 case Number: 5030 case Object: 5031 case Boolean: 5032 case Array: 5033 case String: 5034 jsonContent.push(c); 5035 break; 5036 default: 5037 packJsonContent(); 5038 switch (c.constructor) { 5039 case Uint8Array: 5040 case ArrayBuffer: 5041 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( 5042 /** @type {Uint8Array} */ 5043 c 5044 ))); 5045 left.integrate(transaction, 0); 5046 break; 5047 case Doc: 5048 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( 5049 /** @type {Doc} */ 5050 c 5051 )); 5052 left.integrate(transaction, 0); 5053 break; 5054 default: 5055 if (c instanceof AbstractType) { 5056 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); 5057 left.integrate(transaction, 0); 5058 } else { 5059 throw new Error("Unexpected content type in insert operation"); 5060 } 5061 } 5062 } 5063 } 5064 }); 5065 packJsonContent(); 5066 }; 5067 var lengthExceeded = () => create3("Length exceeded!"); 5068 var typeListInsertGenerics = (transaction, parent, index, content) => { 5069 if (index > parent._length) { 5070 throw lengthExceeded(); 5071 } 5072 if (index === 0) { 5073 if (parent._searchMarker) { 5074 updateMarkerChanges(parent._searchMarker, index, content.length); 5075 } 5076 return typeListInsertGenericsAfter(transaction, parent, null, content); 5077 } 5078 const startIndex = index; 5079 const marker = findMarker(parent, index); 5080 let n = parent._start; 5081 if (marker !== null) { 5082 n = marker.p; 5083 index -= marker.index; 5084 if (index === 0) { 5085 n = n.prev; 5086 index += n && n.countable && !n.deleted ? n.length : 0; 5087 } 5088 } 5089 for (; n !== null; n = n.right) { 5090 if (!n.deleted && n.countable) { 5091 if (index <= n.length) { 5092 if (index < n.length) { 5093 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5094 } 5095 break; 5096 } 5097 index -= n.length; 5098 } 5099 } 5100 if (parent._searchMarker) { 5101 updateMarkerChanges(parent._searchMarker, startIndex, content.length); 5102 } 5103 return typeListInsertGenericsAfter(transaction, parent, n, content); 5104 }; 5105 var typeListPushGenerics = (transaction, parent, content) => { 5106 const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); 5107 let n = marker.p; 5108 if (n) { 5109 while (n.right) { 5110 n = n.right; 5111 } 5112 } 5113 return typeListInsertGenericsAfter(transaction, parent, n, content); 5114 }; 5115 var typeListDelete = (transaction, parent, index, length3) => { 5116 if (length3 === 0) { 5117 return; 5118 } 5119 const startIndex = index; 5120 const startLength = length3; 5121 const marker = findMarker(parent, index); 5122 let n = parent._start; 5123 if (marker !== null) { 5124 n = marker.p; 5125 index -= marker.index; 5126 } 5127 for (; n !== null && index > 0; n = n.right) { 5128 if (!n.deleted && n.countable) { 5129 if (index < n.length) { 5130 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5131 } 5132 index -= n.length; 5133 } 5134 } 5135 while (length3 > 0 && n !== null) { 5136 if (!n.deleted) { 5137 if (length3 < n.length) { 5138 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length3)); 5139 } 5140 n.delete(transaction); 5141 length3 -= n.length; 5142 } 5143 n = n.right; 5144 } 5145 if (length3 > 0) { 5146 throw lengthExceeded(); 5147 } 5148 if (parent._searchMarker) { 5149 updateMarkerChanges( 5150 parent._searchMarker, 5151 startIndex, 5152 -startLength + length3 5153 /* in case we remove the above exception */ 5154 ); 5155 } 5156 }; 5157 var typeMapDelete = (transaction, parent, key) => { 5158 const c = parent._map.get(key); 5159 if (c !== void 0) { 5160 c.delete(transaction); 5161 } 5162 }; 5163 var typeMapSet = (transaction, parent, key, value) => { 5164 const left = parent._map.get(key) || null; 5165 const doc2 = transaction.doc; 5166 const ownClientId = doc2.clientID; 5167 let content; 5168 if (value == null) { 5169 content = new ContentAny([value]); 5170 } else { 5171 switch (value.constructor) { 5172 case Number: 5173 case Object: 5174 case Boolean: 5175 case Array: 5176 case String: 5177 case Date: 5178 case BigInt: 5179 content = new ContentAny([value]); 5180 break; 5181 case Uint8Array: 5182 content = new ContentBinary( 5183 /** @type {Uint8Array} */ 5184 value 5185 ); 5186 break; 5187 case Doc: 5188 content = new ContentDoc( 5189 /** @type {Doc} */ 5190 value 5191 ); 5192 break; 5193 default: 5194 if (value instanceof AbstractType) { 5195 content = new ContentType(value); 5196 } else { 5197 throw new Error("Unexpected content type"); 5198 } 5199 } 5200 } 5201 new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); 5202 }; 5203 var typeMapGet = (parent, key) => { 5204 parent.doc ?? warnPrematureAccess(); 5205 const val = parent._map.get(key); 5206 return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; 5207 }; 5208 var typeMapGetAll = (parent) => { 5209 const res = {}; 5210 parent.doc ?? warnPrematureAccess(); 5211 parent._map.forEach((value, key) => { 5212 if (!value.deleted) { 5213 res[key] = value.content.getContent()[value.length - 1]; 5214 } 5215 }); 5216 return res; 5217 }; 5218 var typeMapHas = (parent, key) => { 5219 parent.doc ?? warnPrematureAccess(); 5220 const val = parent._map.get(key); 5221 return val !== void 0 && !val.deleted; 5222 }; 5223 var typeMapGetSnapshot = (parent, key, snapshot2) => { 5224 let v = parent._map.get(key) || null; 5225 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 5226 v = v.left; 5227 } 5228 return v !== null && isVisible(v, snapshot2) ? v.content.getContent()[v.length - 1] : void 0; 5229 }; 5230 var typeMapGetAllSnapshot = (parent, snapshot2) => { 5231 const res = {}; 5232 parent._map.forEach((value, key) => { 5233 let v = value; 5234 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 5235 v = v.left; 5236 } 5237 if (v !== null && isVisible(v, snapshot2)) { 5238 res[key] = v.content.getContent()[v.length - 1]; 5239 } 5240 }); 5241 return res; 5242 }; 5243 var createMapIterator = (type) => { 5244 type.doc ?? warnPrematureAccess(); 5245 return iteratorFilter( 5246 type._map.entries(), 5247 /** @param {any} entry */ 5248 (entry) => !entry[1].deleted 5249 ); 5250 }; 5251 var YArrayEvent = class extends YEvent { 5252 }; 5253 var YArray = class _YArray extends AbstractType { 5254 constructor() { 5255 super(); 5256 this._prelimContent = []; 5257 this._searchMarker = []; 5258 } 5259 /** 5260 * Construct a new YArray containing the specified items. 5261 * @template {Object<string,any>|Array<any>|number|null|string|Uint8Array} T 5262 * @param {Array<T>} items 5263 * @return {YArray<T>} 5264 */ 5265 static from(items) { 5266 const a = new _YArray(); 5267 a.push(items); 5268 return a; 5269 } 5270 /** 5271 * Integrate this type into the Yjs instance. 5272 * 5273 * * Save this struct in the os 5274 * * This type is sent to other client 5275 * * Observer functions are fired 5276 * 5277 * @param {Doc} y The Yjs instance 5278 * @param {Item} item 5279 */ 5280 _integrate(y, item) { 5281 super._integrate(y, item); 5282 this.insert( 5283 0, 5284 /** @type {Array<any>} */ 5285 this._prelimContent 5286 ); 5287 this._prelimContent = null; 5288 } 5289 /** 5290 * @return {YArray<T>} 5291 */ 5292 _copy() { 5293 return new _YArray(); 5294 } 5295 /** 5296 * Makes a copy of this data type that can be included somewhere else. 5297 * 5298 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 5299 * 5300 * @return {YArray<T>} 5301 */ 5302 clone() { 5303 const arr = new _YArray(); 5304 arr.insert(0, this.toArray().map( 5305 (el) => el instanceof AbstractType ? ( 5306 /** @type {typeof el} */ 5307 el.clone() 5308 ) : el 5309 )); 5310 return arr; 5311 } 5312 get length() { 5313 this.doc ?? warnPrematureAccess(); 5314 return this._length; 5315 } 5316 /** 5317 * Creates YArrayEvent and calls observers. 5318 * 5319 * @param {Transaction} transaction 5320 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 5321 */ 5322 _callObserver(transaction, parentSubs) { 5323 super._callObserver(transaction, parentSubs); 5324 callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); 5325 } 5326 /** 5327 * Inserts new content at an index. 5328 * 5329 * Important: This function expects an array of content. Not just a content 5330 * object. The reason for this "weirdness" is that inserting several elements 5331 * is very efficient when it is done as a single operation. 5332 * 5333 * @example 5334 * // Insert character 'a' at position 0 5335 * yarray.insert(0, ['a']) 5336 * // Insert numbers 1, 2 at position 1 5337 * yarray.insert(1, [1, 2]) 5338 * 5339 * @param {number} index The index to insert content at. 5340 * @param {Array<T>} content The array of content 5341 */ 5342 insert(index, content) { 5343 if (this.doc !== null) { 5344 transact(this.doc, (transaction) => { 5345 typeListInsertGenerics( 5346 transaction, 5347 this, 5348 index, 5349 /** @type {any} */ 5350 content 5351 ); 5352 }); 5353 } else { 5354 this._prelimContent.splice(index, 0, ...content); 5355 } 5356 } 5357 /** 5358 * Appends content to this YArray. 5359 * 5360 * @param {Array<T>} content Array of content to append. 5361 * 5362 * @todo Use the following implementation in all types. 5363 */ 5364 push(content) { 5365 if (this.doc !== null) { 5366 transact(this.doc, (transaction) => { 5367 typeListPushGenerics( 5368 transaction, 5369 this, 5370 /** @type {any} */ 5371 content 5372 ); 5373 }); 5374 } else { 5375 this._prelimContent.push(...content); 5376 } 5377 } 5378 /** 5379 * Prepends content to this YArray. 5380 * 5381 * @param {Array<T>} content Array of content to prepend. 5382 */ 5383 unshift(content) { 5384 this.insert(0, content); 5385 } 5386 /** 5387 * Deletes elements starting from an index. 5388 * 5389 * @param {number} index Index at which to start deleting elements 5390 * @param {number} length The number of elements to remove. Defaults to 1. 5391 */ 5392 delete(index, length3 = 1) { 5393 if (this.doc !== null) { 5394 transact(this.doc, (transaction) => { 5395 typeListDelete(transaction, this, index, length3); 5396 }); 5397 } else { 5398 this._prelimContent.splice(index, length3); 5399 } 5400 } 5401 /** 5402 * Returns the i-th element from a YArray. 5403 * 5404 * @param {number} index The index of the element to return from the YArray 5405 * @return {T} 5406 */ 5407 get(index) { 5408 return typeListGet(this, index); 5409 } 5410 /** 5411 * Transforms this YArray to a JavaScript Array. 5412 * 5413 * @return {Array<T>} 5414 */ 5415 toArray() { 5416 return typeListToArray(this); 5417 } 5418 /** 5419 * Returns a portion of this YArray into a JavaScript Array selected 5420 * from start to end (end not included). 5421 * 5422 * @param {number} [start] 5423 * @param {number} [end] 5424 * @return {Array<T>} 5425 */ 5426 slice(start = 0, end = this.length) { 5427 return typeListSlice(this, start, end); 5428 } 5429 /** 5430 * Transforms this Shared Type to a JSON object. 5431 * 5432 * @return {Array<any>} 5433 */ 5434 toJSON() { 5435 return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); 5436 } 5437 /** 5438 * Returns an Array with the result of calling a provided function on every 5439 * element of this YArray. 5440 * 5441 * @template M 5442 * @param {function(T,number,YArray<T>):M} f Function that produces an element of the new Array 5443 * @return {Array<M>} A new array with each element being the result of the 5444 * callback function 5445 */ 5446 map(f) { 5447 return typeListMap( 5448 this, 5449 /** @type {any} */ 5450 f 5451 ); 5452 } 5453 /** 5454 * Executes a provided function once on every element of this YArray. 5455 * 5456 * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray. 5457 */ 5458 forEach(f) { 5459 typeListForEach(this, f); 5460 } 5461 /** 5462 * @return {IterableIterator<T>} 5463 */ 5464 [Symbol.iterator]() { 5465 return typeListCreateIterator(this); 5466 } 5467 /** 5468 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 5469 */ 5470 _write(encoder) { 5471 encoder.writeTypeRef(YArrayRefID); 5472 } 5473 }; 5474 var readYArray = (_decoder) => new YArray(); 5475 var YMapEvent = class extends YEvent { 5476 /** 5477 * @param {YMap<T>} ymap The YArray that changed. 5478 * @param {Transaction} transaction 5479 * @param {Set<any>} subs The keys that changed. 5480 */ 5481 constructor(ymap, transaction, subs) { 5482 super(ymap, transaction); 5483 this.keysChanged = subs; 5484 } 5485 }; 5486 var YMap = class _YMap extends AbstractType { 5487 /** 5488 * 5489 * @param {Iterable<readonly [string, any]>=} entries - an optional iterable to initialize the YMap 5490 */ 5491 constructor(entries) { 5492 super(); 5493 this._prelimContent = null; 5494 if (entries === void 0) { 5495 this._prelimContent = /* @__PURE__ */ new Map(); 5496 } else { 5497 this._prelimContent = new Map(entries); 5498 } 5499 } 5500 /** 5501 * Integrate this type into the Yjs instance. 5502 * 5503 * * Save this struct in the os 5504 * * This type is sent to other client 5505 * * Observer functions are fired 5506 * 5507 * @param {Doc} y The Yjs instance 5508 * @param {Item} item 5509 */ 5510 _integrate(y, item) { 5511 super._integrate(y, item); 5512 this._prelimContent.forEach((value, key) => { 5513 this.set(key, value); 5514 }); 5515 this._prelimContent = null; 5516 } 5517 /** 5518 * @return {YMap<MapType>} 5519 */ 5520 _copy() { 5521 return new _YMap(); 5522 } 5523 /** 5524 * Makes a copy of this data type that can be included somewhere else. 5525 * 5526 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 5527 * 5528 * @return {YMap<MapType>} 5529 */ 5530 clone() { 5531 const map2 = new _YMap(); 5532 this.forEach((value, key) => { 5533 map2.set(key, value instanceof AbstractType ? ( 5534 /** @type {typeof value} */ 5535 value.clone() 5536 ) : value); 5537 }); 5538 return map2; 5539 } 5540 /** 5541 * Creates YMapEvent and calls observers. 5542 * 5543 * @param {Transaction} transaction 5544 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 5545 */ 5546 _callObserver(transaction, parentSubs) { 5547 callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); 5548 } 5549 /** 5550 * Transforms this Shared Type to a JSON object. 5551 * 5552 * @return {Object<string,any>} 5553 */ 5554 toJSON() { 5555 this.doc ?? warnPrematureAccess(); 5556 const map2 = {}; 5557 this._map.forEach((item, key) => { 5558 if (!item.deleted) { 5559 const v = item.content.getContent()[item.length - 1]; 5560 map2[key] = v instanceof AbstractType ? v.toJSON() : v; 5561 } 5562 }); 5563 return map2; 5564 } 5565 /** 5566 * Returns the size of the YMap (count of key/value pairs) 5567 * 5568 * @return {number} 5569 */ 5570 get size() { 5571 return [...createMapIterator(this)].length; 5572 } 5573 /** 5574 * Returns the keys for each element in the YMap Type. 5575 * 5576 * @return {IterableIterator<string>} 5577 */ 5578 keys() { 5579 return iteratorMap( 5580 createMapIterator(this), 5581 /** @param {any} v */ 5582 (v) => v[0] 5583 ); 5584 } 5585 /** 5586 * Returns the values for each element in the YMap Type. 5587 * 5588 * @return {IterableIterator<MapType>} 5589 */ 5590 values() { 5591 return iteratorMap( 5592 createMapIterator(this), 5593 /** @param {any} v */ 5594 (v) => v[1].content.getContent()[v[1].length - 1] 5595 ); 5596 } 5597 /** 5598 * Returns an Iterator of [key, value] pairs 5599 * 5600 * @return {IterableIterator<[string, MapType]>} 5601 */ 5602 entries() { 5603 return iteratorMap( 5604 createMapIterator(this), 5605 /** @param {any} v */ 5606 (v) => ( 5607 /** @type {any} */ 5608 [v[0], v[1].content.getContent()[v[1].length - 1]] 5609 ) 5610 ); 5611 } 5612 /** 5613 * Executes a provided function on once on every key-value pair. 5614 * 5615 * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray. 5616 */ 5617 forEach(f) { 5618 this.doc ?? warnPrematureAccess(); 5619 this._map.forEach((item, key) => { 5620 if (!item.deleted) { 5621 f(item.content.getContent()[item.length - 1], key, this); 5622 } 5623 }); 5624 } 5625 /** 5626 * Returns an Iterator of [key, value] pairs 5627 * 5628 * @return {IterableIterator<[string, MapType]>} 5629 */ 5630 [Symbol.iterator]() { 5631 return this.entries(); 5632 } 5633 /** 5634 * Remove a specified element from this YMap. 5635 * 5636 * @param {string} key The key of the element to remove. 5637 */ 5638 delete(key) { 5639 if (this.doc !== null) { 5640 transact(this.doc, (transaction) => { 5641 typeMapDelete(transaction, this, key); 5642 }); 5643 } else { 5644 this._prelimContent.delete(key); 5645 } 5646 } 5647 /** 5648 * Adds or updates an element with a specified key and value. 5649 * @template {MapType} VAL 5650 * 5651 * @param {string} key The key of the element to add to this YMap 5652 * @param {VAL} value The value of the element to add 5653 * @return {VAL} 5654 */ 5655 set(key, value) { 5656 if (this.doc !== null) { 5657 transact(this.doc, (transaction) => { 5658 typeMapSet( 5659 transaction, 5660 this, 5661 key, 5662 /** @type {any} */ 5663 value 5664 ); 5665 }); 5666 } else { 5667 this._prelimContent.set(key, value); 5668 } 5669 return value; 5670 } 5671 /** 5672 * Returns a specified element from this YMap. 5673 * 5674 * @param {string} key 5675 * @return {MapType|undefined} 5676 */ 5677 get(key) { 5678 return ( 5679 /** @type {any} */ 5680 typeMapGet(this, key) 5681 ); 5682 } 5683 /** 5684 * Returns a boolean indicating whether the specified key exists or not. 5685 * 5686 * @param {string} key The key to test. 5687 * @return {boolean} 5688 */ 5689 has(key) { 5690 return typeMapHas(this, key); 5691 } 5692 /** 5693 * Removes all elements from this YMap. 5694 */ 5695 clear() { 5696 if (this.doc !== null) { 5697 transact(this.doc, (transaction) => { 5698 this.forEach(function(_value, key, map2) { 5699 typeMapDelete(transaction, map2, key); 5700 }); 5701 }); 5702 } else { 5703 this._prelimContent.clear(); 5704 } 5705 } 5706 /** 5707 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 5708 */ 5709 _write(encoder) { 5710 encoder.writeTypeRef(YMapRefID); 5711 } 5712 }; 5713 var readYMap = (_decoder) => new YMap(); 5714 var equalAttrs = (a, b) => a === b || typeof a === "object" && typeof b === "object" && a && b && equalFlat(a, b); 5715 var ItemTextListPosition = class { 5716 /** 5717 * @param {Item|null} left 5718 * @param {Item|null} right 5719 * @param {number} index 5720 * @param {Map<string,any>} currentAttributes 5721 */ 5722 constructor(left, right, index, currentAttributes) { 5723 this.left = left; 5724 this.right = right; 5725 this.index = index; 5726 this.currentAttributes = currentAttributes; 5727 } 5728 /** 5729 * Only call this if you know that this.right is defined 5730 */ 5731 forward() { 5732 if (this.right === null) { 5733 unexpectedCase(); 5734 } 5735 switch (this.right.content.constructor) { 5736 case ContentFormat: 5737 if (!this.right.deleted) { 5738 updateCurrentAttributes( 5739 this.currentAttributes, 5740 /** @type {ContentFormat} */ 5741 this.right.content 5742 ); 5743 } 5744 break; 5745 default: 5746 if (!this.right.deleted) { 5747 this.index += this.right.length; 5748 } 5749 break; 5750 } 5751 this.left = this.right; 5752 this.right = this.right.right; 5753 } 5754 }; 5755 var findNextPosition = (transaction, pos, count) => { 5756 while (pos.right !== null && count > 0) { 5757 switch (pos.right.content.constructor) { 5758 case ContentFormat: 5759 if (!pos.right.deleted) { 5760 updateCurrentAttributes( 5761 pos.currentAttributes, 5762 /** @type {ContentFormat} */ 5763 pos.right.content 5764 ); 5765 } 5766 break; 5767 default: 5768 if (!pos.right.deleted) { 5769 if (count < pos.right.length) { 5770 getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); 5771 } 5772 pos.index += pos.right.length; 5773 count -= pos.right.length; 5774 } 5775 break; 5776 } 5777 pos.left = pos.right; 5778 pos.right = pos.right.right; 5779 } 5780 return pos; 5781 }; 5782 var findPosition = (transaction, parent, index, useSearchMarker) => { 5783 const currentAttributes = /* @__PURE__ */ new Map(); 5784 const marker = useSearchMarker ? findMarker(parent, index) : null; 5785 if (marker) { 5786 const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); 5787 return findNextPosition(transaction, pos, index - marker.index); 5788 } else { 5789 const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); 5790 return findNextPosition(transaction, pos, index); 5791 } 5792 }; 5793 var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { 5794 while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( 5795 negatedAttributes.get( 5796 /** @type {ContentFormat} */ 5797 currPos.right.content.key 5798 ), 5799 /** @type {ContentFormat} */ 5800 currPos.right.content.value 5801 ))) { 5802 if (!currPos.right.deleted) { 5803 negatedAttributes.delete( 5804 /** @type {ContentFormat} */ 5805 currPos.right.content.key 5806 ); 5807 } 5808 currPos.forward(); 5809 } 5810 const doc2 = transaction.doc; 5811 const ownClientId = doc2.clientID; 5812 negatedAttributes.forEach((val, key) => { 5813 const left = currPos.left; 5814 const right = currPos.right; 5815 const nextFormat = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 5816 nextFormat.integrate(transaction, 0); 5817 currPos.right = nextFormat; 5818 currPos.forward(); 5819 }); 5820 }; 5821 var updateCurrentAttributes = (currentAttributes, format) => { 5822 const { key, value } = format; 5823 if (value === null) { 5824 currentAttributes.delete(key); 5825 } else { 5826 currentAttributes.set(key, value); 5827 } 5828 }; 5829 var minimizeAttributeChanges = (currPos, attributes) => { 5830 while (true) { 5831 if (currPos.right === null) { 5832 break; 5833 } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( 5834 attributes[ 5835 /** @type {ContentFormat} */ 5836 currPos.right.content.key 5837 ] ?? null, 5838 /** @type {ContentFormat} */ 5839 currPos.right.content.value 5840 )) ; 5841 else { 5842 break; 5843 } 5844 currPos.forward(); 5845 } 5846 }; 5847 var insertAttributes = (transaction, parent, currPos, attributes) => { 5848 const doc2 = transaction.doc; 5849 const ownClientId = doc2.clientID; 5850 const negatedAttributes = /* @__PURE__ */ new Map(); 5851 for (const key in attributes) { 5852 const val = attributes[key]; 5853 const currentVal = currPos.currentAttributes.get(key) ?? null; 5854 if (!equalAttrs(currentVal, val)) { 5855 negatedAttributes.set(key, currentVal); 5856 const { left, right } = currPos; 5857 currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 5858 currPos.right.integrate(transaction, 0); 5859 currPos.forward(); 5860 } 5861 } 5862 return negatedAttributes; 5863 }; 5864 var insertText = (transaction, parent, currPos, text2, attributes) => { 5865 currPos.currentAttributes.forEach((_val, key) => { 5866 if (attributes[key] === void 0) { 5867 attributes[key] = null; 5868 } 5869 }); 5870 const doc2 = transaction.doc; 5871 const ownClientId = doc2.clientID; 5872 minimizeAttributeChanges(currPos, attributes); 5873 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 5874 const content = text2.constructor === String ? new ContentString( 5875 /** @type {string} */ 5876 text2 5877 ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); 5878 let { left, right, index } = currPos; 5879 if (parent._searchMarker) { 5880 updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); 5881 } 5882 right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); 5883 right.integrate(transaction, 0); 5884 currPos.right = right; 5885 currPos.index = index; 5886 currPos.forward(); 5887 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 5888 }; 5889 var formatText = (transaction, parent, currPos, length3, attributes) => { 5890 const doc2 = transaction.doc; 5891 const ownClientId = doc2.clientID; 5892 minimizeAttributeChanges(currPos, attributes); 5893 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 5894 iterationLoop: while (currPos.right !== null && (length3 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { 5895 if (!currPos.right.deleted) { 5896 switch (currPos.right.content.constructor) { 5897 case ContentFormat: { 5898 const { key, value } = ( 5899 /** @type {ContentFormat} */ 5900 currPos.right.content 5901 ); 5902 const attr = attributes[key]; 5903 if (attr !== void 0) { 5904 if (equalAttrs(attr, value)) { 5905 negatedAttributes.delete(key); 5906 } else { 5907 if (length3 === 0) { 5908 break iterationLoop; 5909 } 5910 negatedAttributes.set(key, value); 5911 } 5912 currPos.right.delete(transaction); 5913 } else { 5914 currPos.currentAttributes.set(key, value); 5915 } 5916 break; 5917 } 5918 default: 5919 if (length3 < currPos.right.length) { 5920 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length3)); 5921 } 5922 length3 -= currPos.right.length; 5923 break; 5924 } 5925 } 5926 currPos.forward(); 5927 } 5928 if (length3 > 0) { 5929 let newlines = ""; 5930 for (; length3 > 0; length3--) { 5931 newlines += "\n"; 5932 } 5933 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)); 5934 currPos.right.integrate(transaction, 0); 5935 currPos.forward(); 5936 } 5937 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 5938 }; 5939 var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { 5940 let end = start; 5941 const endFormats = create(); 5942 while (end && (!end.countable || end.deleted)) { 5943 if (!end.deleted && end.content.constructor === ContentFormat) { 5944 const cf = ( 5945 /** @type {ContentFormat} */ 5946 end.content 5947 ); 5948 endFormats.set(cf.key, cf); 5949 } 5950 end = end.right; 5951 } 5952 let cleanups = 0; 5953 let reachedCurr = false; 5954 while (start !== end) { 5955 if (curr === start) { 5956 reachedCurr = true; 5957 } 5958 if (!start.deleted) { 5959 const content = start.content; 5960 switch (content.constructor) { 5961 case ContentFormat: { 5962 const { key, value } = ( 5963 /** @type {ContentFormat} */ 5964 content 5965 ); 5966 const startAttrValue = startAttributes.get(key) ?? null; 5967 if (endFormats.get(key) !== content || startAttrValue === value) { 5968 start.delete(transaction); 5969 cleanups++; 5970 if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { 5971 if (startAttrValue === null) { 5972 currAttributes.delete(key); 5973 } else { 5974 currAttributes.set(key, startAttrValue); 5975 } 5976 } 5977 } 5978 if (!reachedCurr && !start.deleted) { 5979 updateCurrentAttributes( 5980 currAttributes, 5981 /** @type {ContentFormat} */ 5982 content 5983 ); 5984 } 5985 break; 5986 } 5987 } 5988 } 5989 start = /** @type {Item} */ 5990 start.right; 5991 } 5992 return cleanups; 5993 }; 5994 var cleanupContextlessFormattingGap = (transaction, item) => { 5995 while (item && item.right && (item.right.deleted || !item.right.countable)) { 5996 item = item.right; 5997 } 5998 const attrs = /* @__PURE__ */ new Set(); 5999 while (item && (item.deleted || !item.countable)) { 6000 if (!item.deleted && item.content.constructor === ContentFormat) { 6001 const key = ( 6002 /** @type {ContentFormat} */ 6003 item.content.key 6004 ); 6005 if (attrs.has(key)) { 6006 item.delete(transaction); 6007 } else { 6008 attrs.add(key); 6009 } 6010 } 6011 item = item.left; 6012 } 6013 }; 6014 var cleanupYTextFormatting = (type) => { 6015 let res = 0; 6016 transact( 6017 /** @type {Doc} */ 6018 type.doc, 6019 (transaction) => { 6020 let start = ( 6021 /** @type {Item} */ 6022 type._start 6023 ); 6024 let end = type._start; 6025 let startAttributes = create(); 6026 const currentAttributes = copy(startAttributes); 6027 while (end) { 6028 if (end.deleted === false) { 6029 switch (end.content.constructor) { 6030 case ContentFormat: 6031 updateCurrentAttributes( 6032 currentAttributes, 6033 /** @type {ContentFormat} */ 6034 end.content 6035 ); 6036 break; 6037 default: 6038 res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); 6039 startAttributes = copy(currentAttributes); 6040 start = end; 6041 break; 6042 } 6043 } 6044 end = end.right; 6045 } 6046 } 6047 ); 6048 return res; 6049 }; 6050 var cleanupYTextAfterTransaction = (transaction) => { 6051 const needFullCleanup = /* @__PURE__ */ new Set(); 6052 const doc2 = transaction.doc; 6053 for (const [client, afterClock] of transaction.afterState.entries()) { 6054 const clock = transaction.beforeState.get(client) || 0; 6055 if (afterClock === clock) { 6056 continue; 6057 } 6058 iterateStructs( 6059 transaction, 6060 /** @type {Array<Item|GC>} */ 6061 doc2.store.clients.get(client), 6062 clock, 6063 afterClock, 6064 (item) => { 6065 if (!item.deleted && /** @type {Item} */ 6066 item.content.constructor === ContentFormat && item.constructor !== GC) { 6067 needFullCleanup.add( 6068 /** @type {any} */ 6069 item.parent 6070 ); 6071 } 6072 } 6073 ); 6074 } 6075 transact(doc2, (t) => { 6076 iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { 6077 if (item instanceof GC || !/** @type {YText} */ 6078 item.parent._hasFormatting || needFullCleanup.has( 6079 /** @type {YText} */ 6080 item.parent 6081 )) { 6082 return; 6083 } 6084 const parent = ( 6085 /** @type {YText} */ 6086 item.parent 6087 ); 6088 if (item.content.constructor === ContentFormat) { 6089 needFullCleanup.add(parent); 6090 } else { 6091 cleanupContextlessFormattingGap(t, item); 6092 } 6093 }); 6094 for (const yText of needFullCleanup) { 6095 cleanupYTextFormatting(yText); 6096 } 6097 }); 6098 }; 6099 var deleteText = (transaction, currPos, length3) => { 6100 const startLength = length3; 6101 const startAttrs = copy(currPos.currentAttributes); 6102 const start = currPos.right; 6103 while (length3 > 0 && currPos.right !== null) { 6104 if (currPos.right.deleted === false) { 6105 switch (currPos.right.content.constructor) { 6106 case ContentType: 6107 case ContentEmbed: 6108 case ContentString: 6109 if (length3 < currPos.right.length) { 6110 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length3)); 6111 } 6112 length3 -= currPos.right.length; 6113 currPos.right.delete(transaction); 6114 break; 6115 } 6116 } 6117 currPos.forward(); 6118 } 6119 if (start) { 6120 cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); 6121 } 6122 const parent = ( 6123 /** @type {AbstractType<any>} */ 6124 /** @type {Item} */ 6125 (currPos.left || currPos.right).parent 6126 ); 6127 if (parent._searchMarker) { 6128 updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length3); 6129 } 6130 return currPos; 6131 }; 6132 var YTextEvent = class extends YEvent { 6133 /** 6134 * @param {YText} ytext 6135 * @param {Transaction} transaction 6136 * @param {Set<any>} subs The keys that changed 6137 */ 6138 constructor(ytext, transaction, subs) { 6139 super(ytext, transaction); 6140 this.childListChanged = false; 6141 this.keysChanged = /* @__PURE__ */ new Set(); 6142 subs.forEach((sub) => { 6143 if (sub === null) { 6144 this.childListChanged = true; 6145 } else { 6146 this.keysChanged.add(sub); 6147 } 6148 }); 6149 } 6150 /** 6151 * @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}>}} 6152 */ 6153 get changes() { 6154 if (this._changes === null) { 6155 const changes = { 6156 keys: this.keys, 6157 delta: this.delta, 6158 added: /* @__PURE__ */ new Set(), 6159 deleted: /* @__PURE__ */ new Set() 6160 }; 6161 this._changes = changes; 6162 } 6163 return ( 6164 /** @type {any} */ 6165 this._changes 6166 ); 6167 } 6168 /** 6169 * Compute the changes in the delta format. 6170 * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. 6171 * 6172 * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>} 6173 * 6174 * @public 6175 */ 6176 get delta() { 6177 if (this._delta === null) { 6178 const y = ( 6179 /** @type {Doc} */ 6180 this.target.doc 6181 ); 6182 const delta = []; 6183 transact(y, (transaction) => { 6184 const currentAttributes = /* @__PURE__ */ new Map(); 6185 const oldAttributes = /* @__PURE__ */ new Map(); 6186 let item = this.target._start; 6187 let action = null; 6188 const attributes = {}; 6189 let insert = ""; 6190 let retain = 0; 6191 let deleteLen = 0; 6192 const addOp = () => { 6193 if (action !== null) { 6194 let op = null; 6195 switch (action) { 6196 case "delete": 6197 if (deleteLen > 0) { 6198 op = { delete: deleteLen }; 6199 } 6200 deleteLen = 0; 6201 break; 6202 case "insert": 6203 if (typeof insert === "object" || insert.length > 0) { 6204 op = { insert }; 6205 if (currentAttributes.size > 0) { 6206 op.attributes = {}; 6207 currentAttributes.forEach((value, key) => { 6208 if (value !== null) { 6209 op.attributes[key] = value; 6210 } 6211 }); 6212 } 6213 } 6214 insert = ""; 6215 break; 6216 case "retain": 6217 if (retain > 0) { 6218 op = { retain }; 6219 if (!isEmpty(attributes)) { 6220 op.attributes = assign({}, attributes); 6221 } 6222 } 6223 retain = 0; 6224 break; 6225 } 6226 if (op) delta.push(op); 6227 action = null; 6228 } 6229 }; 6230 while (item !== null) { 6231 switch (item.content.constructor) { 6232 case ContentType: 6233 case ContentEmbed: 6234 if (this.adds(item)) { 6235 if (!this.deletes(item)) { 6236 addOp(); 6237 action = "insert"; 6238 insert = item.content.getContent()[0]; 6239 addOp(); 6240 } 6241 } else if (this.deletes(item)) { 6242 if (action !== "delete") { 6243 addOp(); 6244 action = "delete"; 6245 } 6246 deleteLen += 1; 6247 } else if (!item.deleted) { 6248 if (action !== "retain") { 6249 addOp(); 6250 action = "retain"; 6251 } 6252 retain += 1; 6253 } 6254 break; 6255 case ContentString: 6256 if (this.adds(item)) { 6257 if (!this.deletes(item)) { 6258 if (action !== "insert") { 6259 addOp(); 6260 action = "insert"; 6261 } 6262 insert += /** @type {ContentString} */ 6263 item.content.str; 6264 } 6265 } else if (this.deletes(item)) { 6266 if (action !== "delete") { 6267 addOp(); 6268 action = "delete"; 6269 } 6270 deleteLen += item.length; 6271 } else if (!item.deleted) { 6272 if (action !== "retain") { 6273 addOp(); 6274 action = "retain"; 6275 } 6276 retain += item.length; 6277 } 6278 break; 6279 case ContentFormat: { 6280 const { key, value } = ( 6281 /** @type {ContentFormat} */ 6282 item.content 6283 ); 6284 if (this.adds(item)) { 6285 if (!this.deletes(item)) { 6286 const curVal = currentAttributes.get(key) ?? null; 6287 if (!equalAttrs(curVal, value)) { 6288 if (action === "retain") { 6289 addOp(); 6290 } 6291 if (equalAttrs(value, oldAttributes.get(key) ?? null)) { 6292 delete attributes[key]; 6293 } else { 6294 attributes[key] = value; 6295 } 6296 } else if (value !== null) { 6297 item.delete(transaction); 6298 } 6299 } 6300 } else if (this.deletes(item)) { 6301 oldAttributes.set(key, value); 6302 const curVal = currentAttributes.get(key) ?? null; 6303 if (!equalAttrs(curVal, value)) { 6304 if (action === "retain") { 6305 addOp(); 6306 } 6307 attributes[key] = curVal; 6308 } 6309 } else if (!item.deleted) { 6310 oldAttributes.set(key, value); 6311 const attr = attributes[key]; 6312 if (attr !== void 0) { 6313 if (!equalAttrs(attr, value)) { 6314 if (action === "retain") { 6315 addOp(); 6316 } 6317 if (value === null) { 6318 delete attributes[key]; 6319 } else { 6320 attributes[key] = value; 6321 } 6322 } else if (attr !== null) { 6323 item.delete(transaction); 6324 } 6325 } 6326 } 6327 if (!item.deleted) { 6328 if (action === "insert") { 6329 addOp(); 6330 } 6331 updateCurrentAttributes( 6332 currentAttributes, 6333 /** @type {ContentFormat} */ 6334 item.content 6335 ); 6336 } 6337 break; 6338 } 6339 } 6340 item = item.right; 6341 } 6342 addOp(); 6343 while (delta.length > 0) { 6344 const lastOp = delta[delta.length - 1]; 6345 if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { 6346 delta.pop(); 6347 } else { 6348 break; 6349 } 6350 } 6351 }); 6352 this._delta = delta; 6353 } 6354 return ( 6355 /** @type {any} */ 6356 this._delta 6357 ); 6358 } 6359 }; 6360 var YText = class _YText extends AbstractType { 6361 /** 6362 * @param {String} [string] The initial value of the YText. 6363 */ 6364 constructor(string) { 6365 super(); 6366 this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; 6367 this._searchMarker = []; 6368 this._hasFormatting = false; 6369 } 6370 /** 6371 * Number of characters of this text type. 6372 * 6373 * @type {number} 6374 */ 6375 get length() { 6376 this.doc ?? warnPrematureAccess(); 6377 return this._length; 6378 } 6379 /** 6380 * @param {Doc} y 6381 * @param {Item} item 6382 */ 6383 _integrate(y, item) { 6384 super._integrate(y, item); 6385 try { 6386 this._pending.forEach((f) => f()); 6387 } catch (e) { 6388 console.error(e); 6389 } 6390 this._pending = null; 6391 } 6392 _copy() { 6393 return new _YText(); 6394 } 6395 /** 6396 * Makes a copy of this data type that can be included somewhere else. 6397 * 6398 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6399 * 6400 * @return {YText} 6401 */ 6402 clone() { 6403 const text2 = new _YText(); 6404 text2.applyDelta(this.toDelta()); 6405 return text2; 6406 } 6407 /** 6408 * Creates YTextEvent and calls observers. 6409 * 6410 * @param {Transaction} transaction 6411 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6412 */ 6413 _callObserver(transaction, parentSubs) { 6414 super._callObserver(transaction, parentSubs); 6415 const event = new YTextEvent(this, transaction, parentSubs); 6416 callTypeObservers(this, transaction, event); 6417 if (!transaction.local && this._hasFormatting) { 6418 transaction._needFormattingCleanup = true; 6419 } 6420 } 6421 /** 6422 * Returns the unformatted string representation of this YText type. 6423 * 6424 * @public 6425 */ 6426 toString() { 6427 this.doc ?? warnPrematureAccess(); 6428 let str = ""; 6429 let n = this._start; 6430 while (n !== null) { 6431 if (!n.deleted && n.countable && n.content.constructor === ContentString) { 6432 str += /** @type {ContentString} */ 6433 n.content.str; 6434 } 6435 n = n.right; 6436 } 6437 return str; 6438 } 6439 /** 6440 * Returns the unformatted string representation of this YText type. 6441 * 6442 * @return {string} 6443 * @public 6444 */ 6445 toJSON() { 6446 return this.toString(); 6447 } 6448 /** 6449 * Apply a {@link Delta} on this shared YText type. 6450 * 6451 * @param {Array<any>} delta The changes to apply on this element. 6452 * @param {object} opts 6453 * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. 6454 * 6455 * 6456 * @public 6457 */ 6458 applyDelta(delta, { sanitize = true } = {}) { 6459 if (this.doc !== null) { 6460 transact(this.doc, (transaction) => { 6461 const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); 6462 for (let i = 0; i < delta.length; i++) { 6463 const op = delta[i]; 6464 if (op.insert !== void 0) { 6465 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; 6466 if (typeof ins !== "string" || ins.length > 0) { 6467 insertText(transaction, this, currPos, ins, op.attributes || {}); 6468 } 6469 } else if (op.retain !== void 0) { 6470 formatText(transaction, this, currPos, op.retain, op.attributes || {}); 6471 } else if (op.delete !== void 0) { 6472 deleteText(transaction, currPos, op.delete); 6473 } 6474 } 6475 }); 6476 } else { 6477 this._pending.push(() => this.applyDelta(delta)); 6478 } 6479 } 6480 /** 6481 * Returns the Delta representation of this YText type. 6482 * 6483 * @param {Snapshot} [snapshot] 6484 * @param {Snapshot} [prevSnapshot] 6485 * @param {function('removed' | 'added', ID):any} [computeYChange] 6486 * @return {any} The Delta representation of this type. 6487 * 6488 * @public 6489 */ 6490 toDelta(snapshot2, prevSnapshot, computeYChange) { 6491 this.doc ?? warnPrematureAccess(); 6492 const ops = []; 6493 const currentAttributes = /* @__PURE__ */ new Map(); 6494 const doc2 = ( 6495 /** @type {Doc} */ 6496 this.doc 6497 ); 6498 let str = ""; 6499 let n = this._start; 6500 function packStr() { 6501 if (str.length > 0) { 6502 const attributes = {}; 6503 let addAttributes = false; 6504 currentAttributes.forEach((value, key) => { 6505 addAttributes = true; 6506 attributes[key] = value; 6507 }); 6508 const op = { insert: str }; 6509 if (addAttributes) { 6510 op.attributes = attributes; 6511 } 6512 ops.push(op); 6513 str = ""; 6514 } 6515 } 6516 const computeDelta = () => { 6517 while (n !== null) { 6518 if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { 6519 switch (n.content.constructor) { 6520 case ContentString: { 6521 const cur = currentAttributes.get("ychange"); 6522 if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { 6523 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { 6524 packStr(); 6525 currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); 6526 } 6527 } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { 6528 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { 6529 packStr(); 6530 currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); 6531 } 6532 } else if (cur !== void 0) { 6533 packStr(); 6534 currentAttributes.delete("ychange"); 6535 } 6536 str += /** @type {ContentString} */ 6537 n.content.str; 6538 break; 6539 } 6540 case ContentType: 6541 case ContentEmbed: { 6542 packStr(); 6543 const op = { 6544 insert: n.content.getContent()[0] 6545 }; 6546 if (currentAttributes.size > 0) { 6547 const attrs = ( 6548 /** @type {Object<string,any>} */ 6549 {} 6550 ); 6551 op.attributes = attrs; 6552 currentAttributes.forEach((value, key) => { 6553 attrs[key] = value; 6554 }); 6555 } 6556 ops.push(op); 6557 break; 6558 } 6559 case ContentFormat: 6560 if (isVisible(n, snapshot2)) { 6561 packStr(); 6562 updateCurrentAttributes( 6563 currentAttributes, 6564 /** @type {ContentFormat} */ 6565 n.content 6566 ); 6567 } 6568 break; 6569 } 6570 } 6571 n = n.right; 6572 } 6573 packStr(); 6574 }; 6575 if (snapshot2 || prevSnapshot) { 6576 transact(doc2, (transaction) => { 6577 if (snapshot2) { 6578 splitSnapshotAffectedStructs(transaction, snapshot2); 6579 } 6580 if (prevSnapshot) { 6581 splitSnapshotAffectedStructs(transaction, prevSnapshot); 6582 } 6583 computeDelta(); 6584 }, "cleanup"); 6585 } else { 6586 computeDelta(); 6587 } 6588 return ops; 6589 } 6590 /** 6591 * Insert text at a given index. 6592 * 6593 * @param {number} index The index at which to start inserting. 6594 * @param {String} text The text to insert at the specified position. 6595 * @param {TextAttributes} [attributes] Optionally define some formatting 6596 * information to apply on the inserted 6597 * Text. 6598 * @public 6599 */ 6600 insert(index, text2, attributes) { 6601 if (text2.length <= 0) { 6602 return; 6603 } 6604 const y = this.doc; 6605 if (y !== null) { 6606 transact(y, (transaction) => { 6607 const pos = findPosition(transaction, this, index, !attributes); 6608 if (!attributes) { 6609 attributes = {}; 6610 pos.currentAttributes.forEach((v, k) => { 6611 attributes[k] = v; 6612 }); 6613 } 6614 insertText(transaction, this, pos, text2, attributes); 6615 }); 6616 } else { 6617 this._pending.push(() => this.insert(index, text2, attributes)); 6618 } 6619 } 6620 /** 6621 * Inserts an embed at a index. 6622 * 6623 * @param {number} index The index to insert the embed at. 6624 * @param {Object | AbstractType<any>} embed The Object that represents the embed. 6625 * @param {TextAttributes} [attributes] Attribute information to apply on the 6626 * embed 6627 * 6628 * @public 6629 */ 6630 insertEmbed(index, embed, attributes) { 6631 const y = this.doc; 6632 if (y !== null) { 6633 transact(y, (transaction) => { 6634 const pos = findPosition(transaction, this, index, !attributes); 6635 insertText(transaction, this, pos, embed, attributes || {}); 6636 }); 6637 } else { 6638 this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); 6639 } 6640 } 6641 /** 6642 * Deletes text starting from an index. 6643 * 6644 * @param {number} index Index at which to start deleting. 6645 * @param {number} length The number of characters to remove. Defaults to 1. 6646 * 6647 * @public 6648 */ 6649 delete(index, length3) { 6650 if (length3 === 0) { 6651 return; 6652 } 6653 const y = this.doc; 6654 if (y !== null) { 6655 transact(y, (transaction) => { 6656 deleteText(transaction, findPosition(transaction, this, index, true), length3); 6657 }); 6658 } else { 6659 this._pending.push(() => this.delete(index, length3)); 6660 } 6661 } 6662 /** 6663 * Assigns properties to a range of text. 6664 * 6665 * @param {number} index The position where to start formatting. 6666 * @param {number} length The amount of characters to assign properties to. 6667 * @param {TextAttributes} attributes Attribute information to apply on the 6668 * text. 6669 * 6670 * @public 6671 */ 6672 format(index, length3, attributes) { 6673 if (length3 === 0) { 6674 return; 6675 } 6676 const y = this.doc; 6677 if (y !== null) { 6678 transact(y, (transaction) => { 6679 const pos = findPosition(transaction, this, index, false); 6680 if (pos.right === null) { 6681 return; 6682 } 6683 formatText(transaction, this, pos, length3, attributes); 6684 }); 6685 } else { 6686 this._pending.push(() => this.format(index, length3, attributes)); 6687 } 6688 } 6689 /** 6690 * Removes an attribute. 6691 * 6692 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 6693 * 6694 * @param {String} attributeName The attribute name that is to be removed. 6695 * 6696 * @public 6697 */ 6698 removeAttribute(attributeName) { 6699 if (this.doc !== null) { 6700 transact(this.doc, (transaction) => { 6701 typeMapDelete(transaction, this, attributeName); 6702 }); 6703 } else { 6704 this._pending.push(() => this.removeAttribute(attributeName)); 6705 } 6706 } 6707 /** 6708 * Sets or updates an attribute. 6709 * 6710 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 6711 * 6712 * @param {String} attributeName The attribute name that is to be set. 6713 * @param {any} attributeValue The attribute value that is to be set. 6714 * 6715 * @public 6716 */ 6717 setAttribute(attributeName, attributeValue) { 6718 if (this.doc !== null) { 6719 transact(this.doc, (transaction) => { 6720 typeMapSet(transaction, this, attributeName, attributeValue); 6721 }); 6722 } else { 6723 this._pending.push(() => this.setAttribute(attributeName, attributeValue)); 6724 } 6725 } 6726 /** 6727 * Returns an attribute value that belongs to the attribute name. 6728 * 6729 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 6730 * 6731 * @param {String} attributeName The attribute name that identifies the 6732 * queried value. 6733 * @return {any} The queried attribute value. 6734 * 6735 * @public 6736 */ 6737 getAttribute(attributeName) { 6738 return ( 6739 /** @type {any} */ 6740 typeMapGet(this, attributeName) 6741 ); 6742 } 6743 /** 6744 * Returns all attribute name/value pairs in a JSON Object. 6745 * 6746 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 6747 * 6748 * @return {Object<string, any>} A JSON Object that describes the attributes. 6749 * 6750 * @public 6751 */ 6752 getAttributes() { 6753 return typeMapGetAll(this); 6754 } 6755 /** 6756 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6757 */ 6758 _write(encoder) { 6759 encoder.writeTypeRef(YTextRefID); 6760 } 6761 }; 6762 var readYText = (_decoder) => new YText(); 6763 var YXmlTreeWalker = class { 6764 /** 6765 * @param {YXmlFragment | YXmlElement} root 6766 * @param {function(AbstractType<any>):boolean} [f] 6767 */ 6768 constructor(root, f = () => true) { 6769 this._filter = f; 6770 this._root = root; 6771 this._currentNode = /** @type {Item} */ 6772 root._start; 6773 this._firstCall = true; 6774 root.doc ?? warnPrematureAccess(); 6775 } 6776 [Symbol.iterator]() { 6777 return this; 6778 } 6779 /** 6780 * Get the next node. 6781 * 6782 * @return {IteratorResult<YXmlElement|YXmlText|YXmlHook>} The next node. 6783 * 6784 * @public 6785 */ 6786 next() { 6787 let n = this._currentNode; 6788 let type = n && n.content && /** @type {any} */ 6789 n.content.type; 6790 if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { 6791 do { 6792 type = /** @type {any} */ 6793 n.content.type; 6794 if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { 6795 n = type._start; 6796 } else { 6797 while (n !== null) { 6798 const nxt = n.next; 6799 if (nxt !== null) { 6800 n = nxt; 6801 break; 6802 } else if (n.parent === this._root) { 6803 n = null; 6804 } else { 6805 n = /** @type {AbstractType<any>} */ 6806 n.parent._item; 6807 } 6808 } 6809 } 6810 } while (n !== null && (n.deleted || !this._filter( 6811 /** @type {ContentType} */ 6812 n.content.type 6813 ))); 6814 } 6815 this._firstCall = false; 6816 if (n === null) { 6817 return { value: void 0, done: true }; 6818 } 6819 this._currentNode = n; 6820 return { value: ( 6821 /** @type {any} */ 6822 n.content.type 6823 ), done: false }; 6824 } 6825 }; 6826 var YXmlFragment = class _YXmlFragment extends AbstractType { 6827 constructor() { 6828 super(); 6829 this._prelimContent = []; 6830 } 6831 /** 6832 * @type {YXmlElement|YXmlText|null} 6833 */ 6834 get firstChild() { 6835 const first = this._first; 6836 return first ? first.content.getContent()[0] : null; 6837 } 6838 /** 6839 * Integrate this type into the Yjs instance. 6840 * 6841 * * Save this struct in the os 6842 * * This type is sent to other client 6843 * * Observer functions are fired 6844 * 6845 * @param {Doc} y The Yjs instance 6846 * @param {Item} item 6847 */ 6848 _integrate(y, item) { 6849 super._integrate(y, item); 6850 this.insert( 6851 0, 6852 /** @type {Array<any>} */ 6853 this._prelimContent 6854 ); 6855 this._prelimContent = null; 6856 } 6857 _copy() { 6858 return new _YXmlFragment(); 6859 } 6860 /** 6861 * Makes a copy of this data type that can be included somewhere else. 6862 * 6863 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6864 * 6865 * @return {YXmlFragment} 6866 */ 6867 clone() { 6868 const el = new _YXmlFragment(); 6869 el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); 6870 return el; 6871 } 6872 get length() { 6873 this.doc ?? warnPrematureAccess(); 6874 return this._prelimContent === null ? this._length : this._prelimContent.length; 6875 } 6876 /** 6877 * Create a subtree of childNodes. 6878 * 6879 * @example 6880 * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') 6881 * for (let node in walker) { 6882 * // `node` is a div node 6883 * nop(node) 6884 * } 6885 * 6886 * @param {function(AbstractType<any>):boolean} filter Function that is called on each child element and 6887 * returns a Boolean indicating whether the child 6888 * is to be included in the subtree. 6889 * @return {YXmlTreeWalker} A subtree and a position within it. 6890 * 6891 * @public 6892 */ 6893 createTreeWalker(filter) { 6894 return new YXmlTreeWalker(this, filter); 6895 } 6896 /** 6897 * Returns the first YXmlElement that matches the query. 6898 * Similar to DOM's {@link querySelector}. 6899 * 6900 * Query support: 6901 * - tagname 6902 * TODO: 6903 * - id 6904 * - attribute 6905 * 6906 * @param {CSS_Selector} query The query on the children. 6907 * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. 6908 * 6909 * @public 6910 */ 6911 querySelector(query) { 6912 query = query.toUpperCase(); 6913 const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); 6914 const next = iterator.next(); 6915 if (next.done) { 6916 return null; 6917 } else { 6918 return next.value; 6919 } 6920 } 6921 /** 6922 * Returns all YXmlElements that match the query. 6923 * Similar to Dom's {@link querySelectorAll}. 6924 * 6925 * @todo Does not yet support all queries. Currently only query by tagName. 6926 * 6927 * @param {CSS_Selector} query The query on the children 6928 * @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query. 6929 * 6930 * @public 6931 */ 6932 querySelectorAll(query) { 6933 query = query.toUpperCase(); 6934 return from(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); 6935 } 6936 /** 6937 * Creates YXmlEvent and calls observers. 6938 * 6939 * @param {Transaction} transaction 6940 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6941 */ 6942 _callObserver(transaction, parentSubs) { 6943 callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); 6944 } 6945 /** 6946 * Get the string representation of all the children of this YXmlFragment. 6947 * 6948 * @return {string} The string representation of all children. 6949 */ 6950 toString() { 6951 return typeListMap(this, (xml) => xml.toString()).join(""); 6952 } 6953 /** 6954 * @return {string} 6955 */ 6956 toJSON() { 6957 return this.toString(); 6958 } 6959 /** 6960 * Creates a Dom Element that mirrors this YXmlElement. 6961 * 6962 * @param {Document} [_document=document] The document object (you must define 6963 * this when calling this method in 6964 * nodejs) 6965 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 6966 * are presented in the DOM 6967 * @param {any} [binding] You should not set this property. This is 6968 * used if DomBinding wants to create a 6969 * association to the created DOM type. 6970 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 6971 * 6972 * @public 6973 */ 6974 toDOM(_document = document, hooks = {}, binding) { 6975 const fragment = _document.createDocumentFragment(); 6976 if (binding !== void 0) { 6977 binding._createAssociation(fragment, this); 6978 } 6979 typeListForEach(this, (xmlType) => { 6980 fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); 6981 }); 6982 return fragment; 6983 } 6984 /** 6985 * Inserts new content at an index. 6986 * 6987 * @example 6988 * // Insert character 'a' at position 0 6989 * xml.insert(0, [new Y.XmlText('text')]) 6990 * 6991 * @param {number} index The index to insert content at 6992 * @param {Array<YXmlElement|YXmlText>} content The array of content 6993 */ 6994 insert(index, content) { 6995 if (this.doc !== null) { 6996 transact(this.doc, (transaction) => { 6997 typeListInsertGenerics(transaction, this, index, content); 6998 }); 6999 } else { 7000 this._prelimContent.splice(index, 0, ...content); 7001 } 7002 } 7003 /** 7004 * Inserts new content at an index. 7005 * 7006 * @example 7007 * // Insert character 'a' at position 0 7008 * xml.insert(0, [new Y.XmlText('text')]) 7009 * 7010 * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at 7011 * @param {Array<YXmlElement|YXmlText>} content The array of content 7012 */ 7013 insertAfter(ref, content) { 7014 if (this.doc !== null) { 7015 transact(this.doc, (transaction) => { 7016 const refItem = ref && ref instanceof AbstractType ? ref._item : ref; 7017 typeListInsertGenericsAfter(transaction, this, refItem, content); 7018 }); 7019 } else { 7020 const pc = ( 7021 /** @type {Array<any>} */ 7022 this._prelimContent 7023 ); 7024 const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; 7025 if (index === 0 && ref !== null) { 7026 throw create3("Reference item not found"); 7027 } 7028 pc.splice(index, 0, ...content); 7029 } 7030 } 7031 /** 7032 * Deletes elements starting from an index. 7033 * 7034 * @param {number} index Index at which to start deleting elements 7035 * @param {number} [length=1] The number of elements to remove. Defaults to 1. 7036 */ 7037 delete(index, length3 = 1) { 7038 if (this.doc !== null) { 7039 transact(this.doc, (transaction) => { 7040 typeListDelete(transaction, this, index, length3); 7041 }); 7042 } else { 7043 this._prelimContent.splice(index, length3); 7044 } 7045 } 7046 /** 7047 * Transforms this YArray to a JavaScript Array. 7048 * 7049 * @return {Array<YXmlElement|YXmlText|YXmlHook>} 7050 */ 7051 toArray() { 7052 return typeListToArray(this); 7053 } 7054 /** 7055 * Appends content to this YArray. 7056 * 7057 * @param {Array<YXmlElement|YXmlText>} content Array of content to append. 7058 */ 7059 push(content) { 7060 this.insert(this.length, content); 7061 } 7062 /** 7063 * Prepends content to this YArray. 7064 * 7065 * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend. 7066 */ 7067 unshift(content) { 7068 this.insert(0, content); 7069 } 7070 /** 7071 * Returns the i-th element from a YArray. 7072 * 7073 * @param {number} index The index of the element to return from the YArray 7074 * @return {YXmlElement|YXmlText} 7075 */ 7076 get(index) { 7077 return typeListGet(this, index); 7078 } 7079 /** 7080 * Returns a portion of this YXmlFragment into a JavaScript Array selected 7081 * from start to end (end not included). 7082 * 7083 * @param {number} [start] 7084 * @param {number} [end] 7085 * @return {Array<YXmlElement|YXmlText>} 7086 */ 7087 slice(start = 0, end = this.length) { 7088 return typeListSlice(this, start, end); 7089 } 7090 /** 7091 * Executes a provided function on once on every child element. 7092 * 7093 * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. 7094 */ 7095 forEach(f) { 7096 typeListForEach(this, f); 7097 } 7098 /** 7099 * Transform the properties of this type to binary and write it to an 7100 * BinaryEncoder. 7101 * 7102 * This is called when this Item is sent to a remote peer. 7103 * 7104 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7105 */ 7106 _write(encoder) { 7107 encoder.writeTypeRef(YXmlFragmentRefID); 7108 } 7109 }; 7110 var readYXmlFragment = (_decoder) => new YXmlFragment(); 7111 var YXmlElement = class _YXmlElement extends YXmlFragment { 7112 constructor(nodeName = "UNDEFINED") { 7113 super(); 7114 this.nodeName = nodeName; 7115 this._prelimAttrs = /* @__PURE__ */ new Map(); 7116 } 7117 /** 7118 * @type {YXmlElement|YXmlText|null} 7119 */ 7120 get nextSibling() { 7121 const n = this._item ? this._item.next : null; 7122 return n ? ( 7123 /** @type {YXmlElement|YXmlText} */ 7124 /** @type {ContentType} */ 7125 n.content.type 7126 ) : null; 7127 } 7128 /** 7129 * @type {YXmlElement|YXmlText|null} 7130 */ 7131 get prevSibling() { 7132 const n = this._item ? this._item.prev : null; 7133 return n ? ( 7134 /** @type {YXmlElement|YXmlText} */ 7135 /** @type {ContentType} */ 7136 n.content.type 7137 ) : null; 7138 } 7139 /** 7140 * Integrate this type into the Yjs instance. 7141 * 7142 * * Save this struct in the os 7143 * * This type is sent to other client 7144 * * Observer functions are fired 7145 * 7146 * @param {Doc} y The Yjs instance 7147 * @param {Item} item 7148 */ 7149 _integrate(y, item) { 7150 super._integrate(y, item); 7151 /** @type {Map<string, any>} */ 7152 this._prelimAttrs.forEach((value, key) => { 7153 this.setAttribute(key, value); 7154 }); 7155 this._prelimAttrs = null; 7156 } 7157 /** 7158 * Creates an Item with the same effect as this Item (without position effect) 7159 * 7160 * @return {YXmlElement} 7161 */ 7162 _copy() { 7163 return new _YXmlElement(this.nodeName); 7164 } 7165 /** 7166 * Makes a copy of this data type that can be included somewhere else. 7167 * 7168 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7169 * 7170 * @return {YXmlElement<KV>} 7171 */ 7172 clone() { 7173 const el = new _YXmlElement(this.nodeName); 7174 const attrs = this.getAttributes(); 7175 forEach(attrs, (value, key) => { 7176 el.setAttribute( 7177 key, 7178 /** @type {any} */ 7179 value 7180 ); 7181 }); 7182 el.insert(0, this.toArray().map((v) => v instanceof AbstractType ? v.clone() : v)); 7183 return el; 7184 } 7185 /** 7186 * Returns the XML serialization of this YXmlElement. 7187 * The attributes are ordered by attribute-name, so you can easily use this 7188 * method to compare YXmlElements 7189 * 7190 * @return {string} The string representation of this type. 7191 * 7192 * @public 7193 */ 7194 toString() { 7195 const attrs = this.getAttributes(); 7196 const stringBuilder = []; 7197 const keys2 = []; 7198 for (const key in attrs) { 7199 keys2.push(key); 7200 } 7201 keys2.sort(); 7202 const keysLen = keys2.length; 7203 for (let i = 0; i < keysLen; i++) { 7204 const key = keys2[i]; 7205 stringBuilder.push(key + '="' + attrs[key] + '"'); 7206 } 7207 const nodeName = this.nodeName.toLocaleLowerCase(); 7208 const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; 7209 return `<$nodeName}$attrsString}>$super.toString()}</$nodeName}>`; 7210 } 7211 /** 7212 * Removes an attribute from this YXmlElement. 7213 * 7214 * @param {string} attributeName The attribute name that is to be removed. 7215 * 7216 * @public 7217 */ 7218 removeAttribute(attributeName) { 7219 if (this.doc !== null) { 7220 transact(this.doc, (transaction) => { 7221 typeMapDelete(transaction, this, attributeName); 7222 }); 7223 } else { 7224 this._prelimAttrs.delete(attributeName); 7225 } 7226 } 7227 /** 7228 * Sets or updates an attribute. 7229 * 7230 * @template {keyof KV & string} KEY 7231 * 7232 * @param {KEY} attributeName The attribute name that is to be set. 7233 * @param {KV[KEY]} attributeValue The attribute value that is to be set. 7234 * 7235 * @public 7236 */ 7237 setAttribute(attributeName, attributeValue) { 7238 if (this.doc !== null) { 7239 transact(this.doc, (transaction) => { 7240 typeMapSet(transaction, this, attributeName, attributeValue); 7241 }); 7242 } else { 7243 this._prelimAttrs.set(attributeName, attributeValue); 7244 } 7245 } 7246 /** 7247 * Returns an attribute value that belongs to the attribute name. 7248 * 7249 * @template {keyof KV & string} KEY 7250 * 7251 * @param {KEY} attributeName The attribute name that identifies the 7252 * queried value. 7253 * @return {KV[KEY]|undefined} The queried attribute value. 7254 * 7255 * @public 7256 */ 7257 getAttribute(attributeName) { 7258 return ( 7259 /** @type {any} */ 7260 typeMapGet(this, attributeName) 7261 ); 7262 } 7263 /** 7264 * Returns whether an attribute exists 7265 * 7266 * @param {string} attributeName The attribute name to check for existence. 7267 * @return {boolean} whether the attribute exists. 7268 * 7269 * @public 7270 */ 7271 hasAttribute(attributeName) { 7272 return ( 7273 /** @type {any} */ 7274 typeMapHas(this, attributeName) 7275 ); 7276 } 7277 /** 7278 * Returns all attribute name/value pairs in a JSON Object. 7279 * 7280 * @param {Snapshot} [snapshot] 7281 * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes. 7282 * 7283 * @public 7284 */ 7285 getAttributes(snapshot2) { 7286 return ( 7287 /** @type {any} */ 7288 snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) 7289 ); 7290 } 7291 /** 7292 * Creates a Dom Element that mirrors this YXmlElement. 7293 * 7294 * @param {Document} [_document=document] The document object (you must define 7295 * this when calling this method in 7296 * nodejs) 7297 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 7298 * are presented in the DOM 7299 * @param {any} [binding] You should not set this property. This is 7300 * used if DomBinding wants to create a 7301 * association to the created DOM type. 7302 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 7303 * 7304 * @public 7305 */ 7306 toDOM(_document = document, hooks = {}, binding) { 7307 const dom = _document.createElement(this.nodeName); 7308 const attrs = this.getAttributes(); 7309 for (const key in attrs) { 7310 const value = attrs[key]; 7311 if (typeof value === "string") { 7312 dom.setAttribute(key, value); 7313 } 7314 } 7315 typeListForEach(this, (yxml) => { 7316 dom.appendChild(yxml.toDOM(_document, hooks, binding)); 7317 }); 7318 if (binding !== void 0) { 7319 binding._createAssociation(dom, this); 7320 } 7321 return dom; 7322 } 7323 /** 7324 * Transform the properties of this type to binary and write it to an 7325 * BinaryEncoder. 7326 * 7327 * This is called when this Item is sent to a remote peer. 7328 * 7329 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7330 */ 7331 _write(encoder) { 7332 encoder.writeTypeRef(YXmlElementRefID); 7333 encoder.writeKey(this.nodeName); 7334 } 7335 }; 7336 var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); 7337 var YXmlEvent = class extends YEvent { 7338 /** 7339 * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. 7340 * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the 7341 * child list changed. 7342 * @param {Transaction} transaction The transaction instance with which the 7343 * change was created. 7344 */ 7345 constructor(target, subs, transaction) { 7346 super(target, transaction); 7347 this.childListChanged = false; 7348 this.attributesChanged = /* @__PURE__ */ new Set(); 7349 subs.forEach((sub) => { 7350 if (sub === null) { 7351 this.childListChanged = true; 7352 } else { 7353 this.attributesChanged.add(sub); 7354 } 7355 }); 7356 } 7357 }; 7358 var YXmlHook = class _YXmlHook extends YMap { 7359 /** 7360 * @param {string} hookName nodeName of the Dom Node. 7361 */ 7362 constructor(hookName) { 7363 super(); 7364 this.hookName = hookName; 7365 } 7366 /** 7367 * Creates an Item with the same effect as this Item (without position effect) 7368 */ 7369 _copy() { 7370 return new _YXmlHook(this.hookName); 7371 } 7372 /** 7373 * Makes a copy of this data type that can be included somewhere else. 7374 * 7375 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7376 * 7377 * @return {YXmlHook} 7378 */ 7379 clone() { 7380 const el = new _YXmlHook(this.hookName); 7381 this.forEach((value, key) => { 7382 el.set(key, value); 7383 }); 7384 return el; 7385 } 7386 /** 7387 * Creates a Dom Element that mirrors this YXmlElement. 7388 * 7389 * @param {Document} [_document=document] The document object (you must define 7390 * this when calling this method in 7391 * nodejs) 7392 * @param {Object.<string, any>} [hooks] Optional property to customize how hooks 7393 * are presented in the DOM 7394 * @param {any} [binding] You should not set this property. This is 7395 * used if DomBinding wants to create a 7396 * association to the created DOM type 7397 * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 7398 * 7399 * @public 7400 */ 7401 toDOM(_document = document, hooks = {}, binding) { 7402 const hook = hooks[this.hookName]; 7403 let dom; 7404 if (hook !== void 0) { 7405 dom = hook.createDom(this); 7406 } else { 7407 dom = document.createElement(this.hookName); 7408 } 7409 dom.setAttribute("data-yjs-hook", this.hookName); 7410 if (binding !== void 0) { 7411 binding._createAssociation(dom, this); 7412 } 7413 return dom; 7414 } 7415 /** 7416 * Transform the properties of this type to binary and write it to an 7417 * BinaryEncoder. 7418 * 7419 * This is called when this Item is sent to a remote peer. 7420 * 7421 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7422 */ 7423 _write(encoder) { 7424 encoder.writeTypeRef(YXmlHookRefID); 7425 encoder.writeKey(this.hookName); 7426 } 7427 }; 7428 var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); 7429 var YXmlText = class _YXmlText extends YText { 7430 /** 7431 * @type {YXmlElement|YXmlText|null} 7432 */ 7433 get nextSibling() { 7434 const n = this._item ? this._item.next : null; 7435 return n ? ( 7436 /** @type {YXmlElement|YXmlText} */ 7437 /** @type {ContentType} */ 7438 n.content.type 7439 ) : null; 7440 } 7441 /** 7442 * @type {YXmlElement|YXmlText|null} 7443 */ 7444 get prevSibling() { 7445 const n = this._item ? this._item.prev : null; 7446 return n ? ( 7447 /** @type {YXmlElement|YXmlText} */ 7448 /** @type {ContentType} */ 7449 n.content.type 7450 ) : null; 7451 } 7452 _copy() { 7453 return new _YXmlText(); 7454 } 7455 /** 7456 * Makes a copy of this data type that can be included somewhere else. 7457 * 7458 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7459 * 7460 * @return {YXmlText} 7461 */ 7462 clone() { 7463 const text2 = new _YXmlText(); 7464 text2.applyDelta(this.toDelta()); 7465 return text2; 7466 } 7467 /** 7468 * Creates a Dom Element that mirrors this YXmlText. 7469 * 7470 * @param {Document} [_document=document] The document object (you must define 7471 * this when calling this method in 7472 * nodejs) 7473 * @param {Object<string, any>} [hooks] Optional property to customize how hooks 7474 * are presented in the DOM 7475 * @param {any} [binding] You should not set this property. This is 7476 * used if DomBinding wants to create a 7477 * association to the created DOM type. 7478 * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 7479 * 7480 * @public 7481 */ 7482 toDOM(_document = document, hooks, binding) { 7483 const dom = _document.createTextNode(this.toString()); 7484 if (binding !== void 0) { 7485 binding._createAssociation(dom, this); 7486 } 7487 return dom; 7488 } 7489 toString() { 7490 return this.toDelta().map((delta) => { 7491 const nestedNodes = []; 7492 for (const nodeName in delta.attributes) { 7493 const attrs = []; 7494 for (const key in delta.attributes[nodeName]) { 7495 attrs.push({ key, value: delta.attributes[nodeName][key] }); 7496 } 7497 attrs.sort((a, b) => a.key < b.key ? -1 : 1); 7498 nestedNodes.push({ nodeName, attrs }); 7499 } 7500 nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1); 7501 let str = ""; 7502 for (let i = 0; i < nestedNodes.length; i++) { 7503 const node = nestedNodes[i]; 7504 str += `<$node.nodeName}`; 7505 for (let j = 0; j < node.attrs.length; j++) { 7506 const attr = node.attrs[j]; 7507 str += ` $attr.key}="$attr.value}"`; 7508 } 7509 str += ">"; 7510 } 7511 str += delta.insert; 7512 for (let i = nestedNodes.length - 1; i >= 0; i--) { 7513 str += `</$nestedNodes[i].nodeName}>`; 7514 } 7515 return str; 7516 }).join(""); 7517 } 7518 /** 7519 * @return {string} 7520 */ 7521 toJSON() { 7522 return this.toString(); 7523 } 7524 /** 7525 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7526 */ 7527 _write(encoder) { 7528 encoder.writeTypeRef(YXmlTextRefID); 7529 } 7530 }; 7531 var readYXmlText = (decoder) => new YXmlText(); 7532 var AbstractStruct = class { 7533 /** 7534 * @param {ID} id 7535 * @param {number} length 7536 */ 7537 constructor(id2, length3) { 7538 this.id = id2; 7539 this.length = length3; 7540 } 7541 /** 7542 * @type {boolean} 7543 */ 7544 get deleted() { 7545 throw methodUnimplemented(); 7546 } 7547 /** 7548 * Merge this struct with the item to the right. 7549 * This method is already assuming that `this.id.clock + this.length === this.id.clock`. 7550 * Also this method does *not* remove right from StructStore! 7551 * @param {AbstractStruct} right 7552 * @return {boolean} whether this merged with right 7553 */ 7554 mergeWith(right) { 7555 return false; 7556 } 7557 /** 7558 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7559 * @param {number} offset 7560 * @param {number} encodingRef 7561 */ 7562 write(encoder, offset, encodingRef) { 7563 throw methodUnimplemented(); 7564 } 7565 /** 7566 * @param {Transaction} transaction 7567 * @param {number} offset 7568 */ 7569 integrate(transaction, offset) { 7570 throw methodUnimplemented(); 7571 } 7572 }; 7573 var structGCRefNumber = 0; 7574 var GC = class extends AbstractStruct { 7575 get deleted() { 7576 return true; 7577 } 7578 delete() { 7579 } 7580 /** 7581 * @param {GC} right 7582 * @return {boolean} 7583 */ 7584 mergeWith(right) { 7585 if (this.constructor !== right.constructor) { 7586 return false; 7587 } 7588 this.length += right.length; 7589 return true; 7590 } 7591 /** 7592 * @param {Transaction} transaction 7593 * @param {number} offset 7594 */ 7595 integrate(transaction, offset) { 7596 if (offset > 0) { 7597 this.id.clock += offset; 7598 this.length -= offset; 7599 } 7600 addStruct(transaction.doc.store, this); 7601 } 7602 /** 7603 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7604 * @param {number} offset 7605 */ 7606 write(encoder, offset) { 7607 encoder.writeInfo(structGCRefNumber); 7608 encoder.writeLen(this.length - offset); 7609 } 7610 /** 7611 * @param {Transaction} transaction 7612 * @param {StructStore} store 7613 * @return {null | number} 7614 */ 7615 getMissing(transaction, store) { 7616 return null; 7617 } 7618 }; 7619 var ContentBinary = class _ContentBinary { 7620 /** 7621 * @param {Uint8Array} content 7622 */ 7623 constructor(content) { 7624 this.content = content; 7625 } 7626 /** 7627 * @return {number} 7628 */ 7629 getLength() { 7630 return 1; 7631 } 7632 /** 7633 * @return {Array<any>} 7634 */ 7635 getContent() { 7636 return [this.content]; 7637 } 7638 /** 7639 * @return {boolean} 7640 */ 7641 isCountable() { 7642 return true; 7643 } 7644 /** 7645 * @return {ContentBinary} 7646 */ 7647 copy() { 7648 return new _ContentBinary(this.content); 7649 } 7650 /** 7651 * @param {number} offset 7652 * @return {ContentBinary} 7653 */ 7654 splice(offset) { 7655 throw methodUnimplemented(); 7656 } 7657 /** 7658 * @param {ContentBinary} right 7659 * @return {boolean} 7660 */ 7661 mergeWith(right) { 7662 return false; 7663 } 7664 /** 7665 * @param {Transaction} transaction 7666 * @param {Item} item 7667 */ 7668 integrate(transaction, item) { 7669 } 7670 /** 7671 * @param {Transaction} transaction 7672 */ 7673 delete(transaction) { 7674 } 7675 /** 7676 * @param {StructStore} store 7677 */ 7678 gc(store) { 7679 } 7680 /** 7681 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7682 * @param {number} offset 7683 */ 7684 write(encoder, offset) { 7685 encoder.writeBuf(this.content); 7686 } 7687 /** 7688 * @return {number} 7689 */ 7690 getRef() { 7691 return 3; 7692 } 7693 }; 7694 var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); 7695 var ContentDeleted = class _ContentDeleted { 7696 /** 7697 * @param {number} len 7698 */ 7699 constructor(len) { 7700 this.len = len; 7701 } 7702 /** 7703 * @return {number} 7704 */ 7705 getLength() { 7706 return this.len; 7707 } 7708 /** 7709 * @return {Array<any>} 7710 */ 7711 getContent() { 7712 return []; 7713 } 7714 /** 7715 * @return {boolean} 7716 */ 7717 isCountable() { 7718 return false; 7719 } 7720 /** 7721 * @return {ContentDeleted} 7722 */ 7723 copy() { 7724 return new _ContentDeleted(this.len); 7725 } 7726 /** 7727 * @param {number} offset 7728 * @return {ContentDeleted} 7729 */ 7730 splice(offset) { 7731 const right = new _ContentDeleted(this.len - offset); 7732 this.len = offset; 7733 return right; 7734 } 7735 /** 7736 * @param {ContentDeleted} right 7737 * @return {boolean} 7738 */ 7739 mergeWith(right) { 7740 this.len += right.len; 7741 return true; 7742 } 7743 /** 7744 * @param {Transaction} transaction 7745 * @param {Item} item 7746 */ 7747 integrate(transaction, item) { 7748 addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); 7749 item.markDeleted(); 7750 } 7751 /** 7752 * @param {Transaction} transaction 7753 */ 7754 delete(transaction) { 7755 } 7756 /** 7757 * @param {StructStore} store 7758 */ 7759 gc(store) { 7760 } 7761 /** 7762 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7763 * @param {number} offset 7764 */ 7765 write(encoder, offset) { 7766 encoder.writeLen(this.len - offset); 7767 } 7768 /** 7769 * @return {number} 7770 */ 7771 getRef() { 7772 return 1; 7773 } 7774 }; 7775 var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); 7776 var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); 7777 var ContentDoc = class _ContentDoc { 7778 /** 7779 * @param {Doc} doc 7780 */ 7781 constructor(doc2) { 7782 if (doc2._item) { 7783 console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); 7784 } 7785 this.doc = doc2; 7786 const opts = {}; 7787 this.opts = opts; 7788 if (!doc2.gc) { 7789 opts.gc = false; 7790 } 7791 if (doc2.autoLoad) { 7792 opts.autoLoad = true; 7793 } 7794 if (doc2.meta !== null) { 7795 opts.meta = doc2.meta; 7796 } 7797 } 7798 /** 7799 * @return {number} 7800 */ 7801 getLength() { 7802 return 1; 7803 } 7804 /** 7805 * @return {Array<any>} 7806 */ 7807 getContent() { 7808 return [this.doc]; 7809 } 7810 /** 7811 * @return {boolean} 7812 */ 7813 isCountable() { 7814 return true; 7815 } 7816 /** 7817 * @return {ContentDoc} 7818 */ 7819 copy() { 7820 return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); 7821 } 7822 /** 7823 * @param {number} offset 7824 * @return {ContentDoc} 7825 */ 7826 splice(offset) { 7827 throw methodUnimplemented(); 7828 } 7829 /** 7830 * @param {ContentDoc} right 7831 * @return {boolean} 7832 */ 7833 mergeWith(right) { 7834 return false; 7835 } 7836 /** 7837 * @param {Transaction} transaction 7838 * @param {Item} item 7839 */ 7840 integrate(transaction, item) { 7841 this.doc._item = item; 7842 transaction.subdocsAdded.add(this.doc); 7843 if (this.doc.shouldLoad) { 7844 transaction.subdocsLoaded.add(this.doc); 7845 } 7846 } 7847 /** 7848 * @param {Transaction} transaction 7849 */ 7850 delete(transaction) { 7851 if (transaction.subdocsAdded.has(this.doc)) { 7852 transaction.subdocsAdded.delete(this.doc); 7853 } else { 7854 transaction.subdocsRemoved.add(this.doc); 7855 } 7856 } 7857 /** 7858 * @param {StructStore} store 7859 */ 7860 gc(store) { 7861 } 7862 /** 7863 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7864 * @param {number} offset 7865 */ 7866 write(encoder, offset) { 7867 encoder.writeString(this.doc.guid); 7868 encoder.writeAny(this.opts); 7869 } 7870 /** 7871 * @return {number} 7872 */ 7873 getRef() { 7874 return 9; 7875 } 7876 }; 7877 var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); 7878 var ContentEmbed = class _ContentEmbed { 7879 /** 7880 * @param {Object} embed 7881 */ 7882 constructor(embed) { 7883 this.embed = embed; 7884 } 7885 /** 7886 * @return {number} 7887 */ 7888 getLength() { 7889 return 1; 7890 } 7891 /** 7892 * @return {Array<any>} 7893 */ 7894 getContent() { 7895 return [this.embed]; 7896 } 7897 /** 7898 * @return {boolean} 7899 */ 7900 isCountable() { 7901 return true; 7902 } 7903 /** 7904 * @return {ContentEmbed} 7905 */ 7906 copy() { 7907 return new _ContentEmbed(this.embed); 7908 } 7909 /** 7910 * @param {number} offset 7911 * @return {ContentEmbed} 7912 */ 7913 splice(offset) { 7914 throw methodUnimplemented(); 7915 } 7916 /** 7917 * @param {ContentEmbed} right 7918 * @return {boolean} 7919 */ 7920 mergeWith(right) { 7921 return false; 7922 } 7923 /** 7924 * @param {Transaction} transaction 7925 * @param {Item} item 7926 */ 7927 integrate(transaction, item) { 7928 } 7929 /** 7930 * @param {Transaction} transaction 7931 */ 7932 delete(transaction) { 7933 } 7934 /** 7935 * @param {StructStore} store 7936 */ 7937 gc(store) { 7938 } 7939 /** 7940 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7941 * @param {number} offset 7942 */ 7943 write(encoder, offset) { 7944 encoder.writeJSON(this.embed); 7945 } 7946 /** 7947 * @return {number} 7948 */ 7949 getRef() { 7950 return 5; 7951 } 7952 }; 7953 var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); 7954 var ContentFormat = class _ContentFormat { 7955 /** 7956 * @param {string} key 7957 * @param {Object} value 7958 */ 7959 constructor(key, value) { 7960 this.key = key; 7961 this.value = value; 7962 } 7963 /** 7964 * @return {number} 7965 */ 7966 getLength() { 7967 return 1; 7968 } 7969 /** 7970 * @return {Array<any>} 7971 */ 7972 getContent() { 7973 return []; 7974 } 7975 /** 7976 * @return {boolean} 7977 */ 7978 isCountable() { 7979 return false; 7980 } 7981 /** 7982 * @return {ContentFormat} 7983 */ 7984 copy() { 7985 return new _ContentFormat(this.key, this.value); 7986 } 7987 /** 7988 * @param {number} _offset 7989 * @return {ContentFormat} 7990 */ 7991 splice(_offset) { 7992 throw methodUnimplemented(); 7993 } 7994 /** 7995 * @param {ContentFormat} _right 7996 * @return {boolean} 7997 */ 7998 mergeWith(_right) { 7999 return false; 8000 } 8001 /** 8002 * @param {Transaction} _transaction 8003 * @param {Item} item 8004 */ 8005 integrate(_transaction, item) { 8006 const p = ( 8007 /** @type {YText} */ 8008 item.parent 8009 ); 8010 p._searchMarker = null; 8011 p._hasFormatting = true; 8012 } 8013 /** 8014 * @param {Transaction} transaction 8015 */ 8016 delete(transaction) { 8017 } 8018 /** 8019 * @param {StructStore} store 8020 */ 8021 gc(store) { 8022 } 8023 /** 8024 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8025 * @param {number} offset 8026 */ 8027 write(encoder, offset) { 8028 encoder.writeKey(this.key); 8029 encoder.writeJSON(this.value); 8030 } 8031 /** 8032 * @return {number} 8033 */ 8034 getRef() { 8035 return 6; 8036 } 8037 }; 8038 var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); 8039 var ContentJSON = class _ContentJSON { 8040 /** 8041 * @param {Array<any>} arr 8042 */ 8043 constructor(arr) { 8044 this.arr = arr; 8045 } 8046 /** 8047 * @return {number} 8048 */ 8049 getLength() { 8050 return this.arr.length; 8051 } 8052 /** 8053 * @return {Array<any>} 8054 */ 8055 getContent() { 8056 return this.arr; 8057 } 8058 /** 8059 * @return {boolean} 8060 */ 8061 isCountable() { 8062 return true; 8063 } 8064 /** 8065 * @return {ContentJSON} 8066 */ 8067 copy() { 8068 return new _ContentJSON(this.arr); 8069 } 8070 /** 8071 * @param {number} offset 8072 * @return {ContentJSON} 8073 */ 8074 splice(offset) { 8075 const right = new _ContentJSON(this.arr.slice(offset)); 8076 this.arr = this.arr.slice(0, offset); 8077 return right; 8078 } 8079 /** 8080 * @param {ContentJSON} right 8081 * @return {boolean} 8082 */ 8083 mergeWith(right) { 8084 this.arr = this.arr.concat(right.arr); 8085 return true; 8086 } 8087 /** 8088 * @param {Transaction} transaction 8089 * @param {Item} item 8090 */ 8091 integrate(transaction, item) { 8092 } 8093 /** 8094 * @param {Transaction} transaction 8095 */ 8096 delete(transaction) { 8097 } 8098 /** 8099 * @param {StructStore} store 8100 */ 8101 gc(store) { 8102 } 8103 /** 8104 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8105 * @param {number} offset 8106 */ 8107 write(encoder, offset) { 8108 const len = this.arr.length; 8109 encoder.writeLen(len - offset); 8110 for (let i = offset; i < len; i++) { 8111 const c = this.arr[i]; 8112 encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); 8113 } 8114 } 8115 /** 8116 * @return {number} 8117 */ 8118 getRef() { 8119 return 2; 8120 } 8121 }; 8122 var readContentJSON = (decoder) => { 8123 const len = decoder.readLen(); 8124 const cs = []; 8125 for (let i = 0; i < len; i++) { 8126 const c = decoder.readString(); 8127 if (c === "undefined") { 8128 cs.push(void 0); 8129 } else { 8130 cs.push(JSON.parse(c)); 8131 } 8132 } 8133 return new ContentJSON(cs); 8134 }; 8135 var isDevMode = getVariable("node_env") === "development"; 8136 var ContentAny = class _ContentAny { 8137 /** 8138 * @param {Array<any>} arr 8139 */ 8140 constructor(arr) { 8141 this.arr = arr; 8142 isDevMode && deepFreeze(arr); 8143 } 8144 /** 8145 * @return {number} 8146 */ 8147 getLength() { 8148 return this.arr.length; 8149 } 8150 /** 8151 * @return {Array<any>} 8152 */ 8153 getContent() { 8154 return this.arr; 8155 } 8156 /** 8157 * @return {boolean} 8158 */ 8159 isCountable() { 8160 return true; 8161 } 8162 /** 8163 * @return {ContentAny} 8164 */ 8165 copy() { 8166 return new _ContentAny(this.arr); 8167 } 8168 /** 8169 * @param {number} offset 8170 * @return {ContentAny} 8171 */ 8172 splice(offset) { 8173 const right = new _ContentAny(this.arr.slice(offset)); 8174 this.arr = this.arr.slice(0, offset); 8175 return right; 8176 } 8177 /** 8178 * @param {ContentAny} right 8179 * @return {boolean} 8180 */ 8181 mergeWith(right) { 8182 this.arr = this.arr.concat(right.arr); 8183 return true; 8184 } 8185 /** 8186 * @param {Transaction} transaction 8187 * @param {Item} item 8188 */ 8189 integrate(transaction, item) { 8190 } 8191 /** 8192 * @param {Transaction} transaction 8193 */ 8194 delete(transaction) { 8195 } 8196 /** 8197 * @param {StructStore} store 8198 */ 8199 gc(store) { 8200 } 8201 /** 8202 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8203 * @param {number} offset 8204 */ 8205 write(encoder, offset) { 8206 const len = this.arr.length; 8207 encoder.writeLen(len - offset); 8208 for (let i = offset; i < len; i++) { 8209 const c = this.arr[i]; 8210 encoder.writeAny(c); 8211 } 8212 } 8213 /** 8214 * @return {number} 8215 */ 8216 getRef() { 8217 return 8; 8218 } 8219 }; 8220 var readContentAny = (decoder) => { 8221 const len = decoder.readLen(); 8222 const cs = []; 8223 for (let i = 0; i < len; i++) { 8224 cs.push(decoder.readAny()); 8225 } 8226 return new ContentAny(cs); 8227 }; 8228 var ContentString = class _ContentString { 8229 /** 8230 * @param {string} str 8231 */ 8232 constructor(str) { 8233 this.str = str; 8234 } 8235 /** 8236 * @return {number} 8237 */ 8238 getLength() { 8239 return this.str.length; 8240 } 8241 /** 8242 * @return {Array<any>} 8243 */ 8244 getContent() { 8245 return this.str.split(""); 8246 } 8247 /** 8248 * @return {boolean} 8249 */ 8250 isCountable() { 8251 return true; 8252 } 8253 /** 8254 * @return {ContentString} 8255 */ 8256 copy() { 8257 return new _ContentString(this.str); 8258 } 8259 /** 8260 * @param {number} offset 8261 * @return {ContentString} 8262 */ 8263 splice(offset) { 8264 const right = new _ContentString(this.str.slice(offset)); 8265 this.str = this.str.slice(0, offset); 8266 const firstCharCode = this.str.charCodeAt(offset - 1); 8267 if (firstCharCode >= 55296 && firstCharCode <= 56319) { 8268 this.str = this.str.slice(0, offset - 1) + "\uFFFD"; 8269 right.str = "\uFFFD" + right.str.slice(1); 8270 } 8271 return right; 8272 } 8273 /** 8274 * @param {ContentString} right 8275 * @return {boolean} 8276 */ 8277 mergeWith(right) { 8278 this.str += right.str; 8279 return true; 8280 } 8281 /** 8282 * @param {Transaction} transaction 8283 * @param {Item} item 8284 */ 8285 integrate(transaction, item) { 8286 } 8287 /** 8288 * @param {Transaction} transaction 8289 */ 8290 delete(transaction) { 8291 } 8292 /** 8293 * @param {StructStore} store 8294 */ 8295 gc(store) { 8296 } 8297 /** 8298 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8299 * @param {number} offset 8300 */ 8301 write(encoder, offset) { 8302 encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); 8303 } 8304 /** 8305 * @return {number} 8306 */ 8307 getRef() { 8308 return 4; 8309 } 8310 }; 8311 var readContentString = (decoder) => new ContentString(decoder.readString()); 8312 var typeRefs = [ 8313 readYArray, 8314 readYMap, 8315 readYText, 8316 readYXmlElement, 8317 readYXmlFragment, 8318 readYXmlHook, 8319 readYXmlText 8320 ]; 8321 var YArrayRefID = 0; 8322 var YMapRefID = 1; 8323 var YTextRefID = 2; 8324 var YXmlElementRefID = 3; 8325 var YXmlFragmentRefID = 4; 8326 var YXmlHookRefID = 5; 8327 var YXmlTextRefID = 6; 8328 var ContentType = class _ContentType { 8329 /** 8330 * @param {AbstractType<any>} type 8331 */ 8332 constructor(type) { 8333 this.type = type; 8334 } 8335 /** 8336 * @return {number} 8337 */ 8338 getLength() { 8339 return 1; 8340 } 8341 /** 8342 * @return {Array<any>} 8343 */ 8344 getContent() { 8345 return [this.type]; 8346 } 8347 /** 8348 * @return {boolean} 8349 */ 8350 isCountable() { 8351 return true; 8352 } 8353 /** 8354 * @return {ContentType} 8355 */ 8356 copy() { 8357 return new _ContentType(this.type._copy()); 8358 } 8359 /** 8360 * @param {number} offset 8361 * @return {ContentType} 8362 */ 8363 splice(offset) { 8364 throw methodUnimplemented(); 8365 } 8366 /** 8367 * @param {ContentType} right 8368 * @return {boolean} 8369 */ 8370 mergeWith(right) { 8371 return false; 8372 } 8373 /** 8374 * @param {Transaction} transaction 8375 * @param {Item} item 8376 */ 8377 integrate(transaction, item) { 8378 this.type._integrate(transaction.doc, item); 8379 } 8380 /** 8381 * @param {Transaction} transaction 8382 */ 8383 delete(transaction) { 8384 let item = this.type._start; 8385 while (item !== null) { 8386 if (!item.deleted) { 8387 item.delete(transaction); 8388 } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { 8389 transaction._mergeStructs.push(item); 8390 } 8391 item = item.right; 8392 } 8393 this.type._map.forEach((item2) => { 8394 if (!item2.deleted) { 8395 item2.delete(transaction); 8396 } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { 8397 transaction._mergeStructs.push(item2); 8398 } 8399 }); 8400 transaction.changed.delete(this.type); 8401 } 8402 /** 8403 * @param {StructStore} store 8404 */ 8405 gc(store) { 8406 let item = this.type._start; 8407 while (item !== null) { 8408 item.gc(store, true); 8409 item = item.right; 8410 } 8411 this.type._start = null; 8412 this.type._map.forEach( 8413 /** @param {Item | null} item */ 8414 (item2) => { 8415 while (item2 !== null) { 8416 item2.gc(store, true); 8417 item2 = item2.left; 8418 } 8419 } 8420 ); 8421 this.type._map = /* @__PURE__ */ new Map(); 8422 } 8423 /** 8424 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8425 * @param {number} offset 8426 */ 8427 write(encoder, offset) { 8428 this.type._write(encoder); 8429 } 8430 /** 8431 * @return {number} 8432 */ 8433 getRef() { 8434 return 7; 8435 } 8436 }; 8437 var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); 8438 var followRedone = (store, id2) => { 8439 let nextID = id2; 8440 let diff = 0; 8441 let item; 8442 do { 8443 if (diff > 0) { 8444 nextID = createID(nextID.client, nextID.clock + diff); 8445 } 8446 item = getItem(store, nextID); 8447 diff = nextID.clock - item.id.clock; 8448 nextID = item.redone; 8449 } while (nextID !== null && item instanceof Item); 8450 return { 8451 item, 8452 diff 8453 }; 8454 }; 8455 var keepItem = (item, keep) => { 8456 while (item !== null && item.keep !== keep) { 8457 item.keep = keep; 8458 item = /** @type {AbstractType<any>} */ 8459 item.parent._item; 8460 } 8461 }; 8462 var splitItem = (transaction, leftItem, diff) => { 8463 const { client, clock } = leftItem.id; 8464 const rightItem = new Item( 8465 createID(client, clock + diff), 8466 leftItem, 8467 createID(client, clock + diff - 1), 8468 leftItem.right, 8469 leftItem.rightOrigin, 8470 leftItem.parent, 8471 leftItem.parentSub, 8472 leftItem.content.splice(diff) 8473 ); 8474 if (leftItem.deleted) { 8475 rightItem.markDeleted(); 8476 } 8477 if (leftItem.keep) { 8478 rightItem.keep = true; 8479 } 8480 if (leftItem.redone !== null) { 8481 rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); 8482 } 8483 leftItem.right = rightItem; 8484 if (rightItem.right !== null) { 8485 rightItem.right.left = rightItem; 8486 } 8487 transaction._mergeStructs.push(rightItem); 8488 if (rightItem.parentSub !== null && rightItem.right === null) { 8489 rightItem.parent._map.set(rightItem.parentSub, rightItem); 8490 } 8491 leftItem.length = diff; 8492 return rightItem; 8493 }; 8494 var isDeletedByUndoStack = (stack, id2) => some( 8495 stack, 8496 /** @param {StackItem} s */ 8497 (s) => isDeleted(s.deletions, id2) 8498 ); 8499 var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { 8500 const doc2 = transaction.doc; 8501 const store = doc2.store; 8502 const ownClientID = doc2.clientID; 8503 const redone = item.redone; 8504 if (redone !== null) { 8505 return getItemCleanStart(transaction, redone); 8506 } 8507 let parentItem = ( 8508 /** @type {AbstractType<any>} */ 8509 item.parent._item 8510 ); 8511 let left = null; 8512 let right; 8513 if (parentItem !== null && parentItem.deleted === true) { 8514 if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { 8515 return null; 8516 } 8517 while (parentItem.redone !== null) { 8518 parentItem = getItemCleanStart(transaction, parentItem.redone); 8519 } 8520 } 8521 const parentType = parentItem === null ? ( 8522 /** @type {AbstractType<any>} */ 8523 item.parent 8524 ) : ( 8525 /** @type {ContentType} */ 8526 parentItem.content.type 8527 ); 8528 if (item.parentSub === null) { 8529 left = item.left; 8530 right = item; 8531 while (left !== null) { 8532 let leftTrace = left; 8533 while (leftTrace !== null && /** @type {AbstractType<any>} */ 8534 leftTrace.parent._item !== parentItem) { 8535 leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); 8536 } 8537 if (leftTrace !== null && /** @type {AbstractType<any>} */ 8538 leftTrace.parent._item === parentItem) { 8539 left = leftTrace; 8540 break; 8541 } 8542 left = left.left; 8543 } 8544 while (right !== null) { 8545 let rightTrace = right; 8546 while (rightTrace !== null && /** @type {AbstractType<any>} */ 8547 rightTrace.parent._item !== parentItem) { 8548 rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); 8549 } 8550 if (rightTrace !== null && /** @type {AbstractType<any>} */ 8551 rightTrace.parent._item === parentItem) { 8552 right = rightTrace; 8553 break; 8554 } 8555 right = right.right; 8556 } 8557 } else { 8558 right = null; 8559 if (item.right && !ignoreRemoteMapChanges) { 8560 left = item; 8561 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))) { 8562 left = left.right; 8563 while (left.redone) left = getItemCleanStart(transaction, left.redone); 8564 } 8565 if (left && left.right !== null) { 8566 return null; 8567 } 8568 } else { 8569 left = parentType._map.get(item.parentSub) || null; 8570 } 8571 } 8572 const nextClock = getState(store, ownClientID); 8573 const nextId = createID(ownClientID, nextClock); 8574 const redoneItem = new Item( 8575 nextId, 8576 left, 8577 left && left.lastId, 8578 right, 8579 right && right.id, 8580 parentType, 8581 item.parentSub, 8582 item.content.copy() 8583 ); 8584 item.redone = nextId; 8585 keepItem(redoneItem, true); 8586 redoneItem.integrate(transaction, 0); 8587 return redoneItem; 8588 }; 8589 var Item = class _Item extends AbstractStruct { 8590 /** 8591 * @param {ID} id 8592 * @param {Item | null} left 8593 * @param {ID | null} origin 8594 * @param {Item | null} right 8595 * @param {ID | null} rightOrigin 8596 * @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. 8597 * @param {string | null} parentSub 8598 * @param {AbstractContent} content 8599 */ 8600 constructor(id2, left, origin2, right, rightOrigin, parent, parentSub, content) { 8601 super(id2, content.getLength()); 8602 this.origin = origin2; 8603 this.left = left; 8604 this.right = right; 8605 this.rightOrigin = rightOrigin; 8606 this.parent = parent; 8607 this.parentSub = parentSub; 8608 this.redone = null; 8609 this.content = content; 8610 this.info = this.content.isCountable() ? BIT2 : 0; 8611 } 8612 /** 8613 * This is used to mark the item as an indexed fast-search marker 8614 * 8615 * @type {boolean} 8616 */ 8617 set marker(isMarked) { 8618 if ((this.info & BIT4) > 0 !== isMarked) { 8619 this.info ^= BIT4; 8620 } 8621 } 8622 get marker() { 8623 return (this.info & BIT4) > 0; 8624 } 8625 /** 8626 * If true, do not garbage collect this Item. 8627 */ 8628 get keep() { 8629 return (this.info & BIT1) > 0; 8630 } 8631 set keep(doKeep) { 8632 if (this.keep !== doKeep) { 8633 this.info ^= BIT1; 8634 } 8635 } 8636 get countable() { 8637 return (this.info & BIT2) > 0; 8638 } 8639 /** 8640 * Whether this item was deleted or not. 8641 * @type {Boolean} 8642 */ 8643 get deleted() { 8644 return (this.info & BIT3) > 0; 8645 } 8646 set deleted(doDelete) { 8647 if (this.deleted !== doDelete) { 8648 this.info ^= BIT3; 8649 } 8650 } 8651 markDeleted() { 8652 this.info |= BIT3; 8653 } 8654 /** 8655 * Return the creator clientID of the missing op or define missing items and return null. 8656 * 8657 * @param {Transaction} transaction 8658 * @param {StructStore} store 8659 * @return {null | number} 8660 */ 8661 getMissing(transaction, store) { 8662 if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store, this.origin.client)) { 8663 return this.origin.client; 8664 } 8665 if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store, this.rightOrigin.client)) { 8666 return this.rightOrigin.client; 8667 } 8668 if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store, this.parent.client)) { 8669 return this.parent.client; 8670 } 8671 if (this.origin) { 8672 this.left = getItemCleanEnd(transaction, store, this.origin); 8673 this.origin = this.left.lastId; 8674 } 8675 if (this.rightOrigin) { 8676 this.right = getItemCleanStart(transaction, this.rightOrigin); 8677 this.rightOrigin = this.right.id; 8678 } 8679 if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { 8680 this.parent = null; 8681 } else if (!this.parent) { 8682 if (this.left && this.left.constructor === _Item) { 8683 this.parent = this.left.parent; 8684 this.parentSub = this.left.parentSub; 8685 } else if (this.right && this.right.constructor === _Item) { 8686 this.parent = this.right.parent; 8687 this.parentSub = this.right.parentSub; 8688 } 8689 } else if (this.parent.constructor === ID) { 8690 const parentItem = getItem(store, this.parent); 8691 if (parentItem.constructor === GC) { 8692 this.parent = null; 8693 } else { 8694 this.parent = /** @type {ContentType} */ 8695 parentItem.content.type; 8696 } 8697 } 8698 return null; 8699 } 8700 /** 8701 * @param {Transaction} transaction 8702 * @param {number} offset 8703 */ 8704 integrate(transaction, offset) { 8705 if (offset > 0) { 8706 this.id.clock += offset; 8707 this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); 8708 this.origin = this.left.lastId; 8709 this.content = this.content.splice(offset); 8710 this.length -= offset; 8711 } 8712 if (this.parent) { 8713 if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { 8714 let left = this.left; 8715 let o; 8716 if (left !== null) { 8717 o = left.right; 8718 } else if (this.parentSub !== null) { 8719 o = /** @type {AbstractType<any>} */ 8720 this.parent._map.get(this.parentSub) || null; 8721 while (o !== null && o.left !== null) { 8722 o = o.left; 8723 } 8724 } else { 8725 o = /** @type {AbstractType<any>} */ 8726 this.parent._start; 8727 } 8728 const conflictingItems = /* @__PURE__ */ new Set(); 8729 const itemsBeforeOrigin = /* @__PURE__ */ new Set(); 8730 while (o !== null && o !== this.right) { 8731 itemsBeforeOrigin.add(o); 8732 conflictingItems.add(o); 8733 if (compareIDs(this.origin, o.origin)) { 8734 if (o.id.client < this.id.client) { 8735 left = o; 8736 conflictingItems.clear(); 8737 } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { 8738 break; 8739 } 8740 } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { 8741 if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { 8742 left = o; 8743 conflictingItems.clear(); 8744 } 8745 } else { 8746 break; 8747 } 8748 o = o.right; 8749 } 8750 this.left = left; 8751 } 8752 if (this.left !== null) { 8753 const right = this.left.right; 8754 this.right = right; 8755 this.left.right = this; 8756 } else { 8757 let r; 8758 if (this.parentSub !== null) { 8759 r = /** @type {AbstractType<any>} */ 8760 this.parent._map.get(this.parentSub) || null; 8761 while (r !== null && r.left !== null) { 8762 r = r.left; 8763 } 8764 } else { 8765 r = /** @type {AbstractType<any>} */ 8766 this.parent._start; 8767 this.parent._start = this; 8768 } 8769 this.right = r; 8770 } 8771 if (this.right !== null) { 8772 this.right.left = this; 8773 } else if (this.parentSub !== null) { 8774 this.parent._map.set(this.parentSub, this); 8775 if (this.left !== null) { 8776 this.left.delete(transaction); 8777 } 8778 } 8779 if (this.parentSub === null && this.countable && !this.deleted) { 8780 this.parent._length += this.length; 8781 } 8782 addStruct(transaction.doc.store, this); 8783 this.content.integrate(transaction, this); 8784 addChangedTypeToTransaction( 8785 transaction, 8786 /** @type {AbstractType<any>} */ 8787 this.parent, 8788 this.parentSub 8789 ); 8790 if ( 8791 /** @type {AbstractType<any>} */ 8792 this.parent._item !== null && /** @type {AbstractType<any>} */ 8793 this.parent._item.deleted || this.parentSub !== null && this.right !== null 8794 ) { 8795 this.delete(transaction); 8796 } 8797 } else { 8798 new GC(this.id, this.length).integrate(transaction, 0); 8799 } 8800 } 8801 /** 8802 * Returns the next non-deleted item 8803 */ 8804 get next() { 8805 let n = this.right; 8806 while (n !== null && n.deleted) { 8807 n = n.right; 8808 } 8809 return n; 8810 } 8811 /** 8812 * Returns the previous non-deleted item 8813 */ 8814 get prev() { 8815 let n = this.left; 8816 while (n !== null && n.deleted) { 8817 n = n.left; 8818 } 8819 return n; 8820 } 8821 /** 8822 * Computes the last content address of this Item. 8823 */ 8824 get lastId() { 8825 return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); 8826 } 8827 /** 8828 * Try to merge two items 8829 * 8830 * @param {Item} right 8831 * @return {boolean} 8832 */ 8833 mergeWith(right) { 8834 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)) { 8835 const searchMarker = ( 8836 /** @type {AbstractType<any>} */ 8837 this.parent._searchMarker 8838 ); 8839 if (searchMarker) { 8840 searchMarker.forEach((marker) => { 8841 if (marker.p === right) { 8842 marker.p = this; 8843 if (!this.deleted && this.countable) { 8844 marker.index -= this.length; 8845 } 8846 } 8847 }); 8848 } 8849 if (right.keep) { 8850 this.keep = true; 8851 } 8852 this.right = right.right; 8853 if (this.right !== null) { 8854 this.right.left = this; 8855 } 8856 this.length += right.length; 8857 return true; 8858 } 8859 return false; 8860 } 8861 /** 8862 * Mark this Item as deleted. 8863 * 8864 * @param {Transaction} transaction 8865 */ 8866 delete(transaction) { 8867 if (!this.deleted) { 8868 const parent = ( 8869 /** @type {AbstractType<any>} */ 8870 this.parent 8871 ); 8872 if (this.countable && this.parentSub === null) { 8873 parent._length -= this.length; 8874 } 8875 this.markDeleted(); 8876 addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); 8877 addChangedTypeToTransaction(transaction, parent, this.parentSub); 8878 this.content.delete(transaction); 8879 } 8880 } 8881 /** 8882 * @param {StructStore} store 8883 * @param {boolean} parentGCd 8884 */ 8885 gc(store, parentGCd) { 8886 if (!this.deleted) { 8887 throw unexpectedCase(); 8888 } 8889 this.content.gc(store); 8890 if (parentGCd) { 8891 replaceStruct(store, this, new GC(this.id, this.length)); 8892 } else { 8893 this.content = new ContentDeleted(this.length); 8894 } 8895 } 8896 /** 8897 * Transform the properties of this type to binary and write it to an 8898 * BinaryEncoder. 8899 * 8900 * This is called when this Item is sent to a remote peer. 8901 * 8902 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8903 * @param {number} offset 8904 */ 8905 write(encoder, offset) { 8906 const origin2 = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; 8907 const rightOrigin = this.rightOrigin; 8908 const parentSub = this.parentSub; 8909 const info = this.content.getRef() & BITS5 | (origin2 === null ? 0 : BIT8) | // origin is defined 8910 (rightOrigin === null ? 0 : BIT7) | // right origin is defined 8911 (parentSub === null ? 0 : BIT6); 8912 encoder.writeInfo(info); 8913 if (origin2 !== null) { 8914 encoder.writeLeftID(origin2); 8915 } 8916 if (rightOrigin !== null) { 8917 encoder.writeRightID(rightOrigin); 8918 } 8919 if (origin2 === null && rightOrigin === null) { 8920 const parent = ( 8921 /** @type {AbstractType<any>} */ 8922 this.parent 8923 ); 8924 if (parent._item !== void 0) { 8925 const parentItem = parent._item; 8926 if (parentItem === null) { 8927 const ykey = findRootTypeKey(parent); 8928 encoder.writeParentInfo(true); 8929 encoder.writeString(ykey); 8930 } else { 8931 encoder.writeParentInfo(false); 8932 encoder.writeLeftID(parentItem.id); 8933 } 8934 } else if (parent.constructor === String) { 8935 encoder.writeParentInfo(true); 8936 encoder.writeString(parent); 8937 } else if (parent.constructor === ID) { 8938 encoder.writeParentInfo(false); 8939 encoder.writeLeftID(parent); 8940 } else { 8941 unexpectedCase(); 8942 } 8943 if (parentSub !== null) { 8944 encoder.writeString(parentSub); 8945 } 8946 } 8947 this.content.write(encoder, offset); 8948 } 8949 }; 8950 var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); 8951 var contentRefs = [ 8952 () => { 8953 unexpectedCase(); 8954 }, 8955 // GC is not ItemContent 8956 readContentDeleted, 8957 // 1 8958 readContentJSON, 8959 // 2 8960 readContentBinary, 8961 // 3 8962 readContentString, 8963 // 4 8964 readContentEmbed, 8965 // 5 8966 readContentFormat, 8967 // 6 8968 readContentType, 8969 // 7 8970 readContentAny, 8971 // 8 8972 readContentDoc, 8973 // 9 8974 () => { 8975 unexpectedCase(); 8976 } 8977 // 10 - Skip is not ItemContent 8978 ]; 8979 var structSkipRefNumber = 10; 8980 var Skip = class extends AbstractStruct { 8981 get deleted() { 8982 return true; 8983 } 8984 delete() { 8985 } 8986 /** 8987 * @param {Skip} right 8988 * @return {boolean} 8989 */ 8990 mergeWith(right) { 8991 if (this.constructor !== right.constructor) { 8992 return false; 8993 } 8994 this.length += right.length; 8995 return true; 8996 } 8997 /** 8998 * @param {Transaction} transaction 8999 * @param {number} offset 9000 */ 9001 integrate(transaction, offset) { 9002 unexpectedCase(); 9003 } 9004 /** 9005 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9006 * @param {number} offset 9007 */ 9008 write(encoder, offset) { 9009 encoder.writeInfo(structSkipRefNumber); 9010 writeVarUint(encoder.restEncoder, this.length - offset); 9011 } 9012 /** 9013 * @param {Transaction} transaction 9014 * @param {StructStore} store 9015 * @return {null | number} 9016 */ 9017 getMissing(transaction, store) { 9018 return null; 9019 } 9020 }; 9021 var glo = ( 9022 /** @type {any} */ 9023 typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} 9024 ); 9025 var importIdentifier = "__ $YJS$ __"; 9026 if (glo[importIdentifier] === true) { 9027 console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); 9028 } 9029 glo[importIdentifier] = true; 9030 9031 // node_modules/y-protocols/awareness.js 9032 var outdatedTimeout = 3e4; 9033 var Awareness = class extends Observable { 9034 /** 9035 * @param {Y.Doc} doc 9036 */ 9037 constructor(doc2) { 9038 super(); 9039 this.doc = doc2; 9040 this.clientID = doc2.clientID; 9041 this.states = /* @__PURE__ */ new Map(); 9042 this.meta = /* @__PURE__ */ new Map(); 9043 this._checkInterval = /** @type {any} */ 9044 setInterval(() => { 9045 const now = getUnixTime(); 9046 if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ 9047 this.meta.get(this.clientID).lastUpdated) { 9048 this.setLocalState(this.getLocalState()); 9049 } 9050 const remove = []; 9051 this.meta.forEach((meta, clientid) => { 9052 if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { 9053 remove.push(clientid); 9054 } 9055 }); 9056 if (remove.length > 0) { 9057 removeAwarenessStates(this, remove, "timeout"); 9058 } 9059 }, floor(outdatedTimeout / 10)); 9060 doc2.on("destroy", () => { 9061 this.destroy(); 9062 }); 9063 this.setLocalState({}); 9064 } 9065 destroy() { 9066 this.emit("destroy", [this]); 9067 this.setLocalState(null); 9068 super.destroy(); 9069 clearInterval(this._checkInterval); 9070 } 9071 /** 9072 * @return {Object<string,any>|null} 9073 */ 9074 getLocalState() { 9075 return this.states.get(this.clientID) || null; 9076 } 9077 /** 9078 * @param {Object<string,any>|null} state 9079 */ 9080 setLocalState(state) { 9081 const clientID = this.clientID; 9082 const currLocalMeta = this.meta.get(clientID); 9083 const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; 9084 const prevState = this.states.get(clientID); 9085 if (state === null) { 9086 this.states.delete(clientID); 9087 } else { 9088 this.states.set(clientID, state); 9089 } 9090 this.meta.set(clientID, { 9091 clock, 9092 lastUpdated: getUnixTime() 9093 }); 9094 const added = []; 9095 const updated = []; 9096 const filteredUpdated = []; 9097 const removed = []; 9098 if (state === null) { 9099 removed.push(clientID); 9100 } else if (prevState == null) { 9101 if (state != null) { 9102 added.push(clientID); 9103 } 9104 } else { 9105 updated.push(clientID); 9106 if (!equalityDeep(prevState, state)) { 9107 filteredUpdated.push(clientID); 9108 } 9109 } 9110 if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { 9111 this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); 9112 } 9113 this.emit("update", [{ added, updated, removed }, "local"]); 9114 } 9115 /** 9116 * @param {string} field 9117 * @param {any} value 9118 */ 9119 setLocalStateField(field, value) { 9120 const state = this.getLocalState(); 9121 if (state !== null) { 9122 this.setLocalState({ 9123 ...state, 9124 [field]: value 9125 }); 9126 } 9127 } 9128 /** 9129 * @return {Map<number,Object<string,any>>} 9130 */ 9131 getStates() { 9132 return this.states; 9133 } 9134 }; 9135 var removeAwarenessStates = (awareness, clients, origin2) => { 9136 const removed = []; 9137 for (let i = 0; i < clients.length; i++) { 9138 const clientID = clients[i]; 9139 if (awareness.states.has(clientID)) { 9140 awareness.states.delete(clientID); 9141 if (clientID === awareness.clientID) { 9142 const curMeta = ( 9143 /** @type {MetaClientState} */ 9144 awareness.meta.get(clientID) 9145 ); 9146 awareness.meta.set(clientID, { 9147 clock: curMeta.clock + 1, 9148 lastUpdated: getUnixTime() 9149 }); 9150 } 9151 removed.push(clientID); 9152 } 9153 } 9154 if (removed.length > 0) { 9155 awareness.emit("change", [{ added: [], updated: [], removed }, origin2]); 9156 awareness.emit("update", [{ added: [], updated: [], removed }, origin2]); 9157 } 9158 }; 9159 9160 // packages/sync/build-module/config.mjs 9161 var CRDT_DOC_VERSION = 1; 9162 var CRDT_DOC_META_PERSISTENCE_KEY = "fromPersistence"; 9163 var CRDT_RECORD_MAP_KEY = "document"; 9164 var CRDT_STATE_MAP_KEY = "state"; 9165 var CRDT_STATE_MAP_SAVED_AT_KEY = "savedAt"; 9166 var CRDT_STATE_MAP_SAVED_BY_KEY = "savedBy"; 9167 var CRDT_STATE_MAP_VERSION_KEY = "version"; 9168 var LOCAL_EDITOR_ORIGIN = "gutenberg"; 9169 var LOCAL_SYNC_MANAGER_ORIGIN = "syncManager"; 9170 var LOCAL_UNDO_IGNORED_ORIGIN = "gutenberg-undo-ignored"; 9171 9172 // packages/sync/build-module/errors.mjs 9173 var ConnectionErrorCode = /* @__PURE__ */ ((ConnectionErrorCode2) => { 9174 ConnectionErrorCode2["AUTHENTICATION_FAILED"] = "authentication-failed"; 9175 ConnectionErrorCode2["CONNECTION_EXPIRED"] = "connection-expired"; 9176 ConnectionErrorCode2["CONNECTION_LIMIT_EXCEEDED"] = "connection-limit-exceeded"; 9177 ConnectionErrorCode2["DOCUMENT_SIZE_LIMIT_EXCEEDED"] = "document-size-limit-exceeded"; 9178 ConnectionErrorCode2["PROTOCOL_MISMATCH"] = "protocol-mismatch"; 9179 ConnectionErrorCode2["UNKNOWN_ERROR"] = "unknown-error"; 9180 return ConnectionErrorCode2; 9181 })(ConnectionErrorCode || {}); 9182 var ConnectionError = class extends Error { 9183 constructor(code = "unknown-error", message) { 9184 super(message); 9185 this.code = code; 9186 this.name = "ConnectionError"; 9187 } 9188 }; 9189 9190 // packages/sync/build-module/lock-unlock.mjs 9191 var import_private_apis = __toESM(require_private_apis(), 1); 9192 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 9193 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 9194 "@wordpress/sync" 9195 ); 9196 9197 // packages/sync/build-module/performance.mjs 9198 function logPerformanceTiming(fn) { 9199 return function(...args2) { 9200 const start = performance.now(); 9201 const result = fn.apply(this, args2); 9202 const end = performance.now(); 9203 console.log( 9204 `[SyncManager][performance]: $fn.name} took ${(end - start).toFixed(2)} ms` 9205 ); 9206 return result; 9207 }; 9208 } 9209 function passThru(fn) { 9210 return ((...args2) => fn(...args2)); 9211 } 9212 9213 // packages/sync/build-module/providers/index.mjs 9214 var import_hooks3 = __toESM(require_hooks(), 1); 9215 9216 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 9217 var import_hooks2 = __toESM(require_hooks(), 1); 9218 9219 // node_modules/y-protocols/sync.js 9220 var messageYjsSyncStep1 = 0; 9221 var messageYjsSyncStep2 = 1; 9222 var messageYjsUpdate = 2; 9223 var writeSyncStep1 = (encoder, doc2) => { 9224 writeVarUint(encoder, messageYjsSyncStep1); 9225 const sv = encodeStateVector(doc2); 9226 writeVarUint8Array(encoder, sv); 9227 }; 9228 var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { 9229 writeVarUint(encoder, messageYjsSyncStep2); 9230 writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); 9231 }; 9232 var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); 9233 var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { 9234 try { 9235 applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); 9236 } catch (error) { 9237 if (errorHandler != null) errorHandler( 9238 /** @type {Error} */ 9239 error 9240 ); 9241 console.error("Caught error while handling a Yjs update", error); 9242 } 9243 }; 9244 var readUpdate2 = readSyncStep2; 9245 var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { 9246 const messageType = readVarUint(decoder); 9247 switch (messageType) { 9248 case messageYjsSyncStep1: 9249 readSyncStep1(decoder, encoder, doc2); 9250 break; 9251 case messageYjsSyncStep2: 9252 readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); 9253 break; 9254 case messageYjsUpdate: 9255 readUpdate2(decoder, doc2, transactionOrigin, errorHandler); 9256 break; 9257 default: 9258 throw new Error("Unknown message type"); 9259 } 9260 return messageType; 9261 }; 9262 9263 // packages/sync/build-module/providers/http-polling/config.mjs 9264 var import_hooks = __toESM(require_hooks(), 1); 9265 var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; 9266 var ERROR_RETRY_DELAYS_SOLO_MS = [ 9267 2e3, 9268 4e3, 9269 8e3, 9270 12e3 9271 // Solo: 26s total retry time solo before dialog 9272 ]; 9273 var ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS = [ 9274 1e3, 9275 2e3, 9276 4e3, 9277 8e3 9278 // With collaborators: 15s total retry time before dialog 9279 ]; 9280 var DISCONNECT_DIALOG_RETRY_MS = 3e4; 9281 var MANUAL_RETRY_INTERVAL_MS = 15e3; 9282 var MAX_ENCODED_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; 9283 var MAX_UPDATE_SIZE_IN_BYTES = Math.floor(MAX_ENCODED_UPDATE_SIZE_IN_BYTES / 4) * 3; 9284 var MAX_ROOMS_PER_REQUEST = 50; 9285 var MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES = 15 * 1024 * 1024; 9286 var MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES = 2 * 1024 * 1024; 9287 var DEFAULT_POLLING_INTERVAL_IN_MS = 4e3; 9288 var DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = 1e3; 9289 function getFilteredPollingInterval(hookName, defaultInterval) { 9290 const filteredInterval = (0, import_hooks.applyFilters)(hookName, defaultInterval); 9291 if (typeof filteredInterval !== "number" || !Number.isFinite(filteredInterval) || filteredInterval <= 0) { 9292 return defaultInterval; 9293 } 9294 return Math.min(filteredInterval, defaultInterval); 9295 } 9296 var POLLING_INTERVAL_IN_MS = getFilteredPollingInterval( 9297 "sync.pollingManager.pollingInterval", 9298 DEFAULT_POLLING_INTERVAL_IN_MS 9299 ); 9300 var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = getFilteredPollingInterval( 9301 "sync.pollingManager.pollingIntervalWithCollaborators", 9302 DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS 9303 ); 9304 var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; 9305 9306 // packages/sync/build-module/providers/http-polling/types.mjs 9307 var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { 9308 SyncUpdateType2["COMPACTION"] = "compaction"; 9309 SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; 9310 SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; 9311 SyncUpdateType2["UPDATE"] = "update"; 9312 return SyncUpdateType2; 9313 })(SyncUpdateType || {}); 9314 9315 // packages/sync/build-module/providers/http-polling/utils.mjs 9316 var import_api_fetch = __toESM(require_api_fetch(), 1); 9317 var SYNC_API_PATH = "/wp-sync/v1/updates"; 9318 function uint8ArrayToBase64(data) { 9319 let binary = ""; 9320 const len = data.byteLength; 9321 for (let i = 0; i < len; i++) { 9322 binary += String.fromCharCode(data[i]); 9323 } 9324 return globalThis.btoa(binary); 9325 } 9326 function base64ToUint8Array(base64) { 9327 const binaryString = globalThis.atob(base64); 9328 const len = binaryString.length; 9329 const bytes = new Uint8Array(len); 9330 for (let i = 0; i < len; i++) { 9331 bytes[i] = binaryString.charCodeAt(i); 9332 } 9333 return bytes; 9334 } 9335 function createSyncUpdate(data, type) { 9336 return { 9337 data: uint8ArrayToBase64(data), 9338 type 9339 }; 9340 } 9341 function createUpdateQueue(initial = [], paused = true) { 9342 let isPaused = paused; 9343 const updates = [...initial]; 9344 return { 9345 add(update) { 9346 updates.push(update); 9347 }, 9348 addBulk(bulkUpdates) { 9349 if (0 === bulkUpdates.length) { 9350 return; 9351 } 9352 updates.push(...bulkUpdates); 9353 }, 9354 clear() { 9355 updates.splice(0, updates.length); 9356 }, 9357 get() { 9358 if (isPaused) { 9359 return []; 9360 } 9361 return updates.splice(0, updates.length); 9362 }, 9363 pause() { 9364 isPaused = true; 9365 }, 9366 peek() { 9367 if (isPaused) { 9368 return []; 9369 } 9370 return [...updates]; 9371 }, 9372 restore(restoredUpdates) { 9373 const filtered = restoredUpdates.filter( 9374 (u) => u.type !== SyncUpdateType.COMPACTION 9375 ); 9376 if (0 === filtered.length) { 9377 return; 9378 } 9379 updates.unshift(...filtered); 9380 }, 9381 restoreExact(restoredUpdates) { 9382 if (0 === restoredUpdates.length) { 9383 return; 9384 } 9385 updates.unshift(...restoredUpdates); 9386 }, 9387 resume() { 9388 isPaused = false; 9389 }, 9390 size() { 9391 return updates.length; 9392 }, 9393 take(count) { 9394 if (isPaused || count <= 0) { 9395 return []; 9396 } 9397 return updates.splice(0, count); 9398 } 9399 }; 9400 } 9401 function postSyncUpdate(payload) { 9402 return (0, import_api_fetch.default)({ 9403 method: "POST", 9404 path: SYNC_API_PATH, 9405 data: payload 9406 }); 9407 } 9408 function postSyncUpdateNonBlocking(payload) { 9409 if (payload.rooms.length === 0) { 9410 return; 9411 } 9412 (0, import_api_fetch.default)({ 9413 method: "POST", 9414 path: SYNC_API_PATH, 9415 data: payload, 9416 keepalive: true 9417 }).catch(() => { 9418 }); 9419 } 9420 function intValueOrDefault(value, defaultValue) { 9421 const intValue = parseInt(String(value), 10); 9422 return isNaN(intValue) ? defaultValue : intValue; 9423 } 9424 function rotateWindow(items, offset, size2) { 9425 if (items.length === 0) { 9426 return { window: [], nextOffset: 0 }; 9427 } 9428 const start = (offset % items.length + items.length) % items.length; 9429 const wrapped = [...items.slice(start), ...items.slice(0, start)]; 9430 return { 9431 window: wrapped.slice(0, Math.max(0, size2)), 9432 nextOffset: (start + Math.max(0, size2)) % items.length 9433 }; 9434 } 9435 9436 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 9437 var POLLING_MANAGER_ORIGIN = "polling-manager"; 9438 function isForbiddenError(error) { 9439 return error?.data?.status === 403; 9440 } 9441 function isRequestBodyTooLargeError(error) { 9442 return error?.data?.status === 413 && error?.code === "rest_sync_body_too_large"; 9443 } 9444 function isProtocolMismatchError(error) { 9445 return error?.code === "rest_sync_protocol_mismatch"; 9446 } 9447 function handleForbiddenError(error, requestedRooms) { 9448 const requestedRoomNames = new Set( 9449 requestedRooms.map((room) => room.room) 9450 ); 9451 const forbiddenRooms = Array.isArray(error.data.rooms) ? error.data.rooms.filter((room) => requestedRoomNames.has(room)) : []; 9452 if (forbiddenRooms.length > 0) { 9453 for (const room of forbiddenRooms) { 9454 const state = roomStates.get(room); 9455 if (state) { 9456 state.log( 9457 "Permission denied, unregistering room", 9458 { error }, 9459 "error", 9460 true 9461 // force 9462 ); 9463 unregisterRoom(room, { sendDisconnectSignal: false }); 9464 } 9465 } 9466 for (const room of requestedRooms) { 9467 if (forbiddenRooms.includes(room.room)) { 9468 continue; 9469 } 9470 if (!roomStates.has(room.room)) { 9471 continue; 9472 } 9473 const remainingState = roomStates.get(room.room); 9474 if (room.updates.length > 0) { 9475 remainingState.updateQueue.restore(room.updates); 9476 } 9477 } 9478 } else { 9479 const rooms = [...roomStates.keys()]; 9480 for (const room of rooms) { 9481 const state = roomStates.get(room); 9482 if (state) { 9483 state.log( 9484 "Permission denied, unregistering room", 9485 { error }, 9486 "error", 9487 true 9488 // force 9489 ); 9490 unregisterRoom(room, { sendDisconnectSignal: false }); 9491 } 9492 } 9493 } 9494 } 9495 var roomStates = /* @__PURE__ */ new Map(); 9496 function createDeprecatedCompactionUpdate(updates) { 9497 const mergeable = updates.filter( 9498 (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( 9499 u.type 9500 ) 9501 ).map((u) => base64ToUint8Array(u.data)); 9502 return createSyncUpdate( 9503 mergeUpdatesV2(mergeable), 9504 SyncUpdateType.COMPACTION 9505 ); 9506 } 9507 function createSyncStep1Update(doc2) { 9508 const encoder = createEncoder(); 9509 writeSyncStep1(encoder, doc2); 9510 return createSyncUpdate( 9511 toUint8Array(encoder), 9512 SyncUpdateType.SYNC_STEP_1 9513 ); 9514 } 9515 function createSyncStep2Update(doc2, step1) { 9516 const decoder = createDecoder(step1); 9517 const encoder = createEncoder(); 9518 readSyncMessage( 9519 decoder, 9520 encoder, 9521 doc2, 9522 POLLING_MANAGER_ORIGIN 9523 ); 9524 return createSyncUpdate( 9525 toUint8Array(encoder), 9526 SyncUpdateType.SYNC_STEP_2 9527 ); 9528 } 9529 function processAwarenessUpdate(state, awareness) { 9530 const currentStates = awareness.getStates(); 9531 const added = /* @__PURE__ */ new Set(); 9532 const updated = /* @__PURE__ */ new Set(); 9533 const removed = new Set( 9534 Array.from(currentStates.keys()).filter( 9535 (clientId) => !state[clientId] 9536 ) 9537 ); 9538 Object.entries(state).forEach(([clientIdString, awarenessState]) => { 9539 const clientId = Number(clientIdString); 9540 if (clientId === awareness.clientID) { 9541 return; 9542 } 9543 if (null === awarenessState) { 9544 currentStates.delete(clientId); 9545 removed.add(clientId); 9546 return; 9547 } 9548 if (!currentStates.has(clientId)) { 9549 currentStates.set(clientId, awarenessState); 9550 added.add(clientId); 9551 return; 9552 } 9553 const currentState = currentStates.get(clientId); 9554 if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { 9555 currentStates.set(clientId, awarenessState); 9556 updated.add(clientId); 9557 } 9558 }); 9559 if (added.size + updated.size > 0) { 9560 awareness.emit("change", [ 9561 { 9562 added: Array.from(added), 9563 updated: Array.from(updated), 9564 // Left blank on purpose, as the removal of clients is handled in the if condition below. 9565 removed: [] 9566 } 9567 ]); 9568 } 9569 if (removed.size > 0) { 9570 removeAwarenessStates( 9571 awareness, 9572 Array.from(removed), 9573 POLLING_MANAGER_ORIGIN 9574 ); 9575 } 9576 } 9577 function processDocUpdate(update, doc2, onSync) { 9578 const data = base64ToUint8Array(update.data); 9579 switch (update.type) { 9580 case SyncUpdateType.SYNC_STEP_1: { 9581 return createSyncStep2Update(doc2, data); 9582 } 9583 case SyncUpdateType.SYNC_STEP_2: { 9584 const decoder = createDecoder(data); 9585 const encoder = createEncoder(); 9586 readSyncMessage( 9587 decoder, 9588 encoder, 9589 doc2, 9590 POLLING_MANAGER_ORIGIN 9591 ); 9592 onSync(); 9593 return; 9594 } 9595 case SyncUpdateType.COMPACTION: 9596 case SyncUpdateType.UPDATE: { 9597 applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); 9598 } 9599 } 9600 } 9601 function checkConnectionLimit(awareness, roomState) { 9602 if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { 9603 return false; 9604 } 9605 hasCheckedConnectionLimit = true; 9606 const maxClientsPerRoom = (0, import_hooks2.applyFilters)( 9607 "sync.pollingProvider.maxClientsPerRoom", 9608 DEFAULT_CLIENT_LIMIT_PER_ROOM, 9609 roomState.room 9610 ); 9611 const clientCount = Object.keys(awareness).length; 9612 const validatedLimit = intValueOrDefault( 9613 maxClientsPerRoom, 9614 DEFAULT_CLIENT_LIMIT_PER_ROOM 9615 ); 9616 if (clientCount > validatedLimit) { 9617 roomState.log("Connection limit exceeded", { 9618 clientCount, 9619 maxClientsPerRoom: validatedLimit, 9620 room: roomState.room 9621 }); 9622 return true; 9623 } 9624 return false; 9625 } 9626 var areListenersRegistered = false; 9627 var consecutiveFailures = 0; 9628 var hasCheckedConnectionLimit = false; 9629 var isManualRetry = false; 9630 var hasCollaborators = false; 9631 var isActiveBrowser = "visible" === document.visibilityState; 9632 var isPolling = false; 9633 var isUnloadPending = false; 9634 var pollInterval = POLLING_INTERVAL_IN_MS; 9635 var pollingTimeoutId = null; 9636 var syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 9637 var roomOverflowOffset = 0; 9638 function handleBeforeUnload() { 9639 isUnloadPending = true; 9640 } 9641 function handlePageHide() { 9642 const rooms = Array.from(roomStates.entries()).map( 9643 ([room, state]) => ({ 9644 after: 0, 9645 awareness: null, 9646 client_id: state.clientId, 9647 room, 9648 updates: [] 9649 }) 9650 ); 9651 for (let i = 0; i < rooms.length; i += MAX_ROOMS_PER_REQUEST) { 9652 postSyncUpdateNonBlocking({ 9653 rooms: rooms.slice(i, i + MAX_ROOMS_PER_REQUEST) 9654 }); 9655 } 9656 } 9657 function handleVisibilityChange() { 9658 const wasActive = isActiveBrowser; 9659 isActiveBrowser = document.visibilityState === "visible"; 9660 if (isActiveBrowser && !wasActive) { 9661 if (pollingTimeoutId) { 9662 clearTimeout(pollingTimeoutId); 9663 pollingTimeoutId = null; 9664 poll(); 9665 } 9666 } 9667 } 9668 function selectRoomsForRequest() { 9669 const allRooms = Array.from(roomStates.values()); 9670 if (allRooms.length <= MAX_ROOMS_PER_REQUEST) { 9671 return allRooms; 9672 } 9673 const primaryRoom = allRooms.find((state) => state.isPrimaryRoom); 9674 const overflowRooms = allRooms.filter((state) => state !== primaryRoom); 9675 const overflowSlotsPerRequest = MAX_ROOMS_PER_REQUEST - (primaryRoom ? 1 : 0); 9676 const { window: overflowSlice, nextOffset } = rotateWindow( 9677 overflowRooms, 9678 roomOverflowOffset, 9679 overflowSlotsPerRequest 9680 ); 9681 roomOverflowOffset = nextOffset; 9682 if (primaryRoom) { 9683 return [primaryRoom, ...overflowSlice]; 9684 } 9685 return overflowSlice; 9686 } 9687 var textEncoder = new TextEncoder(); 9688 function getJsonByteLength(value) { 9689 return textEncoder.encode(JSON.stringify(value)).byteLength; 9690 } 9691 function createPayloadRoom(state, updates = []) { 9692 return { 9693 after: state.endCursor ?? 0, 9694 awareness: state.localAwarenessState, 9695 client_id: state.clientId, 9696 room: state.room, 9697 updates 9698 }; 9699 } 9700 function getUpdatePayloadSizeDelta(existingUpdateCount, update) { 9701 const commaSize = existingUpdateCount === 0 ? 0 : 1; 9702 return commaSize + getJsonByteLength(update); 9703 } 9704 function buildPayloadForRequest(selectedRoomStates) { 9705 const payload = { rooms: [] }; 9706 const roomsInRequest = []; 9707 for (const state of selectedRoomStates) { 9708 const room = createPayloadRoom(state); 9709 const candidate = { rooms: [...payload.rooms, room] }; 9710 if (payload.rooms.length > 0 && getJsonByteLength(candidate) > syncRequestBodySizeLimit) { 9711 break; 9712 } 9713 payload.rooms.push(room); 9714 roomsInRequest.push(state); 9715 } 9716 const pendingUpdates = roomsInRequest.map( 9717 (state) => state.updateQueue.peek() 9718 ); 9719 const sentUpdateCounts = roomsInRequest.map(() => 0); 9720 let payloadSize = getJsonByteLength(payload); 9721 let addedUpdate = true; 9722 while (addedUpdate) { 9723 addedUpdate = false; 9724 for (let i = 0; i < roomsInRequest.length; i++) { 9725 const update = pendingUpdates[i][sentUpdateCounts[i]]; 9726 if (!update) { 9727 continue; 9728 } 9729 const sizeDelta = getUpdatePayloadSizeDelta( 9730 sentUpdateCounts[i], 9731 update 9732 ); 9733 if (payloadSize + sizeDelta > syncRequestBodySizeLimit) { 9734 continue; 9735 } 9736 sentUpdateCounts[i]++; 9737 payloadSize += sizeDelta; 9738 addedUpdate = true; 9739 } 9740 } 9741 for (let i = 0; i < roomsInRequest.length; i++) { 9742 payload.rooms[i].updates = roomsInRequest[i].updateQueue.take( 9743 sentUpdateCounts[i] 9744 ); 9745 } 9746 return { payload, roomsInRequest }; 9747 } 9748 function restoreExactUpdates(payload) { 9749 for (const room of payload.rooms) { 9750 if (!roomStates.has(room.room) || room.updates.length === 0) { 9751 continue; 9752 } 9753 roomStates.get(room.room).updateQueue.restoreExact(room.updates); 9754 } 9755 } 9756 function poll() { 9757 isPolling = true; 9758 pollingTimeoutId = null; 9759 async function start() { 9760 if (0 === roomStates.size) { 9761 isPolling = false; 9762 return; 9763 } 9764 isUnloadPending = false; 9765 const { payload, roomsInRequest } = buildPayloadForRequest( 9766 selectRoomsForRequest() 9767 ); 9768 roomsInRequest.forEach((state) => { 9769 state.onStatusChange({ status: "connecting" }); 9770 }); 9771 try { 9772 const { rooms } = await postSyncUpdate(payload); 9773 consecutiveFailures = 0; 9774 isManualRetry = false; 9775 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 9776 roomsInRequest.forEach((state) => { 9777 if (roomStates.get(state.room) !== state) { 9778 return; 9779 } 9780 state.onStatusChange({ status: "connected" }); 9781 }); 9782 hasCollaborators = false; 9783 rooms.forEach((room) => { 9784 if (!roomStates.has(room.room)) { 9785 return; 9786 } 9787 const roomState = roomStates.get(room.room); 9788 roomState.endCursor = room.end_cursor; 9789 if (checkConnectionLimit(room.awareness, roomState)) { 9790 roomState.onStatusChange({ 9791 status: "disconnected", 9792 error: new ConnectionError( 9793 ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, 9794 "Connection limit exceeded" 9795 ) 9796 }); 9797 unregisterRoom(room.room); 9798 return; 9799 } 9800 roomState.processAwarenessUpdate(room.awareness); 9801 if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { 9802 hasCollaborators = true; 9803 roomStates.forEach((state) => { 9804 state.updateQueue.resume(); 9805 }); 9806 } 9807 const responseUpdates = []; 9808 for (const update of room.updates) { 9809 try { 9810 const response = roomState.processDocUpdate(update); 9811 if (response) { 9812 responseUpdates.push(response); 9813 } 9814 } catch (error) { 9815 roomState.log( 9816 "Failed to apply sync update", 9817 { error, update }, 9818 "error", 9819 true 9820 // force 9821 ); 9822 } 9823 } 9824 roomState.updateQueue.addBulk(responseUpdates); 9825 if (room.should_compact) { 9826 roomState.log("Server requested compaction update"); 9827 roomState.updateQueue.clear(); 9828 roomState.updateQueue.add( 9829 roomState.createCompactionUpdate() 9830 ); 9831 } else if (room.compaction_request) { 9832 roomState.log("Server requested (old) compaction update"); 9833 roomState.updateQueue.add( 9834 createDeprecatedCompactionUpdate( 9835 room.compaction_request 9836 ) 9837 ); 9838 } 9839 }); 9840 if (isActiveBrowser && hasCollaborators) { 9841 pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; 9842 } else if (isActiveBrowser) { 9843 pollInterval = POLLING_INTERVAL_IN_MS; 9844 } else { 9845 pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; 9846 } 9847 } catch (error) { 9848 if (isForbiddenError(error)) { 9849 handleForbiddenError(error, payload.rooms); 9850 if (roomStates.size === 0) { 9851 isPolling = false; 9852 return; 9853 } 9854 } else if (isRequestBodyTooLargeError(error)) { 9855 syncRequestBodySizeLimit = Math.max( 9856 MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES, 9857 Math.floor(syncRequestBodySizeLimit / 2) 9858 ); 9859 pollInterval = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS[0] : ERROR_RETRY_DELAYS_SOLO_MS[0]; 9860 restoreExactUpdates(payload); 9861 for (const room of payload.rooms) { 9862 if (!roomStates.has(room.room)) { 9863 continue; 9864 } 9865 roomStates.get(room.room).log( 9866 "Sync request body too large, retrying with smaller batches", 9867 { 9868 error, 9869 nextPoll: pollInterval, 9870 syncRequestBodySizeLimit 9871 }, 9872 "error", 9873 true 9874 // force 9875 ); 9876 } 9877 } else if (isProtocolMismatchError(error)) { 9878 const affectedRooms = [...roomStates.entries()]; 9879 for (const [, state] of affectedRooms) { 9880 state.onStatusChange({ 9881 status: "disconnected", 9882 error: new ConnectionError( 9883 ConnectionErrorCode.PROTOCOL_MISMATCH, 9884 "Protocol mismatch between client and server" 9885 ) 9886 }); 9887 } 9888 for (const [room] of affectedRooms) { 9889 unregisterRoom(room, { sendDisconnectSignal: false }); 9890 } 9891 isPolling = false; 9892 return; 9893 } else { 9894 consecutiveFailures++; 9895 const retrySchedule = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS : ERROR_RETRY_DELAYS_SOLO_MS; 9896 if (consecutiveFailures <= retrySchedule.length) { 9897 pollInterval = retrySchedule[consecutiveFailures - 1]; 9898 } else { 9899 pollInterval = DISCONNECT_DIALOG_RETRY_MS; 9900 } 9901 if (isManualRetry) { 9902 pollInterval = MANUAL_RETRY_INTERVAL_MS; 9903 isManualRetry = false; 9904 } 9905 for (const room of payload.rooms) { 9906 if (!roomStates.has(room.room)) { 9907 continue; 9908 } 9909 const state = roomStates.get(room.room); 9910 if (room.updates.length > 0 && state.endCursor > 0) { 9911 state.updateQueue.clear(); 9912 state.updateQueue.add(state.createCompactionUpdate()); 9913 } else if (room.updates.length > 0) { 9914 state.updateQueue.restore(room.updates); 9915 } 9916 state.log( 9917 "Error posting sync update, will retry with backoff", 9918 { error, nextPoll: pollInterval }, 9919 "error", 9920 true 9921 // force 9922 ); 9923 } 9924 if (!isUnloadPending) { 9925 const backgroundRetriesFailed = consecutiveFailures > retrySchedule.length; 9926 roomsInRequest.forEach((state) => { 9927 if (roomStates.get(state.room) !== state) { 9928 return; 9929 } 9930 state.onStatusChange({ 9931 status: "disconnected", 9932 canManuallyRetry: true, 9933 consecutiveFailures, 9934 backgroundRetriesFailed, 9935 willAutoRetryInMs: pollInterval 9936 }); 9937 }); 9938 } 9939 } 9940 } 9941 pollingTimeoutId = setTimeout(poll, pollInterval); 9942 } 9943 void start(); 9944 } 9945 function registerRoom({ 9946 room, 9947 doc: doc2, 9948 awareness, 9949 log, 9950 onSync, 9951 onStatusChange 9952 }) { 9953 if (roomStates.has(room)) { 9954 return; 9955 } 9956 const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); 9957 const isPrimaryRoom = 0 === roomStates.size; 9958 function onAwarenessUpdate() { 9959 roomState.localAwarenessState = awareness.getLocalState() ?? {}; 9960 } 9961 function onDocUpdate(update, origin2) { 9962 if (POLLING_MANAGER_ORIGIN === origin2) { 9963 return; 9964 } 9965 if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { 9966 const state = roomStates.get(room); 9967 if (!state) { 9968 return; 9969 } 9970 state.log("Document size limit exceeded", { 9971 maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, 9972 updateSizeInBytes: update.byteLength 9973 }); 9974 state.onStatusChange({ 9975 status: "disconnected", 9976 error: new ConnectionError( 9977 ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, 9978 "Document size limit exceeded" 9979 ) 9980 }); 9981 unregisterRoom(room); 9982 return; 9983 } 9984 updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); 9985 } 9986 function unregister() { 9987 doc2.off("updateV2", onDocUpdate); 9988 awareness.off("change", onAwarenessUpdate); 9989 updateQueue.clear(); 9990 } 9991 const roomState = { 9992 clientId: doc2.clientID, 9993 createCompactionUpdate: () => createSyncUpdate( 9994 encodeStateAsUpdateV2(doc2), 9995 SyncUpdateType.COMPACTION 9996 ), 9997 endCursor: 0, 9998 isPrimaryRoom, 9999 localAwarenessState: awareness.getLocalState() ?? {}, 10000 log, 10001 onStatusChange, 10002 processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), 10003 processDocUpdate: (update) => processDocUpdate(update, doc2, onSync), 10004 room, 10005 unregister, 10006 updateQueue 10007 }; 10008 doc2.on("updateV2", onDocUpdate); 10009 awareness.on("change", onAwarenessUpdate); 10010 roomStates.set(room, roomState); 10011 if (!areListenersRegistered) { 10012 window.addEventListener("beforeunload", handleBeforeUnload); 10013 window.addEventListener("pagehide", handlePageHide); 10014 document.addEventListener("visibilitychange", handleVisibilityChange); 10015 areListenersRegistered = true; 10016 } 10017 if (!isPolling) { 10018 poll(); 10019 } 10020 } 10021 function unregisterRoom(room, { sendDisconnectSignal = true } = {}) { 10022 const state = roomStates.get(room); 10023 if (state) { 10024 if (sendDisconnectSignal) { 10025 const rooms = [ 10026 { 10027 after: 0, 10028 awareness: null, 10029 client_id: state.clientId, 10030 room, 10031 updates: [] 10032 } 10033 ]; 10034 postSyncUpdateNonBlocking({ rooms }); 10035 } 10036 state.unregister(); 10037 roomStates.delete(room); 10038 } 10039 if (0 === roomStates.size && areListenersRegistered) { 10040 window.removeEventListener("beforeunload", handleBeforeUnload); 10041 window.removeEventListener("pagehide", handlePageHide); 10042 document.removeEventListener( 10043 "visibilitychange", 10044 handleVisibilityChange 10045 ); 10046 areListenersRegistered = false; 10047 hasCheckedConnectionLimit = false; 10048 consecutiveFailures = 0; 10049 roomOverflowOffset = 0; 10050 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10051 } 10052 } 10053 function retryNow() { 10054 isManualRetry = true; 10055 if (pollingTimeoutId) { 10056 clearTimeout(pollingTimeoutId); 10057 pollingTimeoutId = null; 10058 poll(); 10059 } 10060 } 10061 var pollingManager = { 10062 registerRoom, 10063 retryNow, 10064 unregisterRoom 10065 }; 10066 10067 // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs 10068 var HttpPollingProvider = class extends ObservableV2 { 10069 constructor(options) { 10070 super(); 10071 this.options = options; 10072 this.log("Initializing", { room: options.room }); 10073 this.awareness = options.awareness ?? new Awareness(options.ydoc); 10074 this.connect(); 10075 } 10076 awareness; 10077 status = "disconnected"; 10078 synced = false; 10079 /** 10080 * Connect to the endpoint and initialize sync. 10081 */ 10082 connect() { 10083 this.log("Connecting"); 10084 pollingManager.registerRoom({ 10085 room: this.options.room, 10086 doc: this.options.ydoc, 10087 awareness: this.awareness, 10088 log: this.log, 10089 onStatusChange: this.emitStatus, 10090 onSync: this.onSync 10091 }); 10092 } 10093 /** 10094 * Destroy the provider and cleanup resources. 10095 */ 10096 destroy() { 10097 this.disconnect(); 10098 super.destroy(); 10099 } 10100 /** 10101 * Disconnect the provider and allow reconnection later. 10102 */ 10103 disconnect() { 10104 this.log("Disconnecting"); 10105 pollingManager.unregisterRoom(this.options.room); 10106 this.emitStatus({ status: "disconnected" }); 10107 } 10108 /** 10109 * Emit connection status, passing the full object through so that 10110 * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. 10111 * 10112 * @param connectionStatus The connection status object 10113 */ 10114 emitStatus = (connectionStatus) => { 10115 const { status } = connectionStatus; 10116 const error = status === "disconnected" ? connectionStatus.error : void 0; 10117 if (this.status === status && !error) { 10118 return; 10119 } 10120 if (status === "connecting" && this.status !== "disconnected") { 10121 return; 10122 } 10123 this.log("Status change", { status, error }); 10124 this.status = status; 10125 this.emit("status", [connectionStatus]); 10126 }; 10127 /** 10128 * Log debug messages if debugging is enabled. 10129 * 10130 * @param message The debug message 10131 * @param debug Additional debug information 10132 * @param errorLevel The console method to use for logging 10133 * @param force Whether to force logging regardless of debug setting 10134 */ 10135 log = (message, debug = {}, errorLevel = "log", force = false) => { 10136 if (!this.options.debug && !force) { 10137 return; 10138 } 10139 const logFn = console[errorLevel] || console.log; 10140 logFn(`[$this.constructor.name}]: $message}`, { 10141 room: this.options.room, 10142 ...debug 10143 }); 10144 }; 10145 /** 10146 * Handle synchronization events from the polling manager. 10147 */ 10148 onSync = () => { 10149 if (!this.synced) { 10150 this.synced = true; 10151 this.log("Synced"); 10152 } 10153 }; 10154 }; 10155 function createHttpPollingProvider() { 10156 return async ({ 10157 awareness, 10158 objectType, 10159 objectId, 10160 ydoc 10161 }) => { 10162 const room = objectId ? `$objectType}:$objectId}` : objectType; 10163 const provider = new HttpPollingProvider({ 10164 awareness, 10165 // debug: true, 10166 room, 10167 ydoc 10168 }); 10169 return { 10170 destroy: () => provider.destroy(), 10171 // Adapter: ObservableV2.on is compatible with ProviderOn 10172 // The callback receives data as the first parameter 10173 on: (event, callback) => { 10174 provider.on(event, callback); 10175 } 10176 }; 10177 }; 10178 } 10179 10180 // packages/sync/build-module/providers/index.mjs 10181 var providerCreators = null; 10182 function getDefaultProviderCreators() { 10183 return [createHttpPollingProvider()]; 10184 } 10185 function isProviderCreator(creator) { 10186 return "function" === typeof creator; 10187 } 10188 function getProviderCreators() { 10189 if (providerCreators) { 10190 return providerCreators; 10191 } 10192 if (!window._wpCollaborationEnabled) { 10193 return []; 10194 } 10195 const filteredProviderCreators = (0, import_hooks3.applyFilters)( 10196 "sync.providers", 10197 getDefaultProviderCreators() 10198 ); 10199 if (!Array.isArray(filteredProviderCreators)) { 10200 providerCreators = []; 10201 return providerCreators; 10202 } 10203 providerCreators = filteredProviderCreators.filter(isProviderCreator); 10204 return providerCreators; 10205 } 10206 10207 // packages/sync/build-module/y-utilities/y-multidoc-undomanager.mjs 10208 var popStackItem2 = (mum, type) => { 10209 const stack = type === "undo" ? mum.undoStack : mum.redoStack; 10210 while (stack.length > 0) { 10211 const um = ( 10212 /** @type {Y.UndoManager} */ 10213 stack.pop() 10214 ); 10215 const prevUmStack = type === "undo" ? um.undoStack : um.redoStack; 10216 const stackItem = ( 10217 /** @type {any} */ 10218 prevUmStack.pop() 10219 ); 10220 let actionPerformed = false; 10221 if (type === "undo") { 10222 um.undoStack = [stackItem]; 10223 actionPerformed = um.undo() !== null; 10224 um.undoStack = prevUmStack; 10225 } else { 10226 um.redoStack = [stackItem]; 10227 actionPerformed = um.redo() !== null; 10228 um.redoStack = prevUmStack; 10229 } 10230 if (actionPerformed) { 10231 return stackItem; 10232 } 10233 } 10234 return null; 10235 }; 10236 var YMultiDocUndoManager = class extends Observable { 10237 /** 10238 * @param {Y.AbstractType<any>|Array<Y.AbstractType<any>>} typeScope Accepts either a single type, or an array of types 10239 * @param {ConstructorParameters<typeof Y.UndoManager>[1]} opts 10240 */ 10241 constructor(typeScope = [], opts = {}) { 10242 super(); 10243 this.docs = /* @__PURE__ */ new Map(); 10244 this.trackedOrigins = opts.trackedOrigins || /* @__PURE__ */ new Set([null]); 10245 opts.trackedOrigins = this.trackedOrigins; 10246 this._defaultOpts = opts; 10247 this.undoStack = []; 10248 this.redoStack = []; 10249 this.addToScope(typeScope); 10250 } 10251 /** 10252 * @param {Array<Y.AbstractType<any>> | Y.AbstractType<any>} ytypes 10253 */ 10254 addToScope(ytypes) { 10255 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 10256 ytypes.forEach((ytype) => { 10257 const ydoc = ( 10258 /** @type {Y.Doc} */ 10259 ytype.doc 10260 ); 10261 const um = setIfUndefined(this.docs, ydoc, () => { 10262 const um2 = new UndoManager([ytype], this._defaultOpts); 10263 um2.on( 10264 "stack-cleared", 10265 /** @param {any} opts */ 10266 ({ 10267 undoStackCleared, 10268 redoStackCleared 10269 }) => { 10270 this.clear(undoStackCleared, redoStackCleared); 10271 } 10272 ); 10273 ydoc.on("destroy", () => { 10274 this.docs.delete(ydoc); 10275 this.undoStack = this.undoStack.filter( 10276 (um3) => um3.doc !== ydoc 10277 ); 10278 this.redoStack = this.redoStack.filter( 10279 (um3) => um3.doc !== ydoc 10280 ); 10281 }); 10282 um2.on( 10283 "stack-item-added", 10284 /** @param {any} change */ 10285 (change) => { 10286 const stack = change.type === "undo" ? this.undoStack : this.redoStack; 10287 stack.push(um2); 10288 this.emit("stack-item-added", [ 10289 { ...change, ydoc }, 10290 this 10291 ]); 10292 } 10293 ); 10294 um2.on( 10295 "stack-item-updated", 10296 /** @param {any} change */ 10297 (change) => { 10298 this.emit("stack-item-updated", [ 10299 { ...change, ydoc }, 10300 this 10301 ]); 10302 } 10303 ); 10304 um2.on( 10305 "stack-item-popped", 10306 /** @param {any} change */ 10307 (change) => { 10308 this.emit("stack-item-popped", [ 10309 { ...change, ydoc }, 10310 this 10311 ]); 10312 } 10313 ); 10314 return um2; 10315 }); 10316 if (um.scope.every((yt) => yt !== ytype)) { 10317 um.scope.push(ytype); 10318 } 10319 }); 10320 } 10321 /** 10322 * @param {any} origin 10323 */ 10324 /* c8 ignore next 3 */ 10325 addTrackedOrigin(origin2) { 10326 this.trackedOrigins.add(origin2); 10327 } 10328 /** 10329 * @param {any} origin 10330 */ 10331 /* c8 ignore next 3 */ 10332 removeTrackedOrigin(origin2) { 10333 this.trackedOrigins.delete(origin2); 10334 } 10335 /** 10336 * Undo last changes on type. 10337 * 10338 * @return {any?} Returns StackItem if a change was applied 10339 */ 10340 undo() { 10341 return popStackItem2(this, "undo"); 10342 } 10343 /** 10344 * Redo last undo operation. 10345 * 10346 * @return {any?} Returns StackItem if a change was applied 10347 */ 10348 redo() { 10349 return popStackItem2(this, "redo"); 10350 } 10351 clear(clearUndoStack = true, clearRedoStack = true) { 10352 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 10353 this.docs.forEach((um) => { 10354 clearUndoStack && (this.undoStack = []); 10355 clearRedoStack && (this.redoStack = []); 10356 um.clear(clearUndoStack, clearRedoStack); 10357 }); 10358 this.emit("stack-cleared", [ 10359 { 10360 undoStackCleared: clearUndoStack, 10361 redoStackCleared: clearRedoStack 10362 } 10363 ]); 10364 } 10365 } 10366 /* c8 ignore next 5 */ 10367 stopCapturing() { 10368 this.docs.forEach((um) => { 10369 um.stopCapturing(); 10370 }); 10371 } 10372 /** 10373 * Are undo steps available? 10374 * 10375 * @return {boolean} `true` if undo is possible 10376 */ 10377 canUndo() { 10378 return this.undoStack.length > 0; 10379 } 10380 /** 10381 * Are redo steps available? 10382 * 10383 * @return {boolean} `true` if redo is possible 10384 */ 10385 canRedo() { 10386 return this.redoStack.length > 0; 10387 } 10388 destroy() { 10389 this.docs.forEach((um) => um.destroy()); 10390 super.destroy(); 10391 } 10392 }; 10393 10394 // packages/sync/build-module/undo-manager.mjs 10395 function createUndoManager() { 10396 const undoMetaHandlers = /* @__PURE__ */ new Map(); 10397 const yUndoManager = new YMultiDocUndoManager([], { 10398 // Throttle undo/redo captures after 500ms of inactivity. 10399 // 500 was selected from subjective local UX testing, shorter timeouts 10400 // may cause mid-word undo stack items. 10401 captureTimeout: 500, 10402 // Ensure that we only scope the undo/redo to the current editor. 10403 // The yjs document's clientID is added once it's available. 10404 trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) 10405 }); 10406 const getUndoStackState = () => ({ 10407 hasRedo: yUndoManager.canRedo(), 10408 hasUndo: yUndoManager.canUndo() 10409 }); 10410 const notifyUndoStackChange = (ydoc) => { 10411 undoMetaHandlers.get(ydoc)?.onUndoStackChange?.(getUndoStackState()); 10412 }; 10413 yUndoManager.on("stack-item-added", (event) => { 10414 const handlers = undoMetaHandlers.get(event.ydoc); 10415 if (!handlers) { 10416 return; 10417 } 10418 handlers.addUndoMeta(event.ydoc, event.stackItem.meta); 10419 notifyUndoStackChange(event.ydoc); 10420 }); 10421 yUndoManager.on("stack-item-updated", (event) => { 10422 notifyUndoStackChange(event.ydoc); 10423 }); 10424 yUndoManager.on("stack-item-popped", (event) => { 10425 const handlers = undoMetaHandlers.get(event.ydoc); 10426 if (!handlers) { 10427 return; 10428 } 10429 handlers.restoreUndoMeta(event.ydoc, event.stackItem.meta); 10430 notifyUndoStackChange(event.ydoc); 10431 }); 10432 yUndoManager.on("stack-cleared", () => { 10433 undoMetaHandlers.forEach((handlers) => { 10434 handlers.onUndoStackChange?.(getUndoStackState()); 10435 }); 10436 }); 10437 return { 10438 /** 10439 * Record changes into the history. 10440 * Since Yjs automatically tracks changes, this method translates the WordPress 10441 * HistoryRecord format into Yjs operations. 10442 * 10443 * @param _record A record of changes to record. 10444 * @param _isStaged Whether to immediately create an undo point or not. 10445 */ 10446 addRecord(_record, _isStaged = false) { 10447 }, 10448 /** 10449 * Add a Yjs map to the scope of the undo manager. 10450 * 10451 * @param {Y.Map< any >} ymap The Yjs map to add to the scope. 10452 * @param handlers Handlers for the scoped document. 10453 * @param handlers.addUndoMeta Handler to add metadata to undo items. 10454 * @param handlers.onUndoStackChange Handler for undo stack changes. 10455 * @param handlers.restoreUndoMeta Handler to restore metadata from undo items. 10456 */ 10457 addToScope(ymap, handlers) { 10458 if (ymap.doc === null) { 10459 return; 10460 } 10461 const ydoc = ymap.doc; 10462 yUndoManager.addToScope(ymap); 10463 if (!undoMetaHandlers.has(ydoc)) { 10464 ydoc.on("destroy", () => undoMetaHandlers.delete(ydoc)); 10465 } 10466 undoMetaHandlers.set(ydoc, handlers); 10467 }, 10468 /** 10469 * Undo the last recorded changes. 10470 * 10471 */ 10472 undo() { 10473 if (!yUndoManager.canUndo()) { 10474 return; 10475 } 10476 yUndoManager.undo(); 10477 return []; 10478 }, 10479 /** 10480 * Redo the last undone changes. 10481 */ 10482 redo() { 10483 if (!yUndoManager.canRedo()) { 10484 return; 10485 } 10486 yUndoManager.redo(); 10487 return []; 10488 }, 10489 /** 10490 * Check if there are changes that can be undone. 10491 * 10492 * @return {boolean} Whether there are changes to undo. 10493 */ 10494 hasUndo() { 10495 return yUndoManager.canUndo(); 10496 }, 10497 /** 10498 * Check if there are changes that can be redone. 10499 * 10500 * @return {boolean} Whether there are changes to redo. 10501 */ 10502 hasRedo() { 10503 return yUndoManager.canRedo(); 10504 }, 10505 /** 10506 * Stop capturing changes into the current undo item. 10507 * The next change will create a new undo item. 10508 */ 10509 stopCapturing() { 10510 yUndoManager.stopCapturing(); 10511 } 10512 }; 10513 } 10514 10515 // packages/sync/build-module/utils.mjs 10516 function createYjsDoc(documentMeta = {}) { 10517 const metaMap = new Map( 10518 Object.entries(documentMeta) 10519 ); 10520 return new Doc({ meta: metaMap }); 10521 } 10522 function initializeYjsDoc(ydoc) { 10523 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 10524 stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); 10525 } 10526 function markEntityAsSaved(ydoc) { 10527 const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); 10528 recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); 10529 recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); 10530 } 10531 function pseudoRandomID() { 10532 return Math.floor(Math.random() * 1e9); 10533 } 10534 function serializeCrdtDoc(crdtDoc) { 10535 return JSON.stringify({ 10536 document: toBase64(encodeStateAsUpdateV2(crdtDoc)), 10537 updateId: pseudoRandomID() 10538 // helps with debugging 10539 }); 10540 } 10541 function deserializeCrdtDoc(serializedCrdtDoc) { 10542 try { 10543 const { document: document2 } = JSON.parse(serializedCrdtDoc); 10544 const docMeta = { 10545 [CRDT_DOC_META_PERSISTENCE_KEY]: true 10546 }; 10547 const ydoc = createYjsDoc(docMeta); 10548 const yupdate = fromBase64(document2); 10549 applyUpdateV2(ydoc, yupdate); 10550 ydoc.clientID = pseudoRandomID(); 10551 return ydoc; 10552 } catch { 10553 return null; 10554 } 10555 } 10556 10557 // packages/sync/build-module/manager.mjs 10558 function getEntityId(objectType, objectId) { 10559 return `$objectType}_$objectId}`; 10560 } 10561 function createSyncManager(debug = false) { 10562 const debugWrap = debug ? logPerformanceTiming : passThru; 10563 const collectionStates = /* @__PURE__ */ new Map(); 10564 const entityStates = /* @__PURE__ */ new Map(); 10565 let undoManager; 10566 function log(component, message, entityId, context = {}) { 10567 if (!debug) { 10568 return; 10569 } 10570 console.log(`[SyncManager][$component}]: $message}`, { 10571 ...context, 10572 entityId 10573 }); 10574 } 10575 async function loadEntity(syncConfig, objectType, objectId, record, handlers) { 10576 const providerCreators2 = getProviderCreators(); 10577 const entityId = getEntityId(objectType, objectId); 10578 if (0 === providerCreators2.length) { 10579 log("loadEntity", "no providers, skipping", entityId); 10580 return; 10581 } 10582 if (entityStates.has(entityId)) { 10583 log("loadEntity", "already loaded", entityId); 10584 return; 10585 } 10586 if (false === syncConfig.shouldSync?.(objectType, objectId)) { 10587 log("loadEntity", "shouldSync false, skipping", entityId); 10588 return; 10589 } 10590 log("loadEntity", "loading", entityId); 10591 handlers = { 10592 addUndoMeta: debugWrap(handlers.addUndoMeta), 10593 editRecord: debugWrap(handlers.editRecord), 10594 getEditedRecord: debugWrap(handlers.getEditedRecord), 10595 onStatusChange: debugWrap(handlers.onStatusChange), 10596 persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), 10597 refetchRecord: debugWrap(handlers.refetchRecord), 10598 restoreUndoMeta: debugWrap(handlers.restoreUndoMeta), 10599 onUndoStackChange: handlers.onUndoStackChange ? debugWrap(handlers.onUndoStackChange) : void 0 10600 }; 10601 const ydoc = createYjsDoc({ objectType }); 10602 const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); 10603 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 10604 const now = Date.now(); 10605 let hasObserversAttached = false; 10606 let isEntityUnloaded = false; 10607 const unload = () => { 10608 log("loadEntity", "unloading", entityId); 10609 isEntityUnloaded = true; 10610 providerResults?.forEach((result) => result.destroy()); 10611 handlers.onStatusChange(null); 10612 if (hasObserversAttached) { 10613 recordMap.unobserveDeep(onRecordUpdate); 10614 stateMap.unobserve(onStateMapUpdate); 10615 } 10616 ydoc.destroy(); 10617 entityStates.delete(entityId); 10618 }; 10619 const awareness = syncConfig.createAwareness?.(ydoc, objectId); 10620 const onRecordUpdate = (_events, transaction) => { 10621 if (transaction.local && !(transaction.origin instanceof UndoManager)) { 10622 return; 10623 } 10624 void internal.updateEntityRecord(objectType, objectId); 10625 }; 10626 const onStateMapUpdate = (event, transaction) => { 10627 if (transaction.local) { 10628 return; 10629 } 10630 event.keysChanged.forEach((key) => { 10631 switch (key) { 10632 case CRDT_STATE_MAP_SAVED_AT_KEY: 10633 const savedAt = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 10634 if ("number" === typeof savedAt && savedAt > now) { 10635 log("loadEntity", "refetching record", entityId); 10636 void handlers.refetchRecord().catch(() => { 10637 }); 10638 } 10639 break; 10640 } 10641 }); 10642 }; 10643 if (!undoManager) { 10644 undoManager = createUndoManager(); 10645 } 10646 const { addUndoMeta, onUndoStackChange, restoreUndoMeta } = handlers; 10647 undoManager.addToScope(recordMap, { 10648 addUndoMeta, 10649 restoreUndoMeta, 10650 onUndoStackChange 10651 }); 10652 let providerResults; 10653 const entityState = { 10654 awareness, 10655 handlers, 10656 objectId, 10657 objectType, 10658 syncConfig, 10659 unload, 10660 ydoc 10661 }; 10662 entityStates.set(entityId, entityState); 10663 log("loadEntity", "connecting", entityId); 10664 providerResults = await Promise.all( 10665 providerCreators2.map(async (create7) => { 10666 const provider = await create7({ 10667 objectType, 10668 objectId, 10669 ydoc, 10670 awareness 10671 }); 10672 provider.on("status", handlers.onStatusChange); 10673 return provider; 10674 }) 10675 ); 10676 if (isEntityUnloaded) { 10677 log("loadEntity", "unloaded during connect, aborting", entityId); 10678 providerResults.forEach((result) => result.destroy()); 10679 return; 10680 } 10681 initializeYjsDoc(ydoc); 10682 internal.applyPersistedCrdtDoc(objectType, objectId, record); 10683 recordMap.observeDeep(onRecordUpdate); 10684 stateMap.observe(onStateMapUpdate); 10685 hasObserversAttached = true; 10686 } 10687 async function loadCollection(syncConfig, objectType, handlers) { 10688 const providerCreators2 = getProviderCreators(); 10689 const entityId = getEntityId(objectType, null); 10690 if (0 === providerCreators2.length) { 10691 log("loadCollection", "no providers, skipping", entityId); 10692 return; 10693 } 10694 if (collectionStates.has(objectType)) { 10695 log("loadCollection", "already loaded", entityId); 10696 return; 10697 } 10698 if (false === syncConfig.shouldSync?.(objectType, null)) { 10699 log("loadCollection", "shouldSync false, skipping", entityId); 10700 return; 10701 } 10702 log("loadCollection", "loading", entityId); 10703 const ydoc = createYjsDoc({ collection: true, objectType }); 10704 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 10705 const now = Date.now(); 10706 let hasObserversAttached = false; 10707 let isCollectionUnloaded = false; 10708 const unload = () => { 10709 log("loadCollection", "unloading", entityId); 10710 isCollectionUnloaded = true; 10711 providerResults?.forEach((result) => result.destroy()); 10712 handlers.onStatusChange(null); 10713 if (hasObserversAttached) { 10714 stateMap.unobserve(onStateMapUpdate); 10715 } 10716 ydoc.destroy(); 10717 collectionStates.delete(objectType); 10718 }; 10719 const onStateMapUpdate = (event, transaction) => { 10720 if (transaction.local) { 10721 return; 10722 } 10723 event.keysChanged.forEach((key) => { 10724 switch (key) { 10725 case CRDT_STATE_MAP_SAVED_AT_KEY: 10726 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 10727 if ("number" === typeof newValue && newValue > now) { 10728 void handlers.refetchRecords().catch(() => { 10729 }); 10730 } 10731 break; 10732 } 10733 }); 10734 }; 10735 const awareness = syncConfig.createAwareness?.(ydoc); 10736 let providerResults; 10737 const collectionState = { 10738 awareness, 10739 handlers, 10740 syncConfig, 10741 unload, 10742 ydoc 10743 }; 10744 collectionStates.set(objectType, collectionState); 10745 log("loadCollection", "connecting", entityId); 10746 providerResults = await Promise.all( 10747 providerCreators2.map(async (create7) => { 10748 const provider = await create7({ 10749 awareness, 10750 objectType, 10751 objectId: null, 10752 ydoc 10753 }); 10754 provider.on("status", handlers.onStatusChange); 10755 return provider; 10756 }) 10757 ); 10758 if (isCollectionUnloaded) { 10759 log( 10760 "loadCollection", 10761 "unloaded during connect, aborting", 10762 entityId 10763 ); 10764 providerResults.forEach((result) => result.destroy()); 10765 return; 10766 } 10767 stateMap.observe(onStateMapUpdate); 10768 hasObserversAttached = true; 10769 initializeYjsDoc(ydoc); 10770 } 10771 function unloadEntity(objectType, objectId) { 10772 const entityId = getEntityId(objectType, objectId); 10773 log("unloadEntity", "unloading", entityId); 10774 entityStates.get(entityId)?.unload(); 10775 updateCRDTDoc(objectType, null, {}, origin, { 10776 isSave: true 10777 }); 10778 } 10779 function unloadAll() { 10780 log("unloadAll", "unloading all entities", "all"); 10781 for (const [, entityState] of [...entityStates]) { 10782 entityState.unload(); 10783 } 10784 entityStates.clear(); 10785 for (const [, collectionState] of [...collectionStates]) { 10786 collectionState.unload(); 10787 } 10788 collectionStates.clear(); 10789 } 10790 function getAwareness(objectType, objectId) { 10791 const entityId = getEntityId(objectType, objectId); 10792 const entityState = entityStates.get(entityId); 10793 if (!entityState || !entityState.awareness) { 10794 return void 0; 10795 } 10796 return entityState.awareness; 10797 } 10798 function _applyPersistedCrdtDoc(objectType, objectId, record) { 10799 const entityId = getEntityId(objectType, objectId); 10800 const entityState = entityStates.get(entityId); 10801 if (!entityState) { 10802 log("applyPersistedCrdtDoc", "no entity state", entityId); 10803 return; 10804 } 10805 const { 10806 handlers, 10807 syncConfig: { 10808 applyChangesToCRDTDoc, 10809 getChangesFromCRDTDoc, 10810 getPersistedCRDTDoc 10811 }, 10812 ydoc: targetDoc 10813 } = entityState; 10814 const serialized = getPersistedCRDTDoc?.(record); 10815 const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; 10816 if (!tempDoc) { 10817 log("applyPersistedCrdtDoc", "no persisted doc", entityId); 10818 targetDoc.transact(() => { 10819 applyChangesToCRDTDoc(targetDoc, record); 10820 handlers.persistCRDTDoc(); 10821 }, LOCAL_SYNC_MANAGER_ORIGIN); 10822 return; 10823 } 10824 const update = encodeStateAsUpdateV2(tempDoc); 10825 applyUpdateV2(targetDoc, update); 10826 const invalidations = getChangesFromCRDTDoc(tempDoc, record); 10827 const invalidatedKeys = Object.keys(invalidations); 10828 tempDoc.destroy(); 10829 if (0 === invalidatedKeys.length) { 10830 log("applyPersistedCrdtDoc", "valid persisted doc", entityId); 10831 return; 10832 } 10833 log("applyPersistedCrdtDoc", "invalidated keys", entityId, { 10834 invalidatedKeys 10835 }); 10836 const changes = invalidatedKeys.reduce( 10837 (acc, key) => Object.assign(acc, { 10838 [key]: record[key] 10839 }), 10840 {} 10841 ); 10842 targetDoc.transact(() => { 10843 applyChangesToCRDTDoc(targetDoc, changes); 10844 handlers.persistCRDTDoc(); 10845 }, LOCAL_SYNC_MANAGER_ORIGIN); 10846 } 10847 function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { 10848 const { isSave = false, isNewUndoLevel = false } = options; 10849 const entityId = getEntityId(objectType, objectId); 10850 const entityState = entityStates.get(entityId); 10851 const collectionState = collectionStates.get(objectType); 10852 if (entityState) { 10853 const { syncConfig, ydoc } = entityState; 10854 if (isNewUndoLevel && undoManager) { 10855 undoManager.stopCapturing?.(); 10856 } 10857 ydoc.transact(() => { 10858 log("updateCRDTDoc", "applying changes", entityId, { 10859 changedKeys: Object.keys(changes) 10860 }); 10861 syncConfig.applyChangesToCRDTDoc(ydoc, changes); 10862 if (isSave) { 10863 markEntityAsSaved(ydoc); 10864 } 10865 }, origin2); 10866 } 10867 if (collectionState && isSave) { 10868 collectionState.ydoc.transact(() => { 10869 markEntityAsSaved(collectionState.ydoc); 10870 }, origin2); 10871 } 10872 } 10873 async function _updateEntityRecord(objectType, objectId) { 10874 const entityId = getEntityId(objectType, objectId); 10875 const entityState = entityStates.get(entityId); 10876 if (!entityState) { 10877 log("updateEntityRecord", "no entity state", entityId); 10878 return; 10879 } 10880 const { handlers, syncConfig, ydoc } = entityState; 10881 const changes = syncConfig.getChangesFromCRDTDoc( 10882 ydoc, 10883 await handlers.getEditedRecord() 10884 ); 10885 const changedKeys = Object.keys(changes); 10886 if (0 === changedKeys.length) { 10887 return; 10888 } 10889 log("updateEntityRecord", "changes", entityId, { 10890 changedKeys 10891 }); 10892 handlers.editRecord(changes); 10893 } 10894 function createPersistedCRDTDoc(objectType, objectId) { 10895 const entityId = getEntityId(objectType, objectId); 10896 const entityState = entityStates.get(entityId); 10897 if (!entityState?.ydoc) { 10898 return null; 10899 } 10900 return serializeCrdtDoc(entityState.ydoc); 10901 } 10902 const internal = { 10903 applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), 10904 updateEntityRecord: debugWrap(_updateEntityRecord) 10905 }; 10906 return { 10907 createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), 10908 getAwareness, 10909 load: debugWrap(loadEntity), 10910 loadCollection: debugWrap(loadCollection), 10911 // Use getter to ensure we always return the current value of `undoManager`. 10912 get undoManager() { 10913 return undoManager; 10914 }, 10915 unload: debugWrap(unloadEntity), 10916 unloadAll: debugWrap(unloadAll), 10917 update: debugWrap(updateCRDTDoc) 10918 }; 10919 } 10920 10921 // packages/sync/node_modules/diff/libesm/diff/base.js 10922 var Diff = class { 10923 diff(oldStr, newStr, options = {}) { 10924 let callback; 10925 if (typeof options === "function") { 10926 callback = options; 10927 options = {}; 10928 } else if ("callback" in options) { 10929 callback = options.callback; 10930 } 10931 const oldString = this.castInput(oldStr, options); 10932 const newString = this.castInput(newStr, options); 10933 const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); 10934 const newTokens = this.removeEmpty(this.tokenize(newString, options)); 10935 return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); 10936 } 10937 diffWithOptionsObj(oldTokens, newTokens, options, callback) { 10938 var _a; 10939 const done = (value) => { 10940 value = this.postProcess(value, options); 10941 if (callback) { 10942 setTimeout(function() { 10943 callback(value); 10944 }, 0); 10945 return void 0; 10946 } else { 10947 return value; 10948 } 10949 }; 10950 const newLen = newTokens.length, oldLen = oldTokens.length; 10951 let editLength = 1; 10952 let maxEditLength = newLen + oldLen; 10953 if (options.maxEditLength != null) { 10954 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 10955 } 10956 const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; 10957 const abortAfterTimestamp = Date.now() + maxExecutionTime; 10958 const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; 10959 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); 10960 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 10961 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); 10962 } 10963 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; 10964 const execEditLength = () => { 10965 for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 10966 let basePath; 10967 const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; 10968 if (removePath) { 10969 bestPath[diagonalPath - 1] = void 0; 10970 } 10971 let canAdd = false; 10972 if (addPath) { 10973 const addPathNewPos = addPath.oldPos - diagonalPath; 10974 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 10975 } 10976 const canRemove = removePath && removePath.oldPos + 1 < oldLen; 10977 if (!canAdd && !canRemove) { 10978 bestPath[diagonalPath] = void 0; 10979 continue; 10980 } 10981 if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { 10982 basePath = this.addToPath(addPath, true, false, 0, options); 10983 } else { 10984 basePath = this.addToPath(removePath, false, true, 1, options); 10985 } 10986 newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); 10987 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 10988 return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; 10989 } else { 10990 bestPath[diagonalPath] = basePath; 10991 if (basePath.oldPos + 1 >= oldLen) { 10992 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 10993 } 10994 if (newPos + 1 >= newLen) { 10995 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 10996 } 10997 } 10998 } 10999 editLength++; 11000 }; 11001 if (callback) { 11002 (function exec() { 11003 setTimeout(function() { 11004 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 11005 return callback(void 0); 11006 } 11007 if (!execEditLength()) { 11008 exec(); 11009 } 11010 }, 0); 11011 })(); 11012 } else { 11013 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 11014 const ret = execEditLength(); 11015 if (ret) { 11016 return ret; 11017 } 11018 } 11019 } 11020 } 11021 addToPath(path, added, removed, oldPosInc, options) { 11022 const last2 = path.lastComponent; 11023 if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { 11024 return { 11025 oldPos: path.oldPos + oldPosInc, 11026 lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } 11027 }; 11028 } else { 11029 return { 11030 oldPos: path.oldPos + oldPosInc, 11031 lastComponent: { count: 1, added, removed, previousComponent: last2 } 11032 }; 11033 } 11034 } 11035 extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { 11036 const newLen = newTokens.length, oldLen = oldTokens.length; 11037 let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; 11038 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { 11039 newPos++; 11040 oldPos++; 11041 commonCount++; 11042 if (options.oneChangePerToken) { 11043 basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; 11044 } 11045 } 11046 if (commonCount && !options.oneChangePerToken) { 11047 basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; 11048 } 11049 basePath.oldPos = oldPos; 11050 return newPos; 11051 } 11052 equals(left, right, options) { 11053 if (options.comparator) { 11054 return options.comparator(left, right); 11055 } else { 11056 return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 11057 } 11058 } 11059 removeEmpty(array) { 11060 const ret = []; 11061 for (let i = 0; i < array.length; i++) { 11062 if (array[i]) { 11063 ret.push(array[i]); 11064 } 11065 } 11066 return ret; 11067 } 11068 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11069 castInput(value, options) { 11070 return value; 11071 } 11072 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11073 tokenize(value, options) { 11074 return Array.from(value); 11075 } 11076 join(chars) { 11077 return chars.join(""); 11078 } 11079 postProcess(changeObjects, options) { 11080 return changeObjects; 11081 } 11082 get useLongestToken() { 11083 return false; 11084 } 11085 buildValues(lastComponent, newTokens, oldTokens) { 11086 const components = []; 11087 let nextComponent; 11088 while (lastComponent) { 11089 components.push(lastComponent); 11090 nextComponent = lastComponent.previousComponent; 11091 delete lastComponent.previousComponent; 11092 lastComponent = nextComponent; 11093 } 11094 components.reverse(); 11095 const componentLen = components.length; 11096 let componentPos = 0, newPos = 0, oldPos = 0; 11097 for (; componentPos < componentLen; componentPos++) { 11098 const component = components[componentPos]; 11099 if (!component.removed) { 11100 if (!component.added && this.useLongestToken) { 11101 let value = newTokens.slice(newPos, newPos + component.count); 11102 value = value.map(function(value2, i) { 11103 const oldValue = oldTokens[oldPos + i]; 11104 return oldValue.length > value2.length ? oldValue : value2; 11105 }); 11106 component.value = this.join(value); 11107 } else { 11108 component.value = this.join(newTokens.slice(newPos, newPos + component.count)); 11109 } 11110 newPos += component.count; 11111 if (!component.added) { 11112 oldPos += component.count; 11113 } 11114 } else { 11115 component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); 11116 oldPos += component.count; 11117 } 11118 } 11119 return components; 11120 } 11121 }; 11122 11123 // packages/sync/node_modules/diff/libesm/diff/character.js 11124 var CharacterDiff = class extends Diff { 11125 }; 11126 var characterDiff = new CharacterDiff(); 11127 function diffChars(oldStr, newStr, options) { 11128 return characterDiff.diff(oldStr, newStr, options); 11129 } 11130 11131 // packages/sync/node_modules/diff/libesm/diff/line.js 11132 var LineDiff = class extends Diff { 11133 constructor() { 11134 super(...arguments); 11135 this.tokenize = tokenize; 11136 } 11137 equals(left, right, options) { 11138 if (options.ignoreWhitespace) { 11139 if (!options.newlineIsToken || !left.includes("\n")) { 11140 left = left.trim(); 11141 } 11142 if (!options.newlineIsToken || !right.includes("\n")) { 11143 right = right.trim(); 11144 } 11145 } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { 11146 if (left.endsWith("\n")) { 11147 left = left.slice(0, -1); 11148 } 11149 if (right.endsWith("\n")) { 11150 right = right.slice(0, -1); 11151 } 11152 } 11153 return super.equals(left, right, options); 11154 } 11155 }; 11156 var lineDiff = new LineDiff(); 11157 function diffLines(oldStr, newStr, options) { 11158 return lineDiff.diff(oldStr, newStr, options); 11159 } 11160 function tokenize(value, options) { 11161 if (options.stripTrailingCr) { 11162 value = value.replace(/\r\n/g, "\n"); 11163 } 11164 const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); 11165 if (!linesAndNewlines[linesAndNewlines.length - 1]) { 11166 linesAndNewlines.pop(); 11167 } 11168 for (let i = 0; i < linesAndNewlines.length; i++) { 11169 const line = linesAndNewlines[i]; 11170 if (i % 2 && !options.newlineIsToken) { 11171 retLines[retLines.length - 1] += line; 11172 } else { 11173 retLines.push(line); 11174 } 11175 } 11176 return retLines; 11177 } 11178 11179 // packages/sync/build-module/quill-delta/Delta.mjs 11180 var import_es62 = __toESM(require_es6(), 1); 11181 11182 // packages/sync/build-module/quill-delta/AttributeMap.mjs 11183 var import_es6 = __toESM(require_es6(), 1); 11184 function cloneDeep(value) { 11185 return JSON.parse(JSON.stringify(value)); 11186 } 11187 var AttributeMap; 11188 ((AttributeMap2) => { 11189 function compose(a = {}, b = {}, keepNull = false) { 11190 if (typeof a !== "object") { 11191 a = {}; 11192 } 11193 if (typeof b !== "object") { 11194 b = {}; 11195 } 11196 let attributes = cloneDeep(b); 11197 if (!keepNull) { 11198 attributes = Object.keys(attributes).reduce( 11199 (copy2, key) => { 11200 if (attributes[key] !== null || attributes[key] !== void 0) { 11201 copy2[key] = attributes[key]; 11202 } 11203 return copy2; 11204 }, 11205 {} 11206 ); 11207 } 11208 for (const key in a) { 11209 if (a[key] !== void 0 && b[key] === void 0) { 11210 attributes[key] = a[key]; 11211 } 11212 } 11213 return Object.keys(attributes).length > 0 ? attributes : void 0; 11214 } 11215 AttributeMap2.compose = compose; 11216 function diff(a = {}, b = {}) { 11217 if (typeof a !== "object") { 11218 a = {}; 11219 } 11220 if (typeof b !== "object") { 11221 b = {}; 11222 } 11223 const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { 11224 if (!(0, import_es6.default)(a[key], b[key])) { 11225 attrs[key] = b[key] === void 0 ? null : b[key]; 11226 } 11227 return attrs; 11228 }, {}); 11229 return Object.keys(attributes).length > 0 ? attributes : void 0; 11230 } 11231 AttributeMap2.diff = diff; 11232 function invert(attr = {}, base = {}) { 11233 attr = attr || {}; 11234 const baseInverted = Object.keys(base).reduce( 11235 (memo, key) => { 11236 if (base[key] !== attr[key] && attr[key] !== void 0) { 11237 memo[key] = base[key]; 11238 } 11239 return memo; 11240 }, 11241 {} 11242 ); 11243 return Object.keys(attr).reduce((memo, key) => { 11244 if (attr[key] !== base[key] && base[key] === void 0) { 11245 memo[key] = null; 11246 } 11247 return memo; 11248 }, baseInverted); 11249 } 11250 AttributeMap2.invert = invert; 11251 function transform(a, b, priority = false) { 11252 if (typeof a !== "object") { 11253 return b; 11254 } 11255 if (typeof b !== "object") { 11256 return void 0; 11257 } 11258 if (!priority) { 11259 return b; 11260 } 11261 const attributes = Object.keys(b).reduce( 11262 (attrs, key) => { 11263 if (a[key] === void 0) { 11264 attrs[key] = b[key]; 11265 } 11266 return attrs; 11267 }, 11268 {} 11269 ); 11270 return Object.keys(attributes).length > 0 ? attributes : void 0; 11271 } 11272 AttributeMap2.transform = transform; 11273 })(AttributeMap || (AttributeMap = {})); 11274 var AttributeMap_default = AttributeMap; 11275 11276 // packages/sync/build-module/quill-delta/Op.mjs 11277 var Op; 11278 ((Op2) => { 11279 function length3(op) { 11280 if (typeof op.delete === "number") { 11281 return op.delete; 11282 } else if (typeof op.retain === "number") { 11283 return op.retain; 11284 } else if (typeof op.retain === "object" && op.retain !== null) { 11285 return 1; 11286 } 11287 return typeof op.insert === "string" ? op.insert.length : 1; 11288 } 11289 Op2.length = length3; 11290 })(Op || (Op = {})); 11291 var Op_default = Op; 11292 11293 // packages/sync/build-module/quill-delta/OpIterator.mjs 11294 var Iterator = class { 11295 ops; 11296 index; 11297 offset; 11298 constructor(ops) { 11299 this.ops = ops; 11300 this.index = 0; 11301 this.offset = 0; 11302 } 11303 hasNext() { 11304 return this.peekLength() < Infinity; 11305 } 11306 next(length3) { 11307 if (!length3) { 11308 length3 = Infinity; 11309 } 11310 const nextOp = this.ops[this.index]; 11311 if (nextOp) { 11312 const offset = this.offset; 11313 const opLength = Op_default.length(nextOp); 11314 if (length3 >= opLength - offset) { 11315 length3 = opLength - offset; 11316 this.index += 1; 11317 this.offset = 0; 11318 } else { 11319 this.offset += length3; 11320 } 11321 if (typeof nextOp.delete === "number") { 11322 return { delete: length3 }; 11323 } 11324 const retOp = {}; 11325 if (nextOp.attributes) { 11326 retOp.attributes = nextOp.attributes; 11327 } 11328 if (typeof nextOp.retain === "number") { 11329 retOp.retain = length3; 11330 } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { 11331 retOp.retain = nextOp.retain; 11332 } else if (typeof nextOp.insert === "string") { 11333 retOp.insert = nextOp.insert.substr(offset, length3); 11334 } else { 11335 retOp.insert = nextOp.insert; 11336 } 11337 return retOp; 11338 } 11339 return { retain: Infinity }; 11340 } 11341 peek() { 11342 return this.ops[this.index]; 11343 } 11344 peekLength() { 11345 if (this.ops[this.index]) { 11346 return Op_default.length(this.ops[this.index]) - this.offset; 11347 } 11348 return Infinity; 11349 } 11350 peekType() { 11351 const op = this.ops[this.index]; 11352 if (op) { 11353 if (typeof op.delete === "number") { 11354 return "delete"; 11355 } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { 11356 return "retain"; 11357 } 11358 return "insert"; 11359 } 11360 return "retain"; 11361 } 11362 rest() { 11363 if (!this.hasNext()) { 11364 return []; 11365 } else if (this.offset === 0) { 11366 return this.ops.slice(this.index); 11367 } 11368 const offset = this.offset; 11369 const index = this.index; 11370 const next = this.next(); 11371 const rest = this.ops.slice(this.index); 11372 this.offset = offset; 11373 this.index = index; 11374 return [next].concat(rest); 11375 } 11376 }; 11377 11378 // packages/sync/build-module/quill-delta/Delta.mjs 11379 function cloneDeep2(value) { 11380 return JSON.parse(JSON.stringify(value)); 11381 } 11382 var NULL_CHARACTER = String.fromCharCode(0); 11383 var STRING_TOO_LARGE_THRESHOLD = 1e4; 11384 function normalizeChangeCounts(changes) { 11385 return changes.map((change) => ({ 11386 ...change, 11387 count: change.value.length 11388 })); 11389 } 11390 var getEmbedTypeAndData = (a, b) => { 11391 if (typeof a !== "object" || a === null) { 11392 throw new Error(`cannot retain a $typeof a}`); 11393 } 11394 if (typeof b !== "object" || b === null) { 11395 throw new Error(`cannot retain a $typeof b}`); 11396 } 11397 const embedType = Object.keys(a)[0]; 11398 if (!embedType || embedType !== Object.keys(b)[0]) { 11399 throw new Error( 11400 `embed types not matched: $embedType} != $Object.keys(b)[0]}` 11401 ); 11402 } 11403 return [embedType, a[embedType], b[embedType]]; 11404 }; 11405 var Delta = class _Delta { 11406 static Op = Op_default; 11407 static OpIterator = Iterator; 11408 static AttributeMap = AttributeMap_default; 11409 static handlers = {}; 11410 static registerEmbed(embedType, handler) { 11411 this.handlers[embedType] = handler; 11412 } 11413 static unregisterEmbed(embedType) { 11414 delete this.handlers[embedType]; 11415 } 11416 static getHandler(embedType) { 11417 const handler = this.handlers[embedType]; 11418 if (!handler) { 11419 throw new Error(`no handlers for embed type "$embedType}"`); 11420 } 11421 return handler; 11422 } 11423 ops; 11424 constructor(ops) { 11425 if (Array.isArray(ops)) { 11426 this.ops = ops; 11427 } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { 11428 this.ops = ops.ops; 11429 } else { 11430 this.ops = []; 11431 } 11432 } 11433 insert(arg, attributes) { 11434 const newOp = {}; 11435 if (typeof arg === "string" && arg.length === 0) { 11436 return this; 11437 } 11438 newOp.insert = arg; 11439 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 11440 newOp.attributes = attributes; 11441 } 11442 return this.push(newOp); 11443 } 11444 delete(length3) { 11445 if (length3 <= 0) { 11446 return this; 11447 } 11448 return this.push({ delete: length3 }); 11449 } 11450 retain(length3, attributes) { 11451 if (typeof length3 === "number" && length3 <= 0) { 11452 return this; 11453 } 11454 const newOp = { retain: length3 }; 11455 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 11456 newOp.attributes = attributes; 11457 } 11458 return this.push(newOp); 11459 } 11460 push(newOp) { 11461 let index = this.ops.length; 11462 let lastOp = this.ops[index - 1]; 11463 newOp = cloneDeep2(newOp); 11464 if (typeof lastOp === "object") { 11465 if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { 11466 this.ops[index - 1] = { 11467 delete: lastOp.delete + newOp.delete 11468 }; 11469 return this; 11470 } 11471 if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { 11472 index -= 1; 11473 lastOp = this.ops[index - 1]; 11474 if (typeof lastOp !== "object") { 11475 this.ops.unshift(newOp); 11476 return this; 11477 } 11478 } 11479 if ((0, import_es62.default)(newOp.attributes, lastOp.attributes)) { 11480 if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { 11481 this.ops[index - 1] = { 11482 insert: lastOp.insert + newOp.insert 11483 }; 11484 if (typeof newOp.attributes === "object") { 11485 this.ops[index - 1].attributes = newOp.attributes; 11486 } 11487 return this; 11488 } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { 11489 this.ops[index - 1] = { 11490 retain: lastOp.retain + newOp.retain 11491 }; 11492 if (typeof newOp.attributes === "object") { 11493 this.ops[index - 1].attributes = newOp.attributes; 11494 } 11495 return this; 11496 } 11497 } 11498 } 11499 if (index === this.ops.length) { 11500 this.ops.push(newOp); 11501 } else { 11502 this.ops.splice(index, 0, newOp); 11503 } 11504 return this; 11505 } 11506 chop() { 11507 const lastOp = this.ops[this.ops.length - 1]; 11508 if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { 11509 this.ops.pop(); 11510 } 11511 return this; 11512 } 11513 filter(predicate) { 11514 return this.ops.filter(predicate); 11515 } 11516 forEach(predicate) { 11517 this.ops.forEach(predicate); 11518 } 11519 map(predicate) { 11520 return this.ops.map(predicate); 11521 } 11522 partition(predicate) { 11523 const passed = []; 11524 const failed = []; 11525 this.forEach((op) => { 11526 const target = predicate(op) ? passed : failed; 11527 target.push(op); 11528 }); 11529 return [passed, failed]; 11530 } 11531 reduce(predicate, initialValue) { 11532 return this.ops.reduce(predicate, initialValue); 11533 } 11534 changeLength() { 11535 return this.reduce((length3, elem) => { 11536 if (elem.insert) { 11537 return length3 + Op_default.length(elem); 11538 } else if (elem.delete) { 11539 return length3 - elem.delete; 11540 } 11541 return length3; 11542 }, 0); 11543 } 11544 length() { 11545 return this.reduce((length3, elem) => { 11546 return length3 + Op_default.length(elem); 11547 }, 0); 11548 } 11549 slice(start = 0, end = Infinity) { 11550 const ops = []; 11551 const iter = new Iterator(this.ops); 11552 let index = 0; 11553 while (index < end && iter.hasNext()) { 11554 let nextOp; 11555 if (index < start) { 11556 nextOp = iter.next(start - index); 11557 } else { 11558 nextOp = iter.next(end - index); 11559 ops.push(nextOp); 11560 } 11561 index += Op_default.length(nextOp); 11562 } 11563 return new _Delta(ops); 11564 } 11565 compose(other) { 11566 const thisIter = new Iterator(this.ops); 11567 const otherIter = new Iterator(other.ops); 11568 const ops = []; 11569 const firstOther = otherIter.peek(); 11570 if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { 11571 let firstLeft = firstOther.retain; 11572 while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { 11573 firstLeft -= thisIter.peekLength(); 11574 ops.push(thisIter.next()); 11575 } 11576 if (firstOther.retain - firstLeft > 0) { 11577 otherIter.next(firstOther.retain - firstLeft); 11578 } 11579 } 11580 const delta = new _Delta(ops); 11581 while (thisIter.hasNext() || otherIter.hasNext()) { 11582 if (otherIter.peekType() === "insert") { 11583 delta.push(otherIter.next()); 11584 } else if (thisIter.peekType() === "delete") { 11585 delta.push(thisIter.next()); 11586 } else { 11587 const length3 = Math.min( 11588 thisIter.peekLength(), 11589 otherIter.peekLength() 11590 ); 11591 const thisOp = thisIter.next(length3); 11592 const otherOp = otherIter.next(length3); 11593 if (otherOp.retain) { 11594 const newOp = {}; 11595 if (typeof thisOp.retain === "number") { 11596 newOp.retain = typeof otherOp.retain === "number" ? length3 : otherOp.retain; 11597 } else if (typeof otherOp.retain === "number") { 11598 if (thisOp.retain === null || thisOp.retain === void 0) { 11599 newOp.insert = thisOp.insert; 11600 } else { 11601 newOp.retain = thisOp.retain; 11602 } 11603 } else { 11604 const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; 11605 const [embedType, thisData, otherData] = getEmbedTypeAndData( 11606 thisOp[action], 11607 otherOp.retain 11608 ); 11609 const handler = _Delta.getHandler(embedType); 11610 newOp[action] = { 11611 [embedType]: handler.compose( 11612 thisData, 11613 otherData, 11614 action === "retain" 11615 ) 11616 }; 11617 } 11618 const attributes = AttributeMap_default.compose( 11619 thisOp.attributes, 11620 otherOp.attributes, 11621 typeof thisOp.retain === "number" 11622 ); 11623 if (attributes) { 11624 newOp.attributes = attributes; 11625 } 11626 delta.push(newOp); 11627 if (!otherIter.hasNext() && (0, import_es62.default)(delta.ops[delta.ops.length - 1], newOp)) { 11628 const rest = new _Delta(thisIter.rest()); 11629 return delta.concat(rest).chop(); 11630 } 11631 } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { 11632 delta.push(otherOp); 11633 } 11634 } 11635 } 11636 return delta.chop(); 11637 } 11638 concat(other) { 11639 const delta = new _Delta(this.ops.slice()); 11640 if (other.ops.length > 0) { 11641 delta.push(other.ops[0]); 11642 delta.ops = delta.ops.concat(other.ops.slice(1)); 11643 } 11644 return delta; 11645 } 11646 diff(other) { 11647 if (this.ops === other.ops) { 11648 return new _Delta(); 11649 } 11650 const strings = this.deltasToStrings(other); 11651 const diffResult = normalizeChangeCounts( 11652 diffChars(strings[0], strings[1]) 11653 ); 11654 const thisIter = new Iterator(this.ops); 11655 const otherIter = new Iterator(other.ops); 11656 const retDelta = this.convertChangesToDelta( 11657 diffResult, 11658 thisIter, 11659 otherIter 11660 ); 11661 return retDelta.chop(); 11662 } 11663 eachLine(predicate, newline = "\n") { 11664 const iter = new Iterator(this.ops); 11665 let line = new _Delta(); 11666 let i = 0; 11667 while (iter.hasNext()) { 11668 if (iter.peekType() !== "insert") { 11669 return; 11670 } 11671 const thisOp = iter.peek(); 11672 const start = Op_default.length(thisOp) - iter.peekLength(); 11673 const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; 11674 if (index < 0) { 11675 line.push(iter.next()); 11676 } else if (index > 0) { 11677 line.push(iter.next(index)); 11678 } else { 11679 if (predicate(line, iter.next(1).attributes || {}, i) === false) { 11680 return; 11681 } 11682 i += 1; 11683 line = new _Delta(); 11684 } 11685 } 11686 if (line.length() > 0) { 11687 predicate(line, {}, i); 11688 } 11689 } 11690 invert(base) { 11691 const inverted = new _Delta(); 11692 this.reduce((baseIndex, op) => { 11693 if (op.insert) { 11694 inverted.delete(Op_default.length(op)); 11695 } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { 11696 inverted.retain(op.retain); 11697 return baseIndex + op.retain; 11698 } else if (op.delete || typeof op.retain === "number") { 11699 const length3 = op.delete || op.retain; 11700 const slice = base.slice(baseIndex, baseIndex + length3); 11701 slice.forEach((baseOp) => { 11702 if (op.delete) { 11703 inverted.push(baseOp); 11704 } else if (op.retain && op.attributes) { 11705 inverted.retain( 11706 Op_default.length(baseOp), 11707 AttributeMap_default.invert( 11708 op.attributes, 11709 baseOp.attributes 11710 ) 11711 ); 11712 } 11713 }); 11714 return baseIndex + length3; 11715 } else if (typeof op.retain === "object" && op.retain !== null) { 11716 const slice = base.slice(baseIndex, baseIndex + 1); 11717 const baseOp = new Iterator(slice.ops).next(); 11718 const [embedType, opData, baseOpData] = getEmbedTypeAndData( 11719 op.retain, 11720 baseOp.insert 11721 ); 11722 const handler = _Delta.getHandler(embedType); 11723 inverted.retain( 11724 { [embedType]: handler.invert(opData, baseOpData) }, 11725 AttributeMap_default.invert(op.attributes, baseOp.attributes) 11726 ); 11727 return baseIndex + 1; 11728 } 11729 return baseIndex; 11730 }, 0); 11731 return inverted.chop(); 11732 } 11733 transform(arg, priority = false) { 11734 priority = !!priority; 11735 if (typeof arg === "number") { 11736 return this.transformPosition(arg, priority); 11737 } 11738 const other = arg; 11739 const thisIter = new Iterator(this.ops); 11740 const otherIter = new Iterator(other.ops); 11741 const delta = new _Delta(); 11742 while (thisIter.hasNext() || otherIter.hasNext()) { 11743 if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { 11744 delta.retain(Op_default.length(thisIter.next())); 11745 } else if (otherIter.peekType() === "insert") { 11746 delta.push(otherIter.next()); 11747 } else { 11748 const length3 = Math.min( 11749 thisIter.peekLength(), 11750 otherIter.peekLength() 11751 ); 11752 const thisOp = thisIter.next(length3); 11753 const otherOp = otherIter.next(length3); 11754 if (thisOp.delete) { 11755 continue; 11756 } else if (otherOp.delete) { 11757 delta.push(otherOp); 11758 } else { 11759 const thisData = thisOp.retain; 11760 const otherData = otherOp.retain; 11761 let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length3; 11762 if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { 11763 const embedType = Object.keys(thisData)[0]; 11764 if (embedType === Object.keys(otherData)[0]) { 11765 const handler = _Delta.getHandler(embedType); 11766 if (handler) { 11767 transformedData = { 11768 [embedType]: handler.transform( 11769 thisData[embedType], 11770 otherData[embedType], 11771 priority 11772 ) 11773 }; 11774 } 11775 } 11776 } 11777 delta.retain( 11778 transformedData, 11779 AttributeMap_default.transform( 11780 thisOp.attributes, 11781 otherOp.attributes, 11782 priority 11783 ) 11784 ); 11785 } 11786 } 11787 } 11788 return delta.chop(); 11789 } 11790 transformPosition(index, priority = false) { 11791 priority = !!priority; 11792 const thisIter = new Iterator(this.ops); 11793 let offset = 0; 11794 while (thisIter.hasNext() && offset <= index) { 11795 const length3 = thisIter.peekLength(); 11796 const nextType = thisIter.peekType(); 11797 thisIter.next(); 11798 if (nextType === "delete") { 11799 index -= Math.min(length3, index - offset); 11800 continue; 11801 } else if (nextType === "insert" && (offset < index || !priority)) { 11802 index += length3; 11803 } 11804 offset += length3; 11805 } 11806 return index; 11807 } 11808 /** 11809 * Given a Delta and a cursor position, do a diff and attempt to adjust 11810 * the diff to place insertions or deletions at the cursor position. 11811 * 11812 * @todo There are at least a few known cases where this produces a corrupted 11813 * diff. When this is fixed, it should not be necessary to verify that the 11814 * transformed diff applies cleanly. 11815 * 11816 * @see import("@wordpress/core-data/src/utils/crdt-blocks").mergeRichTextUpdate() 11817 * 11818 * @param other - The other Delta to diff against. 11819 * @param cursorAfterChange - The cursor position index after the change. 11820 * @return A Delta that attempts to place insertions or deletions at the cursor position. 11821 */ 11822 diffWithCursor(other, cursorAfterChange) { 11823 if (this.ops === other.ops) { 11824 return new _Delta(); 11825 } 11826 const strings = this.deltasToStrings(other); 11827 const maxStringLength = Math.max( 11828 ...strings.map((str) => str.length) 11829 ); 11830 if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { 11831 const diffResult = normalizeChangeCounts( 11832 diffLines(strings[0], strings[1]) 11833 ); 11834 const thisIterLarge = new Iterator(this.ops); 11835 const otherIterLarge = new Iterator(other.ops); 11836 return this.convertChangesToDelta( 11837 diffResult, 11838 thisIterLarge, 11839 otherIterLarge 11840 ).chop(); 11841 } else if (cursorAfterChange === null) { 11842 return this.diff(other); 11843 } 11844 let diffs = normalizeChangeCounts( 11845 diffChars(strings[0], strings[1]) 11846 ); 11847 let lastDiffPosition = 0; 11848 const adjustedDiffs = []; 11849 for (let i = 0; i < diffs.length; i++) { 11850 const diff = diffs[i]; 11851 const segmentStart = lastDiffPosition; 11852 const segmentEnd = lastDiffPosition + (diff.count ?? 0); 11853 const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; 11854 const isUnchangedSegment = !diff.added && !diff.removed; 11855 const isRemovalSegment = diff.removed && !diff.added; 11856 const nextDiff = diffs[i + 1]; 11857 const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; 11858 if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { 11859 const movedSegments = this.tryMoveInsertionToCursor( 11860 diff, 11861 nextDiff, 11862 cursorAfterChange, 11863 segmentStart 11864 ); 11865 if (movedSegments) { 11866 adjustedDiffs.push(...movedSegments); 11867 i++; 11868 lastDiffPosition = segmentEnd; 11869 continue; 11870 } 11871 } 11872 if (isRemovalSegment) { 11873 const movedSegments = this.tryMoveDeletionToCursor( 11874 diff, 11875 adjustedDiffs, 11876 cursorAfterChange, 11877 lastDiffPosition 11878 ); 11879 if (movedSegments) { 11880 adjustedDiffs.pop(); 11881 adjustedDiffs.push(...movedSegments); 11882 lastDiffPosition += diff.count ?? 0; 11883 continue; 11884 } 11885 } 11886 adjustedDiffs.push(diff); 11887 if (!diff.added) { 11888 lastDiffPosition += diff.count ?? 0; 11889 } 11890 } 11891 diffs = adjustedDiffs; 11892 const thisIter = new Iterator(this.ops); 11893 const otherIter = new Iterator(other.ops); 11894 const retDelta = this.convertChangesToDelta( 11895 diffs, 11896 thisIter, 11897 otherIter 11898 ); 11899 return retDelta.chop(); 11900 } 11901 /** 11902 * Try to move an insertion operation from after an unchanged segment to the cursor position within it. 11903 * This is a "look-ahead" strategy. 11904 * 11905 * @param diff - The current unchanged diff segment. 11906 * @param nextDiff - The next diff segment (expected to be an insertion). 11907 * @param cursorAfterChange - The cursor position after the change. 11908 * @param segmentStart - The start position of the current segment. 11909 * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. 11910 */ 11911 tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { 11912 const nextDiffInsert = nextDiff.value; 11913 const insertLength = nextDiffInsert.length; 11914 const insertOffset = cursorAfterChange - segmentStart - insertLength; 11915 const textAtCursor = diff.value.substring( 11916 insertOffset, 11917 insertOffset + nextDiffInsert.length 11918 ); 11919 const isInsertMoveable = textAtCursor === nextDiffInsert; 11920 if (!isInsertMoveable) { 11921 return null; 11922 } 11923 const beforeCursor = diff.value.substring(0, insertOffset); 11924 const afterCursor = diff.value.substring(insertOffset); 11925 const result = []; 11926 if (beforeCursor.length > 0) { 11927 result.push({ 11928 value: beforeCursor, 11929 count: beforeCursor.length, 11930 added: false, 11931 removed: false 11932 }); 11933 } 11934 result.push(nextDiff); 11935 if (afterCursor.length > 0) { 11936 result.push({ 11937 value: afterCursor, 11938 count: afterCursor.length, 11939 added: false, 11940 removed: false 11941 }); 11942 } 11943 return result; 11944 } 11945 /** 11946 * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. 11947 * This is a "look-back" strategy. 11948 * 11949 * @param diff - The current deletion diff segment. 11950 * @param adjustedDiffs - The array of previously processed diff segments. 11951 * @param cursorAfterChange - The cursor position after the change. 11952 * @param lastDiffPosition - The position in the document up to (but not including) the current diff. 11953 * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. 11954 */ 11955 tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { 11956 const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; 11957 if (!prevDiff || prevDiff.added || prevDiff.removed) { 11958 return null; 11959 } 11960 const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); 11961 const prevSegmentEnd = lastDiffPosition; 11962 if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { 11963 return null; 11964 } 11965 const deletedChars = diff.value; 11966 const deleteOffset = cursorAfterChange - prevSegmentStart; 11967 const textAtCursor = prevDiff.value.substring( 11968 deleteOffset, 11969 deleteOffset + deletedChars.length 11970 ); 11971 const canBePlacedHere = textAtCursor === deletedChars; 11972 if (!canBePlacedHere) { 11973 return null; 11974 } 11975 const beforeCursor = prevDiff.value.substring(0, deleteOffset); 11976 const atAndAfterCursor = prevDiff.value.substring(deleteOffset); 11977 const deletionLength = diff.count ?? 0; 11978 const afterDeletion = atAndAfterCursor.substring(deletionLength); 11979 const result = []; 11980 if (beforeCursor.length > 0) { 11981 result.push({ 11982 value: beforeCursor, 11983 count: beforeCursor.length, 11984 added: false, 11985 removed: false 11986 }); 11987 } 11988 result.push(diff); 11989 if (afterDeletion.length > 0) { 11990 result.push({ 11991 value: afterDeletion, 11992 count: afterDeletion.length, 11993 added: false, 11994 removed: false 11995 }); 11996 } 11997 return result; 11998 } 11999 /** 12000 * Convert two Deltas to string representations for diffing. 12001 * 12002 * @param other - The other Delta to convert. 12003 * @return A tuple of [thisString, otherString]. 12004 */ 12005 deltasToStrings(other) { 12006 return [this, other].map((delta) => { 12007 return delta.map((op) => { 12008 if (op.insert !== null || op.insert !== void 0) { 12009 return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; 12010 } 12011 const prep = delta === other ? "on" : "with"; 12012 throw new Error( 12013 "diff() called " + prep + " non-document" 12014 ); 12015 }).join(""); 12016 }); 12017 } 12018 /** 12019 * Process diff changes and convert them to Delta operations. 12020 * 12021 * @param changes - The array of changes from the diff algorithm. 12022 * @param thisIter - Iterator for this Delta's operations. 12023 * @param otherIter - Iterator for the other Delta's operations. 12024 * @return A Delta containing the processed diff operations. 12025 */ 12026 convertChangesToDelta(changes, thisIter, otherIter) { 12027 const retDelta = new _Delta(); 12028 changes.forEach((component) => { 12029 let length3 = component.count ?? 0; 12030 while (length3 > 0) { 12031 let opLength = 0; 12032 if (component.added) { 12033 opLength = Math.min(otherIter.peekLength(), length3); 12034 retDelta.push(otherIter.next(opLength)); 12035 } else if (component.removed) { 12036 opLength = Math.min(length3, thisIter.peekLength()); 12037 thisIter.next(opLength); 12038 retDelta.delete(opLength); 12039 } else { 12040 opLength = Math.min( 12041 thisIter.peekLength(), 12042 otherIter.peekLength(), 12043 length3 12044 ); 12045 const thisOp = thisIter.next(opLength); 12046 const otherOp = otherIter.next(opLength); 12047 if ((0, import_es62.default)(thisOp.insert, otherOp.insert)) { 12048 retDelta.retain( 12049 opLength, 12050 AttributeMap_default.diff( 12051 thisOp.attributes, 12052 otherOp.attributes 12053 ) 12054 ); 12055 } else { 12056 retDelta.push(otherOp).delete(opLength); 12057 } 12058 } 12059 length3 -= opLength; 12060 } 12061 }); 12062 return retDelta; 12063 } 12064 }; 12065 var Delta_default = Delta; 12066 12067 // packages/sync/build-module/private-apis.mjs 12068 var privateApis = {}; 12069 lock(privateApis, { 12070 ConnectionErrorCode, 12071 createSyncManager, 12072 Delta: Delta_default, 12073 CRDT_DOC_META_PERSISTENCE_KEY, 12074 CRDT_RECORD_MAP_KEY, 12075 LOCAL_EDITOR_ORIGIN, 12076 LOCAL_UNDO_IGNORED_ORIGIN, 12077 retrySyncConnection: () => pollingManager.retryNow() 12078 }); 12079 12080 // packages/sync/build-module/index.mjs 12081 var YJS_VERSION = "13"; 12082 return __toCommonJS(index_exports); 12083 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Fri Jul 3 08:20:12 2026 | Cross-referenced by PHPXref |