| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 (function() { 2 "use strict"; 3 var wp; 4 (wp ||= {}).sync = (() => { 5 var __create = Object.create; 6 var __defProp = Object.defineProperty; 7 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 8 var __getOwnPropNames = Object.getOwnPropertyNames; 9 var __getProtoOf = Object.getPrototypeOf; 10 var __hasOwnProp = Object.prototype.hasOwnProperty; 11 var __commonJS = (cb, mod) => function __require() { 12 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 13 }; 14 var __export = (target, all2) => { 15 for (var name in all2) 16 __defProp(target, name, { get: all2[name], enumerable: true }); 17 }; 18 var __copyProps = (to, from2, except, desc) => { 19 if (from2 && typeof from2 === "object" || typeof from2 === "function") { 20 for (let key of __getOwnPropNames(from2)) 21 if (!__hasOwnProp.call(to, key) && key !== except) 22 __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable }); 23 } 24 return to; 25 }; 26 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 27 // If the importer is in node compatibility mode or this is not an ESM 28 // file that has been converted to a CommonJS file using a Babel- 29 // compatible transform (i.e. "__esModule" has not been set), then set 30 // "default" to the CommonJS "module.exports" for node compatibility. 31 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 32 mod 33 )); 34 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 35 36 // package-external:@wordpress/private-apis 37 var require_private_apis = __commonJS({ 38 "package-external:@wordpress/private-apis"(exports, module) { 39 module.exports = window.wp.privateApis; 40 } 41 }); 42 43 // package-external:@wordpress/hooks 44 var require_hooks = __commonJS({ 45 "package-external:@wordpress/hooks"(exports, module) { 46 module.exports = window.wp.hooks; 47 } 48 }); 49 50 // package-external:@wordpress/api-fetch 51 var require_api_fetch = __commonJS({ 52 "package-external:@wordpress/api-fetch"(exports, module) { 53 module.exports = window.wp.apiFetch; 54 } 55 }); 56 57 // node_modules/fast-deep-equal/es6/index.js 58 var require_es6 = __commonJS({ 59 "node_modules/fast-deep-equal/es6/index.js"(exports, module) { 60 "use strict"; 61 module.exports = function equal(a, b) { 62 if (a === b) return true; 63 if (a && b && typeof a == "object" && typeof b == "object") { 64 if (a.constructor !== b.constructor) return false; 65 var length2, i, keys2; 66 if (Array.isArray(a)) { 67 length2 = a.length; 68 if (length2 != b.length) return false; 69 for (i = length2; i-- !== 0; ) 70 if (!equal(a[i], b[i])) return false; 71 return true; 72 } 73 if (a instanceof Map && b instanceof Map) { 74 if (a.size !== b.size) return false; 75 for (i of a.entries()) 76 if (!b.has(i[0])) return false; 77 for (i of a.entries()) 78 if (!equal(i[1], b.get(i[0]))) return false; 79 return true; 80 } 81 if (a instanceof Set && b instanceof Set) { 82 if (a.size !== b.size) return false; 83 for (i of a.entries()) 84 if (!b.has(i[0])) return false; 85 return true; 86 } 87 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 88 length2 = a.length; 89 if (length2 != b.length) return false; 90 for (i = length2; i-- !== 0; ) 91 if (a[i] !== b[i]) return false; 92 return true; 93 } 94 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 95 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 96 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 97 keys2 = Object.keys(a); 98 length2 = keys2.length; 99 if (length2 !== Object.keys(b).length) return false; 100 for (i = length2; i-- !== 0; ) 101 if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false; 102 for (i = length2; i-- !== 0; ) { 103 var key = keys2[i]; 104 if (!equal(a[key], b[key])) return false; 105 } 106 return true; 107 } 108 return a !== a && b !== b; 109 }; 110 } 111 }); 112 113 // packages/sync/build-module/index.mjs 114 var index_exports = {}; 115 __export(index_exports, { 116 Awareness: () => Awareness, 117 Y: () => yjs_exports, 118 YJS_VERSION: () => YJS_VERSION, 119 privateApis: () => privateApis 120 }); 121 122 // node_modules/yjs/dist/yjs.mjs 123 var yjs_exports = {}; 124 __export(yjs_exports, { 125 AbsolutePosition: () => AbsolutePosition, 126 AbstractConnector: () => AbstractConnector, 127 AbstractStruct: () => AbstractStruct, 128 AbstractType: () => AbstractType, 129 Array: () => YArray, 130 ContentAny: () => ContentAny, 131 ContentBinary: () => ContentBinary, 132 ContentDeleted: () => ContentDeleted, 133 ContentDoc: () => ContentDoc, 134 ContentEmbed: () => ContentEmbed, 135 ContentFormat: () => ContentFormat, 136 ContentJSON: () => ContentJSON, 137 ContentString: () => ContentString, 138 ContentType: () => ContentType, 139 Doc: () => Doc, 140 GC: () => GC, 141 ID: () => ID, 142 Item: () => Item, 143 Map: () => YMap, 144 PermanentUserData: () => PermanentUserData, 145 RelativePosition: () => RelativePosition, 146 Skip: () => Skip, 147 Snapshot: () => Snapshot, 148 Text: () => YText, 149 Transaction: () => Transaction, 150 UndoManager: () => UndoManager, 151 UpdateDecoderV1: () => UpdateDecoderV1, 152 UpdateDecoderV2: () => UpdateDecoderV2, 153 UpdateEncoderV1: () => UpdateEncoderV1, 154 UpdateEncoderV2: () => UpdateEncoderV2, 155 XmlElement: () => YXmlElement, 156 XmlFragment: () => YXmlFragment, 157 XmlHook: () => YXmlHook, 158 XmlText: () => YXmlText, 159 YArrayEvent: () => YArrayEvent, 160 YEvent: () => YEvent, 161 YMapEvent: () => YMapEvent, 162 YTextEvent: () => YTextEvent, 163 YXmlEvent: () => YXmlEvent, 164 applyUpdate: () => applyUpdate, 165 applyUpdateV2: () => applyUpdateV2, 166 cleanupYTextFormatting: () => cleanupYTextFormatting, 167 compareIDs: () => compareIDs, 168 compareRelativePositions: () => compareRelativePositions, 169 convertUpdateFormatV1ToV2: () => convertUpdateFormatV1ToV2, 170 convertUpdateFormatV2ToV1: () => convertUpdateFormatV2ToV1, 171 createAbsolutePositionFromRelativePosition: () => createAbsolutePositionFromRelativePosition, 172 createDeleteSet: () => createDeleteSet, 173 createDeleteSetFromStructStore: () => createDeleteSetFromStructStore, 174 createDocFromSnapshot: () => createDocFromSnapshot, 175 createID: () => createID, 176 createRelativePositionFromJSON: () => createRelativePositionFromJSON, 177 createRelativePositionFromTypeIndex: () => createRelativePositionFromTypeIndex, 178 createSnapshot: () => createSnapshot, 179 decodeRelativePosition: () => decodeRelativePosition, 180 decodeSnapshot: () => decodeSnapshot, 181 decodeSnapshotV2: () => decodeSnapshotV2, 182 decodeStateVector: () => decodeStateVector, 183 decodeUpdate: () => decodeUpdate, 184 decodeUpdateV2: () => decodeUpdateV2, 185 diffUpdate: () => diffUpdate, 186 diffUpdateV2: () => diffUpdateV2, 187 emptySnapshot: () => emptySnapshot, 188 encodeRelativePosition: () => encodeRelativePosition, 189 encodeSnapshot: () => encodeSnapshot, 190 encodeSnapshotV2: () => encodeSnapshotV2, 191 encodeStateAsUpdate: () => encodeStateAsUpdate, 192 encodeStateAsUpdateV2: () => encodeStateAsUpdateV2, 193 encodeStateVector: () => encodeStateVector, 194 encodeStateVectorFromUpdate: () => encodeStateVectorFromUpdate, 195 encodeStateVectorFromUpdateV2: () => encodeStateVectorFromUpdateV2, 196 equalDeleteSets: () => equalDeleteSets, 197 equalSnapshots: () => equalSnapshots, 198 findIndexSS: () => findIndexSS, 199 findRootTypeKey: () => findRootTypeKey, 200 getItem: () => getItem, 201 getItemCleanEnd: () => getItemCleanEnd, 202 getItemCleanStart: () => getItemCleanStart, 203 getState: () => getState, 204 getTypeChildren: () => getTypeChildren, 205 isDeleted: () => isDeleted, 206 isParentOf: () => isParentOf, 207 iterateDeletedStructs: () => iterateDeletedStructs, 208 logType: () => logType, 209 logUpdate: () => logUpdate, 210 logUpdateV2: () => logUpdateV2, 211 mergeDeleteSets: () => mergeDeleteSets, 212 mergeUpdates: () => mergeUpdates, 213 mergeUpdatesV2: () => mergeUpdatesV2, 214 obfuscateUpdate: () => obfuscateUpdate, 215 obfuscateUpdateV2: () => obfuscateUpdateV2, 216 parseUpdateMeta: () => parseUpdateMeta, 217 parseUpdateMetaV2: () => parseUpdateMetaV2, 218 readUpdate: () => readUpdate, 219 readUpdateV2: () => readUpdateV2, 220 relativePositionToJSON: () => relativePositionToJSON, 221 snapshot: () => snapshot, 222 snapshotContainsUpdate: () => snapshotContainsUpdate, 223 transact: () => transact, 224 tryGc: () => tryGc, 225 typeListToArraySnapshot: () => typeListToArraySnapshot, 226 typeMapGetAllSnapshot: () => typeMapGetAllSnapshot, 227 typeMapGetSnapshot: () => typeMapGetSnapshot 228 }); 229 230 // node_modules/lib0/map.js 231 var create = () => /* @__PURE__ */ new Map(); 232 var copy = (m) => { 233 const r = create(); 234 m.forEach((v, k) => { 235 r.set(k, v); 236 }); 237 return r; 238 }; 239 var setIfUndefined = (map2, key, createT) => { 240 let set = map2.get(key); 241 if (set === void 0) { 242 map2.set(key, set = createT()); 243 } 244 return set; 245 }; 246 var map = (m, f) => { 247 const res = []; 248 for (const [key, value] of m) { 249 res.push(f(value, key)); 250 } 251 return res; 252 }; 253 var any = (m, f) => { 254 for (const [key, value] of m) { 255 if (f(value, key)) { 256 return true; 257 } 258 } 259 return false; 260 }; 261 262 // node_modules/lib0/set.js 263 var create2 = () => /* @__PURE__ */ new Set(); 264 265 // node_modules/lib0/array.js 266 var last = (arr) => arr[arr.length - 1]; 267 var appendTo = (dest, src) => { 268 for (let i = 0; i < src.length; i++) { 269 dest.push(src[i]); 270 } 271 }; 272 var from = Array.from; 273 var every = (arr, f) => { 274 for (let i = 0; i < arr.length; i++) { 275 if (!f(arr[i], i, arr)) { 276 return false; 277 } 278 } 279 return true; 280 }; 281 var some = (arr, f) => { 282 for (let i = 0; i < arr.length; i++) { 283 if (f(arr[i], i, arr)) { 284 return true; 285 } 286 } 287 return false; 288 }; 289 var unfold = (len, f) => { 290 const array = new Array(len); 291 for (let i = 0; i < len; i++) { 292 array[i] = f(i, array); 293 } 294 return array; 295 }; 296 var isArray = Array.isArray; 297 298 // node_modules/lib0/observable.js 299 var ObservableV2 = class { 300 constructor() { 301 this._observers = create(); 302 } 303 /** 304 * @template {keyof EVENTS & string} NAME 305 * @param {NAME} name 306 * @param {EVENTS[NAME]} f 307 */ 308 on(name, f) { 309 setIfUndefined( 310 this._observers, 311 /** @type {string} */ 312 name, 313 create2 314 ).add(f); 315 return f; 316 } 317 /** 318 * @template {keyof EVENTS & string} NAME 319 * @param {NAME} name 320 * @param {EVENTS[NAME]} f 321 */ 322 once(name, f) { 323 const _f = (...args2) => { 324 this.off( 325 name, 326 /** @type {any} */ 327 _f 328 ); 329 f(...args2); 330 }; 331 this.on( 332 name, 333 /** @type {any} */ 334 _f 335 ); 336 } 337 /** 338 * @template {keyof EVENTS & string} NAME 339 * @param {NAME} name 340 * @param {EVENTS[NAME]} f 341 */ 342 off(name, f) { 343 const observers = this._observers.get(name); 344 if (observers !== void 0) { 345 observers.delete(f); 346 if (observers.size === 0) { 347 this._observers.delete(name); 348 } 349 } 350 } 351 /** 352 * Emit a named event. All registered event listeners that listen to the 353 * specified name will receive the event. 354 * 355 * @todo This should catch exceptions 356 * 357 * @template {keyof EVENTS & string} NAME 358 * @param {NAME} name The event name. 359 * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. 360 */ 361 emit(name, args2) { 362 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 363 } 364 destroy() { 365 this._observers = create(); 366 } 367 }; 368 var Observable = class { 369 constructor() { 370 this._observers = create(); 371 } 372 /** 373 * @param {N} name 374 * @param {function} f 375 */ 376 on(name, f) { 377 setIfUndefined(this._observers, name, create2).add(f); 378 } 379 /** 380 * @param {N} name 381 * @param {function} f 382 */ 383 once(name, f) { 384 const _f = (...args2) => { 385 this.off(name, _f); 386 f(...args2); 387 }; 388 this.on(name, _f); 389 } 390 /** 391 * @param {N} name 392 * @param {function} f 393 */ 394 off(name, f) { 395 const observers = this._observers.get(name); 396 if (observers !== void 0) { 397 observers.delete(f); 398 if (observers.size === 0) { 399 this._observers.delete(name); 400 } 401 } 402 } 403 /** 404 * Emit a named event. All registered event listeners that listen to the 405 * specified name will receive the event. 406 * 407 * @todo This should catch exceptions 408 * 409 * @param {N} name The event name. 410 * @param {Array<any>} args The arguments that are applied to the event listener. 411 */ 412 emit(name, args2) { 413 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 414 } 415 destroy() { 416 this._observers = create(); 417 } 418 }; 419 420 // node_modules/lib0/math.js 421 var floor = Math.floor; 422 var abs = Math.abs; 423 var min = (a, b) => a < b ? a : b; 424 var max = (a, b) => a > b ? a : b; 425 var isNaN2 = Number.isNaN; 426 var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; 427 428 // node_modules/lib0/binary.js 429 var BIT1 = 1; 430 var BIT2 = 2; 431 var BIT3 = 4; 432 var BIT4 = 8; 433 var BIT6 = 32; 434 var BIT7 = 64; 435 var BIT8 = 128; 436 var BIT18 = 1 << 17; 437 var BIT19 = 1 << 18; 438 var BIT20 = 1 << 19; 439 var BIT21 = 1 << 20; 440 var BIT22 = 1 << 21; 441 var BIT23 = 1 << 22; 442 var BIT24 = 1 << 23; 443 var BIT25 = 1 << 24; 444 var BIT26 = 1 << 25; 445 var BIT27 = 1 << 26; 446 var BIT28 = 1 << 27; 447 var BIT29 = 1 << 28; 448 var BIT30 = 1 << 29; 449 var BIT31 = 1 << 30; 450 var BIT32 = 1 << 31; 451 var BITS5 = 31; 452 var BITS6 = 63; 453 var BITS7 = 127; 454 var BITS17 = BIT18 - 1; 455 var BITS18 = BIT19 - 1; 456 var BITS19 = BIT20 - 1; 457 var BITS20 = BIT21 - 1; 458 var BITS21 = BIT22 - 1; 459 var BITS22 = BIT23 - 1; 460 var BITS23 = BIT24 - 1; 461 var BITS24 = BIT25 - 1; 462 var BITS25 = BIT26 - 1; 463 var BITS26 = BIT27 - 1; 464 var BITS27 = BIT28 - 1; 465 var BITS28 = BIT29 - 1; 466 var BITS29 = BIT30 - 1; 467 var BITS30 = BIT31 - 1; 468 var BITS31 = 2147483647; 469 470 // node_modules/lib0/number.js 471 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; 472 var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; 473 var LOWEST_INT32 = 1 << 31; 474 var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); 475 var isNaN3 = Number.isNaN; 476 var parseInt2 = Number.parseInt; 477 478 // node_modules/lib0/string.js 479 var fromCharCode = String.fromCharCode; 480 var fromCodePoint = String.fromCodePoint; 481 var MAX_UTF16_CHARACTER = fromCharCode(65535); 482 var toLowerCase = (s) => s.toLowerCase(); 483 var trimLeftRegex = /^\s*/g; 484 var trimLeft = (s) => s.replace(trimLeftRegex, ""); 485 var fromCamelCaseRegex = /([A-Z])/g; 486 var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match2) => `$separator}$toLowerCase(match2)}`)); 487 var _encodeUtf8Polyfill = (str) => { 488 const encodedString = unescape(encodeURIComponent(str)); 489 const len = encodedString.length; 490 const buf = new Uint8Array(len); 491 for (let i = 0; i < len; i++) { 492 buf[i] = /** @type {number} */ 493 encodedString.codePointAt(i); 494 } 495 return buf; 496 }; 497 var utf8TextEncoder = ( 498 /** @type {TextEncoder} */ 499 typeof TextEncoder !== "undefined" ? new TextEncoder() : null 500 ); 501 var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); 502 var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; 503 var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); 504 if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { 505 utf8TextDecoder = null; 506 } 507 var repeat = (source, n) => unfold(n, () => source).join(""); 508 509 // node_modules/lib0/encoding.js 510 var Encoder = class { 511 constructor() { 512 this.cpos = 0; 513 this.cbuf = new Uint8Array(100); 514 this.bufs = []; 515 } 516 }; 517 var createEncoder = () => new Encoder(); 518 var length = (encoder) => { 519 let len = encoder.cpos; 520 for (let i = 0; i < encoder.bufs.length; i++) { 521 len += encoder.bufs[i].length; 522 } 523 return len; 524 }; 525 var toUint8Array = (encoder) => { 526 const uint8arr = new Uint8Array(length(encoder)); 527 let curPos = 0; 528 for (let i = 0; i < encoder.bufs.length; i++) { 529 const d = encoder.bufs[i]; 530 uint8arr.set(d, curPos); 531 curPos += d.length; 532 } 533 uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); 534 return uint8arr; 535 }; 536 var verifyLen = (encoder, len) => { 537 const bufferLen = encoder.cbuf.length; 538 if (bufferLen - encoder.cpos < len) { 539 encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); 540 encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); 541 encoder.cpos = 0; 542 } 543 }; 544 var write = (encoder, num) => { 545 const bufferLen = encoder.cbuf.length; 546 if (encoder.cpos === bufferLen) { 547 encoder.bufs.push(encoder.cbuf); 548 encoder.cbuf = new Uint8Array(bufferLen * 2); 549 encoder.cpos = 0; 550 } 551 encoder.cbuf[encoder.cpos++] = num; 552 }; 553 var writeUint8 = write; 554 var writeVarUint = (encoder, num) => { 555 while (num > BITS7) { 556 write(encoder, BIT8 | BITS7 & num); 557 num = floor(num / 128); 558 } 559 write(encoder, BITS7 & num); 560 }; 561 var writeVarInt = (encoder, num) => { 562 const isNegative = isNegativeZero(num); 563 if (isNegative) { 564 num = -num; 565 } 566 write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); 567 num = floor(num / 64); 568 while (num > 0) { 569 write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); 570 num = floor(num / 128); 571 } 572 }; 573 var _strBuffer = new Uint8Array(3e4); 574 var _maxStrBSize = _strBuffer.length / 3; 575 var _writeVarStringNative = (encoder, str) => { 576 if (str.length < _maxStrBSize) { 577 const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; 578 writeVarUint(encoder, written); 579 for (let i = 0; i < written; i++) { 580 write(encoder, _strBuffer[i]); 581 } 582 } else { 583 writeVarUint8Array(encoder, encodeUtf8(str)); 584 } 585 }; 586 var _writeVarStringPolyfill = (encoder, str) => { 587 const encodedString = unescape(encodeURIComponent(str)); 588 const len = encodedString.length; 589 writeVarUint(encoder, len); 590 for (let i = 0; i < len; i++) { 591 write( 592 encoder, 593 /** @type {number} */ 594 encodedString.codePointAt(i) 595 ); 596 } 597 }; 598 var writeVarString = utf8TextEncoder && /** @type {any} */ 599 utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; 600 var writeBinaryEncoder = (encoder, append2) => writeUint8Array(encoder, toUint8Array(append2)); 601 var writeUint8Array = (encoder, uint8Array) => { 602 const bufferLen = encoder.cbuf.length; 603 const cpos = encoder.cpos; 604 const leftCopyLen = min(bufferLen - cpos, uint8Array.length); 605 const rightCopyLen = uint8Array.length - leftCopyLen; 606 encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); 607 encoder.cpos += leftCopyLen; 608 if (rightCopyLen > 0) { 609 encoder.bufs.push(encoder.cbuf); 610 encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); 611 encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); 612 encoder.cpos = rightCopyLen; 613 } 614 }; 615 var writeVarUint8Array = (encoder, uint8Array) => { 616 writeVarUint(encoder, uint8Array.byteLength); 617 writeUint8Array(encoder, uint8Array); 618 }; 619 var writeOnDataView = (encoder, len) => { 620 verifyLen(encoder, len); 621 const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); 622 encoder.cpos += len; 623 return dview; 624 }; 625 var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); 626 var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); 627 var writeBigInt64 = (encoder, num) => ( 628 /** @type {any} */ 629 writeOnDataView(encoder, 8).setBigInt64(0, num, false) 630 ); 631 var floatTestBed = new DataView(new ArrayBuffer(4)); 632 var isFloat32 = (num) => { 633 floatTestBed.setFloat32(0, num); 634 return floatTestBed.getFloat32(0) === num; 635 }; 636 var writeAny = (encoder, data) => { 637 switch (typeof data) { 638 case "string": 639 write(encoder, 119); 640 writeVarString(encoder, data); 641 break; 642 case "number": 643 if (isInteger(data) && abs(data) <= BITS31) { 644 write(encoder, 125); 645 writeVarInt(encoder, data); 646 } else if (isFloat32(data)) { 647 write(encoder, 124); 648 writeFloat32(encoder, data); 649 } else { 650 write(encoder, 123); 651 writeFloat64(encoder, data); 652 } 653 break; 654 case "bigint": 655 write(encoder, 122); 656 writeBigInt64(encoder, data); 657 break; 658 case "object": 659 if (data === null) { 660 write(encoder, 126); 661 } else if (isArray(data)) { 662 write(encoder, 117); 663 writeVarUint(encoder, data.length); 664 for (let i = 0; i < data.length; i++) { 665 writeAny(encoder, data[i]); 666 } 667 } else if (data instanceof Uint8Array) { 668 write(encoder, 116); 669 writeVarUint8Array(encoder, data); 670 } else { 671 write(encoder, 118); 672 const keys2 = Object.keys(data); 673 writeVarUint(encoder, keys2.length); 674 for (let i = 0; i < keys2.length; i++) { 675 const key = keys2[i]; 676 writeVarString(encoder, key); 677 writeAny(encoder, data[key]); 678 } 679 } 680 break; 681 case "boolean": 682 write(encoder, data ? 120 : 121); 683 break; 684 default: 685 write(encoder, 127); 686 } 687 }; 688 var RleEncoder = class extends Encoder { 689 /** 690 * @param {function(Encoder, T):void} writer 691 */ 692 constructor(writer) { 693 super(); 694 this.w = writer; 695 this.s = null; 696 this.count = 0; 697 } 698 /** 699 * @param {T} v 700 */ 701 write(v) { 702 if (this.s === v) { 703 this.count++; 704 } else { 705 if (this.count > 0) { 706 writeVarUint(this, this.count - 1); 707 } 708 this.count = 1; 709 this.w(this, v); 710 this.s = v; 711 } 712 } 713 }; 714 var flushUintOptRleEncoder = (encoder) => { 715 if (encoder.count > 0) { 716 writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); 717 if (encoder.count > 1) { 718 writeVarUint(encoder.encoder, encoder.count - 2); 719 } 720 } 721 }; 722 var UintOptRleEncoder = class { 723 constructor() { 724 this.encoder = new Encoder(); 725 this.s = 0; 726 this.count = 0; 727 } 728 /** 729 * @param {number} v 730 */ 731 write(v) { 732 if (this.s === v) { 733 this.count++; 734 } else { 735 flushUintOptRleEncoder(this); 736 this.count = 1; 737 this.s = v; 738 } 739 } 740 /** 741 * Flush the encoded state and transform this to a Uint8Array. 742 * 743 * Note that this should only be called once. 744 */ 745 toUint8Array() { 746 flushUintOptRleEncoder(this); 747 return toUint8Array(this.encoder); 748 } 749 }; 750 var flushIntDiffOptRleEncoder = (encoder) => { 751 if (encoder.count > 0) { 752 const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); 753 writeVarInt(encoder.encoder, encodedDiff); 754 if (encoder.count > 1) { 755 writeVarUint(encoder.encoder, encoder.count - 2); 756 } 757 } 758 }; 759 var IntDiffOptRleEncoder = class { 760 constructor() { 761 this.encoder = new Encoder(); 762 this.s = 0; 763 this.count = 0; 764 this.diff = 0; 765 } 766 /** 767 * @param {number} v 768 */ 769 write(v) { 770 if (this.diff === v - this.s) { 771 this.s = v; 772 this.count++; 773 } else { 774 flushIntDiffOptRleEncoder(this); 775 this.count = 1; 776 this.diff = v - this.s; 777 this.s = v; 778 } 779 } 780 /** 781 * Flush the encoded state and transform this to a Uint8Array. 782 * 783 * Note that this should only be called once. 784 */ 785 toUint8Array() { 786 flushIntDiffOptRleEncoder(this); 787 return toUint8Array(this.encoder); 788 } 789 }; 790 var StringEncoder = class { 791 constructor() { 792 this.sarr = []; 793 this.s = ""; 794 this.lensE = new UintOptRleEncoder(); 795 } 796 /** 797 * @param {string} string 798 */ 799 write(string) { 800 this.s += string; 801 if (this.s.length > 19) { 802 this.sarr.push(this.s); 803 this.s = ""; 804 } 805 this.lensE.write(string.length); 806 } 807 toUint8Array() { 808 const encoder = new Encoder(); 809 this.sarr.push(this.s); 810 this.s = ""; 811 writeVarString(encoder, this.sarr.join("")); 812 writeUint8Array(encoder, this.lensE.toUint8Array()); 813 return toUint8Array(encoder); 814 } 815 }; 816 817 // node_modules/lib0/error.js 818 var create3 = (s) => new Error(s); 819 var methodUnimplemented = () => { 820 throw create3("Method unimplemented"); 821 }; 822 var unexpectedCase = () => { 823 throw create3("Unexpected case"); 824 }; 825 826 // node_modules/lib0/decoding.js 827 var errorUnexpectedEndOfArray = create3("Unexpected end of array"); 828 var errorIntegerOutOfRange = create3("Integer out of Range"); 829 var Decoder = class { 830 /** 831 * @param {Uint8Array<Buf>} uint8Array Binary data to decode 832 */ 833 constructor(uint8Array) { 834 this.arr = uint8Array; 835 this.pos = 0; 836 } 837 }; 838 var createDecoder = (uint8Array) => new Decoder(uint8Array); 839 var hasContent = (decoder) => decoder.pos !== decoder.arr.length; 840 var readUint8Array = (decoder, len) => { 841 const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); 842 decoder.pos += len; 843 return view; 844 }; 845 var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); 846 var readUint8 = (decoder) => decoder.arr[decoder.pos++]; 847 var readVarUint = (decoder) => { 848 let num = 0; 849 let mult = 1; 850 const len = decoder.arr.length; 851 while (decoder.pos < len) { 852 const r = decoder.arr[decoder.pos++]; 853 num = num + (r & BITS7) * mult; 854 mult *= 128; 855 if (r < BIT8) { 856 return num; 857 } 858 if (num > MAX_SAFE_INTEGER) { 859 throw errorIntegerOutOfRange; 860 } 861 } 862 throw errorUnexpectedEndOfArray; 863 }; 864 var readVarInt = (decoder) => { 865 let r = decoder.arr[decoder.pos++]; 866 let num = r & BITS6; 867 let mult = 64; 868 const sign = (r & BIT7) > 0 ? -1 : 1; 869 if ((r & BIT8) === 0) { 870 return sign * num; 871 } 872 const len = decoder.arr.length; 873 while (decoder.pos < len) { 874 r = decoder.arr[decoder.pos++]; 875 num = num + (r & BITS7) * mult; 876 mult *= 128; 877 if (r < BIT8) { 878 return sign * num; 879 } 880 if (num > MAX_SAFE_INTEGER) { 881 throw errorIntegerOutOfRange; 882 } 883 } 884 throw errorUnexpectedEndOfArray; 885 }; 886 var _readVarStringPolyfill = (decoder) => { 887 let remainingLen = readVarUint(decoder); 888 if (remainingLen === 0) { 889 return ""; 890 } else { 891 let encodedString = String.fromCodePoint(readUint8(decoder)); 892 if (--remainingLen < 100) { 893 while (remainingLen--) { 894 encodedString += String.fromCodePoint(readUint8(decoder)); 895 } 896 } else { 897 while (remainingLen > 0) { 898 const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; 899 const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); 900 decoder.pos += nextLen; 901 encodedString += String.fromCodePoint.apply( 902 null, 903 /** @type {any} */ 904 bytes 905 ); 906 remainingLen -= nextLen; 907 } 908 } 909 return decodeURIComponent(escape(encodedString)); 910 } 911 }; 912 var _readVarStringNative = (decoder) => ( 913 /** @type any */ 914 utf8TextDecoder.decode(readVarUint8Array(decoder)) 915 ); 916 var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; 917 var readFromDataView = (decoder, len) => { 918 const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); 919 decoder.pos += len; 920 return dv; 921 }; 922 var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); 923 var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); 924 var readBigInt64 = (decoder) => ( 925 /** @type {any} */ 926 readFromDataView(decoder, 8).getBigInt64(0, false) 927 ); 928 var readAnyLookupTable = [ 929 (decoder) => void 0, 930 // CASE 127: undefined 931 (decoder) => null, 932 // CASE 126: null 933 readVarInt, 934 // CASE 125: integer 935 readFloat32, 936 // CASE 124: float32 937 readFloat64, 938 // CASE 123: float64 939 readBigInt64, 940 // CASE 122: bigint 941 (decoder) => false, 942 // CASE 121: boolean (false) 943 (decoder) => true, 944 // CASE 120: boolean (true) 945 readVarString, 946 // CASE 119: string 947 (decoder) => { 948 const len = readVarUint(decoder); 949 const obj = {}; 950 for (let i = 0; i < len; i++) { 951 const key = readVarString(decoder); 952 obj[key] = readAny(decoder); 953 } 954 return obj; 955 }, 956 (decoder) => { 957 const len = readVarUint(decoder); 958 const arr = []; 959 for (let i = 0; i < len; i++) { 960 arr.push(readAny(decoder)); 961 } 962 return arr; 963 }, 964 readVarUint8Array 965 // CASE 116: Uint8Array 966 ]; 967 var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); 968 var RleDecoder = class extends Decoder { 969 /** 970 * @param {Uint8Array} uint8Array 971 * @param {function(Decoder):T} reader 972 */ 973 constructor(uint8Array, reader) { 974 super(uint8Array); 975 this.reader = reader; 976 this.s = null; 977 this.count = 0; 978 } 979 read() { 980 if (this.count === 0) { 981 this.s = this.reader(this); 982 if (hasContent(this)) { 983 this.count = readVarUint(this) + 1; 984 } else { 985 this.count = -1; 986 } 987 } 988 this.count--; 989 return ( 990 /** @type {T} */ 991 this.s 992 ); 993 } 994 }; 995 var UintOptRleDecoder = class extends Decoder { 996 /** 997 * @param {Uint8Array} uint8Array 998 */ 999 constructor(uint8Array) { 1000 super(uint8Array); 1001 this.s = 0; 1002 this.count = 0; 1003 } 1004 read() { 1005 if (this.count === 0) { 1006 this.s = readVarInt(this); 1007 const isNegative = isNegativeZero(this.s); 1008 this.count = 1; 1009 if (isNegative) { 1010 this.s = -this.s; 1011 this.count = readVarUint(this) + 2; 1012 } 1013 } 1014 this.count--; 1015 return ( 1016 /** @type {number} */ 1017 this.s 1018 ); 1019 } 1020 }; 1021 var IntDiffOptRleDecoder = class extends Decoder { 1022 /** 1023 * @param {Uint8Array} uint8Array 1024 */ 1025 constructor(uint8Array) { 1026 super(uint8Array); 1027 this.s = 0; 1028 this.count = 0; 1029 this.diff = 0; 1030 } 1031 /** 1032 * @return {number} 1033 */ 1034 read() { 1035 if (this.count === 0) { 1036 const diff = readVarInt(this); 1037 const hasCount = diff & 1; 1038 this.diff = floor(diff / 2); 1039 this.count = 1; 1040 if (hasCount) { 1041 this.count = readVarUint(this) + 2; 1042 } 1043 } 1044 this.s += this.diff; 1045 this.count--; 1046 return this.s; 1047 } 1048 }; 1049 var StringDecoder = class { 1050 /** 1051 * @param {Uint8Array} uint8Array 1052 */ 1053 constructor(uint8Array) { 1054 this.decoder = new UintOptRleDecoder(uint8Array); 1055 this.str = readVarString(this.decoder); 1056 this.spos = 0; 1057 } 1058 /** 1059 * @return {string} 1060 */ 1061 read() { 1062 const end = this.spos + this.decoder.read(); 1063 const res = this.str.slice(this.spos, end); 1064 this.spos = end; 1065 return res; 1066 } 1067 }; 1068 1069 // node_modules/lib0/webcrypto.js 1070 var subtle = crypto.subtle; 1071 var getRandomValues = crypto.getRandomValues.bind(crypto); 1072 1073 // node_modules/lib0/random.js 1074 var uint32 = () => getRandomValues(new Uint32Array(1))[0]; 1075 var uuidv4Template = "10000000-1000-4000-8000" + -1e11; 1076 var uuidv4 = () => uuidv4Template.replace( 1077 /[018]/g, 1078 /** @param {number} c */ 1079 (c) => (c ^ uint32() & 15 >> c / 4).toString(16) 1080 ); 1081 1082 // node_modules/lib0/time.js 1083 var getUnixTime = Date.now; 1084 1085 // node_modules/lib0/promise.js 1086 var create4 = (f) => ( 1087 /** @type {Promise<T>} */ 1088 new Promise(f) 1089 ); 1090 var all = Promise.all.bind(Promise); 1091 1092 // node_modules/lib0/conditions.js 1093 var undefinedToNull = (v) => v === void 0 ? null : v; 1094 1095 // node_modules/lib0/storage.js 1096 var VarStoragePolyfill = class { 1097 constructor() { 1098 this.map = /* @__PURE__ */ new Map(); 1099 } 1100 /** 1101 * @param {string} key 1102 * @param {any} newValue 1103 */ 1104 setItem(key, newValue) { 1105 this.map.set(key, newValue); 1106 } 1107 /** 1108 * @param {string} key 1109 */ 1110 getItem(key) { 1111 return this.map.get(key); 1112 } 1113 }; 1114 var _localStorage = new VarStoragePolyfill(); 1115 var usePolyfill = true; 1116 try { 1117 if (typeof localStorage !== "undefined" && localStorage) { 1118 _localStorage = localStorage; 1119 usePolyfill = false; 1120 } 1121 } catch (e) { 1122 } 1123 var varStorage = _localStorage; 1124 1125 // node_modules/lib0/trait/equality.js 1126 var EqualityTraitSymbol = /* @__PURE__ */ Symbol("Equality"); 1127 var equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false; 1128 1129 // node_modules/lib0/object.js 1130 var isObject = (o) => typeof o === "object"; 1131 var assign = Object.assign; 1132 var keys = Object.keys; 1133 var forEach = (obj, f) => { 1134 for (const key in obj) { 1135 f(obj[key], key); 1136 } 1137 }; 1138 var size = (obj) => keys(obj).length; 1139 var isEmpty = (obj) => { 1140 for (const _k in obj) { 1141 return false; 1142 } 1143 return true; 1144 }; 1145 var every2 = (obj, f) => { 1146 for (const key in obj) { 1147 if (!f(obj[key], key)) { 1148 return false; 1149 } 1150 } 1151 return true; 1152 }; 1153 var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); 1154 var equalFlat = (a, b) => a === b || size(a) === size(b) && every2(a, (val, key) => (val !== void 0 || hasProperty(b, key)) && equals(b[key], val)); 1155 var freeze = Object.freeze; 1156 var deepFreeze = (o) => { 1157 for (const key in o) { 1158 const c = o[key]; 1159 if (typeof c === "object" || typeof c === "function") { 1160 deepFreeze(o[key]); 1161 } 1162 } 1163 return freeze(o); 1164 }; 1165 1166 // node_modules/lib0/function.js 1167 var callAll = (fs, args2, i = 0) => { 1168 try { 1169 for (; i < fs.length; i++) { 1170 fs[i](...args2); 1171 } 1172 } finally { 1173 if (i < fs.length) { 1174 callAll(fs, args2, i + 1); 1175 } 1176 } 1177 }; 1178 var id = (a) => a; 1179 var equalityDeep = (a, b) => { 1180 if (a === b) { 1181 return true; 1182 } 1183 if (a == null || b == null || a.constructor !== b.constructor && (a.constructor || Object) !== (b.constructor || Object)) { 1184 return false; 1185 } 1186 if (a[EqualityTraitSymbol] != null) { 1187 return a[EqualityTraitSymbol](b); 1188 } 1189 switch (a.constructor) { 1190 case ArrayBuffer: 1191 a = new Uint8Array(a); 1192 b = new Uint8Array(b); 1193 // eslint-disable-next-line no-fallthrough 1194 case Uint8Array: { 1195 if (a.byteLength !== b.byteLength) { 1196 return false; 1197 } 1198 for (let i = 0; i < a.length; i++) { 1199 if (a[i] !== b[i]) { 1200 return false; 1201 } 1202 } 1203 break; 1204 } 1205 case Set: { 1206 if (a.size !== b.size) { 1207 return false; 1208 } 1209 for (const value of a) { 1210 if (!b.has(value)) { 1211 return false; 1212 } 1213 } 1214 break; 1215 } 1216 case Map: { 1217 if (a.size !== b.size) { 1218 return false; 1219 } 1220 for (const key of a.keys()) { 1221 if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) { 1222 return false; 1223 } 1224 } 1225 break; 1226 } 1227 case void 0: 1228 case Object: 1229 if (size(a) !== size(b)) { 1230 return false; 1231 } 1232 for (const key in a) { 1233 if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) { 1234 return false; 1235 } 1236 } 1237 break; 1238 case Array: 1239 if (a.length !== b.length) { 1240 return false; 1241 } 1242 for (let i = 0; i < a.length; i++) { 1243 if (!equalityDeep(a[i], b[i])) { 1244 return false; 1245 } 1246 } 1247 break; 1248 default: 1249 return false; 1250 } 1251 return true; 1252 }; 1253 var isOneOf = (value, options) => options.includes(value); 1254 1255 // node_modules/lib0/environment.js 1256 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]"; 1257 var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; 1258 var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; 1259 var params; 1260 var args = []; 1261 var computeParams = () => { 1262 if (params === void 0) { 1263 if (isNode) { 1264 params = create(); 1265 const pargs = process.argv; 1266 let currParamName = null; 1267 for (let i = 0; i < pargs.length; i++) { 1268 const parg = pargs[i]; 1269 if (parg[0] === "-") { 1270 if (currParamName !== null) { 1271 params.set(currParamName, ""); 1272 } 1273 currParamName = parg; 1274 } else { 1275 if (currParamName !== null) { 1276 params.set(currParamName, parg); 1277 currParamName = null; 1278 } else { 1279 args.push(parg); 1280 } 1281 } 1282 } 1283 if (currParamName !== null) { 1284 params.set(currParamName, ""); 1285 } 1286 } else if (typeof location === "object") { 1287 params = create(); 1288 (location.search || "?").slice(1).split("&").forEach((kv) => { 1289 if (kv.length !== 0) { 1290 const [key, value] = kv.split("="); 1291 params.set(`--$fromCamelCase(key, "-")}`, value); 1292 params.set(`-$fromCamelCase(key, "-")}`, value); 1293 } 1294 }); 1295 } else { 1296 params = create(); 1297 } 1298 } 1299 return params; 1300 }; 1301 var hasParam = (name) => computeParams().has(name); 1302 var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); 1303 var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; 1304 var production = hasConf("production"); 1305 var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); 1306 var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors 1307 !hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); 1308 1309 // node_modules/lib0/buffer.js 1310 var createUint8ArrayFromLen = (len) => new Uint8Array(len); 1311 var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length2) => new Uint8Array(buffer, byteOffset, length2); 1312 var toBase64Browser = (bytes) => { 1313 let s = ""; 1314 for (let i = 0; i < bytes.byteLength; i++) { 1315 s += fromCharCode(bytes[i]); 1316 } 1317 return btoa(s); 1318 }; 1319 var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); 1320 var fromBase64Browser = (s) => { 1321 const a = atob(s); 1322 const bytes = createUint8ArrayFromLen(a.length); 1323 for (let i = 0; i < a.length; i++) { 1324 bytes[i] = a.charCodeAt(i); 1325 } 1326 return bytes; 1327 }; 1328 var fromBase64Node = (s) => { 1329 const buf = Buffer.from(s, "base64"); 1330 return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); 1331 }; 1332 var toBase64 = isBrowser ? toBase64Browser : toBase64Node; 1333 var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; 1334 var copyUint8Array = (uint8Array) => { 1335 const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); 1336 newBuf.set(uint8Array); 1337 return newBuf; 1338 }; 1339 1340 // node_modules/lib0/pair.js 1341 var Pair = class { 1342 /** 1343 * @param {L} left 1344 * @param {R} right 1345 */ 1346 constructor(left, right) { 1347 this.left = left; 1348 this.right = right; 1349 } 1350 }; 1351 var create5 = (left, right) => new Pair(left, right); 1352 1353 // node_modules/lib0/prng.js 1354 var bool = (gen) => gen.next() >= 0.5; 1355 var int53 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); 1356 var int32 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); 1357 var int31 = (gen, min2, max2) => int32(gen, min2, max2); 1358 var letter = (gen) => fromCharCode(int31(gen, 97, 122)); 1359 var word = (gen, minLen = 0, maxLen = 20) => { 1360 const len = int31(gen, minLen, maxLen); 1361 let str = ""; 1362 for (let i = 0; i < len; i++) { 1363 str += letter(gen); 1364 } 1365 return str; 1366 }; 1367 var oneOf = (gen, array) => array[int31(gen, 0, array.length - 1)]; 1368 1369 // node_modules/lib0/schema.js 1370 var schemaSymbol = /* @__PURE__ */ Symbol("0schema"); 1371 var ValidationError = class { 1372 constructor() { 1373 this._rerrs = []; 1374 } 1375 /** 1376 * @param {string?} path 1377 * @param {string} expected 1378 * @param {string} has 1379 * @param {string?} message 1380 */ 1381 extend(path, expected, has, message = null) { 1382 this._rerrs.push({ path, expected, has, message }); 1383 } 1384 toString() { 1385 const s = []; 1386 for (let i = this._rerrs.length - 1; i > 0; i--) { 1387 const r = this._rerrs[i]; 1388 s.push(repeat(" ", (this._rerrs.length - i) * 2) + `$r.path != null ? `[$r.path}] ` : ""}$r.has} doesn't match $r.expected}. $r.message}`); 1389 } 1390 return s.join("\n"); 1391 } 1392 }; 1393 var shapeExtends = (a, b) => { 1394 if (a === b) return true; 1395 if (a == null || b == null || a.constructor !== b.constructor) return false; 1396 if (a[EqualityTraitSymbol]) return equals(a, b); 1397 if (isArray(a)) { 1398 return every( 1399 a, 1400 (aitem) => some(b, (bitem) => shapeExtends(aitem, bitem)) 1401 ); 1402 } else if (isObject(a)) { 1403 return every2( 1404 a, 1405 (aitem, akey) => shapeExtends(aitem, b[akey]) 1406 ); 1407 } 1408 return false; 1409 }; 1410 var Schema = class { 1411 // this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore 1412 /** 1413 * If true, the more things are added to the shape the more objects this schema will accept (e.g. 1414 * union). By default, the more objects are added, the the fewer objects this schema will accept. 1415 * @protected 1416 */ 1417 static _dilutes = false; 1418 /** 1419 * @param {Schema<any>} other 1420 */ 1421 extends(other) { 1422 let [a, b] = [ 1423 /** @type {any} */ 1424 this.shape, 1425 /** @type {any} */ 1426 other.shape 1427 ]; 1428 if ( 1429 /** @type {typeof Schema<any>} */ 1430 this.constructor._dilutes 1431 ) [b, a] = [a, b]; 1432 return shapeExtends(a, b); 1433 } 1434 /** 1435 * Overwrite this when necessary. By default, we only check the `shape` property which every shape 1436 * should have. 1437 * @param {Schema<any>} other 1438 */ 1439 equals(other) { 1440 return this.constructor === other.constructor && equalityDeep(this.shape, other.shape); 1441 } 1442 [schemaSymbol]() { 1443 return true; 1444 } 1445 /** 1446 * @param {object} other 1447 */ 1448 [EqualityTraitSymbol](other) { 1449 return this.equals( 1450 /** @type {any} */ 1451 other 1452 ); 1453 } 1454 /** 1455 * Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of 1456 * Schema. Validate will check the structure of the parameter and return true iff the instance 1457 * really is an instance of Schema. 1458 * 1459 * @param {T} o 1460 * @return {boolean} 1461 */ 1462 validate(o) { 1463 return this.check(o); 1464 } 1465 /* c8 ignore start */ 1466 /** 1467 * Similar to validate, but this method accepts untyped parameters. 1468 * 1469 * @param {any} _o 1470 * @param {ValidationError} [_err] 1471 * @return {_o is T} 1472 */ 1473 check(_o, _err) { 1474 methodUnimplemented(); 1475 } 1476 /* c8 ignore stop */ 1477 /** 1478 * @type {Schema<T?>} 1479 */ 1480 get nullable() { 1481 return $union(this, $null); 1482 } 1483 /** 1484 * @type {$Optional<Schema<T>>} 1485 */ 1486 get optional() { 1487 return new $Optional( 1488 /** @type {Schema<T>} */ 1489 this 1490 ); 1491 } 1492 /** 1493 * Cast a variable to a specific type. Returns the casted value, or throws an exception otherwise. 1494 * Use this if you know that the type is of a specific type and you just want to convince the type 1495 * system. 1496 * 1497 * **Do not rely on these error messages!** 1498 * Performs an assertion check only if not in a production environment. 1499 * 1500 * @template OO 1501 * @param {OO} o 1502 * @return {Extract<OO, T> extends never ? T : (OO extends Array<never> ? T : Extract<OO,T>)} 1503 */ 1504 cast(o) { 1505 assert(o, this); 1506 return ( 1507 /** @type {any} */ 1508 o 1509 ); 1510 } 1511 /** 1512 * EXPECTO PATRONUM!! 🪄 1513 * This function protects against type errors. Though it may not work in the real world. 1514 * 1515 * "After all this time?" 1516 * "Always." - Snape, talking about type safety 1517 * 1518 * Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed. 1519 * Use this if you know that the type is of a specific type and you just want to convince the type 1520 * system. 1521 * 1522 * Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).expect((n) => n + 1)` 1523 * 1524 * **Do not rely on these error messages!** 1525 * Performs an assertion check if not in a production environment. 1526 * 1527 * @param {T} o 1528 * @return {o extends T ? T : never} 1529 */ 1530 expect(o) { 1531 assert(o, this); 1532 return o; 1533 } 1534 }; 1535 var $ConstructedBy = class extends Schema { 1536 /** 1537 * @param {C} c 1538 * @param {((o:Instance<C>)=>boolean)|null} check 1539 */ 1540 constructor(c, check) { 1541 super(); 1542 this.shape = c; 1543 this._c = check; 1544 } 1545 /** 1546 * @param {any} o 1547 * @param {ValidationError} [err] 1548 * @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o 1549 */ 1550 check(o, err = void 0) { 1551 const c = o?.constructor === this.shape && (this._c == null || this._c(o)); 1552 !c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? "Constructor match failed" : "Check failed"); 1553 return c; 1554 } 1555 }; 1556 var $constructedBy = (c, check = null) => new $ConstructedBy(c, check); 1557 var $$constructedBy = $constructedBy($ConstructedBy); 1558 var $Custom = class extends Schema { 1559 /** 1560 * @param {(o:any) => boolean} check 1561 */ 1562 constructor(check) { 1563 super(); 1564 this.shape = check; 1565 } 1566 /** 1567 * @param {any} o 1568 * @param {ValidationError} err 1569 * @return {o is any} 1570 */ 1571 check(o, err) { 1572 const c = this.shape(o); 1573 !c && err?.extend(null, "custom prop", o?.constructor.name, "failed to check custom prop"); 1574 return c; 1575 } 1576 }; 1577 var $custom = (check) => new $Custom(check); 1578 var $$custom = $constructedBy($Custom); 1579 var $Literal = class extends Schema { 1580 /** 1581 * @param {Array<T>} literals 1582 */ 1583 constructor(literals) { 1584 super(); 1585 this.shape = literals; 1586 } 1587 /** 1588 * 1589 * @param {any} o 1590 * @param {ValidationError} [err] 1591 * @return {o is T} 1592 */ 1593 check(o, err) { 1594 const c = this.shape.some((a) => a === o); 1595 !c && err?.extend(null, this.shape.join(" | "), o.toString()); 1596 return c; 1597 } 1598 }; 1599 var $literal = (...literals) => new $Literal(literals); 1600 var $$literal = $constructedBy($Literal); 1601 var _regexEscape = ( 1602 /** @type {any} */ 1603 RegExp.escape || /** @type {(str:string) => string} */ 1604 ((str) => str.replace(/[().|&,$^[\]]/g, (s) => "\\" + s)) 1605 ); 1606 var _schemaStringTemplateToRegex = (s) => { 1607 if ($string.check(s)) { 1608 return [_regexEscape(s)]; 1609 } 1610 if ($$literal.check(s)) { 1611 return ( 1612 /** @type {Array<string|number>} */ 1613 s.shape.map((v) => v + "") 1614 ); 1615 } 1616 if ($$number.check(s)) { 1617 return ["[+-]?\\d+.?\\d*"]; 1618 } 1619 if ($$string.check(s)) { 1620 return [".*"]; 1621 } 1622 if ($$union.check(s)) { 1623 return s.shape.map(_schemaStringTemplateToRegex).flat(1); 1624 } 1625 unexpectedCase(); 1626 }; 1627 var $StringTemplate = class extends Schema { 1628 /** 1629 * @param {T} shape 1630 */ 1631 constructor(shape) { 1632 super(); 1633 this.shape = shape; 1634 this._r = new RegExp("^" + shape.map(_schemaStringTemplateToRegex).map((opts) => `($opts.join("|")})`).join("") + "$"); 1635 } 1636 /** 1637 * @param {any} o 1638 * @param {ValidationError} [err] 1639 * @return {o is CastStringTemplateArgsToTemplate<T>} 1640 */ 1641 check(o, err) { 1642 const c = this._r.exec(o) != null; 1643 !c && err?.extend(null, this._r.toString(), o.toString(), "String doesn't match string template."); 1644 return c; 1645 } 1646 }; 1647 var $$stringTemplate = $constructedBy($StringTemplate); 1648 var isOptionalSymbol = /* @__PURE__ */ Symbol("optional"); 1649 var $Optional = class extends Schema { 1650 /** 1651 * @param {S} shape 1652 */ 1653 constructor(shape) { 1654 super(); 1655 this.shape = shape; 1656 } 1657 /** 1658 * @param {any} o 1659 * @param {ValidationError} [err] 1660 * @return {o is (Unwrap<S>|undefined)} 1661 */ 1662 check(o, err) { 1663 const c = o === void 0 || this.shape.check(o); 1664 !c && err?.extend(null, "undefined (optional)", "()"); 1665 return c; 1666 } 1667 get [isOptionalSymbol]() { 1668 return true; 1669 } 1670 }; 1671 var $$optional = $constructedBy($Optional); 1672 var $Never = class extends Schema { 1673 /** 1674 * @param {any} _o 1675 * @param {ValidationError} [err] 1676 * @return {_o is never} 1677 */ 1678 check(_o, err) { 1679 err?.extend(null, "never", typeof _o); 1680 return false; 1681 } 1682 }; 1683 var $never = new $Never(); 1684 var $$never = $constructedBy($Never); 1685 var $Object = class _$Object extends Schema { 1686 /** 1687 * @param {S} shape 1688 * @param {boolean} partial 1689 */ 1690 constructor(shape, partial = false) { 1691 super(); 1692 this.shape = shape; 1693 this._isPartial = partial; 1694 } 1695 static _dilutes = true; 1696 /** 1697 * @type {Schema<Partial<$ObjectToType<S>>>} 1698 */ 1699 get partial() { 1700 return new _$Object(this.shape, true); 1701 } 1702 /** 1703 * @param {any} o 1704 * @param {ValidationError} err 1705 * @return {o is $ObjectToType<S>} 1706 */ 1707 check(o, err) { 1708 if (o == null) { 1709 err?.extend(null, "object", "null"); 1710 return false; 1711 } 1712 return every2(this.shape, (vv, vk) => { 1713 const c = this._isPartial && !hasProperty(o, vk) || vv.check(o[vk], err); 1714 !c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], "Object property does not match"); 1715 return c; 1716 }); 1717 } 1718 }; 1719 var $object = (def) => ( 1720 /** @type {any} */ 1721 new $Object(def) 1722 ); 1723 var $$object = $constructedBy($Object); 1724 var $objectAny = $custom((o) => o != null && (o.constructor === Object || o.constructor == null)); 1725 var $Record = class extends Schema { 1726 /** 1727 * @param {Keys} keys 1728 * @param {Values} values 1729 */ 1730 constructor(keys2, values) { 1731 super(); 1732 this.shape = { 1733 keys: keys2, 1734 values 1735 }; 1736 } 1737 /** 1738 * @param {any} o 1739 * @param {ValidationError} err 1740 * @return {o is { [key in Unwrap<Keys>]: Unwrap<Values> }} 1741 */ 1742 check(o, err) { 1743 return o != null && every2(o, (vv, vk) => { 1744 const ck = this.shape.keys.check(vk, err); 1745 !ck && err?.extend(vk + "", "Record", typeof o, ck ? "Key doesn't match schema" : "Value doesn't match value"); 1746 return ck && this.shape.values.check(vv, err); 1747 }); 1748 } 1749 }; 1750 var $record = (keys2, values) => new $Record(keys2, values); 1751 var $$record = $constructedBy($Record); 1752 var $Tuple = class extends Schema { 1753 /** 1754 * @param {S} shape 1755 */ 1756 constructor(shape) { 1757 super(); 1758 this.shape = shape; 1759 } 1760 /** 1761 * @param {any} o 1762 * @param {ValidationError} err 1763 * @return {o is { [K in keyof S]: S[K] extends Schema<infer Type> ? Type : never }} 1764 */ 1765 check(o, err) { 1766 return o != null && every2(this.shape, (vv, vk) => { 1767 const c = ( 1768 /** @type {Schema<any>} */ 1769 vv.check(o[vk], err) 1770 ); 1771 !c && err?.extend(vk.toString(), "Tuple", typeof vv); 1772 return c; 1773 }); 1774 } 1775 }; 1776 var $tuple = (...def) => new $Tuple(def); 1777 var $$tuple = $constructedBy($Tuple); 1778 var $Array = class extends Schema { 1779 /** 1780 * @param {Array<S>} v 1781 */ 1782 constructor(v) { 1783 super(); 1784 this.shape = v.length === 1 ? v[0] : new $Union(v); 1785 } 1786 /** 1787 * @param {any} o 1788 * @param {ValidationError} [err] 1789 * @return {o is Array<S extends Schema<infer T> ? T : never>} o 1790 */ 1791 check(o, err) { 1792 const c = isArray(o) && every(o, (oi) => this.shape.check(oi)); 1793 !c && err?.extend(null, "Array", ""); 1794 return c; 1795 } 1796 }; 1797 var $array = (...def) => new $Array(def); 1798 var $$array = $constructedBy($Array); 1799 var $arrayAny = $custom((o) => isArray(o)); 1800 var $InstanceOf = class extends Schema { 1801 /** 1802 * @param {new (...args:any) => T} constructor 1803 * @param {((o:T) => boolean)|null} check 1804 */ 1805 constructor(constructor, check) { 1806 super(); 1807 this.shape = constructor; 1808 this._c = check; 1809 } 1810 /** 1811 * @param {any} o 1812 * @param {ValidationError} err 1813 * @return {o is T} 1814 */ 1815 check(o, err) { 1816 const c = o instanceof this.shape && (this._c == null || this._c(o)); 1817 !c && err?.extend(null, this.shape.name, o?.constructor.name); 1818 return c; 1819 } 1820 }; 1821 var $instanceOf = (c, check = null) => new $InstanceOf(c, check); 1822 var $$instanceOf = $constructedBy($InstanceOf); 1823 var $$schema = $instanceOf(Schema); 1824 var $Lambda = class extends Schema { 1825 /** 1826 * @param {Args} args 1827 */ 1828 constructor(args2) { 1829 super(); 1830 this.len = args2.length - 1; 1831 this.args = $tuple(...args2.slice(-1)); 1832 this.res = args2[this.len]; 1833 } 1834 /** 1835 * @param {any} f 1836 * @param {ValidationError} err 1837 * @return {f is _LArgsToLambdaDef<Args>} 1838 */ 1839 check(f, err) { 1840 const c = f.constructor === Function && f.length <= this.len; 1841 !c && err?.extend(null, "function", typeof f); 1842 return c; 1843 } 1844 }; 1845 var $$lambda = $constructedBy($Lambda); 1846 var $function = $custom((o) => typeof o === "function"); 1847 var $Intersection = class extends Schema { 1848 /** 1849 * @param {T} v 1850 */ 1851 constructor(v) { 1852 super(); 1853 this.shape = v; 1854 } 1855 /** 1856 * @param {any} o 1857 * @param {ValidationError} [err] 1858 * @return {o is Intersect<UnwrapArray<T>>} 1859 */ 1860 check(o, err) { 1861 const c = every(this.shape, (check) => check.check(o, err)); 1862 !c && err?.extend(null, "Intersectinon", typeof o); 1863 return c; 1864 } 1865 }; 1866 var $$intersect = $constructedBy($Intersection, (o) => o.shape.length > 0); 1867 var $Union = class extends Schema { 1868 static _dilutes = true; 1869 /** 1870 * @param {Array<Schema<S>>} v 1871 */ 1872 constructor(v) { 1873 super(); 1874 this.shape = v; 1875 } 1876 /** 1877 * @param {any} o 1878 * @param {ValidationError} [err] 1879 * @return {o is S} 1880 */ 1881 check(o, err) { 1882 const c = some(this.shape, (vv) => vv.check(o, err)); 1883 err?.extend(null, "Union", typeof o); 1884 return c; 1885 } 1886 }; 1887 var $union = (...schemas) => schemas.findIndex(($s) => $$union.check($s)) >= 0 ? $union(...schemas.map(($s) => $($s)).map(($s) => $$union.check($s) ? $s.shape : [$s]).flat(1)) : schemas.length === 1 ? schemas[0] : new $Union(schemas); 1888 var $$union = ( 1889 /** @type {Schema<$Union<any>>} */ 1890 $constructedBy($Union) 1891 ); 1892 var _t = () => true; 1893 var $any = $custom(_t); 1894 var $$any = ( 1895 /** @type {Schema<Schema<any>>} */ 1896 $constructedBy($Custom, (o) => o.shape === _t) 1897 ); 1898 var $bigint = $custom((o) => typeof o === "bigint"); 1899 var $$bigint = ( 1900 /** @type {Schema<Schema<BigInt>>} */ 1901 $custom((o) => o === $bigint) 1902 ); 1903 var $symbol = $custom((o) => typeof o === "symbol"); 1904 var $$symbol = ( 1905 /** @type {Schema<Schema<Symbol>>} */ 1906 $custom((o) => o === $symbol) 1907 ); 1908 var $number = $custom((o) => typeof o === "number"); 1909 var $$number = ( 1910 /** @type {Schema<Schema<number>>} */ 1911 $custom((o) => o === $number) 1912 ); 1913 var $string = $custom((o) => typeof o === "string"); 1914 var $$string = ( 1915 /** @type {Schema<Schema<string>>} */ 1916 $custom((o) => o === $string) 1917 ); 1918 var $boolean = $custom((o) => typeof o === "boolean"); 1919 var $$boolean = ( 1920 /** @type {Schema<Schema<Boolean>>} */ 1921 $custom((o) => o === $boolean) 1922 ); 1923 var $undefined = $literal(void 0); 1924 var $$undefined = ( 1925 /** @type {Schema<Schema<undefined>>} */ 1926 $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === void 0) 1927 ); 1928 var $void = $literal(void 0); 1929 var $null = $literal(null); 1930 var $$null = ( 1931 /** @type {Schema<Schema<null>>} */ 1932 $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === null) 1933 ); 1934 var $uint8Array = $constructedBy(Uint8Array); 1935 var $$uint8Array = ( 1936 /** @type {Schema<Schema<Uint8Array>>} */ 1937 $constructedBy($ConstructedBy, (o) => o.shape === Uint8Array) 1938 ); 1939 var $primitive = $union($number, $string, $null, $undefined, $bigint, $boolean, $symbol); 1940 var $json = (() => { 1941 const $jsonArr = ( 1942 /** @type {$Array<$any>} */ 1943 $array($any) 1944 ); 1945 const $jsonRecord = ( 1946 /** @type {$Record<$string,$any>} */ 1947 $record($string, $any) 1948 ); 1949 const $json2 = $union($number, $string, $null, $boolean, $jsonArr, $jsonRecord); 1950 $jsonArr.shape = $json2; 1951 $jsonRecord.shape.values = $json2; 1952 return $json2; 1953 })(); 1954 var $ = (o) => { 1955 if ($$schema.check(o)) { 1956 return ( 1957 /** @type {any} */ 1958 o 1959 ); 1960 } else if ($objectAny.check(o)) { 1961 const o2 = {}; 1962 for (const k in o) { 1963 o2[k] = $(o[k]); 1964 } 1965 return ( 1966 /** @type {any} */ 1967 $object(o2) 1968 ); 1969 } else if ($arrayAny.check(o)) { 1970 return ( 1971 /** @type {any} */ 1972 $union(...o.map($)) 1973 ); 1974 } else if ($primitive.check(o)) { 1975 return ( 1976 /** @type {any} */ 1977 $literal(o) 1978 ); 1979 } else if ($function.check(o)) { 1980 return ( 1981 /** @type {any} */ 1982 $constructedBy( 1983 /** @type {any} */ 1984 o 1985 ) 1986 ); 1987 } 1988 unexpectedCase(); 1989 }; 1990 var assert = production ? () => { 1991 } : (o, schema) => { 1992 const err = new ValidationError(); 1993 if (!schema.check(o, err)) { 1994 throw create3(`Expected value to be of type $schema.constructor.name}. 1995 $err.toString()}`); 1996 } 1997 }; 1998 var PatternMatcher = class { 1999 /** 2000 * @param {Schema<State>} [$state] 2001 */ 2002 constructor($state) { 2003 this.patterns = []; 2004 this.$state = $state; 2005 } 2006 /** 2007 * @template P 2008 * @template R 2009 * @param {P} pattern 2010 * @param {(o:NoInfer<Unwrap<ReadSchema<P>>>,s:State)=>R} handler 2011 * @return {PatternMatcher<State,Patterns|Pattern<Unwrap<ReadSchema<P>>,R>>} 2012 */ 2013 if(pattern, handler) { 2014 this.patterns.push({ if: $(pattern), h: handler }); 2015 return this; 2016 } 2017 /** 2018 * @template R 2019 * @param {(o:any,s:State)=>R} h 2020 */ 2021 else(h) { 2022 return this.if($any, h); 2023 } 2024 /** 2025 * @return {State extends undefined 2026 * ? <In extends Unwrap<Patterns['if']>>(o:In,state?:undefined)=>PatternMatchResult<Patterns,In> 2027 * : <In extends Unwrap<Patterns['if']>>(o:In,state:State)=>PatternMatchResult<Patterns,In>} 2028 */ 2029 done() { 2030 return ( 2031 /** @type {any} */ 2032 (o, s) => { 2033 for (let i = 0; i < this.patterns.length; i++) { 2034 const p = this.patterns[i]; 2035 if (p.if.check(o)) { 2036 return p.h(o, s); 2037 } 2038 } 2039 throw create3("Unhandled pattern"); 2040 } 2041 ); 2042 } 2043 }; 2044 var match = (state) => new PatternMatcher( 2045 /** @type {any} */ 2046 state 2047 ); 2048 var _random = ( 2049 /** @type {any} */ 2050 match( 2051 /** @type {Schema<prng.PRNG>} */ 2052 $any 2053 ).if($$number, (_o, gen) => int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER)).if($$string, (_o, gen) => word(gen)).if($$boolean, (_o, gen) => bool(gen)).if($$bigint, (_o, gen) => BigInt(int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER))).if($$union, (o, gen) => random(gen, oneOf(gen, o.shape))).if($$object, (o, gen) => { 2054 const res = {}; 2055 for (const k in o.shape) { 2056 let prop = o.shape[k]; 2057 if ($$optional.check(prop)) { 2058 if (bool(gen)) { 2059 continue; 2060 } 2061 prop = prop.shape; 2062 } 2063 res[k] = _random(prop, gen); 2064 } 2065 return res; 2066 }).if($$array, (o, gen) => { 2067 const arr = []; 2068 const n = int32(gen, 0, 42); 2069 for (let i = 0; i < n; i++) { 2070 arr.push(random(gen, o.shape)); 2071 } 2072 return arr; 2073 }).if($$literal, (o, gen) => { 2074 return oneOf(gen, o.shape); 2075 }).if($$null, (o, gen) => { 2076 return null; 2077 }).if($$lambda, (o, gen) => { 2078 const res = random(gen, o.res); 2079 return () => res; 2080 }).if($$any, (o, gen) => random(gen, oneOf(gen, [ 2081 $number, 2082 $string, 2083 $null, 2084 $undefined, 2085 $bigint, 2086 $boolean, 2087 $array($number), 2088 $record($union("a", "b", "c"), $number) 2089 ]))).if($$record, (o, gen) => { 2090 const res = {}; 2091 const keysN = int53(gen, 0, 3); 2092 for (let i = 0; i < keysN; i++) { 2093 const key = random(gen, o.shape.keys); 2094 const val = random(gen, o.shape.values); 2095 res[key] = val; 2096 } 2097 return res; 2098 }).done() 2099 ); 2100 var random = (gen, schema) => ( 2101 /** @type {any} */ 2102 _random($(schema), gen) 2103 ); 2104 2105 // node_modules/lib0/dom.js 2106 var doc = ( 2107 /** @type {Document} */ 2108 typeof document !== "undefined" ? document : {} 2109 ); 2110 var $fragment = $custom((el) => el.nodeType === DOCUMENT_FRAGMENT_NODE); 2111 var domParser = ( 2112 /** @type {DOMParser} */ 2113 typeof DOMParser !== "undefined" ? new DOMParser() : null 2114 ); 2115 var $element = $custom((el) => el.nodeType === ELEMENT_NODE); 2116 var $text = $custom((el) => el.nodeType === TEXT_NODE); 2117 var mapToStyleString = (m) => map(m, (value, key) => `$key}:$value};`).join(""); 2118 var ELEMENT_NODE = doc.ELEMENT_NODE; 2119 var TEXT_NODE = doc.TEXT_NODE; 2120 var CDATA_SECTION_NODE = doc.CDATA_SECTION_NODE; 2121 var COMMENT_NODE = doc.COMMENT_NODE; 2122 var DOCUMENT_NODE = doc.DOCUMENT_NODE; 2123 var DOCUMENT_TYPE_NODE = doc.DOCUMENT_TYPE_NODE; 2124 var DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE; 2125 var $node = $custom((el) => el.nodeType === DOCUMENT_NODE); 2126 2127 // node_modules/lib0/symbol.js 2128 var create6 = Symbol; 2129 2130 // node_modules/lib0/logging.common.js 2131 var BOLD = create6(); 2132 var UNBOLD = create6(); 2133 var BLUE = create6(); 2134 var GREY = create6(); 2135 var GREEN = create6(); 2136 var RED = create6(); 2137 var PURPLE = create6(); 2138 var ORANGE = create6(); 2139 var UNCOLOR = create6(); 2140 var computeNoColorLoggingArgs = (args2) => { 2141 if (args2.length === 1 && args2[0]?.constructor === Function) { 2142 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2143 /** @type {[function]} */ 2144 args2[0](); 2145 } 2146 const strBuilder = []; 2147 const logArgs = []; 2148 let i = 0; 2149 for (; i < args2.length; i++) { 2150 const arg = args2[i]; 2151 if (arg === void 0) { 2152 break; 2153 } else if (arg.constructor === String || arg.constructor === Number) { 2154 strBuilder.push(arg); 2155 } else if (arg.constructor === Object) { 2156 break; 2157 } 2158 } 2159 if (i > 0) { 2160 logArgs.push(strBuilder.join("")); 2161 } 2162 for (; i < args2.length; i++) { 2163 const arg = args2[i]; 2164 if (!(arg instanceof Symbol)) { 2165 logArgs.push(arg); 2166 } 2167 } 2168 return logArgs; 2169 }; 2170 var lastLoggingTime = getUnixTime(); 2171 2172 // node_modules/lib0/logging.js 2173 var _browserStyleMap = { 2174 [BOLD]: create5("font-weight", "bold"), 2175 [UNBOLD]: create5("font-weight", "normal"), 2176 [BLUE]: create5("color", "blue"), 2177 [GREEN]: create5("color", "green"), 2178 [GREY]: create5("color", "grey"), 2179 [RED]: create5("color", "red"), 2180 [PURPLE]: create5("color", "purple"), 2181 [ORANGE]: create5("color", "orange"), 2182 // not well supported in chrome when debugging node with inspector - TODO: deprecate 2183 [UNCOLOR]: create5("color", "black") 2184 }; 2185 var computeBrowserLoggingArgs = (args2) => { 2186 if (args2.length === 1 && args2[0]?.constructor === Function) { 2187 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2188 /** @type {[function]} */ 2189 args2[0](); 2190 } 2191 const strBuilder = []; 2192 const styles = []; 2193 const currentStyle = create(); 2194 let logArgs = []; 2195 let i = 0; 2196 for (; i < args2.length; i++) { 2197 const arg = args2[i]; 2198 const style = _browserStyleMap[arg]; 2199 if (style !== void 0) { 2200 currentStyle.set(style.left, style.right); 2201 } else { 2202 if (arg === void 0) { 2203 break; 2204 } 2205 if (arg.constructor === String || arg.constructor === Number) { 2206 const style2 = mapToStyleString(currentStyle); 2207 if (i > 0 || style2.length > 0) { 2208 strBuilder.push("%c" + arg); 2209 styles.push(style2); 2210 } else { 2211 strBuilder.push(arg); 2212 } 2213 } else { 2214 break; 2215 } 2216 } 2217 } 2218 if (i > 0) { 2219 logArgs = styles; 2220 logArgs.unshift(strBuilder.join("")); 2221 } 2222 for (; i < args2.length; i++) { 2223 const arg = args2[i]; 2224 if (!(arg instanceof Symbol)) { 2225 logArgs.push(arg); 2226 } 2227 } 2228 return logArgs; 2229 }; 2230 var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; 2231 var print = (...args2) => { 2232 console.log(...computeLoggingArgs(args2)); 2233 vconsoles.forEach((vc) => vc.print(args2)); 2234 }; 2235 var warn = (...args2) => { 2236 console.warn(...computeLoggingArgs(args2)); 2237 args2.unshift(ORANGE); 2238 vconsoles.forEach((vc) => vc.print(args2)); 2239 }; 2240 var vconsoles = create2(); 2241 2242 // node_modules/lib0/iterator.js 2243 var createIterator = (next) => ({ 2244 /** 2245 * @return {IterableIterator<T>} 2246 */ 2247 [Symbol.iterator]() { 2248 return this; 2249 }, 2250 // @ts-ignore 2251 next 2252 }); 2253 var iteratorFilter = (iterator, filter) => createIterator(() => { 2254 let res; 2255 do { 2256 res = iterator.next(); 2257 } while (!res.done && !filter(res.value)); 2258 return res; 2259 }); 2260 var iteratorMap = (iterator, fmap) => createIterator(() => { 2261 const { done, value } = iterator.next(); 2262 return { done, value: done ? void 0 : fmap(value) }; 2263 }); 2264 2265 // node_modules/yjs/dist/yjs.mjs 2266 var AbstractConnector = class extends ObservableV2 { 2267 /** 2268 * @param {Doc} ydoc 2269 * @param {any} awareness 2270 */ 2271 constructor(ydoc, awareness) { 2272 super(); 2273 this.doc = ydoc; 2274 this.awareness = awareness; 2275 } 2276 }; 2277 var DeleteItem = class { 2278 /** 2279 * @param {number} clock 2280 * @param {number} len 2281 */ 2282 constructor(clock, len) { 2283 this.clock = clock; 2284 this.len = len; 2285 } 2286 }; 2287 var DeleteSet = class { 2288 constructor() { 2289 this.clients = /* @__PURE__ */ new Map(); 2290 } 2291 }; 2292 var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { 2293 const structs = ( 2294 /** @type {Array<GC|Item>} */ 2295 transaction.doc.store.clients.get(clientid) 2296 ); 2297 if (structs != null) { 2298 const lastStruct = structs[structs.length - 1]; 2299 const clockState = lastStruct.id.clock + lastStruct.length; 2300 for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) { 2301 iterateStructs(transaction, structs, del.clock, del.len, f); 2302 } 2303 } 2304 }); 2305 var findIndexDS = (dis, clock) => { 2306 let left = 0; 2307 let right = dis.length - 1; 2308 while (left <= right) { 2309 const midindex = floor((left + right) / 2); 2310 const mid = dis[midindex]; 2311 const midclock = mid.clock; 2312 if (midclock <= clock) { 2313 if (clock < midclock + mid.len) { 2314 return midindex; 2315 } 2316 left = midindex + 1; 2317 } else { 2318 right = midindex - 1; 2319 } 2320 } 2321 return null; 2322 }; 2323 var isDeleted = (ds, id2) => { 2324 const dis = ds.clients.get(id2.client); 2325 return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; 2326 }; 2327 var sortAndMergeDeleteSet = (ds) => { 2328 ds.clients.forEach((dels) => { 2329 dels.sort((a, b) => a.clock - b.clock); 2330 let i, j; 2331 for (i = 1, j = 1; i < dels.length; i++) { 2332 const left = dels[j - 1]; 2333 const right = dels[i]; 2334 if (left.clock + left.len >= right.clock) { 2335 left.len = max(left.len, right.clock + right.len - left.clock); 2336 } else { 2337 if (j < i) { 2338 dels[j] = right; 2339 } 2340 j++; 2341 } 2342 } 2343 dels.length = j; 2344 }); 2345 }; 2346 var mergeDeleteSets = (dss) => { 2347 const merged = new DeleteSet(); 2348 for (let dssI = 0; dssI < dss.length; dssI++) { 2349 dss[dssI].clients.forEach((delsLeft, client) => { 2350 if (!merged.clients.has(client)) { 2351 const dels = delsLeft.slice(); 2352 for (let i = dssI + 1; i < dss.length; i++) { 2353 appendTo(dels, dss[i].clients.get(client) || []); 2354 } 2355 merged.clients.set(client, dels); 2356 } 2357 }); 2358 } 2359 sortAndMergeDeleteSet(merged); 2360 return merged; 2361 }; 2362 var addToDeleteSet = (ds, client, clock, length2) => { 2363 setIfUndefined(ds.clients, client, () => ( 2364 /** @type {Array<DeleteItem>} */ 2365 [] 2366 )).push(new DeleteItem(clock, length2)); 2367 }; 2368 var createDeleteSet = () => new DeleteSet(); 2369 var createDeleteSetFromStructStore = (ss) => { 2370 const ds = createDeleteSet(); 2371 ss.clients.forEach((structs, client) => { 2372 const dsitems = []; 2373 for (let i = 0; i < structs.length; i++) { 2374 const struct = structs[i]; 2375 if (struct.deleted) { 2376 const clock = struct.id.clock; 2377 let len = struct.length; 2378 if (i + 1 < structs.length) { 2379 for (let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1]) { 2380 len += next.length; 2381 } 2382 } 2383 dsitems.push(new DeleteItem(clock, len)); 2384 } 2385 } 2386 if (dsitems.length > 0) { 2387 ds.clients.set(client, dsitems); 2388 } 2389 }); 2390 return ds; 2391 }; 2392 var writeDeleteSet = (encoder, ds) => { 2393 writeVarUint(encoder.restEncoder, ds.clients.size); 2394 from(ds.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, dsitems]) => { 2395 encoder.resetDsCurVal(); 2396 writeVarUint(encoder.restEncoder, client); 2397 const len = dsitems.length; 2398 writeVarUint(encoder.restEncoder, len); 2399 for (let i = 0; i < len; i++) { 2400 const item = dsitems[i]; 2401 encoder.writeDsClock(item.clock); 2402 encoder.writeDsLen(item.len); 2403 } 2404 }); 2405 }; 2406 var readDeleteSet = (decoder) => { 2407 const ds = new DeleteSet(); 2408 const numClients = readVarUint(decoder.restDecoder); 2409 for (let i = 0; i < numClients; i++) { 2410 decoder.resetDsCurVal(); 2411 const client = readVarUint(decoder.restDecoder); 2412 const numberOfDeletes = readVarUint(decoder.restDecoder); 2413 if (numberOfDeletes > 0) { 2414 const dsField = setIfUndefined(ds.clients, client, () => ( 2415 /** @type {Array<DeleteItem>} */ 2416 [] 2417 )); 2418 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2419 dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); 2420 } 2421 } 2422 } 2423 return ds; 2424 }; 2425 var readAndApplyDeleteSet = (decoder, transaction, store) => { 2426 const unappliedDS = new DeleteSet(); 2427 const numClients = readVarUint(decoder.restDecoder); 2428 for (let i = 0; i < numClients; i++) { 2429 decoder.resetDsCurVal(); 2430 const client = readVarUint(decoder.restDecoder); 2431 const numberOfDeletes = readVarUint(decoder.restDecoder); 2432 const structs = store.clients.get(client) || []; 2433 const state = getState(store, client); 2434 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2435 const clock = decoder.readDsClock(); 2436 const clockEnd = clock + decoder.readDsLen(); 2437 if (clock < state) { 2438 if (state < clockEnd) { 2439 addToDeleteSet(unappliedDS, client, state, clockEnd - state); 2440 } 2441 let index = findIndexSS(structs, clock); 2442 let struct = structs[index]; 2443 if (!struct.deleted && struct.id.clock < clock) { 2444 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 2445 index++; 2446 } 2447 while (index < structs.length) { 2448 struct = structs[index++]; 2449 if (struct.id.clock < clockEnd) { 2450 if (!struct.deleted) { 2451 if (clockEnd < struct.id.clock + struct.length) { 2452 structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); 2453 } 2454 struct.delete(transaction); 2455 } 2456 } else { 2457 break; 2458 } 2459 } 2460 } else { 2461 addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); 2462 } 2463 } 2464 } 2465 if (unappliedDS.clients.size > 0) { 2466 const ds = new UpdateEncoderV2(); 2467 writeVarUint(ds.restEncoder, 0); 2468 writeDeleteSet(ds, unappliedDS); 2469 return ds.toUint8Array(); 2470 } 2471 return null; 2472 }; 2473 var equalDeleteSets = (ds1, ds2) => { 2474 if (ds1.clients.size !== ds2.clients.size) return false; 2475 for (const [client, deleteItems1] of ds1.clients.entries()) { 2476 const deleteItems2 = ( 2477 /** @type {Array<import('../internals.js').DeleteItem>} */ 2478 ds2.clients.get(client) 2479 ); 2480 if (deleteItems2 === void 0 || deleteItems1.length !== deleteItems2.length) return false; 2481 for (let i = 0; i < deleteItems1.length; i++) { 2482 const di1 = deleteItems1[i]; 2483 const di2 = deleteItems2[i]; 2484 if (di1.clock !== di2.clock || di1.len !== di2.len) { 2485 return false; 2486 } 2487 } 2488 } 2489 return true; 2490 }; 2491 var generateNewClientId = uint32; 2492 var Doc = class _Doc extends ObservableV2 { 2493 /** 2494 * @param {DocOpts} opts configuration 2495 */ 2496 constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { 2497 super(); 2498 this.gc = gc; 2499 this.gcFilter = gcFilter; 2500 this.clientID = generateNewClientId(); 2501 this.guid = guid; 2502 this.collectionid = collectionid; 2503 this.share = /* @__PURE__ */ new Map(); 2504 this.store = new StructStore(); 2505 this._transaction = null; 2506 this._transactionCleanups = []; 2507 this.subdocs = /* @__PURE__ */ new Set(); 2508 this._item = null; 2509 this.shouldLoad = shouldLoad; 2510 this.autoLoad = autoLoad; 2511 this.meta = meta; 2512 this.isLoaded = false; 2513 this.isSynced = false; 2514 this.isDestroyed = false; 2515 this.whenLoaded = create4((resolve) => { 2516 this.on("load", () => { 2517 this.isLoaded = true; 2518 resolve(this); 2519 }); 2520 }); 2521 const provideSyncedPromise = () => create4((resolve) => { 2522 const eventHandler = (isSynced) => { 2523 if (isSynced === void 0 || isSynced === true) { 2524 this.off("sync", eventHandler); 2525 resolve(); 2526 } 2527 }; 2528 this.on("sync", eventHandler); 2529 }); 2530 this.on("sync", (isSynced) => { 2531 if (isSynced === false && this.isSynced) { 2532 this.whenSynced = provideSyncedPromise(); 2533 } 2534 this.isSynced = isSynced === void 0 || isSynced === true; 2535 if (this.isSynced && !this.isLoaded) { 2536 this.emit("load", [this]); 2537 } 2538 }); 2539 this.whenSynced = provideSyncedPromise(); 2540 } 2541 /** 2542 * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). 2543 * 2544 * `load()` might be used in the future to request any provider to load the most current data. 2545 * 2546 * It is safe to call `load()` multiple times. 2547 */ 2548 load() { 2549 const item = this._item; 2550 if (item !== null && !this.shouldLoad) { 2551 transact( 2552 /** @type {any} */ 2553 item.parent.doc, 2554 (transaction) => { 2555 transaction.subdocsLoaded.add(this); 2556 }, 2557 null, 2558 true 2559 ); 2560 } 2561 this.shouldLoad = true; 2562 } 2563 getSubdocs() { 2564 return this.subdocs; 2565 } 2566 getSubdocGuids() { 2567 return new Set(from(this.subdocs).map((doc2) => doc2.guid)); 2568 } 2569 /** 2570 * Changes that happen inside of a transaction are bundled. This means that 2571 * the observer fires _after_ the transaction is finished and that all changes 2572 * that happened inside of the transaction are sent as one message to the 2573 * other peers. 2574 * 2575 * @template T 2576 * @param {function(Transaction):T} f The function that should be executed as a transaction 2577 * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin 2578 * @return T 2579 * 2580 * @public 2581 */ 2582 transact(f, origin2 = null) { 2583 return transact(this, f, origin2); 2584 } 2585 /** 2586 * Define a shared data type. 2587 * 2588 * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result 2589 * and do not overwrite each other. I.e. 2590 * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` 2591 * 2592 * After this method is called, the type is also available on `ydoc.share.get(name)`. 2593 * 2594 * *Best Practices:* 2595 * Define all types right after the Y.Doc instance is created and store them in a separate object. 2596 * Also use the typed methods `getText(name)`, `getArray(name)`, .. 2597 * 2598 * @template {typeof AbstractType<any>} Type 2599 * @example 2600 * const ydoc = new Y.Doc(..) 2601 * const appState = { 2602 * document: ydoc.getText('document') 2603 * comments: ydoc.getArray('comments') 2604 * } 2605 * 2606 * @param {string} name 2607 * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... 2608 * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor 2609 * 2610 * @public 2611 */ 2612 get(name, TypeConstructor = ( 2613 /** @type {any} */ 2614 AbstractType 2615 )) { 2616 const type = setIfUndefined(this.share, name, () => { 2617 const t = new TypeConstructor(); 2618 t._integrate(this, null); 2619 return t; 2620 }); 2621 const Constr = type.constructor; 2622 if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { 2623 if (Constr === AbstractType) { 2624 const t = new TypeConstructor(); 2625 t._map = type._map; 2626 type._map.forEach( 2627 /** @param {Item?} n */ 2628 (n) => { 2629 for (; n !== null; n = n.left) { 2630 n.parent = t; 2631 } 2632 } 2633 ); 2634 t._start = type._start; 2635 for (let n = t._start; n !== null; n = n.right) { 2636 n.parent = t; 2637 } 2638 t._length = type._length; 2639 this.share.set(name, t); 2640 t._integrate(this, null); 2641 return ( 2642 /** @type {InstanceType<Type>} */ 2643 t 2644 ); 2645 } else { 2646 throw new Error(`Type with the name $name} has already been defined with a different constructor`); 2647 } 2648 } 2649 return ( 2650 /** @type {InstanceType<Type>} */ 2651 type 2652 ); 2653 } 2654 /** 2655 * @template T 2656 * @param {string} [name] 2657 * @return {YArray<T>} 2658 * 2659 * @public 2660 */ 2661 getArray(name = "") { 2662 return ( 2663 /** @type {YArray<T>} */ 2664 this.get(name, YArray) 2665 ); 2666 } 2667 /** 2668 * @param {string} [name] 2669 * @return {YText} 2670 * 2671 * @public 2672 */ 2673 getText(name = "") { 2674 return this.get(name, YText); 2675 } 2676 /** 2677 * @template T 2678 * @param {string} [name] 2679 * @return {YMap<T>} 2680 * 2681 * @public 2682 */ 2683 getMap(name = "") { 2684 return ( 2685 /** @type {YMap<T>} */ 2686 this.get(name, YMap) 2687 ); 2688 } 2689 /** 2690 * @param {string} [name] 2691 * @return {YXmlElement} 2692 * 2693 * @public 2694 */ 2695 getXmlElement(name = "") { 2696 return ( 2697 /** @type {YXmlElement<{[key:string]:string}>} */ 2698 this.get(name, YXmlElement) 2699 ); 2700 } 2701 /** 2702 * @param {string} [name] 2703 * @return {YXmlFragment} 2704 * 2705 * @public 2706 */ 2707 getXmlFragment(name = "") { 2708 return this.get(name, YXmlFragment); 2709 } 2710 /** 2711 * Converts the entire document into a js object, recursively traversing each yjs type 2712 * Doesn't log types that have not been defined (using ydoc.getType(..)). 2713 * 2714 * @deprecated Do not use this method and rather call toJSON directly on the shared types. 2715 * 2716 * @return {Object<string, any>} 2717 */ 2718 toJSON() { 2719 const doc2 = {}; 2720 this.share.forEach((value, key) => { 2721 doc2[key] = value.toJSON(); 2722 }); 2723 return doc2; 2724 } 2725 /** 2726 * Emit `destroy` event and unregister all event handlers. 2727 */ 2728 destroy() { 2729 this.isDestroyed = true; 2730 from(this.subdocs).forEach((subdoc) => subdoc.destroy()); 2731 const item = this._item; 2732 if (item !== null) { 2733 this._item = null; 2734 const content = ( 2735 /** @type {ContentDoc} */ 2736 item.content 2737 ); 2738 content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); 2739 content.doc._item = item; 2740 transact( 2741 /** @type {any} */ 2742 item.parent.doc, 2743 (transaction) => { 2744 const doc2 = content.doc; 2745 if (!item.deleted) { 2746 transaction.subdocsAdded.add(doc2); 2747 } 2748 transaction.subdocsRemoved.add(this); 2749 }, 2750 null, 2751 true 2752 ); 2753 } 2754 this.emit("destroyed", [true]); 2755 this.emit("destroy", [this]); 2756 super.destroy(); 2757 } 2758 }; 2759 var DSDecoderV1 = class { 2760 /** 2761 * @param {decoding.Decoder} decoder 2762 */ 2763 constructor(decoder) { 2764 this.restDecoder = decoder; 2765 } 2766 resetDsCurVal() { 2767 } 2768 /** 2769 * @return {number} 2770 */ 2771 readDsClock() { 2772 return readVarUint(this.restDecoder); 2773 } 2774 /** 2775 * @return {number} 2776 */ 2777 readDsLen() { 2778 return readVarUint(this.restDecoder); 2779 } 2780 }; 2781 var UpdateDecoderV1 = class extends DSDecoderV1 { 2782 /** 2783 * @return {ID} 2784 */ 2785 readLeftID() { 2786 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2787 } 2788 /** 2789 * @return {ID} 2790 */ 2791 readRightID() { 2792 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2793 } 2794 /** 2795 * Read the next client id. 2796 * Use this in favor of readID whenever possible to reduce the number of objects created. 2797 */ 2798 readClient() { 2799 return readVarUint(this.restDecoder); 2800 } 2801 /** 2802 * @return {number} info An unsigned 8-bit integer 2803 */ 2804 readInfo() { 2805 return readUint8(this.restDecoder); 2806 } 2807 /** 2808 * @return {string} 2809 */ 2810 readString() { 2811 return readVarString(this.restDecoder); 2812 } 2813 /** 2814 * @return {boolean} isKey 2815 */ 2816 readParentInfo() { 2817 return readVarUint(this.restDecoder) === 1; 2818 } 2819 /** 2820 * @return {number} info An unsigned 8-bit integer 2821 */ 2822 readTypeRef() { 2823 return readVarUint(this.restDecoder); 2824 } 2825 /** 2826 * Write len of a struct - well suited for Opt RLE encoder. 2827 * 2828 * @return {number} len 2829 */ 2830 readLen() { 2831 return readVarUint(this.restDecoder); 2832 } 2833 /** 2834 * @return {any} 2835 */ 2836 readAny() { 2837 return readAny(this.restDecoder); 2838 } 2839 /** 2840 * @return {Uint8Array} 2841 */ 2842 readBuf() { 2843 return copyUint8Array(readVarUint8Array(this.restDecoder)); 2844 } 2845 /** 2846 * Legacy implementation uses JSON parse. We use any-decoding in v2. 2847 * 2848 * @return {any} 2849 */ 2850 readJSON() { 2851 return JSON.parse(readVarString(this.restDecoder)); 2852 } 2853 /** 2854 * @return {string} 2855 */ 2856 readKey() { 2857 return readVarString(this.restDecoder); 2858 } 2859 }; 2860 var DSDecoderV2 = class { 2861 /** 2862 * @param {decoding.Decoder} decoder 2863 */ 2864 constructor(decoder) { 2865 this.dsCurrVal = 0; 2866 this.restDecoder = decoder; 2867 } 2868 resetDsCurVal() { 2869 this.dsCurrVal = 0; 2870 } 2871 /** 2872 * @return {number} 2873 */ 2874 readDsClock() { 2875 this.dsCurrVal += readVarUint(this.restDecoder); 2876 return this.dsCurrVal; 2877 } 2878 /** 2879 * @return {number} 2880 */ 2881 readDsLen() { 2882 const diff = readVarUint(this.restDecoder) + 1; 2883 this.dsCurrVal += diff; 2884 return diff; 2885 } 2886 }; 2887 var UpdateDecoderV2 = class extends DSDecoderV2 { 2888 /** 2889 * @param {decoding.Decoder} decoder 2890 */ 2891 constructor(decoder) { 2892 super(decoder); 2893 this.keys = []; 2894 readVarUint(decoder); 2895 this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2896 this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2897 this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2898 this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2899 this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2900 this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); 2901 this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2902 this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2903 this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2904 } 2905 /** 2906 * @return {ID} 2907 */ 2908 readLeftID() { 2909 return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); 2910 } 2911 /** 2912 * @return {ID} 2913 */ 2914 readRightID() { 2915 return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); 2916 } 2917 /** 2918 * Read the next client id. 2919 * Use this in favor of readID whenever possible to reduce the number of objects created. 2920 */ 2921 readClient() { 2922 return this.clientDecoder.read(); 2923 } 2924 /** 2925 * @return {number} info An unsigned 8-bit integer 2926 */ 2927 readInfo() { 2928 return ( 2929 /** @type {number} */ 2930 this.infoDecoder.read() 2931 ); 2932 } 2933 /** 2934 * @return {string} 2935 */ 2936 readString() { 2937 return this.stringDecoder.read(); 2938 } 2939 /** 2940 * @return {boolean} 2941 */ 2942 readParentInfo() { 2943 return this.parentInfoDecoder.read() === 1; 2944 } 2945 /** 2946 * @return {number} An unsigned 8-bit integer 2947 */ 2948 readTypeRef() { 2949 return this.typeRefDecoder.read(); 2950 } 2951 /** 2952 * Write len of a struct - well suited for Opt RLE encoder. 2953 * 2954 * @return {number} 2955 */ 2956 readLen() { 2957 return this.lenDecoder.read(); 2958 } 2959 /** 2960 * @return {any} 2961 */ 2962 readAny() { 2963 return readAny(this.restDecoder); 2964 } 2965 /** 2966 * @return {Uint8Array} 2967 */ 2968 readBuf() { 2969 return readVarUint8Array(this.restDecoder); 2970 } 2971 /** 2972 * This is mainly here for legacy purposes. 2973 * 2974 * 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. 2975 * 2976 * @return {any} 2977 */ 2978 readJSON() { 2979 return readAny(this.restDecoder); 2980 } 2981 /** 2982 * @return {string} 2983 */ 2984 readKey() { 2985 const keyClock = this.keyClockDecoder.read(); 2986 if (keyClock < this.keys.length) { 2987 return this.keys[keyClock]; 2988 } else { 2989 const key = this.stringDecoder.read(); 2990 this.keys.push(key); 2991 return key; 2992 } 2993 } 2994 }; 2995 var DSEncoderV1 = class { 2996 constructor() { 2997 this.restEncoder = createEncoder(); 2998 } 2999 toUint8Array() { 3000 return toUint8Array(this.restEncoder); 3001 } 3002 resetDsCurVal() { 3003 } 3004 /** 3005 * @param {number} clock 3006 */ 3007 writeDsClock(clock) { 3008 writeVarUint(this.restEncoder, clock); 3009 } 3010 /** 3011 * @param {number} len 3012 */ 3013 writeDsLen(len) { 3014 writeVarUint(this.restEncoder, len); 3015 } 3016 }; 3017 var UpdateEncoderV1 = class extends DSEncoderV1 { 3018 /** 3019 * @param {ID} id 3020 */ 3021 writeLeftID(id2) { 3022 writeVarUint(this.restEncoder, id2.client); 3023 writeVarUint(this.restEncoder, id2.clock); 3024 } 3025 /** 3026 * @param {ID} id 3027 */ 3028 writeRightID(id2) { 3029 writeVarUint(this.restEncoder, id2.client); 3030 writeVarUint(this.restEncoder, id2.clock); 3031 } 3032 /** 3033 * Use writeClient and writeClock instead of writeID if possible. 3034 * @param {number} client 3035 */ 3036 writeClient(client) { 3037 writeVarUint(this.restEncoder, client); 3038 } 3039 /** 3040 * @param {number} info An unsigned 8-bit integer 3041 */ 3042 writeInfo(info) { 3043 writeUint8(this.restEncoder, info); 3044 } 3045 /** 3046 * @param {string} s 3047 */ 3048 writeString(s) { 3049 writeVarString(this.restEncoder, s); 3050 } 3051 /** 3052 * @param {boolean} isYKey 3053 */ 3054 writeParentInfo(isYKey) { 3055 writeVarUint(this.restEncoder, isYKey ? 1 : 0); 3056 } 3057 /** 3058 * @param {number} info An unsigned 8-bit integer 3059 */ 3060 writeTypeRef(info) { 3061 writeVarUint(this.restEncoder, info); 3062 } 3063 /** 3064 * Write len of a struct - well suited for Opt RLE encoder. 3065 * 3066 * @param {number} len 3067 */ 3068 writeLen(len) { 3069 writeVarUint(this.restEncoder, len); 3070 } 3071 /** 3072 * @param {any} any 3073 */ 3074 writeAny(any2) { 3075 writeAny(this.restEncoder, any2); 3076 } 3077 /** 3078 * @param {Uint8Array} buf 3079 */ 3080 writeBuf(buf) { 3081 writeVarUint8Array(this.restEncoder, buf); 3082 } 3083 /** 3084 * @param {any} embed 3085 */ 3086 writeJSON(embed) { 3087 writeVarString(this.restEncoder, JSON.stringify(embed)); 3088 } 3089 /** 3090 * @param {string} key 3091 */ 3092 writeKey(key) { 3093 writeVarString(this.restEncoder, key); 3094 } 3095 }; 3096 var DSEncoderV2 = class { 3097 constructor() { 3098 this.restEncoder = createEncoder(); 3099 this.dsCurrVal = 0; 3100 } 3101 toUint8Array() { 3102 return toUint8Array(this.restEncoder); 3103 } 3104 resetDsCurVal() { 3105 this.dsCurrVal = 0; 3106 } 3107 /** 3108 * @param {number} clock 3109 */ 3110 writeDsClock(clock) { 3111 const diff = clock - this.dsCurrVal; 3112 this.dsCurrVal = clock; 3113 writeVarUint(this.restEncoder, diff); 3114 } 3115 /** 3116 * @param {number} len 3117 */ 3118 writeDsLen(len) { 3119 if (len === 0) { 3120 unexpectedCase(); 3121 } 3122 writeVarUint(this.restEncoder, len - 1); 3123 this.dsCurrVal += len; 3124 } 3125 }; 3126 var UpdateEncoderV2 = class extends DSEncoderV2 { 3127 constructor() { 3128 super(); 3129 this.keyMap = /* @__PURE__ */ new Map(); 3130 this.keyClock = 0; 3131 this.keyClockEncoder = new IntDiffOptRleEncoder(); 3132 this.clientEncoder = new UintOptRleEncoder(); 3133 this.leftClockEncoder = new IntDiffOptRleEncoder(); 3134 this.rightClockEncoder = new IntDiffOptRleEncoder(); 3135 this.infoEncoder = new RleEncoder(writeUint8); 3136 this.stringEncoder = new StringEncoder(); 3137 this.parentInfoEncoder = new RleEncoder(writeUint8); 3138 this.typeRefEncoder = new UintOptRleEncoder(); 3139 this.lenEncoder = new UintOptRleEncoder(); 3140 } 3141 toUint8Array() { 3142 const encoder = createEncoder(); 3143 writeVarUint(encoder, 0); 3144 writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); 3145 writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); 3146 writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); 3147 writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); 3148 writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); 3149 writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); 3150 writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); 3151 writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); 3152 writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); 3153 writeUint8Array(encoder, toUint8Array(this.restEncoder)); 3154 return toUint8Array(encoder); 3155 } 3156 /** 3157 * @param {ID} id 3158 */ 3159 writeLeftID(id2) { 3160 this.clientEncoder.write(id2.client); 3161 this.leftClockEncoder.write(id2.clock); 3162 } 3163 /** 3164 * @param {ID} id 3165 */ 3166 writeRightID(id2) { 3167 this.clientEncoder.write(id2.client); 3168 this.rightClockEncoder.write(id2.clock); 3169 } 3170 /** 3171 * @param {number} client 3172 */ 3173 writeClient(client) { 3174 this.clientEncoder.write(client); 3175 } 3176 /** 3177 * @param {number} info An unsigned 8-bit integer 3178 */ 3179 writeInfo(info) { 3180 this.infoEncoder.write(info); 3181 } 3182 /** 3183 * @param {string} s 3184 */ 3185 writeString(s) { 3186 this.stringEncoder.write(s); 3187 } 3188 /** 3189 * @param {boolean} isYKey 3190 */ 3191 writeParentInfo(isYKey) { 3192 this.parentInfoEncoder.write(isYKey ? 1 : 0); 3193 } 3194 /** 3195 * @param {number} info An unsigned 8-bit integer 3196 */ 3197 writeTypeRef(info) { 3198 this.typeRefEncoder.write(info); 3199 } 3200 /** 3201 * Write len of a struct - well suited for Opt RLE encoder. 3202 * 3203 * @param {number} len 3204 */ 3205 writeLen(len) { 3206 this.lenEncoder.write(len); 3207 } 3208 /** 3209 * @param {any} any 3210 */ 3211 writeAny(any2) { 3212 writeAny(this.restEncoder, any2); 3213 } 3214 /** 3215 * @param {Uint8Array} buf 3216 */ 3217 writeBuf(buf) { 3218 writeVarUint8Array(this.restEncoder, buf); 3219 } 3220 /** 3221 * This is mainly here for legacy purposes. 3222 * 3223 * 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. 3224 * 3225 * @param {any} embed 3226 */ 3227 writeJSON(embed) { 3228 writeAny(this.restEncoder, embed); 3229 } 3230 /** 3231 * Property keys are often reused. For example, in y-prosemirror the key `bold` might 3232 * occur very often. For a 3d application, the key `position` might occur very often. 3233 * 3234 * We cache these keys in a Map and refer to them via a unique number. 3235 * 3236 * @param {string} key 3237 */ 3238 writeKey(key) { 3239 const clock = this.keyMap.get(key); 3240 if (clock === void 0) { 3241 this.keyClockEncoder.write(this.keyClock++); 3242 this.stringEncoder.write(key); 3243 } else { 3244 this.keyClockEncoder.write(clock); 3245 } 3246 } 3247 }; 3248 var writeStructs = (encoder, structs, client, clock) => { 3249 clock = max(clock, structs[0].id.clock); 3250 const startNewStructs = findIndexSS(structs, clock); 3251 writeVarUint(encoder.restEncoder, structs.length - startNewStructs); 3252 encoder.writeClient(client); 3253 writeVarUint(encoder.restEncoder, clock); 3254 const firstStruct = structs[startNewStructs]; 3255 firstStruct.write(encoder, clock - firstStruct.id.clock); 3256 for (let i = startNewStructs + 1; i < structs.length; i++) { 3257 structs[i].write(encoder, 0); 3258 } 3259 }; 3260 var writeClientsStructs = (encoder, store, _sm) => { 3261 const sm = /* @__PURE__ */ new Map(); 3262 _sm.forEach((clock, client) => { 3263 if (getState(store, client) > clock) { 3264 sm.set(client, clock); 3265 } 3266 }); 3267 getStateVector(store).forEach((_clock, client) => { 3268 if (!_sm.has(client)) { 3269 sm.set(client, 0); 3270 } 3271 }); 3272 writeVarUint(encoder.restEncoder, sm.size); 3273 from(sm.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3274 writeStructs( 3275 encoder, 3276 /** @type {Array<GC|Item>} */ 3277 store.clients.get(client), 3278 client, 3279 clock 3280 ); 3281 }); 3282 }; 3283 var readClientsStructRefs = (decoder, doc2) => { 3284 const clientRefs = create(); 3285 const numOfStateUpdates = readVarUint(decoder.restDecoder); 3286 for (let i = 0; i < numOfStateUpdates; i++) { 3287 const numberOfStructs = readVarUint(decoder.restDecoder); 3288 const refs = new Array(numberOfStructs); 3289 const client = decoder.readClient(); 3290 let clock = readVarUint(decoder.restDecoder); 3291 clientRefs.set(client, { i: 0, refs }); 3292 for (let i2 = 0; i2 < numberOfStructs; i2++) { 3293 const info = decoder.readInfo(); 3294 switch (BITS5 & info) { 3295 case 0: { 3296 const len = decoder.readLen(); 3297 refs[i2] = new GC(createID(client, clock), len); 3298 clock += len; 3299 break; 3300 } 3301 case 10: { 3302 const len = readVarUint(decoder.restDecoder); 3303 refs[i2] = new Skip(createID(client, clock), len); 3304 clock += len; 3305 break; 3306 } 3307 default: { 3308 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 3309 const struct = new Item( 3310 createID(client, clock), 3311 null, 3312 // left 3313 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 3314 // origin 3315 null, 3316 // right 3317 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 3318 // right origin 3319 cantCopyParentInfo ? decoder.readParentInfo() ? doc2.get(decoder.readString()) : decoder.readLeftID() : null, 3320 // parent 3321 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 3322 // parentSub 3323 readItemContent(decoder, info) 3324 // item content 3325 ); 3326 refs[i2] = struct; 3327 clock += struct.length; 3328 } 3329 } 3330 } 3331 } 3332 return clientRefs; 3333 }; 3334 var integrateStructs = (transaction, store, clientsStructRefs) => { 3335 const stack = []; 3336 let clientsStructRefsIds = from(clientsStructRefs.keys()).sort((a, b) => a - b); 3337 if (clientsStructRefsIds.length === 0) { 3338 return null; 3339 } 3340 const getNextStructTarget = () => { 3341 if (clientsStructRefsIds.length === 0) { 3342 return null; 3343 } 3344 let nextStructsTarget = ( 3345 /** @type {{i:number,refs:Array<GC|Item>}} */ 3346 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) 3347 ); 3348 while (nextStructsTarget.refs.length === nextStructsTarget.i) { 3349 clientsStructRefsIds.pop(); 3350 if (clientsStructRefsIds.length > 0) { 3351 nextStructsTarget = /** @type {{i:number,refs:Array<GC|Item>}} */ 3352 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); 3353 } else { 3354 return null; 3355 } 3356 } 3357 return nextStructsTarget; 3358 }; 3359 let curStructsTarget = getNextStructTarget(); 3360 if (curStructsTarget === null) { 3361 return null; 3362 } 3363 const restStructs = new StructStore(); 3364 const missingSV = /* @__PURE__ */ new Map(); 3365 const updateMissingSv = (client, clock) => { 3366 const mclock = missingSV.get(client); 3367 if (mclock == null || mclock > clock) { 3368 missingSV.set(client, clock); 3369 } 3370 }; 3371 let stackHead = ( 3372 /** @type {any} */ 3373 curStructsTarget.refs[ 3374 /** @type {any} */ 3375 curStructsTarget.i++ 3376 ] 3377 ); 3378 const state = /* @__PURE__ */ new Map(); 3379 const addStackToRestSS = () => { 3380 for (const item of stack) { 3381 const client = item.id.client; 3382 const inapplicableItems = clientsStructRefs.get(client); 3383 if (inapplicableItems) { 3384 inapplicableItems.i--; 3385 restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); 3386 clientsStructRefs.delete(client); 3387 inapplicableItems.i = 0; 3388 inapplicableItems.refs = []; 3389 } else { 3390 restStructs.clients.set(client, [item]); 3391 } 3392 clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); 3393 } 3394 stack.length = 0; 3395 }; 3396 while (true) { 3397 if (stackHead.constructor !== Skip) { 3398 const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store, stackHead.id.client)); 3399 const offset = localClock - stackHead.id.clock; 3400 if (offset < 0) { 3401 stack.push(stackHead); 3402 updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); 3403 addStackToRestSS(); 3404 } else { 3405 const missing = stackHead.getMissing(transaction, store); 3406 if (missing !== null) { 3407 stack.push(stackHead); 3408 const structRefs = clientsStructRefs.get( 3409 /** @type {number} */ 3410 missing 3411 ) || { refs: [], i: 0 }; 3412 if (structRefs.refs.length === structRefs.i) { 3413 updateMissingSv( 3414 /** @type {number} */ 3415 missing, 3416 getState(store, missing) 3417 ); 3418 addStackToRestSS(); 3419 } else { 3420 stackHead = structRefs.refs[structRefs.i++]; 3421 continue; 3422 } 3423 } else if (offset === 0 || offset < stackHead.length) { 3424 stackHead.integrate(transaction, offset); 3425 state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); 3426 } 3427 } 3428 } 3429 if (stack.length > 0) { 3430 stackHead = /** @type {GC|Item} */ 3431 stack.pop(); 3432 } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { 3433 stackHead = /** @type {GC|Item} */ 3434 curStructsTarget.refs[curStructsTarget.i++]; 3435 } else { 3436 curStructsTarget = getNextStructTarget(); 3437 if (curStructsTarget === null) { 3438 break; 3439 } else { 3440 stackHead = /** @type {GC|Item} */ 3441 curStructsTarget.refs[curStructsTarget.i++]; 3442 } 3443 } 3444 } 3445 if (restStructs.clients.size > 0) { 3446 const encoder = new UpdateEncoderV2(); 3447 writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); 3448 writeVarUint(encoder.restEncoder, 0); 3449 return { missing: missingSV, update: encoder.toUint8Array() }; 3450 } 3451 return null; 3452 }; 3453 var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); 3454 var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { 3455 transaction.local = false; 3456 let retry = false; 3457 const doc2 = transaction.doc; 3458 const store = doc2.store; 3459 const ss = readClientsStructRefs(structDecoder, doc2); 3460 const restStructs = integrateStructs(transaction, store, ss); 3461 const pending = store.pendingStructs; 3462 if (pending) { 3463 for (const [client, clock] of pending.missing) { 3464 if (clock < getState(store, client)) { 3465 retry = true; 3466 break; 3467 } 3468 } 3469 if (restStructs) { 3470 for (const [client, clock] of restStructs.missing) { 3471 const mclock = pending.missing.get(client); 3472 if (mclock == null || mclock > clock) { 3473 pending.missing.set(client, clock); 3474 } 3475 } 3476 pending.update = mergeUpdatesV2([pending.update, restStructs.update]); 3477 } 3478 } else { 3479 store.pendingStructs = restStructs; 3480 } 3481 const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store); 3482 if (store.pendingDs) { 3483 const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store.pendingDs)); 3484 readVarUint(pendingDSUpdate.restDecoder); 3485 const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store); 3486 if (dsRest && dsRest2) { 3487 store.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); 3488 } else { 3489 store.pendingDs = dsRest || dsRest2; 3490 } 3491 } else { 3492 store.pendingDs = dsRest; 3493 } 3494 if (retry) { 3495 const update = ( 3496 /** @type {{update: Uint8Array}} */ 3497 store.pendingStructs.update 3498 ); 3499 store.pendingStructs = null; 3500 applyUpdateV2(transaction.doc, update); 3501 } 3502 }, transactionOrigin, false); 3503 var readUpdate = (decoder, ydoc, transactionOrigin) => readUpdateV2(decoder, ydoc, transactionOrigin, new UpdateDecoderV1(decoder)); 3504 var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { 3505 const decoder = createDecoder(update); 3506 readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); 3507 }; 3508 var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); 3509 var writeStateAsUpdate = (encoder, doc2, targetStateVector = /* @__PURE__ */ new Map()) => { 3510 writeClientsStructs(encoder, doc2.store, targetStateVector); 3511 writeDeleteSet(encoder, createDeleteSetFromStructStore(doc2.store)); 3512 }; 3513 var encodeStateAsUpdateV2 = (doc2, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { 3514 const targetStateVector = decodeStateVector(encodedTargetStateVector); 3515 writeStateAsUpdate(encoder, doc2, targetStateVector); 3516 const updates = [encoder.toUint8Array()]; 3517 if (doc2.store.pendingDs) { 3518 updates.push(doc2.store.pendingDs); 3519 } 3520 if (doc2.store.pendingStructs) { 3521 updates.push(diffUpdateV2(doc2.store.pendingStructs.update, encodedTargetStateVector)); 3522 } 3523 if (updates.length > 1) { 3524 if (encoder.constructor === UpdateEncoderV1) { 3525 return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); 3526 } else if (encoder.constructor === UpdateEncoderV2) { 3527 return mergeUpdatesV2(updates); 3528 } 3529 } 3530 return updates[0]; 3531 }; 3532 var encodeStateAsUpdate = (doc2, encodedTargetStateVector) => encodeStateAsUpdateV2(doc2, encodedTargetStateVector, new UpdateEncoderV1()); 3533 var readStateVector = (decoder) => { 3534 const ss = /* @__PURE__ */ new Map(); 3535 const ssLength = readVarUint(decoder.restDecoder); 3536 for (let i = 0; i < ssLength; i++) { 3537 const client = readVarUint(decoder.restDecoder); 3538 const clock = readVarUint(decoder.restDecoder); 3539 ss.set(client, clock); 3540 } 3541 return ss; 3542 }; 3543 var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); 3544 var writeStateVector = (encoder, sv) => { 3545 writeVarUint(encoder.restEncoder, sv.size); 3546 from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3547 writeVarUint(encoder.restEncoder, client); 3548 writeVarUint(encoder.restEncoder, clock); 3549 }); 3550 return encoder; 3551 }; 3552 var writeDocumentStateVector = (encoder, doc2) => writeStateVector(encoder, getStateVector(doc2.store)); 3553 var encodeStateVectorV2 = (doc2, encoder = new DSEncoderV2()) => { 3554 if (doc2 instanceof Map) { 3555 writeStateVector(encoder, doc2); 3556 } else { 3557 writeDocumentStateVector(encoder, doc2); 3558 } 3559 return encoder.toUint8Array(); 3560 }; 3561 var encodeStateVector = (doc2) => encodeStateVectorV2(doc2, new DSEncoderV1()); 3562 var EventHandler = class { 3563 constructor() { 3564 this.l = []; 3565 } 3566 }; 3567 var createEventHandler = () => new EventHandler(); 3568 var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); 3569 var removeEventHandlerListener = (eventHandler, f) => { 3570 const l = eventHandler.l; 3571 const len = l.length; 3572 eventHandler.l = l.filter((g) => f !== g); 3573 if (len === eventHandler.l.length) { 3574 console.error("[yjs] Tried to remove event handler that doesn't exist."); 3575 } 3576 }; 3577 var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); 3578 var ID = class { 3579 /** 3580 * @param {number} client client id 3581 * @param {number} clock unique per client id, continuous number 3582 */ 3583 constructor(client, clock) { 3584 this.client = client; 3585 this.clock = clock; 3586 } 3587 }; 3588 var compareIDs = (a, b) => a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock; 3589 var createID = (client, clock) => new ID(client, clock); 3590 var writeID = (encoder, id2) => { 3591 writeVarUint(encoder, id2.client); 3592 writeVarUint(encoder, id2.clock); 3593 }; 3594 var readID = (decoder) => createID(readVarUint(decoder), readVarUint(decoder)); 3595 var findRootTypeKey = (type) => { 3596 for (const [key, value] of type.doc.share.entries()) { 3597 if (value === type) { 3598 return key; 3599 } 3600 } 3601 throw unexpectedCase(); 3602 }; 3603 var isParentOf = (parent, child) => { 3604 while (child !== null) { 3605 if (child.parent === parent) { 3606 return true; 3607 } 3608 child = /** @type {AbstractType<any>} */ 3609 child.parent._item; 3610 } 3611 return false; 3612 }; 3613 var logType = (type) => { 3614 const res = []; 3615 let n = type._start; 3616 while (n) { 3617 res.push(n); 3618 n = n.right; 3619 } 3620 console.log("Children: ", res); 3621 console.log("Children content: ", res.filter((m) => !m.deleted).map((m) => m.content)); 3622 }; 3623 var PermanentUserData = class { 3624 /** 3625 * @param {Doc} doc 3626 * @param {YMap<any>} [storeType] 3627 */ 3628 constructor(doc2, storeType = doc2.getMap("users")) { 3629 const dss = /* @__PURE__ */ new Map(); 3630 this.yusers = storeType; 3631 this.doc = doc2; 3632 this.clients = /* @__PURE__ */ new Map(); 3633 this.dss = dss; 3634 const initUser = (user, userDescription) => { 3635 const ds = user.get("ds"); 3636 const ids = user.get("ids"); 3637 const addClientId = ( 3638 /** @param {number} clientid */ 3639 (clientid) => this.clients.set(clientid, userDescription) 3640 ); 3641 ds.observe( 3642 /** @param {YArrayEvent<any>} event */ 3643 (event) => { 3644 event.changes.added.forEach((item) => { 3645 item.content.getContent().forEach((encodedDs) => { 3646 if (encodedDs instanceof Uint8Array) { 3647 this.dss.set(userDescription, mergeDeleteSets([this.dss.get(userDescription) || createDeleteSet(), readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))])); 3648 } 3649 }); 3650 }); 3651 } 3652 ); 3653 this.dss.set(userDescription, mergeDeleteSets(ds.map((encodedDs) => readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))))); 3654 ids.observe( 3655 /** @param {YArrayEvent<any>} event */ 3656 (event) => event.changes.added.forEach((item) => item.content.getContent().forEach(addClientId)) 3657 ); 3658 ids.forEach(addClientId); 3659 }; 3660 storeType.observe((event) => { 3661 event.keysChanged.forEach( 3662 (userDescription) => initUser(storeType.get(userDescription), userDescription) 3663 ); 3664 }); 3665 storeType.forEach(initUser); 3666 } 3667 /** 3668 * @param {Doc} doc 3669 * @param {number} clientid 3670 * @param {string} userDescription 3671 * @param {Object} conf 3672 * @param {function(Transaction, DeleteSet):boolean} [conf.filter] 3673 */ 3674 setUserMapping(doc2, clientid, userDescription, { filter = () => true } = {}) { 3675 const users = this.yusers; 3676 let user = users.get(userDescription); 3677 if (!user) { 3678 user = new YMap(); 3679 user.set("ids", new YArray()); 3680 user.set("ds", new YArray()); 3681 users.set(userDescription, user); 3682 } 3683 user.get("ids").push([clientid]); 3684 users.observe((_event) => { 3685 setTimeout(() => { 3686 const userOverwrite = users.get(userDescription); 3687 if (userOverwrite !== user) { 3688 user = userOverwrite; 3689 this.clients.forEach((_userDescription, clientid2) => { 3690 if (userDescription === _userDescription) { 3691 user.get("ids").push([clientid2]); 3692 } 3693 }); 3694 const encoder = new DSEncoderV1(); 3695 const ds = this.dss.get(userDescription); 3696 if (ds) { 3697 writeDeleteSet(encoder, ds); 3698 user.get("ds").push([encoder.toUint8Array()]); 3699 } 3700 } 3701 }, 0); 3702 }); 3703 doc2.on( 3704 "afterTransaction", 3705 /** @param {Transaction} transaction */ 3706 (transaction) => { 3707 setTimeout(() => { 3708 const yds = user.get("ds"); 3709 const ds = transaction.deleteSet; 3710 if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) { 3711 const encoder = new DSEncoderV1(); 3712 writeDeleteSet(encoder, ds); 3713 yds.push([encoder.toUint8Array()]); 3714 } 3715 }); 3716 } 3717 ); 3718 } 3719 /** 3720 * @param {number} clientid 3721 * @return {any} 3722 */ 3723 getUserByClientId(clientid) { 3724 return this.clients.get(clientid) || null; 3725 } 3726 /** 3727 * @param {ID} id 3728 * @return {string | null} 3729 */ 3730 getUserByDeletedId(id2) { 3731 for (const [userDescription, ds] of this.dss.entries()) { 3732 if (isDeleted(ds, id2)) { 3733 return userDescription; 3734 } 3735 } 3736 return null; 3737 } 3738 }; 3739 var RelativePosition = class { 3740 /** 3741 * @param {ID|null} type 3742 * @param {string|null} tname 3743 * @param {ID|null} item 3744 * @param {number} assoc 3745 */ 3746 constructor(type, tname, item, assoc = 0) { 3747 this.type = type; 3748 this.tname = tname; 3749 this.item = item; 3750 this.assoc = assoc; 3751 } 3752 }; 3753 var relativePositionToJSON = (rpos) => { 3754 const json = {}; 3755 if (rpos.type) { 3756 json.type = rpos.type; 3757 } 3758 if (rpos.tname) { 3759 json.tname = rpos.tname; 3760 } 3761 if (rpos.item) { 3762 json.item = rpos.item; 3763 } 3764 if (rpos.assoc != null) { 3765 json.assoc = rpos.assoc; 3766 } 3767 return json; 3768 }; 3769 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); 3770 var AbsolutePosition = class { 3771 /** 3772 * @param {AbstractType<any>} type 3773 * @param {number} index 3774 * @param {number} [assoc] 3775 */ 3776 constructor(type, index, assoc = 0) { 3777 this.type = type; 3778 this.index = index; 3779 this.assoc = assoc; 3780 } 3781 }; 3782 var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); 3783 var createRelativePosition = (type, item, assoc) => { 3784 let typeid = null; 3785 let tname = null; 3786 if (type._item === null) { 3787 tname = findRootTypeKey(type); 3788 } else { 3789 typeid = createID(type._item.id.client, type._item.id.clock); 3790 } 3791 return new RelativePosition(typeid, tname, item, assoc); 3792 }; 3793 var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { 3794 let t = type._start; 3795 if (assoc < 0) { 3796 if (index === 0) { 3797 return createRelativePosition(type, null, assoc); 3798 } 3799 index--; 3800 } 3801 while (t !== null) { 3802 if (!t.deleted && t.countable) { 3803 if (t.length > index) { 3804 return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); 3805 } 3806 index -= t.length; 3807 } 3808 if (t.right === null && assoc < 0) { 3809 return createRelativePosition(type, t.lastId, assoc); 3810 } 3811 t = t.right; 3812 } 3813 return createRelativePosition(type, null, assoc); 3814 }; 3815 var writeRelativePosition = (encoder, rpos) => { 3816 const { type, tname, item, assoc } = rpos; 3817 if (item !== null) { 3818 writeVarUint(encoder, 0); 3819 writeID(encoder, item); 3820 } else if (tname !== null) { 3821 writeUint8(encoder, 1); 3822 writeVarString(encoder, tname); 3823 } else if (type !== null) { 3824 writeUint8(encoder, 2); 3825 writeID(encoder, type); 3826 } else { 3827 throw unexpectedCase(); 3828 } 3829 writeVarInt(encoder, assoc); 3830 return encoder; 3831 }; 3832 var encodeRelativePosition = (rpos) => { 3833 const encoder = createEncoder(); 3834 writeRelativePosition(encoder, rpos); 3835 return toUint8Array(encoder); 3836 }; 3837 var readRelativePosition = (decoder) => { 3838 let type = null; 3839 let tname = null; 3840 let itemID = null; 3841 switch (readVarUint(decoder)) { 3842 case 0: 3843 itemID = readID(decoder); 3844 break; 3845 case 1: 3846 tname = readVarString(decoder); 3847 break; 3848 case 2: { 3849 type = readID(decoder); 3850 } 3851 } 3852 const assoc = hasContent(decoder) ? readVarInt(decoder) : 0; 3853 return new RelativePosition(type, tname, itemID, assoc); 3854 }; 3855 var decodeRelativePosition = (uint8Array) => readRelativePosition(createDecoder(uint8Array)); 3856 var getItemWithOffset = (store, id2) => { 3857 const item = getItem(store, id2); 3858 const diff = id2.clock - item.id.clock; 3859 return { 3860 item, 3861 diff 3862 }; 3863 }; 3864 var createAbsolutePositionFromRelativePosition = (rpos, doc2, followUndoneDeletions = true) => { 3865 const store = doc2.store; 3866 const rightID = rpos.item; 3867 const typeID = rpos.type; 3868 const tname = rpos.tname; 3869 const assoc = rpos.assoc; 3870 let type = null; 3871 let index = 0; 3872 if (rightID !== null) { 3873 if (getState(store, rightID.client) <= rightID.clock) { 3874 return null; 3875 } 3876 const res = followUndoneDeletions ? followRedone(store, rightID) : getItemWithOffset(store, rightID); 3877 const right = res.item; 3878 if (!(right instanceof Item)) { 3879 return null; 3880 } 3881 type = /** @type {AbstractType<any>} */ 3882 right.parent; 3883 if (type._item === null || !type._item.deleted) { 3884 index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); 3885 let n = right.left; 3886 while (n !== null) { 3887 if (!n.deleted && n.countable) { 3888 index += n.length; 3889 } 3890 n = n.left; 3891 } 3892 } 3893 } else { 3894 if (tname !== null) { 3895 type = doc2.get(tname); 3896 } else if (typeID !== null) { 3897 if (getState(store, typeID.client) <= typeID.clock) { 3898 return null; 3899 } 3900 const { item } = followUndoneDeletions ? followRedone(store, typeID) : { item: getItem(store, typeID) }; 3901 if (item instanceof Item && item.content instanceof ContentType) { 3902 type = item.content.type; 3903 } else { 3904 return null; 3905 } 3906 } else { 3907 throw unexpectedCase(); 3908 } 3909 if (assoc >= 0) { 3910 index = type._length; 3911 } else { 3912 index = 0; 3913 } 3914 } 3915 return createAbsolutePosition(type, index, rpos.assoc); 3916 }; 3917 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; 3918 var Snapshot = class { 3919 /** 3920 * @param {DeleteSet} ds 3921 * @param {Map<number,number>} sv state map 3922 */ 3923 constructor(ds, sv) { 3924 this.ds = ds; 3925 this.sv = sv; 3926 } 3927 }; 3928 var equalSnapshots = (snap1, snap2) => { 3929 const ds1 = snap1.ds.clients; 3930 const ds2 = snap2.ds.clients; 3931 const sv1 = snap1.sv; 3932 const sv2 = snap2.sv; 3933 if (sv1.size !== sv2.size || ds1.size !== ds2.size) { 3934 return false; 3935 } 3936 for (const [key, value] of sv1.entries()) { 3937 if (sv2.get(key) !== value) { 3938 return false; 3939 } 3940 } 3941 for (const [client, dsitems1] of ds1.entries()) { 3942 const dsitems2 = ds2.get(client) || []; 3943 if (dsitems1.length !== dsitems2.length) { 3944 return false; 3945 } 3946 for (let i = 0; i < dsitems1.length; i++) { 3947 const dsitem1 = dsitems1[i]; 3948 const dsitem2 = dsitems2[i]; 3949 if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) { 3950 return false; 3951 } 3952 } 3953 } 3954 return true; 3955 }; 3956 var encodeSnapshotV2 = (snapshot2, encoder = new DSEncoderV2()) => { 3957 writeDeleteSet(encoder, snapshot2.ds); 3958 writeStateVector(encoder, snapshot2.sv); 3959 return encoder.toUint8Array(); 3960 }; 3961 var encodeSnapshot = (snapshot2) => encodeSnapshotV2(snapshot2, new DSEncoderV1()); 3962 var decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(createDecoder(buf))) => { 3963 return new Snapshot(readDeleteSet(decoder), readStateVector(decoder)); 3964 }; 3965 var decodeSnapshot = (buf) => decodeSnapshotV2(buf, new DSDecoderV1(createDecoder(buf))); 3966 var createSnapshot = (ds, sm) => new Snapshot(ds, sm); 3967 var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); 3968 var snapshot = (doc2) => createSnapshot(createDeleteSetFromStructStore(doc2.store), getStateVector(doc2.store)); 3969 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); 3970 var splitSnapshotAffectedStructs = (transaction, snapshot2) => { 3971 const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); 3972 const store = transaction.doc.store; 3973 if (!meta.has(snapshot2)) { 3974 snapshot2.sv.forEach((clock, client) => { 3975 if (clock < getState(store, client)) { 3976 getItemCleanStart(transaction, createID(client, clock)); 3977 } 3978 }); 3979 iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { 3980 }); 3981 meta.add(snapshot2); 3982 } 3983 }; 3984 var createDocFromSnapshot = (originDoc, snapshot2, newDoc = new Doc()) => { 3985 if (originDoc.gc) { 3986 throw new Error("Garbage-collection must be disabled in `originDoc`!"); 3987 } 3988 const { sv, ds } = snapshot2; 3989 const encoder = new UpdateEncoderV2(); 3990 originDoc.transact((transaction) => { 3991 let size2 = 0; 3992 sv.forEach((clock) => { 3993 if (clock > 0) { 3994 size2++; 3995 } 3996 }); 3997 writeVarUint(encoder.restEncoder, size2); 3998 for (const [client, clock] of sv) { 3999 if (clock === 0) { 4000 continue; 4001 } 4002 if (clock < getState(originDoc.store, client)) { 4003 getItemCleanStart(transaction, createID(client, clock)); 4004 } 4005 const structs = originDoc.store.clients.get(client) || []; 4006 const lastStructIndex = findIndexSS(structs, clock - 1); 4007 writeVarUint(encoder.restEncoder, lastStructIndex + 1); 4008 encoder.writeClient(client); 4009 writeVarUint(encoder.restEncoder, 0); 4010 for (let i = 0; i <= lastStructIndex; i++) { 4011 structs[i].write(encoder, 0); 4012 } 4013 } 4014 writeDeleteSet(encoder, ds); 4015 }); 4016 applyUpdateV2(newDoc, encoder.toUint8Array(), "snapshot"); 4017 return newDoc; 4018 }; 4019 var snapshotContainsUpdateV2 = (snapshot2, update, YDecoder = UpdateDecoderV2) => { 4020 const updateDecoder = new YDecoder(createDecoder(update)); 4021 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4022 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4023 if ((snapshot2.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) { 4024 return false; 4025 } 4026 } 4027 const mergedDS = mergeDeleteSets([snapshot2.ds, readDeleteSet(updateDecoder)]); 4028 return equalDeleteSets(snapshot2.ds, mergedDS); 4029 }; 4030 var snapshotContainsUpdate = (snapshot2, update) => snapshotContainsUpdateV2(snapshot2, update, UpdateDecoderV1); 4031 var StructStore = class { 4032 constructor() { 4033 this.clients = /* @__PURE__ */ new Map(); 4034 this.pendingStructs = null; 4035 this.pendingDs = null; 4036 } 4037 }; 4038 var getStateVector = (store) => { 4039 const sm = /* @__PURE__ */ new Map(); 4040 store.clients.forEach((structs, client) => { 4041 const struct = structs[structs.length - 1]; 4042 sm.set(client, struct.id.clock + struct.length); 4043 }); 4044 return sm; 4045 }; 4046 var getState = (store, client) => { 4047 const structs = store.clients.get(client); 4048 if (structs === void 0) { 4049 return 0; 4050 } 4051 const lastStruct = structs[structs.length - 1]; 4052 return lastStruct.id.clock + lastStruct.length; 4053 }; 4054 var addStruct = (store, struct) => { 4055 let structs = store.clients.get(struct.id.client); 4056 if (structs === void 0) { 4057 structs = []; 4058 store.clients.set(struct.id.client, structs); 4059 } else { 4060 const lastStruct = structs[structs.length - 1]; 4061 if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { 4062 throw unexpectedCase(); 4063 } 4064 } 4065 structs.push(struct); 4066 }; 4067 var findIndexSS = (structs, clock) => { 4068 let left = 0; 4069 let right = structs.length - 1; 4070 let mid = structs[right]; 4071 let midclock = mid.id.clock; 4072 if (midclock === clock) { 4073 return right; 4074 } 4075 let midindex = floor(clock / (midclock + mid.length - 1) * right); 4076 while (left <= right) { 4077 mid = structs[midindex]; 4078 midclock = mid.id.clock; 4079 if (midclock <= clock) { 4080 if (clock < midclock + mid.length) { 4081 return midindex; 4082 } 4083 left = midindex + 1; 4084 } else { 4085 right = midindex - 1; 4086 } 4087 midindex = floor((left + right) / 2); 4088 } 4089 throw unexpectedCase(); 4090 }; 4091 var find = (store, id2) => { 4092 const structs = store.clients.get(id2.client); 4093 return structs[findIndexSS(structs, id2.clock)]; 4094 }; 4095 var getItem = ( 4096 /** @type {function(StructStore,ID):Item} */ 4097 find 4098 ); 4099 var findIndexCleanStart = (transaction, structs, clock) => { 4100 const index = findIndexSS(structs, clock); 4101 const struct = structs[index]; 4102 if (struct.id.clock < clock && struct instanceof Item) { 4103 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 4104 return index + 1; 4105 } 4106 return index; 4107 }; 4108 var getItemCleanStart = (transaction, id2) => { 4109 const structs = ( 4110 /** @type {Array<Item>} */ 4111 transaction.doc.store.clients.get(id2.client) 4112 ); 4113 return structs[findIndexCleanStart(transaction, structs, id2.clock)]; 4114 }; 4115 var getItemCleanEnd = (transaction, store, id2) => { 4116 const structs = store.clients.get(id2.client); 4117 const index = findIndexSS(structs, id2.clock); 4118 const struct = structs[index]; 4119 if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { 4120 structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); 4121 } 4122 return struct; 4123 }; 4124 var replaceStruct = (store, struct, newStruct) => { 4125 const structs = ( 4126 /** @type {Array<GC|Item>} */ 4127 store.clients.get(struct.id.client) 4128 ); 4129 structs[findIndexSS(structs, struct.id.clock)] = newStruct; 4130 }; 4131 var iterateStructs = (transaction, structs, clockStart, len, f) => { 4132 if (len === 0) { 4133 return; 4134 } 4135 const clockEnd = clockStart + len; 4136 let index = findIndexCleanStart(transaction, structs, clockStart); 4137 let struct; 4138 do { 4139 struct = structs[index++]; 4140 if (clockEnd < struct.id.clock + struct.length) { 4141 findIndexCleanStart(transaction, structs, clockEnd); 4142 } 4143 f(struct); 4144 } while (index < structs.length && structs[index].id.clock < clockEnd); 4145 }; 4146 var Transaction = class { 4147 /** 4148 * @param {Doc} doc 4149 * @param {any} origin 4150 * @param {boolean} local 4151 */ 4152 constructor(doc2, origin2, local) { 4153 this.doc = doc2; 4154 this.deleteSet = new DeleteSet(); 4155 this.beforeState = getStateVector(doc2.store); 4156 this.afterState = /* @__PURE__ */ new Map(); 4157 this.changed = /* @__PURE__ */ new Map(); 4158 this.changedParentTypes = /* @__PURE__ */ new Map(); 4159 this._mergeStructs = []; 4160 this.origin = origin2; 4161 this.meta = /* @__PURE__ */ new Map(); 4162 this.local = local; 4163 this.subdocsAdded = /* @__PURE__ */ new Set(); 4164 this.subdocsRemoved = /* @__PURE__ */ new Set(); 4165 this.subdocsLoaded = /* @__PURE__ */ new Set(); 4166 this._needFormattingCleanup = false; 4167 } 4168 }; 4169 var writeUpdateMessageFromTransaction = (encoder, transaction) => { 4170 if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { 4171 return false; 4172 } 4173 sortAndMergeDeleteSet(transaction.deleteSet); 4174 writeStructsFromTransaction(encoder, transaction); 4175 writeDeleteSet(encoder, transaction.deleteSet); 4176 return true; 4177 }; 4178 var addChangedTypeToTransaction = (transaction, type, parentSub) => { 4179 const item = type._item; 4180 if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { 4181 setIfUndefined(transaction.changed, type, create2).add(parentSub); 4182 } 4183 }; 4184 var tryToMergeWithLefts = (structs, pos) => { 4185 let right = structs[pos]; 4186 let left = structs[pos - 1]; 4187 let i = pos; 4188 for (; i > 0; right = left, left = structs[--i - 1]) { 4189 if (left.deleted === right.deleted && left.constructor === right.constructor) { 4190 if (left.mergeWith(right)) { 4191 if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ 4192 right.parent._map.get(right.parentSub) === right) { 4193 right.parent._map.set( 4194 right.parentSub, 4195 /** @type {Item} */ 4196 left 4197 ); 4198 } 4199 continue; 4200 } 4201 } 4202 break; 4203 } 4204 const merged = pos - i; 4205 if (merged) { 4206 structs.splice(pos + 1 - merged, merged); 4207 } 4208 return merged; 4209 }; 4210 var tryGcDeleteSet = (ds, store, gcFilter) => { 4211 for (const [client, deleteItems] of ds.clients.entries()) { 4212 const structs = ( 4213 /** @type {Array<GC|Item>} */ 4214 store.clients.get(client) 4215 ); 4216 for (let di = deleteItems.length - 1; di >= 0; di--) { 4217 const deleteItem = deleteItems[di]; 4218 const endDeleteItemClock = deleteItem.clock + deleteItem.len; 4219 for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { 4220 const struct2 = structs[si]; 4221 if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { 4222 break; 4223 } 4224 if (struct2 instanceof Item && struct2.deleted && !struct2.keep && gcFilter(struct2)) { 4225 struct2.gc(store, false); 4226 } 4227 } 4228 } 4229 } 4230 }; 4231 var tryMergeDeleteSet = (ds, store) => { 4232 ds.clients.forEach((deleteItems, client) => { 4233 const structs = ( 4234 /** @type {Array<GC|Item>} */ 4235 store.clients.get(client) 4236 ); 4237 for (let di = deleteItems.length - 1; di >= 0; di--) { 4238 const deleteItem = deleteItems[di]; 4239 const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); 4240 for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { 4241 si -= 1 + tryToMergeWithLefts(structs, si); 4242 } 4243 } 4244 }); 4245 }; 4246 var tryGc = (ds, store, gcFilter) => { 4247 tryGcDeleteSet(ds, store, gcFilter); 4248 tryMergeDeleteSet(ds, store); 4249 }; 4250 var cleanupTransactions = (transactionCleanups, i) => { 4251 if (i < transactionCleanups.length) { 4252 const transaction = transactionCleanups[i]; 4253 const doc2 = transaction.doc; 4254 const store = doc2.store; 4255 const ds = transaction.deleteSet; 4256 const mergeStructs = transaction._mergeStructs; 4257 try { 4258 sortAndMergeDeleteSet(ds); 4259 transaction.afterState = getStateVector(transaction.doc.store); 4260 doc2.emit("beforeObserverCalls", [transaction, doc2]); 4261 const fs = []; 4262 transaction.changed.forEach( 4263 (subs, itemtype) => fs.push(() => { 4264 if (itemtype._item === null || !itemtype._item.deleted) { 4265 itemtype._callObserver(transaction, subs); 4266 } 4267 }) 4268 ); 4269 fs.push(() => { 4270 transaction.changedParentTypes.forEach((events, type) => { 4271 if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { 4272 events = events.filter( 4273 (event) => event.target._item === null || !event.target._item.deleted 4274 ); 4275 events.forEach((event) => { 4276 event.currentTarget = type; 4277 event._path = null; 4278 }); 4279 events.sort((event1, event2) => event1.path.length - event2.path.length); 4280 fs.push(() => { 4281 callEventHandlerListeners(type._dEH, events, transaction); 4282 }); 4283 } 4284 }); 4285 fs.push(() => doc2.emit("afterTransaction", [transaction, doc2])); 4286 fs.push(() => { 4287 if (transaction._needFormattingCleanup) { 4288 cleanupYTextAfterTransaction(transaction); 4289 } 4290 }); 4291 }); 4292 callAll(fs, []); 4293 } finally { 4294 if (doc2.gc) { 4295 tryGcDeleteSet(ds, store, doc2.gcFilter); 4296 } 4297 tryMergeDeleteSet(ds, store); 4298 transaction.afterState.forEach((clock, client) => { 4299 const beforeClock = transaction.beforeState.get(client) || 0; 4300 if (beforeClock !== clock) { 4301 const structs = ( 4302 /** @type {Array<GC|Item>} */ 4303 store.clients.get(client) 4304 ); 4305 const firstChangePos = max(findIndexSS(structs, beforeClock), 1); 4306 for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { 4307 i2 -= 1 + tryToMergeWithLefts(structs, i2); 4308 } 4309 } 4310 }); 4311 for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { 4312 const { client, clock } = mergeStructs[i2].id; 4313 const structs = ( 4314 /** @type {Array<GC|Item>} */ 4315 store.clients.get(client) 4316 ); 4317 const replacedStructPos = findIndexSS(structs, clock); 4318 if (replacedStructPos + 1 < structs.length) { 4319 if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { 4320 continue; 4321 } 4322 } 4323 if (replacedStructPos > 0) { 4324 tryToMergeWithLefts(structs, replacedStructPos); 4325 } 4326 } 4327 if (!transaction.local && transaction.afterState.get(doc2.clientID) !== transaction.beforeState.get(doc2.clientID)) { 4328 print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); 4329 doc2.clientID = generateNewClientId(); 4330 } 4331 doc2.emit("afterTransactionCleanup", [transaction, doc2]); 4332 if (doc2._observers.has("update")) { 4333 const encoder = new UpdateEncoderV1(); 4334 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4335 if (hasContent2) { 4336 doc2.emit("update", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4337 } 4338 } 4339 if (doc2._observers.has("updateV2")) { 4340 const encoder = new UpdateEncoderV2(); 4341 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4342 if (hasContent2) { 4343 doc2.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4344 } 4345 } 4346 const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; 4347 if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { 4348 subdocsAdded.forEach((subdoc) => { 4349 subdoc.clientID = doc2.clientID; 4350 if (subdoc.collectionid == null) { 4351 subdoc.collectionid = doc2.collectionid; 4352 } 4353 doc2.subdocs.add(subdoc); 4354 }); 4355 subdocsRemoved.forEach((subdoc) => doc2.subdocs.delete(subdoc)); 4356 doc2.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc2, transaction]); 4357 subdocsRemoved.forEach((subdoc) => subdoc.destroy()); 4358 } 4359 if (transactionCleanups.length <= i + 1) { 4360 doc2._transactionCleanups = []; 4361 doc2.emit("afterAllTransactions", [doc2, transactionCleanups]); 4362 } else { 4363 cleanupTransactions(transactionCleanups, i + 1); 4364 } 4365 } 4366 } 4367 }; 4368 var transact = (doc2, f, origin2 = null, local = true) => { 4369 const transactionCleanups = doc2._transactionCleanups; 4370 let initialCall = false; 4371 let result = null; 4372 if (doc2._transaction === null) { 4373 initialCall = true; 4374 doc2._transaction = new Transaction(doc2, origin2, local); 4375 transactionCleanups.push(doc2._transaction); 4376 if (transactionCleanups.length === 1) { 4377 doc2.emit("beforeAllTransactions", [doc2]); 4378 } 4379 doc2.emit("beforeTransaction", [doc2._transaction, doc2]); 4380 } 4381 try { 4382 result = f(doc2._transaction); 4383 } finally { 4384 if (initialCall) { 4385 const finishCleanup = doc2._transaction === transactionCleanups[0]; 4386 doc2._transaction = null; 4387 if (finishCleanup) { 4388 cleanupTransactions(transactionCleanups, 0); 4389 } 4390 } 4391 } 4392 return result; 4393 }; 4394 var StackItem = class { 4395 /** 4396 * @param {DeleteSet} deletions 4397 * @param {DeleteSet} insertions 4398 */ 4399 constructor(deletions, insertions) { 4400 this.insertions = insertions; 4401 this.deletions = deletions; 4402 this.meta = /* @__PURE__ */ new Map(); 4403 } 4404 }; 4405 var clearUndoManagerStackItem = (tr, um, stackItem) => { 4406 iterateDeletedStructs(tr, stackItem.deletions, (item) => { 4407 if (item instanceof Item && um.scope.some((type) => type === tr.doc || isParentOf( 4408 /** @type {AbstractType<any>} */ 4409 type, 4410 item 4411 ))) { 4412 keepItem(item, false); 4413 } 4414 }); 4415 }; 4416 var popStackItem = (undoManager, stack, eventType) => { 4417 let _tr = null; 4418 const doc2 = undoManager.doc; 4419 const scope = undoManager.scope; 4420 transact(doc2, (transaction) => { 4421 while (stack.length > 0 && undoManager.currStackItem === null) { 4422 const store = doc2.store; 4423 const stackItem = ( 4424 /** @type {StackItem} */ 4425 stack.pop() 4426 ); 4427 const itemsToRedo = /* @__PURE__ */ new Set(); 4428 const itemsToDelete = []; 4429 let performedChange = false; 4430 iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { 4431 if (struct instanceof Item) { 4432 if (struct.redone !== null) { 4433 let { item, diff } = followRedone(store, struct.id); 4434 if (diff > 0) { 4435 item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); 4436 } 4437 struct = item; 4438 } 4439 if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( 4440 /** @type {AbstractType<any>} */ 4441 type, 4442 /** @type {Item} */ 4443 struct 4444 ))) { 4445 itemsToDelete.push(struct); 4446 } 4447 } 4448 }); 4449 iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { 4450 if (struct instanceof Item && scope.some((type) => type === transaction.doc || isParentOf( 4451 /** @type {AbstractType<any>} */ 4452 type, 4453 struct 4454 )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. 4455 !isDeleted(stackItem.insertions, struct.id)) { 4456 itemsToRedo.add(struct); 4457 } 4458 }); 4459 itemsToRedo.forEach((struct) => { 4460 performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange; 4461 }); 4462 for (let i = itemsToDelete.length - 1; i >= 0; i--) { 4463 const item = itemsToDelete[i]; 4464 if (undoManager.deleteFilter(item)) { 4465 item.delete(transaction); 4466 performedChange = true; 4467 } 4468 } 4469 undoManager.currStackItem = performedChange ? stackItem : null; 4470 } 4471 transaction.changed.forEach((subProps, type) => { 4472 if (subProps.has(null) && type._searchMarker) { 4473 type._searchMarker.length = 0; 4474 } 4475 }); 4476 _tr = transaction; 4477 }, undoManager); 4478 const res = undoManager.currStackItem; 4479 if (res != null) { 4480 const changedParentTypes = _tr.changedParentTypes; 4481 undoManager.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager }, undoManager]); 4482 undoManager.currStackItem = null; 4483 } 4484 return res; 4485 }; 4486 var UndoManager = class extends ObservableV2 { 4487 /** 4488 * @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. 4489 * @param {UndoManagerOptions} options 4490 */ 4491 constructor(typeScope, { 4492 captureTimeout = 500, 4493 captureTransaction = (_tr) => true, 4494 deleteFilter = () => true, 4495 trackedOrigins = /* @__PURE__ */ new Set([null]), 4496 ignoreRemoteMapChanges = false, 4497 doc: doc2 = ( 4498 /** @type {Doc} */ 4499 isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc 4500 ) 4501 } = {}) { 4502 super(); 4503 this.scope = []; 4504 this.doc = doc2; 4505 this.addToScope(typeScope); 4506 this.deleteFilter = deleteFilter; 4507 trackedOrigins.add(this); 4508 this.trackedOrigins = trackedOrigins; 4509 this.captureTransaction = captureTransaction; 4510 this.undoStack = []; 4511 this.redoStack = []; 4512 this.undoing = false; 4513 this.redoing = false; 4514 this.currStackItem = null; 4515 this.lastChange = 0; 4516 this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; 4517 this.captureTimeout = captureTimeout; 4518 this.afterTransactionHandler = (transaction) => { 4519 if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( 4520 /** @type {AbstractType<any>} */ 4521 type 4522 ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { 4523 return; 4524 } 4525 const undoing = this.undoing; 4526 const redoing = this.redoing; 4527 const stack = undoing ? this.redoStack : this.undoStack; 4528 if (undoing) { 4529 this.stopCapturing(); 4530 } else if (!redoing) { 4531 this.clear(false, true); 4532 } 4533 const insertions = new DeleteSet(); 4534 transaction.afterState.forEach((endClock, client) => { 4535 const startClock = transaction.beforeState.get(client) || 0; 4536 const len = endClock - startClock; 4537 if (len > 0) { 4538 addToDeleteSet(insertions, client, startClock, len); 4539 } 4540 }); 4541 const now = getUnixTime(); 4542 let didAdd = false; 4543 if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { 4544 const lastOp = stack[stack.length - 1]; 4545 lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); 4546 lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); 4547 } else { 4548 stack.push(new StackItem(transaction.deleteSet, insertions)); 4549 didAdd = true; 4550 } 4551 if (!undoing && !redoing) { 4552 this.lastChange = now; 4553 } 4554 iterateDeletedStructs( 4555 transaction, 4556 transaction.deleteSet, 4557 /** @param {Item|GC} item */ 4558 (item) => { 4559 if (item instanceof Item && this.scope.some((type) => type === transaction.doc || isParentOf( 4560 /** @type {AbstractType<any>} */ 4561 type, 4562 item 4563 ))) { 4564 keepItem(item, true); 4565 } 4566 } 4567 ); 4568 const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; 4569 if (didAdd) { 4570 this.emit("stack-item-added", changeEvent); 4571 } else { 4572 this.emit("stack-item-updated", changeEvent); 4573 } 4574 }; 4575 this.doc.on("afterTransaction", this.afterTransactionHandler); 4576 this.doc.on("destroy", () => { 4577 this.destroy(); 4578 }); 4579 } 4580 /** 4581 * Extend the scope. 4582 * 4583 * @param {Array<AbstractType<any> | Doc> | AbstractType<any> | Doc} ytypes 4584 */ 4585 addToScope(ytypes) { 4586 const tmpSet = new Set(this.scope); 4587 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 4588 ytypes.forEach((ytype) => { 4589 if (!tmpSet.has(ytype)) { 4590 tmpSet.add(ytype); 4591 if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn("[yjs#509] Not same Y.Doc"); 4592 this.scope.push(ytype); 4593 } 4594 }); 4595 } 4596 /** 4597 * @param {any} origin 4598 */ 4599 addTrackedOrigin(origin2) { 4600 this.trackedOrigins.add(origin2); 4601 } 4602 /** 4603 * @param {any} origin 4604 */ 4605 removeTrackedOrigin(origin2) { 4606 this.trackedOrigins.delete(origin2); 4607 } 4608 clear(clearUndoStack = true, clearRedoStack = true) { 4609 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 4610 this.doc.transact((tr) => { 4611 if (clearUndoStack) { 4612 this.undoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 4613 this.undoStack = []; 4614 } 4615 if (clearRedoStack) { 4616 this.redoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 4617 this.redoStack = []; 4618 } 4619 this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); 4620 }); 4621 } 4622 } 4623 /** 4624 * UndoManager merges Undo-StackItem if they are created within time-gap 4625 * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next 4626 * StackItem won't be merged. 4627 * 4628 * 4629 * @example 4630 * // without stopCapturing 4631 * ytext.insert(0, 'a') 4632 * ytext.insert(1, 'b') 4633 * um.undo() 4634 * ytext.toString() // => '' (note that 'ab' was removed) 4635 * // with stopCapturing 4636 * ytext.insert(0, 'a') 4637 * um.stopCapturing() 4638 * ytext.insert(0, 'b') 4639 * um.undo() 4640 * ytext.toString() // => 'a' (note that only 'b' was removed) 4641 * 4642 */ 4643 stopCapturing() { 4644 this.lastChange = 0; 4645 } 4646 /** 4647 * Undo last changes on type. 4648 * 4649 * @return {StackItem?} Returns StackItem if a change was applied 4650 */ 4651 undo() { 4652 this.undoing = true; 4653 let res; 4654 try { 4655 res = popStackItem(this, this.undoStack, "undo"); 4656 } finally { 4657 this.undoing = false; 4658 } 4659 return res; 4660 } 4661 /** 4662 * Redo last undo operation. 4663 * 4664 * @return {StackItem?} Returns StackItem if a change was applied 4665 */ 4666 redo() { 4667 this.redoing = true; 4668 let res; 4669 try { 4670 res = popStackItem(this, this.redoStack, "redo"); 4671 } finally { 4672 this.redoing = false; 4673 } 4674 return res; 4675 } 4676 /** 4677 * Are undo steps available? 4678 * 4679 * @return {boolean} `true` if undo is possible 4680 */ 4681 canUndo() { 4682 return this.undoStack.length > 0; 4683 } 4684 /** 4685 * Are redo steps available? 4686 * 4687 * @return {boolean} `true` if redo is possible 4688 */ 4689 canRedo() { 4690 return this.redoStack.length > 0; 4691 } 4692 destroy() { 4693 this.trackedOrigins.delete(this); 4694 this.doc.off("afterTransaction", this.afterTransactionHandler); 4695 super.destroy(); 4696 } 4697 }; 4698 function* lazyStructReaderGenerator(decoder) { 4699 const numOfStateUpdates = readVarUint(decoder.restDecoder); 4700 for (let i = 0; i < numOfStateUpdates; i++) { 4701 const numberOfStructs = readVarUint(decoder.restDecoder); 4702 const client = decoder.readClient(); 4703 let clock = readVarUint(decoder.restDecoder); 4704 for (let i2 = 0; i2 < numberOfStructs; i2++) { 4705 const info = decoder.readInfo(); 4706 if (info === 10) { 4707 const len = readVarUint(decoder.restDecoder); 4708 yield new Skip(createID(client, clock), len); 4709 clock += len; 4710 } else if ((BITS5 & info) !== 0) { 4711 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 4712 const struct = new Item( 4713 createID(client, clock), 4714 null, 4715 // left 4716 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 4717 // origin 4718 null, 4719 // right 4720 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 4721 // right origin 4722 // @ts-ignore Force writing a string here. 4723 cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, 4724 // parent 4725 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 4726 // parentSub 4727 readItemContent(decoder, info) 4728 // item content 4729 ); 4730 yield struct; 4731 clock += struct.length; 4732 } else { 4733 const len = decoder.readLen(); 4734 yield new GC(createID(client, clock), len); 4735 clock += len; 4736 } 4737 } 4738 } 4739 } 4740 var LazyStructReader = class { 4741 /** 4742 * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder 4743 * @param {boolean} filterSkips 4744 */ 4745 constructor(decoder, filterSkips) { 4746 this.gen = lazyStructReaderGenerator(decoder); 4747 this.curr = null; 4748 this.done = false; 4749 this.filterSkips = filterSkips; 4750 this.next(); 4751 } 4752 /** 4753 * @return {Item | GC | Skip |null} 4754 */ 4755 next() { 4756 do { 4757 this.curr = this.gen.next().value || null; 4758 } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); 4759 return this.curr; 4760 } 4761 }; 4762 var logUpdate = (update) => logUpdateV2(update, UpdateDecoderV1); 4763 var logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4764 const structs = []; 4765 const updateDecoder = new YDecoder(createDecoder(update)); 4766 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4767 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4768 structs.push(curr); 4769 } 4770 print("Structs: ", structs); 4771 const ds = readDeleteSet(updateDecoder); 4772 print("DeleteSet: ", ds); 4773 }; 4774 var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1); 4775 var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4776 const structs = []; 4777 const updateDecoder = new YDecoder(createDecoder(update)); 4778 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4779 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4780 structs.push(curr); 4781 } 4782 return { 4783 structs, 4784 ds: readDeleteSet(updateDecoder) 4785 }; 4786 }; 4787 var LazyStructWriter = class { 4788 /** 4789 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 4790 */ 4791 constructor(encoder) { 4792 this.currClient = 0; 4793 this.startClock = 0; 4794 this.written = 0; 4795 this.encoder = encoder; 4796 this.clientStructs = []; 4797 } 4798 }; 4799 var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); 4800 var encodeStateVectorFromUpdateV2 = (update, YEncoder = DSEncoderV2, YDecoder = UpdateDecoderV2) => { 4801 const encoder = new YEncoder(); 4802 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4803 let curr = updateDecoder.curr; 4804 if (curr !== null) { 4805 let size2 = 0; 4806 let currClient = curr.id.client; 4807 let stopCounting = curr.id.clock !== 0; 4808 let currClock = stopCounting ? 0 : curr.id.clock + curr.length; 4809 for (; curr !== null; curr = updateDecoder.next()) { 4810 if (currClient !== curr.id.client) { 4811 if (currClock !== 0) { 4812 size2++; 4813 writeVarUint(encoder.restEncoder, currClient); 4814 writeVarUint(encoder.restEncoder, currClock); 4815 } 4816 currClient = curr.id.client; 4817 currClock = 0; 4818 stopCounting = curr.id.clock !== 0; 4819 } 4820 if (curr.constructor === Skip) { 4821 stopCounting = true; 4822 } 4823 if (!stopCounting) { 4824 currClock = curr.id.clock + curr.length; 4825 } 4826 } 4827 if (currClock !== 0) { 4828 size2++; 4829 writeVarUint(encoder.restEncoder, currClient); 4830 writeVarUint(encoder.restEncoder, currClock); 4831 } 4832 const enc = createEncoder(); 4833 writeVarUint(enc, size2); 4834 writeBinaryEncoder(enc, encoder.restEncoder); 4835 encoder.restEncoder = enc; 4836 return encoder.toUint8Array(); 4837 } else { 4838 writeVarUint(encoder.restEncoder, 0); 4839 return encoder.toUint8Array(); 4840 } 4841 }; 4842 var encodeStateVectorFromUpdate = (update) => encodeStateVectorFromUpdateV2(update, DSEncoderV1, UpdateDecoderV1); 4843 var parseUpdateMetaV2 = (update, YDecoder = UpdateDecoderV2) => { 4844 const from2 = /* @__PURE__ */ new Map(); 4845 const to = /* @__PURE__ */ new Map(); 4846 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4847 let curr = updateDecoder.curr; 4848 if (curr !== null) { 4849 let currClient = curr.id.client; 4850 let currClock = curr.id.clock; 4851 from2.set(currClient, currClock); 4852 for (; curr !== null; curr = updateDecoder.next()) { 4853 if (currClient !== curr.id.client) { 4854 to.set(currClient, currClock); 4855 from2.set(curr.id.client, curr.id.clock); 4856 currClient = curr.id.client; 4857 } 4858 currClock = curr.id.clock + curr.length; 4859 } 4860 to.set(currClient, currClock); 4861 } 4862 return { from: from2, to }; 4863 }; 4864 var parseUpdateMeta = (update) => parseUpdateMetaV2(update, UpdateDecoderV1); 4865 var sliceStruct = (left, diff) => { 4866 if (left.constructor === GC) { 4867 const { client, clock } = left.id; 4868 return new GC(createID(client, clock + diff), left.length - diff); 4869 } else if (left.constructor === Skip) { 4870 const { client, clock } = left.id; 4871 return new Skip(createID(client, clock + diff), left.length - diff); 4872 } else { 4873 const leftItem = ( 4874 /** @type {Item} */ 4875 left 4876 ); 4877 const { client, clock } = leftItem.id; 4878 return new Item( 4879 createID(client, clock + diff), 4880 null, 4881 createID(client, clock + diff - 1), 4882 null, 4883 leftItem.rightOrigin, 4884 leftItem.parent, 4885 leftItem.parentSub, 4886 leftItem.content.splice(diff) 4887 ); 4888 } 4889 }; 4890 var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4891 if (updates.length === 1) { 4892 return updates[0]; 4893 } 4894 const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); 4895 let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); 4896 let currWrite = null; 4897 const updateEncoder = new YEncoder(); 4898 const lazyStructEncoder = new LazyStructWriter(updateEncoder); 4899 while (true) { 4900 lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); 4901 lazyStructDecoders.sort( 4902 /** @type {function(any,any):number} */ 4903 (dec1, dec2) => { 4904 if (dec1.curr.id.client === dec2.curr.id.client) { 4905 const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; 4906 if (clockDiff === 0) { 4907 return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; 4908 } else { 4909 return clockDiff; 4910 } 4911 } else { 4912 return dec2.curr.id.client - dec1.curr.id.client; 4913 } 4914 } 4915 ); 4916 if (lazyStructDecoders.length === 0) { 4917 break; 4918 } 4919 const currDecoder = lazyStructDecoders[0]; 4920 const firstClient = ( 4921 /** @type {Item | GC} */ 4922 currDecoder.curr.id.client 4923 ); 4924 if (currWrite !== null) { 4925 let curr = ( 4926 /** @type {Item | GC | null} */ 4927 currDecoder.curr 4928 ); 4929 let iterated = false; 4930 while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { 4931 curr = currDecoder.next(); 4932 iterated = true; 4933 } 4934 if (curr === null || // current decoder is empty 4935 curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` 4936 iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { 4937 continue; 4938 } 4939 if (firstClient !== currWrite.struct.id.client) { 4940 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4941 currWrite = { struct: curr, offset: 0 }; 4942 currDecoder.next(); 4943 } else { 4944 if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { 4945 if (currWrite.struct.constructor === Skip) { 4946 currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; 4947 } else { 4948 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4949 const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; 4950 const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); 4951 currWrite = { struct, offset: 0 }; 4952 } 4953 } else { 4954 const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; 4955 if (diff > 0) { 4956 if (currWrite.struct.constructor === Skip) { 4957 currWrite.struct.length -= diff; 4958 } else { 4959 curr = sliceStruct(curr, diff); 4960 } 4961 } 4962 if (!currWrite.struct.mergeWith( 4963 /** @type {any} */ 4964 curr 4965 )) { 4966 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4967 currWrite = { struct: curr, offset: 0 }; 4968 currDecoder.next(); 4969 } 4970 } 4971 } 4972 } else { 4973 currWrite = { struct: ( 4974 /** @type {Item | GC} */ 4975 currDecoder.curr 4976 ), offset: 0 }; 4977 currDecoder.next(); 4978 } 4979 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()) { 4980 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4981 currWrite = { struct: next, offset: 0 }; 4982 } 4983 } 4984 if (currWrite !== null) { 4985 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4986 currWrite = null; 4987 } 4988 finishLazyStructWriting(lazyStructEncoder); 4989 const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); 4990 const ds = mergeDeleteSets(dss); 4991 writeDeleteSet(updateEncoder, ds); 4992 return updateEncoder.toUint8Array(); 4993 }; 4994 var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4995 const state = decodeStateVector(sv); 4996 const encoder = new YEncoder(); 4997 const lazyStructWriter = new LazyStructWriter(encoder); 4998 const decoder = new YDecoder(createDecoder(update)); 4999 const reader = new LazyStructReader(decoder, false); 5000 while (reader.curr) { 5001 const curr = reader.curr; 5002 const currClient = curr.id.client; 5003 const svClock = state.get(currClient) || 0; 5004 if (reader.curr.constructor === Skip) { 5005 reader.next(); 5006 continue; 5007 } 5008 if (curr.id.clock + curr.length > svClock) { 5009 writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); 5010 reader.next(); 5011 while (reader.curr && reader.curr.id.client === currClient) { 5012 writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); 5013 reader.next(); 5014 } 5015 } else { 5016 while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { 5017 reader.next(); 5018 } 5019 } 5020 } 5021 finishLazyStructWriting(lazyStructWriter); 5022 const ds = readDeleteSet(decoder); 5023 writeDeleteSet(encoder, ds); 5024 return encoder.toUint8Array(); 5025 }; 5026 var diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1); 5027 var flushLazyStructWriter = (lazyWriter) => { 5028 if (lazyWriter.written > 0) { 5029 lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); 5030 lazyWriter.encoder.restEncoder = createEncoder(); 5031 lazyWriter.written = 0; 5032 } 5033 }; 5034 var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { 5035 if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { 5036 flushLazyStructWriter(lazyWriter); 5037 } 5038 if (lazyWriter.written === 0) { 5039 lazyWriter.currClient = struct.id.client; 5040 lazyWriter.encoder.writeClient(struct.id.client); 5041 writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); 5042 } 5043 struct.write(lazyWriter.encoder, offset); 5044 lazyWriter.written++; 5045 }; 5046 var finishLazyStructWriting = (lazyWriter) => { 5047 flushLazyStructWriter(lazyWriter); 5048 const restEncoder = lazyWriter.encoder.restEncoder; 5049 writeVarUint(restEncoder, lazyWriter.clientStructs.length); 5050 for (let i = 0; i < lazyWriter.clientStructs.length; i++) { 5051 const partStructs = lazyWriter.clientStructs[i]; 5052 writeVarUint(restEncoder, partStructs.written); 5053 writeUint8Array(restEncoder, partStructs.restEncoder); 5054 } 5055 }; 5056 var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { 5057 const updateDecoder = new YDecoder(createDecoder(update)); 5058 const lazyDecoder = new LazyStructReader(updateDecoder, false); 5059 const updateEncoder = new YEncoder(); 5060 const lazyWriter = new LazyStructWriter(updateEncoder); 5061 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 5062 writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); 5063 } 5064 finishLazyStructWriting(lazyWriter); 5065 const ds = readDeleteSet(updateDecoder); 5066 writeDeleteSet(updateEncoder, ds); 5067 return updateEncoder.toUint8Array(); 5068 }; 5069 var createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {}) => { 5070 let i = 0; 5071 const mapKeyCache = create(); 5072 const nodeNameCache = create(); 5073 const formattingKeyCache = create(); 5074 const formattingValueCache = create(); 5075 formattingValueCache.set(null, null); 5076 return (block) => { 5077 switch (block.constructor) { 5078 case GC: 5079 case Skip: 5080 return block; 5081 case Item: { 5082 const item = ( 5083 /** @type {Item} */ 5084 block 5085 ); 5086 const content = item.content; 5087 switch (content.constructor) { 5088 case ContentDeleted: 5089 break; 5090 case ContentType: { 5091 if (yxml) { 5092 const type = ( 5093 /** @type {ContentType} */ 5094 content.type 5095 ); 5096 if (type instanceof YXmlElement) { 5097 type.nodeName = setIfUndefined(nodeNameCache, type.nodeName, () => "node-" + i); 5098 } 5099 if (type instanceof YXmlHook) { 5100 type.hookName = setIfUndefined(nodeNameCache, type.hookName, () => "hook-" + i); 5101 } 5102 } 5103 break; 5104 } 5105 case ContentAny: { 5106 const c = ( 5107 /** @type {ContentAny} */ 5108 content 5109 ); 5110 c.arr = c.arr.map(() => i); 5111 break; 5112 } 5113 case ContentBinary: { 5114 const c = ( 5115 /** @type {ContentBinary} */ 5116 content 5117 ); 5118 c.content = new Uint8Array([i]); 5119 break; 5120 } 5121 case ContentDoc: { 5122 const c = ( 5123 /** @type {ContentDoc} */ 5124 content 5125 ); 5126 if (subdocs) { 5127 c.opts = {}; 5128 c.doc.guid = i + ""; 5129 } 5130 break; 5131 } 5132 case ContentEmbed: { 5133 const c = ( 5134 /** @type {ContentEmbed} */ 5135 content 5136 ); 5137 c.embed = {}; 5138 break; 5139 } 5140 case ContentFormat: { 5141 const c = ( 5142 /** @type {ContentFormat} */ 5143 content 5144 ); 5145 if (formatting) { 5146 c.key = setIfUndefined(formattingKeyCache, c.key, () => i + ""); 5147 c.value = setIfUndefined(formattingValueCache, c.value, () => ({ i })); 5148 } 5149 break; 5150 } 5151 case ContentJSON: { 5152 const c = ( 5153 /** @type {ContentJSON} */ 5154 content 5155 ); 5156 c.arr = c.arr.map(() => i); 5157 break; 5158 } 5159 case ContentString: { 5160 const c = ( 5161 /** @type {ContentString} */ 5162 content 5163 ); 5164 c.str = repeat(i % 10 + "", c.str.length); 5165 break; 5166 } 5167 default: 5168 unexpectedCase(); 5169 } 5170 if (item.parentSub) { 5171 item.parentSub = setIfUndefined(mapKeyCache, item.parentSub, () => i + ""); 5172 } 5173 i++; 5174 return block; 5175 } 5176 default: 5177 unexpectedCase(); 5178 } 5179 }; 5180 }; 5181 var obfuscateUpdate = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV1, UpdateEncoderV1); 5182 var obfuscateUpdateV2 = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV2, UpdateEncoderV2); 5183 var convertUpdateFormatV1ToV2 = (update) => convertUpdateFormat(update, id, UpdateDecoderV1, UpdateEncoderV2); 5184 var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); 5185 var errorComputeChanges = "You must not compute changes after the event-handler fired."; 5186 var YEvent = class { 5187 /** 5188 * @param {T} target The changed type. 5189 * @param {Transaction} transaction 5190 */ 5191 constructor(target, transaction) { 5192 this.target = target; 5193 this.currentTarget = target; 5194 this.transaction = transaction; 5195 this._changes = null; 5196 this._keys = null; 5197 this._delta = null; 5198 this._path = null; 5199 } 5200 /** 5201 * Computes the path from `y` to the changed type. 5202 * 5203 * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. 5204 * 5205 * The following property holds: 5206 * @example 5207 * let type = y 5208 * event.path.forEach(dir => { 5209 * type = type.get(dir) 5210 * }) 5211 * type === event.target // => true 5212 */ 5213 get path() { 5214 return this._path || (this._path = getPathTo(this.currentTarget, this.target)); 5215 } 5216 /** 5217 * Check if a struct is deleted by this event. 5218 * 5219 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5220 * 5221 * @param {AbstractStruct} struct 5222 * @return {boolean} 5223 */ 5224 deletes(struct) { 5225 return isDeleted(this.transaction.deleteSet, struct.id); 5226 } 5227 /** 5228 * @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>} 5229 */ 5230 get keys() { 5231 if (this._keys === null) { 5232 if (this.transaction.doc._transactionCleanups.length === 0) { 5233 throw create3(errorComputeChanges); 5234 } 5235 const keys2 = /* @__PURE__ */ new Map(); 5236 const target = this.target; 5237 const changed = ( 5238 /** @type Set<string|null> */ 5239 this.transaction.changed.get(target) 5240 ); 5241 changed.forEach((key) => { 5242 if (key !== null) { 5243 const item = ( 5244 /** @type {Item} */ 5245 target._map.get(key) 5246 ); 5247 let action; 5248 let oldValue; 5249 if (this.adds(item)) { 5250 let prev = item.left; 5251 while (prev !== null && this.adds(prev)) { 5252 prev = prev.left; 5253 } 5254 if (this.deletes(item)) { 5255 if (prev !== null && this.deletes(prev)) { 5256 action = "delete"; 5257 oldValue = last(prev.content.getContent()); 5258 } else { 5259 return; 5260 } 5261 } else { 5262 if (prev !== null && this.deletes(prev)) { 5263 action = "update"; 5264 oldValue = last(prev.content.getContent()); 5265 } else { 5266 action = "add"; 5267 oldValue = void 0; 5268 } 5269 } 5270 } else { 5271 if (this.deletes(item)) { 5272 action = "delete"; 5273 oldValue = last( 5274 /** @type {Item} */ 5275 item.content.getContent() 5276 ); 5277 } else { 5278 return; 5279 } 5280 } 5281 keys2.set(key, { action, oldValue }); 5282 } 5283 }); 5284 this._keys = keys2; 5285 } 5286 return this._keys; 5287 } 5288 /** 5289 * This is a computed property. Note that this can only be safely computed during the 5290 * event call. Computing this property after other changes happened might result in 5291 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5292 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5293 * 5294 * @type {Array<{insert?: string | Array<any> | object | AbstractType<any>, retain?: number, delete?: number, attributes?: Object<string, any>}>} 5295 */ 5296 get delta() { 5297 return this.changes.delta; 5298 } 5299 /** 5300 * Check if a struct is added by this event. 5301 * 5302 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5303 * 5304 * @param {AbstractStruct} struct 5305 * @return {boolean} 5306 */ 5307 adds(struct) { 5308 return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); 5309 } 5310 /** 5311 * This is a computed property. Note that this can only be safely computed during the 5312 * event call. Computing this property after other changes happened might result in 5313 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5314 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5315 * 5316 * @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}>}} 5317 */ 5318 get changes() { 5319 let changes = this._changes; 5320 if (changes === null) { 5321 if (this.transaction.doc._transactionCleanups.length === 0) { 5322 throw create3(errorComputeChanges); 5323 } 5324 const target = this.target; 5325 const added = create2(); 5326 const deleted = create2(); 5327 const delta = []; 5328 changes = { 5329 added, 5330 deleted, 5331 delta, 5332 keys: this.keys 5333 }; 5334 const changed = ( 5335 /** @type Set<string|null> */ 5336 this.transaction.changed.get(target) 5337 ); 5338 if (changed.has(null)) { 5339 let lastOp = null; 5340 const packOp = () => { 5341 if (lastOp) { 5342 delta.push(lastOp); 5343 } 5344 }; 5345 for (let item = target._start; item !== null; item = item.right) { 5346 if (item.deleted) { 5347 if (this.deletes(item) && !this.adds(item)) { 5348 if (lastOp === null || lastOp.delete === void 0) { 5349 packOp(); 5350 lastOp = { delete: 0 }; 5351 } 5352 lastOp.delete += item.length; 5353 deleted.add(item); 5354 } 5355 } else { 5356 if (this.adds(item)) { 5357 if (lastOp === null || lastOp.insert === void 0) { 5358 packOp(); 5359 lastOp = { insert: [] }; 5360 } 5361 lastOp.insert = lastOp.insert.concat(item.content.getContent()); 5362 added.add(item); 5363 } else { 5364 if (lastOp === null || lastOp.retain === void 0) { 5365 packOp(); 5366 lastOp = { retain: 0 }; 5367 } 5368 lastOp.retain += item.length; 5369 } 5370 } 5371 } 5372 if (lastOp !== null && lastOp.retain === void 0) { 5373 packOp(); 5374 } 5375 } 5376 this._changes = changes; 5377 } 5378 return ( 5379 /** @type {any} */ 5380 changes 5381 ); 5382 } 5383 }; 5384 var getPathTo = (parent, child) => { 5385 const path = []; 5386 while (child._item !== null && child !== parent) { 5387 if (child._item.parentSub !== null) { 5388 path.unshift(child._item.parentSub); 5389 } else { 5390 let i = 0; 5391 let c = ( 5392 /** @type {AbstractType<any>} */ 5393 child._item.parent._start 5394 ); 5395 while (c !== child._item && c !== null) { 5396 if (!c.deleted && c.countable) { 5397 i += c.length; 5398 } 5399 c = c.right; 5400 } 5401 path.unshift(i); 5402 } 5403 child = /** @type {AbstractType<any>} */ 5404 child._item.parent; 5405 } 5406 return path; 5407 }; 5408 var warnPrematureAccess = () => { 5409 warn("Invalid access: Add Yjs type to a document before reading data."); 5410 }; 5411 var maxSearchMarker = 80; 5412 var globalSearchMarkerTimestamp = 0; 5413 var ArraySearchMarker = class { 5414 /** 5415 * @param {Item} p 5416 * @param {number} index 5417 */ 5418 constructor(p, index) { 5419 p.marker = true; 5420 this.p = p; 5421 this.index = index; 5422 this.timestamp = globalSearchMarkerTimestamp++; 5423 } 5424 }; 5425 var refreshMarkerTimestamp = (marker) => { 5426 marker.timestamp = globalSearchMarkerTimestamp++; 5427 }; 5428 var overwriteMarker = (marker, p, index) => { 5429 marker.p.marker = false; 5430 marker.p = p; 5431 p.marker = true; 5432 marker.index = index; 5433 marker.timestamp = globalSearchMarkerTimestamp++; 5434 }; 5435 var markPosition = (searchMarker, p, index) => { 5436 if (searchMarker.length >= maxSearchMarker) { 5437 const marker = searchMarker.reduce((a, b) => a.timestamp < b.timestamp ? a : b); 5438 overwriteMarker(marker, p, index); 5439 return marker; 5440 } else { 5441 const pm = new ArraySearchMarker(p, index); 5442 searchMarker.push(pm); 5443 return pm; 5444 } 5445 }; 5446 var findMarker = (yarray, index) => { 5447 if (yarray._start === null || index === 0 || yarray._searchMarker === null) { 5448 return null; 5449 } 5450 const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b) => abs(index - a.index) < abs(index - b.index) ? a : b); 5451 let p = yarray._start; 5452 let pindex = 0; 5453 if (marker !== null) { 5454 p = marker.p; 5455 pindex = marker.index; 5456 refreshMarkerTimestamp(marker); 5457 } 5458 while (p.right !== null && pindex < index) { 5459 if (!p.deleted && p.countable) { 5460 if (index < pindex + p.length) { 5461 break; 5462 } 5463 pindex += p.length; 5464 } 5465 p = p.right; 5466 } 5467 while (p.left !== null && pindex > index) { 5468 p = p.left; 5469 if (!p.deleted && p.countable) { 5470 pindex -= p.length; 5471 } 5472 } 5473 while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { 5474 p = p.left; 5475 if (!p.deleted && p.countable) { 5476 pindex -= p.length; 5477 } 5478 } 5479 if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray<any>} */ 5480 p.parent.length / maxSearchMarker) { 5481 overwriteMarker(marker, p, pindex); 5482 return marker; 5483 } else { 5484 return markPosition(yarray._searchMarker, p, pindex); 5485 } 5486 }; 5487 var updateMarkerChanges = (searchMarker, index, len) => { 5488 for (let i = searchMarker.length - 1; i >= 0; i--) { 5489 const m = searchMarker[i]; 5490 if (len > 0) { 5491 let p = m.p; 5492 p.marker = false; 5493 while (p && (p.deleted || !p.countable)) { 5494 p = p.left; 5495 if (p && !p.deleted && p.countable) { 5496 m.index -= p.length; 5497 } 5498 } 5499 if (p === null || p.marker === true) { 5500 searchMarker.splice(i, 1); 5501 continue; 5502 } 5503 m.p = p; 5504 p.marker = true; 5505 } 5506 if (index < m.index || len > 0 && index === m.index) { 5507 m.index = max(index, m.index + len); 5508 } 5509 } 5510 }; 5511 var getTypeChildren = (t) => { 5512 t.doc ?? warnPrematureAccess(); 5513 let s = t._start; 5514 const arr = []; 5515 while (s) { 5516 arr.push(s); 5517 s = s.right; 5518 } 5519 return arr; 5520 }; 5521 var callTypeObservers = (type, transaction, event) => { 5522 const changedType = type; 5523 const changedParentTypes = transaction.changedParentTypes; 5524 while (true) { 5525 setIfUndefined(changedParentTypes, type, () => []).push(event); 5526 if (type._item === null) { 5527 break; 5528 } 5529 type = /** @type {AbstractType<any>} */ 5530 type._item.parent; 5531 } 5532 callEventHandlerListeners(changedType._eH, event, transaction); 5533 }; 5534 var AbstractType = class { 5535 constructor() { 5536 this._item = null; 5537 this._map = /* @__PURE__ */ new Map(); 5538 this._start = null; 5539 this.doc = null; 5540 this._length = 0; 5541 this._eH = createEventHandler(); 5542 this._dEH = createEventHandler(); 5543 this._searchMarker = null; 5544 } 5545 /** 5546 * @return {AbstractType<any>|null} 5547 */ 5548 get parent() { 5549 return this._item ? ( 5550 /** @type {AbstractType<any>} */ 5551 this._item.parent 5552 ) : null; 5553 } 5554 /** 5555 * Integrate this type into the Yjs instance. 5556 * 5557 * * Save this struct in the os 5558 * * This type is sent to other client 5559 * * Observer functions are fired 5560 * 5561 * @param {Doc} y The Yjs instance 5562 * @param {Item|null} item 5563 */ 5564 _integrate(y, item) { 5565 this.doc = y; 5566 this._item = item; 5567 } 5568 /** 5569 * @return {AbstractType<EventType>} 5570 */ 5571 _copy() { 5572 throw methodUnimplemented(); 5573 } 5574 /** 5575 * Makes a copy of this data type that can be included somewhere else. 5576 * 5577 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 5578 * 5579 * @return {AbstractType<EventType>} 5580 */ 5581 clone() { 5582 throw methodUnimplemented(); 5583 } 5584 /** 5585 * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder 5586 */ 5587 _write(_encoder) { 5588 } 5589 /** 5590 * The first non-deleted item 5591 */ 5592 get _first() { 5593 let n = this._start; 5594 while (n !== null && n.deleted) { 5595 n = n.right; 5596 } 5597 return n; 5598 } 5599 /** 5600 * Creates YEvent and calls all type observers. 5601 * Must be implemented by each type. 5602 * 5603 * @param {Transaction} transaction 5604 * @param {Set<null|string>} _parentSubs Keys changed on this type. `null` if list was modified. 5605 */ 5606 _callObserver(transaction, _parentSubs) { 5607 if (!transaction.local && this._searchMarker) { 5608 this._searchMarker.length = 0; 5609 } 5610 } 5611 /** 5612 * Observe all events that are created on this type. 5613 * 5614 * @param {function(EventType, Transaction):void} f Observer function 5615 */ 5616 observe(f) { 5617 addEventHandlerListener(this._eH, f); 5618 } 5619 /** 5620 * Observe all events that are created by this type and its children. 5621 * 5622 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 5623 */ 5624 observeDeep(f) { 5625 addEventHandlerListener(this._dEH, f); 5626 } 5627 /** 5628 * Unregister an observer function. 5629 * 5630 * @param {function(EventType,Transaction):void} f Observer function 5631 */ 5632 unobserve(f) { 5633 removeEventHandlerListener(this._eH, f); 5634 } 5635 /** 5636 * Unregister an observer function. 5637 * 5638 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 5639 */ 5640 unobserveDeep(f) { 5641 removeEventHandlerListener(this._dEH, f); 5642 } 5643 /** 5644 * @abstract 5645 * @return {any} 5646 */ 5647 toJSON() { 5648 } 5649 }; 5650 var typeListSlice = (type, start, end) => { 5651 type.doc ?? warnPrematureAccess(); 5652 if (start < 0) { 5653 start = type._length + start; 5654 } 5655 if (end < 0) { 5656 end = type._length + end; 5657 } 5658 let len = end - start; 5659 const cs = []; 5660 let n = type._start; 5661 while (n !== null && len > 0) { 5662 if (n.countable && !n.deleted) { 5663 const c = n.content.getContent(); 5664 if (c.length <= start) { 5665 start -= c.length; 5666 } else { 5667 for (let i = start; i < c.length && len > 0; i++) { 5668 cs.push(c[i]); 5669 len--; 5670 } 5671 start = 0; 5672 } 5673 } 5674 n = n.right; 5675 } 5676 return cs; 5677 }; 5678 var typeListToArray = (type) => { 5679 type.doc ?? warnPrematureAccess(); 5680 const cs = []; 5681 let n = type._start; 5682 while (n !== null) { 5683 if (n.countable && !n.deleted) { 5684 const c = n.content.getContent(); 5685 for (let i = 0; i < c.length; i++) { 5686 cs.push(c[i]); 5687 } 5688 } 5689 n = n.right; 5690 } 5691 return cs; 5692 }; 5693 var typeListToArraySnapshot = (type, snapshot2) => { 5694 const cs = []; 5695 let n = type._start; 5696 while (n !== null) { 5697 if (n.countable && isVisible(n, snapshot2)) { 5698 const c = n.content.getContent(); 5699 for (let i = 0; i < c.length; i++) { 5700 cs.push(c[i]); 5701 } 5702 } 5703 n = n.right; 5704 } 5705 return cs; 5706 }; 5707 var typeListForEach = (type, f) => { 5708 let index = 0; 5709 let n = type._start; 5710 type.doc ?? warnPrematureAccess(); 5711 while (n !== null) { 5712 if (n.countable && !n.deleted) { 5713 const c = n.content.getContent(); 5714 for (let i = 0; i < c.length; i++) { 5715 f(c[i], index++, type); 5716 } 5717 } 5718 n = n.right; 5719 } 5720 }; 5721 var typeListMap = (type, f) => { 5722 const result = []; 5723 typeListForEach(type, (c, i) => { 5724 result.push(f(c, i, type)); 5725 }); 5726 return result; 5727 }; 5728 var typeListCreateIterator = (type) => { 5729 let n = type._start; 5730 let currentContent = null; 5731 let currentContentIndex = 0; 5732 return { 5733 [Symbol.iterator]() { 5734 return this; 5735 }, 5736 next: () => { 5737 if (currentContent === null) { 5738 while (n !== null && n.deleted) { 5739 n = n.right; 5740 } 5741 if (n === null) { 5742 return { 5743 done: true, 5744 value: void 0 5745 }; 5746 } 5747 currentContent = n.content.getContent(); 5748 currentContentIndex = 0; 5749 n = n.right; 5750 } 5751 const value = currentContent[currentContentIndex++]; 5752 if (currentContent.length <= currentContentIndex) { 5753 currentContent = null; 5754 } 5755 return { 5756 done: false, 5757 value 5758 }; 5759 } 5760 }; 5761 }; 5762 var typeListGet = (type, index) => { 5763 type.doc ?? warnPrematureAccess(); 5764 const marker = findMarker(type, index); 5765 let n = type._start; 5766 if (marker !== null) { 5767 n = marker.p; 5768 index -= marker.index; 5769 } 5770 for (; n !== null; n = n.right) { 5771 if (!n.deleted && n.countable) { 5772 if (index < n.length) { 5773 return n.content.getContent()[index]; 5774 } 5775 index -= n.length; 5776 } 5777 } 5778 }; 5779 var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { 5780 let left = referenceItem; 5781 const doc2 = transaction.doc; 5782 const ownClientId = doc2.clientID; 5783 const store = doc2.store; 5784 const right = referenceItem === null ? parent._start : referenceItem.right; 5785 let jsonContent = []; 5786 const packJsonContent = () => { 5787 if (jsonContent.length > 0) { 5788 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); 5789 left.integrate(transaction, 0); 5790 jsonContent = []; 5791 } 5792 }; 5793 content.forEach((c) => { 5794 if (c === null) { 5795 jsonContent.push(c); 5796 } else { 5797 switch (c.constructor) { 5798 case Number: 5799 case Object: 5800 case Boolean: 5801 case Array: 5802 case String: 5803 jsonContent.push(c); 5804 break; 5805 default: 5806 packJsonContent(); 5807 switch (c.constructor) { 5808 case Uint8Array: 5809 case ArrayBuffer: 5810 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( 5811 /** @type {Uint8Array} */ 5812 c 5813 ))); 5814 left.integrate(transaction, 0); 5815 break; 5816 case Doc: 5817 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( 5818 /** @type {Doc} */ 5819 c 5820 )); 5821 left.integrate(transaction, 0); 5822 break; 5823 default: 5824 if (c instanceof AbstractType) { 5825 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); 5826 left.integrate(transaction, 0); 5827 } else { 5828 throw new Error("Unexpected content type in insert operation"); 5829 } 5830 } 5831 } 5832 } 5833 }); 5834 packJsonContent(); 5835 }; 5836 var lengthExceeded = () => create3("Length exceeded!"); 5837 var typeListInsertGenerics = (transaction, parent, index, content) => { 5838 if (index > parent._length) { 5839 throw lengthExceeded(); 5840 } 5841 if (index === 0) { 5842 if (parent._searchMarker) { 5843 updateMarkerChanges(parent._searchMarker, index, content.length); 5844 } 5845 return typeListInsertGenericsAfter(transaction, parent, null, content); 5846 } 5847 const startIndex = index; 5848 const marker = findMarker(parent, index); 5849 let n = parent._start; 5850 if (marker !== null) { 5851 n = marker.p; 5852 index -= marker.index; 5853 if (index === 0) { 5854 n = n.prev; 5855 index += n && n.countable && !n.deleted ? n.length : 0; 5856 } 5857 } 5858 for (; n !== null; n = n.right) { 5859 if (!n.deleted && n.countable) { 5860 if (index <= n.length) { 5861 if (index < n.length) { 5862 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5863 } 5864 break; 5865 } 5866 index -= n.length; 5867 } 5868 } 5869 if (parent._searchMarker) { 5870 updateMarkerChanges(parent._searchMarker, startIndex, content.length); 5871 } 5872 return typeListInsertGenericsAfter(transaction, parent, n, content); 5873 }; 5874 var typeListPushGenerics = (transaction, parent, content) => { 5875 const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); 5876 let n = marker.p; 5877 if (n) { 5878 while (n.right) { 5879 n = n.right; 5880 } 5881 } 5882 return typeListInsertGenericsAfter(transaction, parent, n, content); 5883 }; 5884 var typeListDelete = (transaction, parent, index, length2) => { 5885 if (length2 === 0) { 5886 return; 5887 } 5888 const startIndex = index; 5889 const startLength = length2; 5890 const marker = findMarker(parent, index); 5891 let n = parent._start; 5892 if (marker !== null) { 5893 n = marker.p; 5894 index -= marker.index; 5895 } 5896 for (; n !== null && index > 0; n = n.right) { 5897 if (!n.deleted && n.countable) { 5898 if (index < n.length) { 5899 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5900 } 5901 index -= n.length; 5902 } 5903 } 5904 while (length2 > 0 && n !== null) { 5905 if (!n.deleted) { 5906 if (length2 < n.length) { 5907 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length2)); 5908 } 5909 n.delete(transaction); 5910 length2 -= n.length; 5911 } 5912 n = n.right; 5913 } 5914 if (length2 > 0) { 5915 throw lengthExceeded(); 5916 } 5917 if (parent._searchMarker) { 5918 updateMarkerChanges( 5919 parent._searchMarker, 5920 startIndex, 5921 -startLength + length2 5922 /* in case we remove the above exception */ 5923 ); 5924 } 5925 }; 5926 var typeMapDelete = (transaction, parent, key) => { 5927 const c = parent._map.get(key); 5928 if (c !== void 0) { 5929 c.delete(transaction); 5930 } 5931 }; 5932 var typeMapSet = (transaction, parent, key, value) => { 5933 const left = parent._map.get(key) || null; 5934 const doc2 = transaction.doc; 5935 const ownClientId = doc2.clientID; 5936 let content; 5937 if (value == null) { 5938 content = new ContentAny([value]); 5939 } else { 5940 switch (value.constructor) { 5941 case Number: 5942 case Object: 5943 case Boolean: 5944 case Array: 5945 case String: 5946 case Date: 5947 case BigInt: 5948 content = new ContentAny([value]); 5949 break; 5950 case Uint8Array: 5951 content = new ContentBinary( 5952 /** @type {Uint8Array} */ 5953 value 5954 ); 5955 break; 5956 case Doc: 5957 content = new ContentDoc( 5958 /** @type {Doc} */ 5959 value 5960 ); 5961 break; 5962 default: 5963 if (value instanceof AbstractType) { 5964 content = new ContentType(value); 5965 } else { 5966 throw new Error("Unexpected content type"); 5967 } 5968 } 5969 } 5970 new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); 5971 }; 5972 var typeMapGet = (parent, key) => { 5973 parent.doc ?? warnPrematureAccess(); 5974 const val = parent._map.get(key); 5975 return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; 5976 }; 5977 var typeMapGetAll = (parent) => { 5978 const res = {}; 5979 parent.doc ?? warnPrematureAccess(); 5980 parent._map.forEach((value, key) => { 5981 if (!value.deleted) { 5982 res[key] = value.content.getContent()[value.length - 1]; 5983 } 5984 }); 5985 return res; 5986 }; 5987 var typeMapHas = (parent, key) => { 5988 parent.doc ?? warnPrematureAccess(); 5989 const val = parent._map.get(key); 5990 return val !== void 0 && !val.deleted; 5991 }; 5992 var typeMapGetSnapshot = (parent, key, snapshot2) => { 5993 let v = parent._map.get(key) || null; 5994 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 5995 v = v.left; 5996 } 5997 return v !== null && isVisible(v, snapshot2) ? v.content.getContent()[v.length - 1] : void 0; 5998 }; 5999 var typeMapGetAllSnapshot = (parent, snapshot2) => { 6000 const res = {}; 6001 parent._map.forEach((value, key) => { 6002 let v = value; 6003 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 6004 v = v.left; 6005 } 6006 if (v !== null && isVisible(v, snapshot2)) { 6007 res[key] = v.content.getContent()[v.length - 1]; 6008 } 6009 }); 6010 return res; 6011 }; 6012 var createMapIterator = (type) => { 6013 type.doc ?? warnPrematureAccess(); 6014 return iteratorFilter( 6015 type._map.entries(), 6016 /** @param {any} entry */ 6017 (entry) => !entry[1].deleted 6018 ); 6019 }; 6020 var YArrayEvent = class extends YEvent { 6021 }; 6022 var YArray = class _YArray extends AbstractType { 6023 constructor() { 6024 super(); 6025 this._prelimContent = []; 6026 this._searchMarker = []; 6027 } 6028 /** 6029 * Construct a new YArray containing the specified items. 6030 * @template {Object<string,any>|Array<any>|number|null|string|Uint8Array} T 6031 * @param {Array<T>} items 6032 * @return {YArray<T>} 6033 */ 6034 static from(items) { 6035 const a = new _YArray(); 6036 a.push(items); 6037 return a; 6038 } 6039 /** 6040 * Integrate this type into the Yjs instance. 6041 * 6042 * * Save this struct in the os 6043 * * This type is sent to other client 6044 * * Observer functions are fired 6045 * 6046 * @param {Doc} y The Yjs instance 6047 * @param {Item} item 6048 */ 6049 _integrate(y, item) { 6050 super._integrate(y, item); 6051 this.insert( 6052 0, 6053 /** @type {Array<any>} */ 6054 this._prelimContent 6055 ); 6056 this._prelimContent = null; 6057 } 6058 /** 6059 * @return {YArray<T>} 6060 */ 6061 _copy() { 6062 return new _YArray(); 6063 } 6064 /** 6065 * Makes a copy of this data type that can be included somewhere else. 6066 * 6067 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6068 * 6069 * @return {YArray<T>} 6070 */ 6071 clone() { 6072 const arr = new _YArray(); 6073 arr.insert(0, this.toArray().map( 6074 (el) => el instanceof AbstractType ? ( 6075 /** @type {typeof el} */ 6076 el.clone() 6077 ) : el 6078 )); 6079 return arr; 6080 } 6081 get length() { 6082 this.doc ?? warnPrematureAccess(); 6083 return this._length; 6084 } 6085 /** 6086 * Creates YArrayEvent and calls observers. 6087 * 6088 * @param {Transaction} transaction 6089 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6090 */ 6091 _callObserver(transaction, parentSubs) { 6092 super._callObserver(transaction, parentSubs); 6093 callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); 6094 } 6095 /** 6096 * Inserts new content at an index. 6097 * 6098 * Important: This function expects an array of content. Not just a content 6099 * object. The reason for this "weirdness" is that inserting several elements 6100 * is very efficient when it is done as a single operation. 6101 * 6102 * @example 6103 * // Insert character 'a' at position 0 6104 * yarray.insert(0, ['a']) 6105 * // Insert numbers 1, 2 at position 1 6106 * yarray.insert(1, [1, 2]) 6107 * 6108 * @param {number} index The index to insert content at. 6109 * @param {Array<T>} content The array of content 6110 */ 6111 insert(index, content) { 6112 if (this.doc !== null) { 6113 transact(this.doc, (transaction) => { 6114 typeListInsertGenerics( 6115 transaction, 6116 this, 6117 index, 6118 /** @type {any} */ 6119 content 6120 ); 6121 }); 6122 } else { 6123 this._prelimContent.splice(index, 0, ...content); 6124 } 6125 } 6126 /** 6127 * Appends content to this YArray. 6128 * 6129 * @param {Array<T>} content Array of content to append. 6130 * 6131 * @todo Use the following implementation in all types. 6132 */ 6133 push(content) { 6134 if (this.doc !== null) { 6135 transact(this.doc, (transaction) => { 6136 typeListPushGenerics( 6137 transaction, 6138 this, 6139 /** @type {any} */ 6140 content 6141 ); 6142 }); 6143 } else { 6144 this._prelimContent.push(...content); 6145 } 6146 } 6147 /** 6148 * Prepends content to this YArray. 6149 * 6150 * @param {Array<T>} content Array of content to prepend. 6151 */ 6152 unshift(content) { 6153 this.insert(0, content); 6154 } 6155 /** 6156 * Deletes elements starting from an index. 6157 * 6158 * @param {number} index Index at which to start deleting elements 6159 * @param {number} length The number of elements to remove. Defaults to 1. 6160 */ 6161 delete(index, length2 = 1) { 6162 if (this.doc !== null) { 6163 transact(this.doc, (transaction) => { 6164 typeListDelete(transaction, this, index, length2); 6165 }); 6166 } else { 6167 this._prelimContent.splice(index, length2); 6168 } 6169 } 6170 /** 6171 * Returns the i-th element from a YArray. 6172 * 6173 * @param {number} index The index of the element to return from the YArray 6174 * @return {T} 6175 */ 6176 get(index) { 6177 return typeListGet(this, index); 6178 } 6179 /** 6180 * Transforms this YArray to a JavaScript Array. 6181 * 6182 * @return {Array<T>} 6183 */ 6184 toArray() { 6185 return typeListToArray(this); 6186 } 6187 /** 6188 * Returns a portion of this YArray into a JavaScript Array selected 6189 * from start to end (end not included). 6190 * 6191 * @param {number} [start] 6192 * @param {number} [end] 6193 * @return {Array<T>} 6194 */ 6195 slice(start = 0, end = this.length) { 6196 return typeListSlice(this, start, end); 6197 } 6198 /** 6199 * Transforms this Shared Type to a JSON object. 6200 * 6201 * @return {Array<any>} 6202 */ 6203 toJSON() { 6204 return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); 6205 } 6206 /** 6207 * Returns an Array with the result of calling a provided function on every 6208 * element of this YArray. 6209 * 6210 * @template M 6211 * @param {function(T,number,YArray<T>):M} f Function that produces an element of the new Array 6212 * @return {Array<M>} A new array with each element being the result of the 6213 * callback function 6214 */ 6215 map(f) { 6216 return typeListMap( 6217 this, 6218 /** @type {any} */ 6219 f 6220 ); 6221 } 6222 /** 6223 * Executes a provided function once on every element of this YArray. 6224 * 6225 * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray. 6226 */ 6227 forEach(f) { 6228 typeListForEach(this, f); 6229 } 6230 /** 6231 * @return {IterableIterator<T>} 6232 */ 6233 [Symbol.iterator]() { 6234 return typeListCreateIterator(this); 6235 } 6236 /** 6237 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6238 */ 6239 _write(encoder) { 6240 encoder.writeTypeRef(YArrayRefID); 6241 } 6242 }; 6243 var readYArray = (_decoder) => new YArray(); 6244 var YMapEvent = class extends YEvent { 6245 /** 6246 * @param {YMap<T>} ymap The YArray that changed. 6247 * @param {Transaction} transaction 6248 * @param {Set<any>} subs The keys that changed. 6249 */ 6250 constructor(ymap, transaction, subs) { 6251 super(ymap, transaction); 6252 this.keysChanged = subs; 6253 } 6254 }; 6255 var YMap = class _YMap extends AbstractType { 6256 /** 6257 * 6258 * @param {Iterable<readonly [string, any]>=} entries - an optional iterable to initialize the YMap 6259 */ 6260 constructor(entries) { 6261 super(); 6262 this._prelimContent = null; 6263 if (entries === void 0) { 6264 this._prelimContent = /* @__PURE__ */ new Map(); 6265 } else { 6266 this._prelimContent = new Map(entries); 6267 } 6268 } 6269 /** 6270 * Integrate this type into the Yjs instance. 6271 * 6272 * * Save this struct in the os 6273 * * This type is sent to other client 6274 * * Observer functions are fired 6275 * 6276 * @param {Doc} y The Yjs instance 6277 * @param {Item} item 6278 */ 6279 _integrate(y, item) { 6280 super._integrate(y, item); 6281 this._prelimContent.forEach((value, key) => { 6282 this.set(key, value); 6283 }); 6284 this._prelimContent = null; 6285 } 6286 /** 6287 * @return {YMap<MapType>} 6288 */ 6289 _copy() { 6290 return new _YMap(); 6291 } 6292 /** 6293 * Makes a copy of this data type that can be included somewhere else. 6294 * 6295 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6296 * 6297 * @return {YMap<MapType>} 6298 */ 6299 clone() { 6300 const map2 = new _YMap(); 6301 this.forEach((value, key) => { 6302 map2.set(key, value instanceof AbstractType ? ( 6303 /** @type {typeof value} */ 6304 value.clone() 6305 ) : value); 6306 }); 6307 return map2; 6308 } 6309 /** 6310 * Creates YMapEvent and calls observers. 6311 * 6312 * @param {Transaction} transaction 6313 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6314 */ 6315 _callObserver(transaction, parentSubs) { 6316 callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); 6317 } 6318 /** 6319 * Transforms this Shared Type to a JSON object. 6320 * 6321 * @return {Object<string,any>} 6322 */ 6323 toJSON() { 6324 this.doc ?? warnPrematureAccess(); 6325 const map2 = {}; 6326 this._map.forEach((item, key) => { 6327 if (!item.deleted) { 6328 const v = item.content.getContent()[item.length - 1]; 6329 map2[key] = v instanceof AbstractType ? v.toJSON() : v; 6330 } 6331 }); 6332 return map2; 6333 } 6334 /** 6335 * Returns the size of the YMap (count of key/value pairs) 6336 * 6337 * @return {number} 6338 */ 6339 get size() { 6340 return [...createMapIterator(this)].length; 6341 } 6342 /** 6343 * Returns the keys for each element in the YMap Type. 6344 * 6345 * @return {IterableIterator<string>} 6346 */ 6347 keys() { 6348 return iteratorMap( 6349 createMapIterator(this), 6350 /** @param {any} v */ 6351 (v) => v[0] 6352 ); 6353 } 6354 /** 6355 * Returns the values for each element in the YMap Type. 6356 * 6357 * @return {IterableIterator<MapType>} 6358 */ 6359 values() { 6360 return iteratorMap( 6361 createMapIterator(this), 6362 /** @param {any} v */ 6363 (v) => v[1].content.getContent()[v[1].length - 1] 6364 ); 6365 } 6366 /** 6367 * Returns an Iterator of [key, value] pairs 6368 * 6369 * @return {IterableIterator<[string, MapType]>} 6370 */ 6371 entries() { 6372 return iteratorMap( 6373 createMapIterator(this), 6374 /** @param {any} v */ 6375 (v) => ( 6376 /** @type {any} */ 6377 [v[0], v[1].content.getContent()[v[1].length - 1]] 6378 ) 6379 ); 6380 } 6381 /** 6382 * Executes a provided function on once on every key-value pair. 6383 * 6384 * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray. 6385 */ 6386 forEach(f) { 6387 this.doc ?? warnPrematureAccess(); 6388 this._map.forEach((item, key) => { 6389 if (!item.deleted) { 6390 f(item.content.getContent()[item.length - 1], key, this); 6391 } 6392 }); 6393 } 6394 /** 6395 * Returns an Iterator of [key, value] pairs 6396 * 6397 * @return {IterableIterator<[string, MapType]>} 6398 */ 6399 [Symbol.iterator]() { 6400 return this.entries(); 6401 } 6402 /** 6403 * Remove a specified element from this YMap. 6404 * 6405 * @param {string} key The key of the element to remove. 6406 */ 6407 delete(key) { 6408 if (this.doc !== null) { 6409 transact(this.doc, (transaction) => { 6410 typeMapDelete(transaction, this, key); 6411 }); 6412 } else { 6413 this._prelimContent.delete(key); 6414 } 6415 } 6416 /** 6417 * Adds or updates an element with a specified key and value. 6418 * @template {MapType} VAL 6419 * 6420 * @param {string} key The key of the element to add to this YMap 6421 * @param {VAL} value The value of the element to add 6422 * @return {VAL} 6423 */ 6424 set(key, value) { 6425 if (this.doc !== null) { 6426 transact(this.doc, (transaction) => { 6427 typeMapSet( 6428 transaction, 6429 this, 6430 key, 6431 /** @type {any} */ 6432 value 6433 ); 6434 }); 6435 } else { 6436 this._prelimContent.set(key, value); 6437 } 6438 return value; 6439 } 6440 /** 6441 * Returns a specified element from this YMap. 6442 * 6443 * @param {string} key 6444 * @return {MapType|undefined} 6445 */ 6446 get(key) { 6447 return ( 6448 /** @type {any} */ 6449 typeMapGet(this, key) 6450 ); 6451 } 6452 /** 6453 * Returns a boolean indicating whether the specified key exists or not. 6454 * 6455 * @param {string} key The key to test. 6456 * @return {boolean} 6457 */ 6458 has(key) { 6459 return typeMapHas(this, key); 6460 } 6461 /** 6462 * Removes all elements from this YMap. 6463 */ 6464 clear() { 6465 if (this.doc !== null) { 6466 transact(this.doc, (transaction) => { 6467 this.forEach(function(_value, key, map2) { 6468 typeMapDelete(transaction, map2, key); 6469 }); 6470 }); 6471 } else { 6472 this._prelimContent.clear(); 6473 } 6474 } 6475 /** 6476 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6477 */ 6478 _write(encoder) { 6479 encoder.writeTypeRef(YMapRefID); 6480 } 6481 }; 6482 var readYMap = (_decoder) => new YMap(); 6483 var equalAttrs = (a, b) => a === b || typeof a === "object" && typeof b === "object" && a && b && equalFlat(a, b); 6484 var ItemTextListPosition = class { 6485 /** 6486 * @param {Item|null} left 6487 * @param {Item|null} right 6488 * @param {number} index 6489 * @param {Map<string,any>} currentAttributes 6490 */ 6491 constructor(left, right, index, currentAttributes) { 6492 this.left = left; 6493 this.right = right; 6494 this.index = index; 6495 this.currentAttributes = currentAttributes; 6496 } 6497 /** 6498 * Only call this if you know that this.right is defined 6499 */ 6500 forward() { 6501 if (this.right === null) { 6502 unexpectedCase(); 6503 } 6504 switch (this.right.content.constructor) { 6505 case ContentFormat: 6506 if (!this.right.deleted) { 6507 updateCurrentAttributes( 6508 this.currentAttributes, 6509 /** @type {ContentFormat} */ 6510 this.right.content 6511 ); 6512 } 6513 break; 6514 default: 6515 if (!this.right.deleted) { 6516 this.index += this.right.length; 6517 } 6518 break; 6519 } 6520 this.left = this.right; 6521 this.right = this.right.right; 6522 } 6523 }; 6524 var findNextPosition = (transaction, pos, count) => { 6525 while (pos.right !== null && count > 0) { 6526 switch (pos.right.content.constructor) { 6527 case ContentFormat: 6528 if (!pos.right.deleted) { 6529 updateCurrentAttributes( 6530 pos.currentAttributes, 6531 /** @type {ContentFormat} */ 6532 pos.right.content 6533 ); 6534 } 6535 break; 6536 default: 6537 if (!pos.right.deleted) { 6538 if (count < pos.right.length) { 6539 getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); 6540 } 6541 pos.index += pos.right.length; 6542 count -= pos.right.length; 6543 } 6544 break; 6545 } 6546 pos.left = pos.right; 6547 pos.right = pos.right.right; 6548 } 6549 return pos; 6550 }; 6551 var findPosition = (transaction, parent, index, useSearchMarker) => { 6552 const currentAttributes = /* @__PURE__ */ new Map(); 6553 const marker = useSearchMarker ? findMarker(parent, index) : null; 6554 if (marker) { 6555 const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); 6556 return findNextPosition(transaction, pos, index - marker.index); 6557 } else { 6558 const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); 6559 return findNextPosition(transaction, pos, index); 6560 } 6561 }; 6562 var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { 6563 while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( 6564 negatedAttributes.get( 6565 /** @type {ContentFormat} */ 6566 currPos.right.content.key 6567 ), 6568 /** @type {ContentFormat} */ 6569 currPos.right.content.value 6570 ))) { 6571 if (!currPos.right.deleted) { 6572 negatedAttributes.delete( 6573 /** @type {ContentFormat} */ 6574 currPos.right.content.key 6575 ); 6576 } 6577 currPos.forward(); 6578 } 6579 const doc2 = transaction.doc; 6580 const ownClientId = doc2.clientID; 6581 negatedAttributes.forEach((val, key) => { 6582 const left = currPos.left; 6583 const right = currPos.right; 6584 const nextFormat = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 6585 nextFormat.integrate(transaction, 0); 6586 currPos.right = nextFormat; 6587 currPos.forward(); 6588 }); 6589 }; 6590 var updateCurrentAttributes = (currentAttributes, format) => { 6591 const { key, value } = format; 6592 if (value === null) { 6593 currentAttributes.delete(key); 6594 } else { 6595 currentAttributes.set(key, value); 6596 } 6597 }; 6598 var minimizeAttributeChanges = (currPos, attributes) => { 6599 while (true) { 6600 if (currPos.right === null) { 6601 break; 6602 } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( 6603 attributes[ 6604 /** @type {ContentFormat} */ 6605 currPos.right.content.key 6606 ] ?? null, 6607 /** @type {ContentFormat} */ 6608 currPos.right.content.value 6609 )) ; 6610 else { 6611 break; 6612 } 6613 currPos.forward(); 6614 } 6615 }; 6616 var insertAttributes = (transaction, parent, currPos, attributes) => { 6617 const doc2 = transaction.doc; 6618 const ownClientId = doc2.clientID; 6619 const negatedAttributes = /* @__PURE__ */ new Map(); 6620 for (const key in attributes) { 6621 const val = attributes[key]; 6622 const currentVal = currPos.currentAttributes.get(key) ?? null; 6623 if (!equalAttrs(currentVal, val)) { 6624 negatedAttributes.set(key, currentVal); 6625 const { left, right } = currPos; 6626 currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 6627 currPos.right.integrate(transaction, 0); 6628 currPos.forward(); 6629 } 6630 } 6631 return negatedAttributes; 6632 }; 6633 var insertText = (transaction, parent, currPos, text2, attributes) => { 6634 currPos.currentAttributes.forEach((_val, key) => { 6635 if (attributes[key] === void 0) { 6636 attributes[key] = null; 6637 } 6638 }); 6639 const doc2 = transaction.doc; 6640 const ownClientId = doc2.clientID; 6641 minimizeAttributeChanges(currPos, attributes); 6642 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 6643 const content = text2.constructor === String ? new ContentString( 6644 /** @type {string} */ 6645 text2 6646 ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); 6647 let { left, right, index } = currPos; 6648 if (parent._searchMarker) { 6649 updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); 6650 } 6651 right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); 6652 right.integrate(transaction, 0); 6653 currPos.right = right; 6654 currPos.index = index; 6655 currPos.forward(); 6656 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 6657 }; 6658 var formatText = (transaction, parent, currPos, length2, attributes) => { 6659 const doc2 = transaction.doc; 6660 const ownClientId = doc2.clientID; 6661 minimizeAttributeChanges(currPos, attributes); 6662 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 6663 iterationLoop: while (currPos.right !== null && (length2 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { 6664 if (!currPos.right.deleted) { 6665 switch (currPos.right.content.constructor) { 6666 case ContentFormat: { 6667 const { key, value } = ( 6668 /** @type {ContentFormat} */ 6669 currPos.right.content 6670 ); 6671 const attr = attributes[key]; 6672 if (attr !== void 0) { 6673 if (equalAttrs(attr, value)) { 6674 negatedAttributes.delete(key); 6675 } else { 6676 if (length2 === 0) { 6677 break iterationLoop; 6678 } 6679 negatedAttributes.set(key, value); 6680 } 6681 currPos.right.delete(transaction); 6682 } else { 6683 currPos.currentAttributes.set(key, value); 6684 } 6685 break; 6686 } 6687 default: 6688 if (length2 < currPos.right.length) { 6689 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); 6690 } 6691 length2 -= currPos.right.length; 6692 break; 6693 } 6694 } 6695 currPos.forward(); 6696 } 6697 if (length2 > 0) { 6698 let newlines = ""; 6699 for (; length2 > 0; length2--) { 6700 newlines += "\n"; 6701 } 6702 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)); 6703 currPos.right.integrate(transaction, 0); 6704 currPos.forward(); 6705 } 6706 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 6707 }; 6708 var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { 6709 let end = start; 6710 const endFormats = create(); 6711 while (end && (!end.countable || end.deleted)) { 6712 if (!end.deleted && end.content.constructor === ContentFormat) { 6713 const cf = ( 6714 /** @type {ContentFormat} */ 6715 end.content 6716 ); 6717 endFormats.set(cf.key, cf); 6718 } 6719 end = end.right; 6720 } 6721 let cleanups = 0; 6722 let reachedCurr = false; 6723 while (start !== end) { 6724 if (curr === start) { 6725 reachedCurr = true; 6726 } 6727 if (!start.deleted) { 6728 const content = start.content; 6729 switch (content.constructor) { 6730 case ContentFormat: { 6731 const { key, value } = ( 6732 /** @type {ContentFormat} */ 6733 content 6734 ); 6735 const startAttrValue = startAttributes.get(key) ?? null; 6736 if (endFormats.get(key) !== content || startAttrValue === value) { 6737 start.delete(transaction); 6738 cleanups++; 6739 if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { 6740 if (startAttrValue === null) { 6741 currAttributes.delete(key); 6742 } else { 6743 currAttributes.set(key, startAttrValue); 6744 } 6745 } 6746 } 6747 if (!reachedCurr && !start.deleted) { 6748 updateCurrentAttributes( 6749 currAttributes, 6750 /** @type {ContentFormat} */ 6751 content 6752 ); 6753 } 6754 break; 6755 } 6756 } 6757 } 6758 start = /** @type {Item} */ 6759 start.right; 6760 } 6761 return cleanups; 6762 }; 6763 var cleanupContextlessFormattingGap = (transaction, item) => { 6764 while (item && item.right && (item.right.deleted || !item.right.countable)) { 6765 item = item.right; 6766 } 6767 const attrs = /* @__PURE__ */ new Set(); 6768 while (item && (item.deleted || !item.countable)) { 6769 if (!item.deleted && item.content.constructor === ContentFormat) { 6770 const key = ( 6771 /** @type {ContentFormat} */ 6772 item.content.key 6773 ); 6774 if (attrs.has(key)) { 6775 item.delete(transaction); 6776 } else { 6777 attrs.add(key); 6778 } 6779 } 6780 item = item.left; 6781 } 6782 }; 6783 var cleanupYTextFormatting = (type) => { 6784 let res = 0; 6785 transact( 6786 /** @type {Doc} */ 6787 type.doc, 6788 (transaction) => { 6789 let start = ( 6790 /** @type {Item} */ 6791 type._start 6792 ); 6793 let end = type._start; 6794 let startAttributes = create(); 6795 const currentAttributes = copy(startAttributes); 6796 while (end) { 6797 if (end.deleted === false) { 6798 switch (end.content.constructor) { 6799 case ContentFormat: 6800 updateCurrentAttributes( 6801 currentAttributes, 6802 /** @type {ContentFormat} */ 6803 end.content 6804 ); 6805 break; 6806 default: 6807 res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); 6808 startAttributes = copy(currentAttributes); 6809 start = end; 6810 break; 6811 } 6812 } 6813 end = end.right; 6814 } 6815 } 6816 ); 6817 return res; 6818 }; 6819 var cleanupYTextAfterTransaction = (transaction) => { 6820 const needFullCleanup = /* @__PURE__ */ new Set(); 6821 const doc2 = transaction.doc; 6822 for (const [client, afterClock] of transaction.afterState.entries()) { 6823 const clock = transaction.beforeState.get(client) || 0; 6824 if (afterClock === clock) { 6825 continue; 6826 } 6827 iterateStructs( 6828 transaction, 6829 /** @type {Array<Item|GC>} */ 6830 doc2.store.clients.get(client), 6831 clock, 6832 afterClock, 6833 (item) => { 6834 if (!item.deleted && /** @type {Item} */ 6835 item.content.constructor === ContentFormat && item.constructor !== GC) { 6836 needFullCleanup.add( 6837 /** @type {any} */ 6838 item.parent 6839 ); 6840 } 6841 } 6842 ); 6843 } 6844 transact(doc2, (t) => { 6845 iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { 6846 if (item instanceof GC || !/** @type {YText} */ 6847 item.parent._hasFormatting || needFullCleanup.has( 6848 /** @type {YText} */ 6849 item.parent 6850 )) { 6851 return; 6852 } 6853 const parent = ( 6854 /** @type {YText} */ 6855 item.parent 6856 ); 6857 if (item.content.constructor === ContentFormat) { 6858 needFullCleanup.add(parent); 6859 } else { 6860 cleanupContextlessFormattingGap(t, item); 6861 } 6862 }); 6863 for (const yText of needFullCleanup) { 6864 cleanupYTextFormatting(yText); 6865 } 6866 }); 6867 }; 6868 var deleteText = (transaction, currPos, length2) => { 6869 const startLength = length2; 6870 const startAttrs = copy(currPos.currentAttributes); 6871 const start = currPos.right; 6872 while (length2 > 0 && currPos.right !== null) { 6873 if (currPos.right.deleted === false) { 6874 switch (currPos.right.content.constructor) { 6875 case ContentType: 6876 case ContentEmbed: 6877 case ContentString: 6878 if (length2 < currPos.right.length) { 6879 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); 6880 } 6881 length2 -= currPos.right.length; 6882 currPos.right.delete(transaction); 6883 break; 6884 } 6885 } 6886 currPos.forward(); 6887 } 6888 if (start) { 6889 cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); 6890 } 6891 const parent = ( 6892 /** @type {AbstractType<any>} */ 6893 /** @type {Item} */ 6894 (currPos.left || currPos.right).parent 6895 ); 6896 if (parent._searchMarker) { 6897 updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length2); 6898 } 6899 return currPos; 6900 }; 6901 var YTextEvent = class extends YEvent { 6902 /** 6903 * @param {YText} ytext 6904 * @param {Transaction} transaction 6905 * @param {Set<any>} subs The keys that changed 6906 */ 6907 constructor(ytext, transaction, subs) { 6908 super(ytext, transaction); 6909 this.childListChanged = false; 6910 this.keysChanged = /* @__PURE__ */ new Set(); 6911 subs.forEach((sub) => { 6912 if (sub === null) { 6913 this.childListChanged = true; 6914 } else { 6915 this.keysChanged.add(sub); 6916 } 6917 }); 6918 } 6919 /** 6920 * @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}>}} 6921 */ 6922 get changes() { 6923 if (this._changes === null) { 6924 const changes = { 6925 keys: this.keys, 6926 delta: this.delta, 6927 added: /* @__PURE__ */ new Set(), 6928 deleted: /* @__PURE__ */ new Set() 6929 }; 6930 this._changes = changes; 6931 } 6932 return ( 6933 /** @type {any} */ 6934 this._changes 6935 ); 6936 } 6937 /** 6938 * Compute the changes in the delta format. 6939 * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. 6940 * 6941 * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>} 6942 * 6943 * @public 6944 */ 6945 get delta() { 6946 if (this._delta === null) { 6947 const y = ( 6948 /** @type {Doc} */ 6949 this.target.doc 6950 ); 6951 const delta = []; 6952 transact(y, (transaction) => { 6953 const currentAttributes = /* @__PURE__ */ new Map(); 6954 const oldAttributes = /* @__PURE__ */ new Map(); 6955 let item = this.target._start; 6956 let action = null; 6957 const attributes = {}; 6958 let insert = ""; 6959 let retain = 0; 6960 let deleteLen = 0; 6961 const addOp = () => { 6962 if (action !== null) { 6963 let op = null; 6964 switch (action) { 6965 case "delete": 6966 if (deleteLen > 0) { 6967 op = { delete: deleteLen }; 6968 } 6969 deleteLen = 0; 6970 break; 6971 case "insert": 6972 if (typeof insert === "object" || insert.length > 0) { 6973 op = { insert }; 6974 if (currentAttributes.size > 0) { 6975 op.attributes = {}; 6976 currentAttributes.forEach((value, key) => { 6977 if (value !== null) { 6978 op.attributes[key] = value; 6979 } 6980 }); 6981 } 6982 } 6983 insert = ""; 6984 break; 6985 case "retain": 6986 if (retain > 0) { 6987 op = { retain }; 6988 if (!isEmpty(attributes)) { 6989 op.attributes = assign({}, attributes); 6990 } 6991 } 6992 retain = 0; 6993 break; 6994 } 6995 if (op) delta.push(op); 6996 action = null; 6997 } 6998 }; 6999 while (item !== null) { 7000 switch (item.content.constructor) { 7001 case ContentType: 7002 case ContentEmbed: 7003 if (this.adds(item)) { 7004 if (!this.deletes(item)) { 7005 addOp(); 7006 action = "insert"; 7007 insert = item.content.getContent()[0]; 7008 addOp(); 7009 } 7010 } else if (this.deletes(item)) { 7011 if (action !== "delete") { 7012 addOp(); 7013 action = "delete"; 7014 } 7015 deleteLen += 1; 7016 } else if (!item.deleted) { 7017 if (action !== "retain") { 7018 addOp(); 7019 action = "retain"; 7020 } 7021 retain += 1; 7022 } 7023 break; 7024 case ContentString: 7025 if (this.adds(item)) { 7026 if (!this.deletes(item)) { 7027 if (action !== "insert") { 7028 addOp(); 7029 action = "insert"; 7030 } 7031 insert += /** @type {ContentString} */ 7032 item.content.str; 7033 } 7034 } else if (this.deletes(item)) { 7035 if (action !== "delete") { 7036 addOp(); 7037 action = "delete"; 7038 } 7039 deleteLen += item.length; 7040 } else if (!item.deleted) { 7041 if (action !== "retain") { 7042 addOp(); 7043 action = "retain"; 7044 } 7045 retain += item.length; 7046 } 7047 break; 7048 case ContentFormat: { 7049 const { key, value } = ( 7050 /** @type {ContentFormat} */ 7051 item.content 7052 ); 7053 if (this.adds(item)) { 7054 if (!this.deletes(item)) { 7055 const curVal = currentAttributes.get(key) ?? null; 7056 if (!equalAttrs(curVal, value)) { 7057 if (action === "retain") { 7058 addOp(); 7059 } 7060 if (equalAttrs(value, oldAttributes.get(key) ?? null)) { 7061 delete attributes[key]; 7062 } else { 7063 attributes[key] = value; 7064 } 7065 } else if (value !== null) { 7066 item.delete(transaction); 7067 } 7068 } 7069 } else if (this.deletes(item)) { 7070 oldAttributes.set(key, value); 7071 const curVal = currentAttributes.get(key) ?? null; 7072 if (!equalAttrs(curVal, value)) { 7073 if (action === "retain") { 7074 addOp(); 7075 } 7076 attributes[key] = curVal; 7077 } 7078 } else if (!item.deleted) { 7079 oldAttributes.set(key, value); 7080 const attr = attributes[key]; 7081 if (attr !== void 0) { 7082 if (!equalAttrs(attr, value)) { 7083 if (action === "retain") { 7084 addOp(); 7085 } 7086 if (value === null) { 7087 delete attributes[key]; 7088 } else { 7089 attributes[key] = value; 7090 } 7091 } else if (attr !== null) { 7092 item.delete(transaction); 7093 } 7094 } 7095 } 7096 if (!item.deleted) { 7097 if (action === "insert") { 7098 addOp(); 7099 } 7100 updateCurrentAttributes( 7101 currentAttributes, 7102 /** @type {ContentFormat} */ 7103 item.content 7104 ); 7105 } 7106 break; 7107 } 7108 } 7109 item = item.right; 7110 } 7111 addOp(); 7112 while (delta.length > 0) { 7113 const lastOp = delta[delta.length - 1]; 7114 if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { 7115 delta.pop(); 7116 } else { 7117 break; 7118 } 7119 } 7120 }); 7121 this._delta = delta; 7122 } 7123 return ( 7124 /** @type {any} */ 7125 this._delta 7126 ); 7127 } 7128 }; 7129 var YText = class _YText extends AbstractType { 7130 /** 7131 * @param {String} [string] The initial value of the YText. 7132 */ 7133 constructor(string) { 7134 super(); 7135 this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; 7136 this._searchMarker = []; 7137 this._hasFormatting = false; 7138 } 7139 /** 7140 * Number of characters of this text type. 7141 * 7142 * @type {number} 7143 */ 7144 get length() { 7145 this.doc ?? warnPrematureAccess(); 7146 return this._length; 7147 } 7148 /** 7149 * @param {Doc} y 7150 * @param {Item} item 7151 */ 7152 _integrate(y, item) { 7153 super._integrate(y, item); 7154 try { 7155 this._pending.forEach((f) => f()); 7156 } catch (e) { 7157 console.error(e); 7158 } 7159 this._pending = null; 7160 } 7161 _copy() { 7162 return new _YText(); 7163 } 7164 /** 7165 * Makes a copy of this data type that can be included somewhere else. 7166 * 7167 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7168 * 7169 * @return {YText} 7170 */ 7171 clone() { 7172 const text2 = new _YText(); 7173 text2.applyDelta(this.toDelta()); 7174 return text2; 7175 } 7176 /** 7177 * Creates YTextEvent and calls observers. 7178 * 7179 * @param {Transaction} transaction 7180 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7181 */ 7182 _callObserver(transaction, parentSubs) { 7183 super._callObserver(transaction, parentSubs); 7184 const event = new YTextEvent(this, transaction, parentSubs); 7185 callTypeObservers(this, transaction, event); 7186 if (!transaction.local && this._hasFormatting) { 7187 transaction._needFormattingCleanup = true; 7188 } 7189 } 7190 /** 7191 * Returns the unformatted string representation of this YText type. 7192 * 7193 * @public 7194 */ 7195 toString() { 7196 this.doc ?? warnPrematureAccess(); 7197 let str = ""; 7198 let n = this._start; 7199 while (n !== null) { 7200 if (!n.deleted && n.countable && n.content.constructor === ContentString) { 7201 str += /** @type {ContentString} */ 7202 n.content.str; 7203 } 7204 n = n.right; 7205 } 7206 return str; 7207 } 7208 /** 7209 * Returns the unformatted string representation of this YText type. 7210 * 7211 * @return {string} 7212 * @public 7213 */ 7214 toJSON() { 7215 return this.toString(); 7216 } 7217 /** 7218 * Apply a {@link Delta} on this shared YText type. 7219 * 7220 * @param {Array<any>} delta The changes to apply on this element. 7221 * @param {object} opts 7222 * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. 7223 * 7224 * 7225 * @public 7226 */ 7227 applyDelta(delta, { sanitize = true } = {}) { 7228 if (this.doc !== null) { 7229 transact(this.doc, (transaction) => { 7230 const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); 7231 for (let i = 0; i < delta.length; i++) { 7232 const op = delta[i]; 7233 if (op.insert !== void 0) { 7234 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; 7235 if (typeof ins !== "string" || ins.length > 0) { 7236 insertText(transaction, this, currPos, ins, op.attributes || {}); 7237 } 7238 } else if (op.retain !== void 0) { 7239 formatText(transaction, this, currPos, op.retain, op.attributes || {}); 7240 } else if (op.delete !== void 0) { 7241 deleteText(transaction, currPos, op.delete); 7242 } 7243 } 7244 }); 7245 } else { 7246 this._pending.push(() => this.applyDelta(delta)); 7247 } 7248 } 7249 /** 7250 * Returns the Delta representation of this YText type. 7251 * 7252 * @param {Snapshot} [snapshot] 7253 * @param {Snapshot} [prevSnapshot] 7254 * @param {function('removed' | 'added', ID):any} [computeYChange] 7255 * @return {any} The Delta representation of this type. 7256 * 7257 * @public 7258 */ 7259 toDelta(snapshot2, prevSnapshot, computeYChange) { 7260 this.doc ?? warnPrematureAccess(); 7261 const ops = []; 7262 const currentAttributes = /* @__PURE__ */ new Map(); 7263 const doc2 = ( 7264 /** @type {Doc} */ 7265 this.doc 7266 ); 7267 let str = ""; 7268 let n = this._start; 7269 function packStr() { 7270 if (str.length > 0) { 7271 const attributes = {}; 7272 let addAttributes = false; 7273 currentAttributes.forEach((value, key) => { 7274 addAttributes = true; 7275 attributes[key] = value; 7276 }); 7277 const op = { insert: str }; 7278 if (addAttributes) { 7279 op.attributes = attributes; 7280 } 7281 ops.push(op); 7282 str = ""; 7283 } 7284 } 7285 const computeDelta = () => { 7286 while (n !== null) { 7287 if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { 7288 switch (n.content.constructor) { 7289 case ContentString: { 7290 const cur = currentAttributes.get("ychange"); 7291 if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { 7292 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { 7293 packStr(); 7294 currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); 7295 } 7296 } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { 7297 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { 7298 packStr(); 7299 currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); 7300 } 7301 } else if (cur !== void 0) { 7302 packStr(); 7303 currentAttributes.delete("ychange"); 7304 } 7305 str += /** @type {ContentString} */ 7306 n.content.str; 7307 break; 7308 } 7309 case ContentType: 7310 case ContentEmbed: { 7311 packStr(); 7312 const op = { 7313 insert: n.content.getContent()[0] 7314 }; 7315 if (currentAttributes.size > 0) { 7316 const attrs = ( 7317 /** @type {Object<string,any>} */ 7318 {} 7319 ); 7320 op.attributes = attrs; 7321 currentAttributes.forEach((value, key) => { 7322 attrs[key] = value; 7323 }); 7324 } 7325 ops.push(op); 7326 break; 7327 } 7328 case ContentFormat: 7329 if (isVisible(n, snapshot2)) { 7330 packStr(); 7331 updateCurrentAttributes( 7332 currentAttributes, 7333 /** @type {ContentFormat} */ 7334 n.content 7335 ); 7336 } 7337 break; 7338 } 7339 } 7340 n = n.right; 7341 } 7342 packStr(); 7343 }; 7344 if (snapshot2 || prevSnapshot) { 7345 transact(doc2, (transaction) => { 7346 if (snapshot2) { 7347 splitSnapshotAffectedStructs(transaction, snapshot2); 7348 } 7349 if (prevSnapshot) { 7350 splitSnapshotAffectedStructs(transaction, prevSnapshot); 7351 } 7352 computeDelta(); 7353 }, "cleanup"); 7354 } else { 7355 computeDelta(); 7356 } 7357 return ops; 7358 } 7359 /** 7360 * Insert text at a given index. 7361 * 7362 * @param {number} index The index at which to start inserting. 7363 * @param {String} text The text to insert at the specified position. 7364 * @param {TextAttributes} [attributes] Optionally define some formatting 7365 * information to apply on the inserted 7366 * Text. 7367 * @public 7368 */ 7369 insert(index, text2, attributes) { 7370 if (text2.length <= 0) { 7371 return; 7372 } 7373 const y = this.doc; 7374 if (y !== null) { 7375 transact(y, (transaction) => { 7376 const pos = findPosition(transaction, this, index, !attributes); 7377 if (!attributes) { 7378 attributes = {}; 7379 pos.currentAttributes.forEach((v, k) => { 7380 attributes[k] = v; 7381 }); 7382 } 7383 insertText(transaction, this, pos, text2, attributes); 7384 }); 7385 } else { 7386 this._pending.push(() => this.insert(index, text2, attributes)); 7387 } 7388 } 7389 /** 7390 * Inserts an embed at a index. 7391 * 7392 * @param {number} index The index to insert the embed at. 7393 * @param {Object | AbstractType<any>} embed The Object that represents the embed. 7394 * @param {TextAttributes} [attributes] Attribute information to apply on the 7395 * embed 7396 * 7397 * @public 7398 */ 7399 insertEmbed(index, embed, attributes) { 7400 const y = this.doc; 7401 if (y !== null) { 7402 transact(y, (transaction) => { 7403 const pos = findPosition(transaction, this, index, !attributes); 7404 insertText(transaction, this, pos, embed, attributes || {}); 7405 }); 7406 } else { 7407 this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); 7408 } 7409 } 7410 /** 7411 * Deletes text starting from an index. 7412 * 7413 * @param {number} index Index at which to start deleting. 7414 * @param {number} length The number of characters to remove. Defaults to 1. 7415 * 7416 * @public 7417 */ 7418 delete(index, length2) { 7419 if (length2 === 0) { 7420 return; 7421 } 7422 const y = this.doc; 7423 if (y !== null) { 7424 transact(y, (transaction) => { 7425 deleteText(transaction, findPosition(transaction, this, index, true), length2); 7426 }); 7427 } else { 7428 this._pending.push(() => this.delete(index, length2)); 7429 } 7430 } 7431 /** 7432 * Assigns properties to a range of text. 7433 * 7434 * @param {number} index The position where to start formatting. 7435 * @param {number} length The amount of characters to assign properties to. 7436 * @param {TextAttributes} attributes Attribute information to apply on the 7437 * text. 7438 * 7439 * @public 7440 */ 7441 format(index, length2, attributes) { 7442 if (length2 === 0) { 7443 return; 7444 } 7445 const y = this.doc; 7446 if (y !== null) { 7447 transact(y, (transaction) => { 7448 const pos = findPosition(transaction, this, index, false); 7449 if (pos.right === null) { 7450 return; 7451 } 7452 formatText(transaction, this, pos, length2, attributes); 7453 }); 7454 } else { 7455 this._pending.push(() => this.format(index, length2, attributes)); 7456 } 7457 } 7458 /** 7459 * Removes an attribute. 7460 * 7461 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7462 * 7463 * @param {String} attributeName The attribute name that is to be removed. 7464 * 7465 * @public 7466 */ 7467 removeAttribute(attributeName) { 7468 if (this.doc !== null) { 7469 transact(this.doc, (transaction) => { 7470 typeMapDelete(transaction, this, attributeName); 7471 }); 7472 } else { 7473 this._pending.push(() => this.removeAttribute(attributeName)); 7474 } 7475 } 7476 /** 7477 * Sets or updates an attribute. 7478 * 7479 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7480 * 7481 * @param {String} attributeName The attribute name that is to be set. 7482 * @param {any} attributeValue The attribute value that is to be set. 7483 * 7484 * @public 7485 */ 7486 setAttribute(attributeName, attributeValue) { 7487 if (this.doc !== null) { 7488 transact(this.doc, (transaction) => { 7489 typeMapSet(transaction, this, attributeName, attributeValue); 7490 }); 7491 } else { 7492 this._pending.push(() => this.setAttribute(attributeName, attributeValue)); 7493 } 7494 } 7495 /** 7496 * Returns an attribute value that belongs to the attribute name. 7497 * 7498 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7499 * 7500 * @param {String} attributeName The attribute name that identifies the 7501 * queried value. 7502 * @return {any} The queried attribute value. 7503 * 7504 * @public 7505 */ 7506 getAttribute(attributeName) { 7507 return ( 7508 /** @type {any} */ 7509 typeMapGet(this, attributeName) 7510 ); 7511 } 7512 /** 7513 * Returns all attribute name/value pairs in a JSON Object. 7514 * 7515 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7516 * 7517 * @return {Object<string, any>} A JSON Object that describes the attributes. 7518 * 7519 * @public 7520 */ 7521 getAttributes() { 7522 return typeMapGetAll(this); 7523 } 7524 /** 7525 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7526 */ 7527 _write(encoder) { 7528 encoder.writeTypeRef(YTextRefID); 7529 } 7530 }; 7531 var readYText = (_decoder) => new YText(); 7532 var YXmlTreeWalker = class { 7533 /** 7534 * @param {YXmlFragment | YXmlElement} root 7535 * @param {function(AbstractType<any>):boolean} [f] 7536 */ 7537 constructor(root, f = () => true) { 7538 this._filter = f; 7539 this._root = root; 7540 this._currentNode = /** @type {Item} */ 7541 root._start; 7542 this._firstCall = true; 7543 root.doc ?? warnPrematureAccess(); 7544 } 7545 [Symbol.iterator]() { 7546 return this; 7547 } 7548 /** 7549 * Get the next node. 7550 * 7551 * @return {IteratorResult<YXmlElement|YXmlText|YXmlHook>} The next node. 7552 * 7553 * @public 7554 */ 7555 next() { 7556 let n = this._currentNode; 7557 let type = n && n.content && /** @type {any} */ 7558 n.content.type; 7559 if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { 7560 do { 7561 type = /** @type {any} */ 7562 n.content.type; 7563 if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { 7564 n = type._start; 7565 } else { 7566 while (n !== null) { 7567 const nxt = n.next; 7568 if (nxt !== null) { 7569 n = nxt; 7570 break; 7571 } else if (n.parent === this._root) { 7572 n = null; 7573 } else { 7574 n = /** @type {AbstractType<any>} */ 7575 n.parent._item; 7576 } 7577 } 7578 } 7579 } while (n !== null && (n.deleted || !this._filter( 7580 /** @type {ContentType} */ 7581 n.content.type 7582 ))); 7583 } 7584 this._firstCall = false; 7585 if (n === null) { 7586 return { value: void 0, done: true }; 7587 } 7588 this._currentNode = n; 7589 return { value: ( 7590 /** @type {any} */ 7591 n.content.type 7592 ), done: false }; 7593 } 7594 }; 7595 var YXmlFragment = class _YXmlFragment extends AbstractType { 7596 constructor() { 7597 super(); 7598 this._prelimContent = []; 7599 } 7600 /** 7601 * @type {YXmlElement|YXmlText|null} 7602 */ 7603 get firstChild() { 7604 const first = this._first; 7605 return first ? first.content.getContent()[0] : null; 7606 } 7607 /** 7608 * Integrate this type into the Yjs instance. 7609 * 7610 * * Save this struct in the os 7611 * * This type is sent to other client 7612 * * Observer functions are fired 7613 * 7614 * @param {Doc} y The Yjs instance 7615 * @param {Item} item 7616 */ 7617 _integrate(y, item) { 7618 super._integrate(y, item); 7619 this.insert( 7620 0, 7621 /** @type {Array<any>} */ 7622 this._prelimContent 7623 ); 7624 this._prelimContent = null; 7625 } 7626 _copy() { 7627 return new _YXmlFragment(); 7628 } 7629 /** 7630 * Makes a copy of this data type that can be included somewhere else. 7631 * 7632 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7633 * 7634 * @return {YXmlFragment} 7635 */ 7636 clone() { 7637 const el = new _YXmlFragment(); 7638 el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); 7639 return el; 7640 } 7641 get length() { 7642 this.doc ?? warnPrematureAccess(); 7643 return this._prelimContent === null ? this._length : this._prelimContent.length; 7644 } 7645 /** 7646 * Create a subtree of childNodes. 7647 * 7648 * @example 7649 * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') 7650 * for (let node in walker) { 7651 * // `node` is a div node 7652 * nop(node) 7653 * } 7654 * 7655 * @param {function(AbstractType<any>):boolean} filter Function that is called on each child element and 7656 * returns a Boolean indicating whether the child 7657 * is to be included in the subtree. 7658 * @return {YXmlTreeWalker} A subtree and a position within it. 7659 * 7660 * @public 7661 */ 7662 createTreeWalker(filter) { 7663 return new YXmlTreeWalker(this, filter); 7664 } 7665 /** 7666 * Returns the first YXmlElement that matches the query. 7667 * Similar to DOM's {@link querySelector}. 7668 * 7669 * Query support: 7670 * - tagname 7671 * TODO: 7672 * - id 7673 * - attribute 7674 * 7675 * @param {CSS_Selector} query The query on the children. 7676 * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. 7677 * 7678 * @public 7679 */ 7680 querySelector(query) { 7681 query = query.toUpperCase(); 7682 const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); 7683 const next = iterator.next(); 7684 if (next.done) { 7685 return null; 7686 } else { 7687 return next.value; 7688 } 7689 } 7690 /** 7691 * Returns all YXmlElements that match the query. 7692 * Similar to Dom's {@link querySelectorAll}. 7693 * 7694 * @todo Does not yet support all queries. Currently only query by tagName. 7695 * 7696 * @param {CSS_Selector} query The query on the children 7697 * @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query. 7698 * 7699 * @public 7700 */ 7701 querySelectorAll(query) { 7702 query = query.toUpperCase(); 7703 return from(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); 7704 } 7705 /** 7706 * Creates YXmlEvent and calls observers. 7707 * 7708 * @param {Transaction} transaction 7709 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7710 */ 7711 _callObserver(transaction, parentSubs) { 7712 callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); 7713 } 7714 /** 7715 * Get the string representation of all the children of this YXmlFragment. 7716 * 7717 * @return {string} The string representation of all children. 7718 */ 7719 toString() { 7720 return typeListMap(this, (xml) => xml.toString()).join(""); 7721 } 7722 /** 7723 * @return {string} 7724 */ 7725 toJSON() { 7726 return this.toString(); 7727 } 7728 /** 7729 * Creates a Dom Element that mirrors this YXmlElement. 7730 * 7731 * @param {Document} [_document=document] The document object (you must define 7732 * this when calling this method in 7733 * nodejs) 7734 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 7735 * are presented in the DOM 7736 * @param {any} [binding] You should not set this property. This is 7737 * used if DomBinding wants to create a 7738 * association to the created DOM type. 7739 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 7740 * 7741 * @public 7742 */ 7743 toDOM(_document = document, hooks = {}, binding) { 7744 const fragment = _document.createDocumentFragment(); 7745 if (binding !== void 0) { 7746 binding._createAssociation(fragment, this); 7747 } 7748 typeListForEach(this, (xmlType) => { 7749 fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); 7750 }); 7751 return fragment; 7752 } 7753 /** 7754 * Inserts new content at an index. 7755 * 7756 * @example 7757 * // Insert character 'a' at position 0 7758 * xml.insert(0, [new Y.XmlText('text')]) 7759 * 7760 * @param {number} index The index to insert content at 7761 * @param {Array<YXmlElement|YXmlText>} content The array of content 7762 */ 7763 insert(index, content) { 7764 if (this.doc !== null) { 7765 transact(this.doc, (transaction) => { 7766 typeListInsertGenerics(transaction, this, index, content); 7767 }); 7768 } else { 7769 this._prelimContent.splice(index, 0, ...content); 7770 } 7771 } 7772 /** 7773 * Inserts new content at an index. 7774 * 7775 * @example 7776 * // Insert character 'a' at position 0 7777 * xml.insert(0, [new Y.XmlText('text')]) 7778 * 7779 * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at 7780 * @param {Array<YXmlElement|YXmlText>} content The array of content 7781 */ 7782 insertAfter(ref, content) { 7783 if (this.doc !== null) { 7784 transact(this.doc, (transaction) => { 7785 const refItem = ref && ref instanceof AbstractType ? ref._item : ref; 7786 typeListInsertGenericsAfter(transaction, this, refItem, content); 7787 }); 7788 } else { 7789 const pc = ( 7790 /** @type {Array<any>} */ 7791 this._prelimContent 7792 ); 7793 const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; 7794 if (index === 0 && ref !== null) { 7795 throw create3("Reference item not found"); 7796 } 7797 pc.splice(index, 0, ...content); 7798 } 7799 } 7800 /** 7801 * Deletes elements starting from an index. 7802 * 7803 * @param {number} index Index at which to start deleting elements 7804 * @param {number} [length=1] The number of elements to remove. Defaults to 1. 7805 */ 7806 delete(index, length2 = 1) { 7807 if (this.doc !== null) { 7808 transact(this.doc, (transaction) => { 7809 typeListDelete(transaction, this, index, length2); 7810 }); 7811 } else { 7812 this._prelimContent.splice(index, length2); 7813 } 7814 } 7815 /** 7816 * Transforms this YArray to a JavaScript Array. 7817 * 7818 * @return {Array<YXmlElement|YXmlText|YXmlHook>} 7819 */ 7820 toArray() { 7821 return typeListToArray(this); 7822 } 7823 /** 7824 * Appends content to this YArray. 7825 * 7826 * @param {Array<YXmlElement|YXmlText>} content Array of content to append. 7827 */ 7828 push(content) { 7829 this.insert(this.length, content); 7830 } 7831 /** 7832 * Prepends content to this YArray. 7833 * 7834 * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend. 7835 */ 7836 unshift(content) { 7837 this.insert(0, content); 7838 } 7839 /** 7840 * Returns the i-th element from a YArray. 7841 * 7842 * @param {number} index The index of the element to return from the YArray 7843 * @return {YXmlElement|YXmlText} 7844 */ 7845 get(index) { 7846 return typeListGet(this, index); 7847 } 7848 /** 7849 * Returns a portion of this YXmlFragment into a JavaScript Array selected 7850 * from start to end (end not included). 7851 * 7852 * @param {number} [start] 7853 * @param {number} [end] 7854 * @return {Array<YXmlElement|YXmlText>} 7855 */ 7856 slice(start = 0, end = this.length) { 7857 return typeListSlice(this, start, end); 7858 } 7859 /** 7860 * Executes a provided function on once on every child element. 7861 * 7862 * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. 7863 */ 7864 forEach(f) { 7865 typeListForEach(this, f); 7866 } 7867 /** 7868 * Transform the properties of this type to binary and write it to an 7869 * BinaryEncoder. 7870 * 7871 * This is called when this Item is sent to a remote peer. 7872 * 7873 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7874 */ 7875 _write(encoder) { 7876 encoder.writeTypeRef(YXmlFragmentRefID); 7877 } 7878 }; 7879 var readYXmlFragment = (_decoder) => new YXmlFragment(); 7880 var YXmlElement = class _YXmlElement extends YXmlFragment { 7881 constructor(nodeName = "UNDEFINED") { 7882 super(); 7883 this.nodeName = nodeName; 7884 this._prelimAttrs = /* @__PURE__ */ new Map(); 7885 } 7886 /** 7887 * @type {YXmlElement|YXmlText|null} 7888 */ 7889 get nextSibling() { 7890 const n = this._item ? this._item.next : null; 7891 return n ? ( 7892 /** @type {YXmlElement|YXmlText} */ 7893 /** @type {ContentType} */ 7894 n.content.type 7895 ) : null; 7896 } 7897 /** 7898 * @type {YXmlElement|YXmlText|null} 7899 */ 7900 get prevSibling() { 7901 const n = this._item ? this._item.prev : null; 7902 return n ? ( 7903 /** @type {YXmlElement|YXmlText} */ 7904 /** @type {ContentType} */ 7905 n.content.type 7906 ) : null; 7907 } 7908 /** 7909 * Integrate this type into the Yjs instance. 7910 * 7911 * * Save this struct in the os 7912 * * This type is sent to other client 7913 * * Observer functions are fired 7914 * 7915 * @param {Doc} y The Yjs instance 7916 * @param {Item} item 7917 */ 7918 _integrate(y, item) { 7919 super._integrate(y, item); 7920 /** @type {Map<string, any>} */ 7921 this._prelimAttrs.forEach((value, key) => { 7922 this.setAttribute(key, value); 7923 }); 7924 this._prelimAttrs = null; 7925 } 7926 /** 7927 * Creates an Item with the same effect as this Item (without position effect) 7928 * 7929 * @return {YXmlElement} 7930 */ 7931 _copy() { 7932 return new _YXmlElement(this.nodeName); 7933 } 7934 /** 7935 * Makes a copy of this data type that can be included somewhere else. 7936 * 7937 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7938 * 7939 * @return {YXmlElement<KV>} 7940 */ 7941 clone() { 7942 const el = new _YXmlElement(this.nodeName); 7943 const attrs = this.getAttributes(); 7944 forEach(attrs, (value, key) => { 7945 el.setAttribute( 7946 key, 7947 /** @type {any} */ 7948 value 7949 ); 7950 }); 7951 el.insert(0, this.toArray().map((v) => v instanceof AbstractType ? v.clone() : v)); 7952 return el; 7953 } 7954 /** 7955 * Returns the XML serialization of this YXmlElement. 7956 * The attributes are ordered by attribute-name, so you can easily use this 7957 * method to compare YXmlElements 7958 * 7959 * @return {string} The string representation of this type. 7960 * 7961 * @public 7962 */ 7963 toString() { 7964 const attrs = this.getAttributes(); 7965 const stringBuilder = []; 7966 const keys2 = []; 7967 for (const key in attrs) { 7968 keys2.push(key); 7969 } 7970 keys2.sort(); 7971 const keysLen = keys2.length; 7972 for (let i = 0; i < keysLen; i++) { 7973 const key = keys2[i]; 7974 stringBuilder.push(key + '="' + attrs[key] + '"'); 7975 } 7976 const nodeName = this.nodeName.toLocaleLowerCase(); 7977 const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; 7978 return `<$nodeName}$attrsString}>$super.toString()}</$nodeName}>`; 7979 } 7980 /** 7981 * Removes an attribute from this YXmlElement. 7982 * 7983 * @param {string} attributeName The attribute name that is to be removed. 7984 * 7985 * @public 7986 */ 7987 removeAttribute(attributeName) { 7988 if (this.doc !== null) { 7989 transact(this.doc, (transaction) => { 7990 typeMapDelete(transaction, this, attributeName); 7991 }); 7992 } else { 7993 this._prelimAttrs.delete(attributeName); 7994 } 7995 } 7996 /** 7997 * Sets or updates an attribute. 7998 * 7999 * @template {keyof KV & string} KEY 8000 * 8001 * @param {KEY} attributeName The attribute name that is to be set. 8002 * @param {KV[KEY]} attributeValue The attribute value that is to be set. 8003 * 8004 * @public 8005 */ 8006 setAttribute(attributeName, attributeValue) { 8007 if (this.doc !== null) { 8008 transact(this.doc, (transaction) => { 8009 typeMapSet(transaction, this, attributeName, attributeValue); 8010 }); 8011 } else { 8012 this._prelimAttrs.set(attributeName, attributeValue); 8013 } 8014 } 8015 /** 8016 * Returns an attribute value that belongs to the attribute name. 8017 * 8018 * @template {keyof KV & string} KEY 8019 * 8020 * @param {KEY} attributeName The attribute name that identifies the 8021 * queried value. 8022 * @return {KV[KEY]|undefined} The queried attribute value. 8023 * 8024 * @public 8025 */ 8026 getAttribute(attributeName) { 8027 return ( 8028 /** @type {any} */ 8029 typeMapGet(this, attributeName) 8030 ); 8031 } 8032 /** 8033 * Returns whether an attribute exists 8034 * 8035 * @param {string} attributeName The attribute name to check for existence. 8036 * @return {boolean} whether the attribute exists. 8037 * 8038 * @public 8039 */ 8040 hasAttribute(attributeName) { 8041 return ( 8042 /** @type {any} */ 8043 typeMapHas(this, attributeName) 8044 ); 8045 } 8046 /** 8047 * Returns all attribute name/value pairs in a JSON Object. 8048 * 8049 * @param {Snapshot} [snapshot] 8050 * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes. 8051 * 8052 * @public 8053 */ 8054 getAttributes(snapshot2) { 8055 return ( 8056 /** @type {any} */ 8057 snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) 8058 ); 8059 } 8060 /** 8061 * Creates a Dom Element that mirrors this YXmlElement. 8062 * 8063 * @param {Document} [_document=document] The document object (you must define 8064 * this when calling this method in 8065 * nodejs) 8066 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 8067 * are presented in the DOM 8068 * @param {any} [binding] You should not set this property. This is 8069 * used if DomBinding wants to create a 8070 * association to the created DOM type. 8071 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8072 * 8073 * @public 8074 */ 8075 toDOM(_document = document, hooks = {}, binding) { 8076 const dom = _document.createElement(this.nodeName); 8077 const attrs = this.getAttributes(); 8078 for (const key in attrs) { 8079 const value = attrs[key]; 8080 if (typeof value === "string") { 8081 dom.setAttribute(key, value); 8082 } 8083 } 8084 typeListForEach(this, (yxml) => { 8085 dom.appendChild(yxml.toDOM(_document, hooks, binding)); 8086 }); 8087 if (binding !== void 0) { 8088 binding._createAssociation(dom, this); 8089 } 8090 return dom; 8091 } 8092 /** 8093 * Transform the properties of this type to binary and write it to an 8094 * BinaryEncoder. 8095 * 8096 * This is called when this Item is sent to a remote peer. 8097 * 8098 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8099 */ 8100 _write(encoder) { 8101 encoder.writeTypeRef(YXmlElementRefID); 8102 encoder.writeKey(this.nodeName); 8103 } 8104 }; 8105 var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); 8106 var YXmlEvent = class extends YEvent { 8107 /** 8108 * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. 8109 * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the 8110 * child list changed. 8111 * @param {Transaction} transaction The transaction instance with which the 8112 * change was created. 8113 */ 8114 constructor(target, subs, transaction) { 8115 super(target, transaction); 8116 this.childListChanged = false; 8117 this.attributesChanged = /* @__PURE__ */ new Set(); 8118 subs.forEach((sub) => { 8119 if (sub === null) { 8120 this.childListChanged = true; 8121 } else { 8122 this.attributesChanged.add(sub); 8123 } 8124 }); 8125 } 8126 }; 8127 var YXmlHook = class _YXmlHook extends YMap { 8128 /** 8129 * @param {string} hookName nodeName of the Dom Node. 8130 */ 8131 constructor(hookName) { 8132 super(); 8133 this.hookName = hookName; 8134 } 8135 /** 8136 * Creates an Item with the same effect as this Item (without position effect) 8137 */ 8138 _copy() { 8139 return new _YXmlHook(this.hookName); 8140 } 8141 /** 8142 * Makes a copy of this data type that can be included somewhere else. 8143 * 8144 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8145 * 8146 * @return {YXmlHook} 8147 */ 8148 clone() { 8149 const el = new _YXmlHook(this.hookName); 8150 this.forEach((value, key) => { 8151 el.set(key, value); 8152 }); 8153 return el; 8154 } 8155 /** 8156 * Creates a Dom Element that mirrors this YXmlElement. 8157 * 8158 * @param {Document} [_document=document] The document object (you must define 8159 * this when calling this method in 8160 * nodejs) 8161 * @param {Object.<string, any>} [hooks] Optional property to customize how hooks 8162 * are presented in the DOM 8163 * @param {any} [binding] You should not set this property. This is 8164 * used if DomBinding wants to create a 8165 * association to the created DOM type 8166 * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8167 * 8168 * @public 8169 */ 8170 toDOM(_document = document, hooks = {}, binding) { 8171 const hook = hooks[this.hookName]; 8172 let dom; 8173 if (hook !== void 0) { 8174 dom = hook.createDom(this); 8175 } else { 8176 dom = document.createElement(this.hookName); 8177 } 8178 dom.setAttribute("data-yjs-hook", this.hookName); 8179 if (binding !== void 0) { 8180 binding._createAssociation(dom, this); 8181 } 8182 return dom; 8183 } 8184 /** 8185 * Transform the properties of this type to binary and write it to an 8186 * BinaryEncoder. 8187 * 8188 * This is called when this Item is sent to a remote peer. 8189 * 8190 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8191 */ 8192 _write(encoder) { 8193 encoder.writeTypeRef(YXmlHookRefID); 8194 encoder.writeKey(this.hookName); 8195 } 8196 }; 8197 var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); 8198 var YXmlText = class _YXmlText extends YText { 8199 /** 8200 * @type {YXmlElement|YXmlText|null} 8201 */ 8202 get nextSibling() { 8203 const n = this._item ? this._item.next : null; 8204 return n ? ( 8205 /** @type {YXmlElement|YXmlText} */ 8206 /** @type {ContentType} */ 8207 n.content.type 8208 ) : null; 8209 } 8210 /** 8211 * @type {YXmlElement|YXmlText|null} 8212 */ 8213 get prevSibling() { 8214 const n = this._item ? this._item.prev : null; 8215 return n ? ( 8216 /** @type {YXmlElement|YXmlText} */ 8217 /** @type {ContentType} */ 8218 n.content.type 8219 ) : null; 8220 } 8221 _copy() { 8222 return new _YXmlText(); 8223 } 8224 /** 8225 * Makes a copy of this data type that can be included somewhere else. 8226 * 8227 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8228 * 8229 * @return {YXmlText} 8230 */ 8231 clone() { 8232 const text2 = new _YXmlText(); 8233 text2.applyDelta(this.toDelta()); 8234 return text2; 8235 } 8236 /** 8237 * Creates a Dom Element that mirrors this YXmlText. 8238 * 8239 * @param {Document} [_document=document] The document object (you must define 8240 * this when calling this method in 8241 * nodejs) 8242 * @param {Object<string, any>} [hooks] Optional property to customize how hooks 8243 * are presented in the DOM 8244 * @param {any} [binding] You should not set this property. This is 8245 * used if DomBinding wants to create a 8246 * association to the created DOM type. 8247 * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8248 * 8249 * @public 8250 */ 8251 toDOM(_document = document, hooks, binding) { 8252 const dom = _document.createTextNode(this.toString()); 8253 if (binding !== void 0) { 8254 binding._createAssociation(dom, this); 8255 } 8256 return dom; 8257 } 8258 toString() { 8259 return this.toDelta().map((delta) => { 8260 const nestedNodes = []; 8261 for (const nodeName in delta.attributes) { 8262 const attrs = []; 8263 for (const key in delta.attributes[nodeName]) { 8264 attrs.push({ key, value: delta.attributes[nodeName][key] }); 8265 } 8266 attrs.sort((a, b) => a.key < b.key ? -1 : 1); 8267 nestedNodes.push({ nodeName, attrs }); 8268 } 8269 nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1); 8270 let str = ""; 8271 for (let i = 0; i < nestedNodes.length; i++) { 8272 const node = nestedNodes[i]; 8273 str += `<$node.nodeName}`; 8274 for (let j = 0; j < node.attrs.length; j++) { 8275 const attr = node.attrs[j]; 8276 str += ` $attr.key}="$attr.value}"`; 8277 } 8278 str += ">"; 8279 } 8280 str += delta.insert; 8281 for (let i = nestedNodes.length - 1; i >= 0; i--) { 8282 str += `</$nestedNodes[i].nodeName}>`; 8283 } 8284 return str; 8285 }).join(""); 8286 } 8287 /** 8288 * @return {string} 8289 */ 8290 toJSON() { 8291 return this.toString(); 8292 } 8293 /** 8294 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8295 */ 8296 _write(encoder) { 8297 encoder.writeTypeRef(YXmlTextRefID); 8298 } 8299 }; 8300 var readYXmlText = (decoder) => new YXmlText(); 8301 var AbstractStruct = class { 8302 /** 8303 * @param {ID} id 8304 * @param {number} length 8305 */ 8306 constructor(id2, length2) { 8307 this.id = id2; 8308 this.length = length2; 8309 } 8310 /** 8311 * @type {boolean} 8312 */ 8313 get deleted() { 8314 throw methodUnimplemented(); 8315 } 8316 /** 8317 * Merge this struct with the item to the right. 8318 * This method is already assuming that `this.id.clock + this.length === this.id.clock`. 8319 * Also this method does *not* remove right from StructStore! 8320 * @param {AbstractStruct} right 8321 * @return {boolean} whether this merged with right 8322 */ 8323 mergeWith(right) { 8324 return false; 8325 } 8326 /** 8327 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8328 * @param {number} offset 8329 * @param {number} encodingRef 8330 */ 8331 write(encoder, offset, encodingRef) { 8332 throw methodUnimplemented(); 8333 } 8334 /** 8335 * @param {Transaction} transaction 8336 * @param {number} offset 8337 */ 8338 integrate(transaction, offset) { 8339 throw methodUnimplemented(); 8340 } 8341 }; 8342 var structGCRefNumber = 0; 8343 var GC = class extends AbstractStruct { 8344 get deleted() { 8345 return true; 8346 } 8347 delete() { 8348 } 8349 /** 8350 * @param {GC} right 8351 * @return {boolean} 8352 */ 8353 mergeWith(right) { 8354 if (this.constructor !== right.constructor) { 8355 return false; 8356 } 8357 this.length += right.length; 8358 return true; 8359 } 8360 /** 8361 * @param {Transaction} transaction 8362 * @param {number} offset 8363 */ 8364 integrate(transaction, offset) { 8365 if (offset > 0) { 8366 this.id.clock += offset; 8367 this.length -= offset; 8368 } 8369 addStruct(transaction.doc.store, this); 8370 } 8371 /** 8372 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8373 * @param {number} offset 8374 */ 8375 write(encoder, offset) { 8376 encoder.writeInfo(structGCRefNumber); 8377 encoder.writeLen(this.length - offset); 8378 } 8379 /** 8380 * @param {Transaction} transaction 8381 * @param {StructStore} store 8382 * @return {null | number} 8383 */ 8384 getMissing(transaction, store) { 8385 return null; 8386 } 8387 }; 8388 var ContentBinary = class _ContentBinary { 8389 /** 8390 * @param {Uint8Array} content 8391 */ 8392 constructor(content) { 8393 this.content = content; 8394 } 8395 /** 8396 * @return {number} 8397 */ 8398 getLength() { 8399 return 1; 8400 } 8401 /** 8402 * @return {Array<any>} 8403 */ 8404 getContent() { 8405 return [this.content]; 8406 } 8407 /** 8408 * @return {boolean} 8409 */ 8410 isCountable() { 8411 return true; 8412 } 8413 /** 8414 * @return {ContentBinary} 8415 */ 8416 copy() { 8417 return new _ContentBinary(this.content); 8418 } 8419 /** 8420 * @param {number} offset 8421 * @return {ContentBinary} 8422 */ 8423 splice(offset) { 8424 throw methodUnimplemented(); 8425 } 8426 /** 8427 * @param {ContentBinary} right 8428 * @return {boolean} 8429 */ 8430 mergeWith(right) { 8431 return false; 8432 } 8433 /** 8434 * @param {Transaction} transaction 8435 * @param {Item} item 8436 */ 8437 integrate(transaction, item) { 8438 } 8439 /** 8440 * @param {Transaction} transaction 8441 */ 8442 delete(transaction) { 8443 } 8444 /** 8445 * @param {StructStore} store 8446 */ 8447 gc(store) { 8448 } 8449 /** 8450 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8451 * @param {number} offset 8452 */ 8453 write(encoder, offset) { 8454 encoder.writeBuf(this.content); 8455 } 8456 /** 8457 * @return {number} 8458 */ 8459 getRef() { 8460 return 3; 8461 } 8462 }; 8463 var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); 8464 var ContentDeleted = class _ContentDeleted { 8465 /** 8466 * @param {number} len 8467 */ 8468 constructor(len) { 8469 this.len = len; 8470 } 8471 /** 8472 * @return {number} 8473 */ 8474 getLength() { 8475 return this.len; 8476 } 8477 /** 8478 * @return {Array<any>} 8479 */ 8480 getContent() { 8481 return []; 8482 } 8483 /** 8484 * @return {boolean} 8485 */ 8486 isCountable() { 8487 return false; 8488 } 8489 /** 8490 * @return {ContentDeleted} 8491 */ 8492 copy() { 8493 return new _ContentDeleted(this.len); 8494 } 8495 /** 8496 * @param {number} offset 8497 * @return {ContentDeleted} 8498 */ 8499 splice(offset) { 8500 const right = new _ContentDeleted(this.len - offset); 8501 this.len = offset; 8502 return right; 8503 } 8504 /** 8505 * @param {ContentDeleted} right 8506 * @return {boolean} 8507 */ 8508 mergeWith(right) { 8509 this.len += right.len; 8510 return true; 8511 } 8512 /** 8513 * @param {Transaction} transaction 8514 * @param {Item} item 8515 */ 8516 integrate(transaction, item) { 8517 addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); 8518 item.markDeleted(); 8519 } 8520 /** 8521 * @param {Transaction} transaction 8522 */ 8523 delete(transaction) { 8524 } 8525 /** 8526 * @param {StructStore} store 8527 */ 8528 gc(store) { 8529 } 8530 /** 8531 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8532 * @param {number} offset 8533 */ 8534 write(encoder, offset) { 8535 encoder.writeLen(this.len - offset); 8536 } 8537 /** 8538 * @return {number} 8539 */ 8540 getRef() { 8541 return 1; 8542 } 8543 }; 8544 var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); 8545 var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); 8546 var ContentDoc = class _ContentDoc { 8547 /** 8548 * @param {Doc} doc 8549 */ 8550 constructor(doc2) { 8551 if (doc2._item) { 8552 console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); 8553 } 8554 this.doc = doc2; 8555 const opts = {}; 8556 this.opts = opts; 8557 if (!doc2.gc) { 8558 opts.gc = false; 8559 } 8560 if (doc2.autoLoad) { 8561 opts.autoLoad = true; 8562 } 8563 if (doc2.meta !== null) { 8564 opts.meta = doc2.meta; 8565 } 8566 } 8567 /** 8568 * @return {number} 8569 */ 8570 getLength() { 8571 return 1; 8572 } 8573 /** 8574 * @return {Array<any>} 8575 */ 8576 getContent() { 8577 return [this.doc]; 8578 } 8579 /** 8580 * @return {boolean} 8581 */ 8582 isCountable() { 8583 return true; 8584 } 8585 /** 8586 * @return {ContentDoc} 8587 */ 8588 copy() { 8589 return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); 8590 } 8591 /** 8592 * @param {number} offset 8593 * @return {ContentDoc} 8594 */ 8595 splice(offset) { 8596 throw methodUnimplemented(); 8597 } 8598 /** 8599 * @param {ContentDoc} right 8600 * @return {boolean} 8601 */ 8602 mergeWith(right) { 8603 return false; 8604 } 8605 /** 8606 * @param {Transaction} transaction 8607 * @param {Item} item 8608 */ 8609 integrate(transaction, item) { 8610 this.doc._item = item; 8611 transaction.subdocsAdded.add(this.doc); 8612 if (this.doc.shouldLoad) { 8613 transaction.subdocsLoaded.add(this.doc); 8614 } 8615 } 8616 /** 8617 * @param {Transaction} transaction 8618 */ 8619 delete(transaction) { 8620 if (transaction.subdocsAdded.has(this.doc)) { 8621 transaction.subdocsAdded.delete(this.doc); 8622 } else { 8623 transaction.subdocsRemoved.add(this.doc); 8624 } 8625 } 8626 /** 8627 * @param {StructStore} store 8628 */ 8629 gc(store) { 8630 } 8631 /** 8632 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8633 * @param {number} offset 8634 */ 8635 write(encoder, offset) { 8636 encoder.writeString(this.doc.guid); 8637 encoder.writeAny(this.opts); 8638 } 8639 /** 8640 * @return {number} 8641 */ 8642 getRef() { 8643 return 9; 8644 } 8645 }; 8646 var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); 8647 var ContentEmbed = class _ContentEmbed { 8648 /** 8649 * @param {Object} embed 8650 */ 8651 constructor(embed) { 8652 this.embed = embed; 8653 } 8654 /** 8655 * @return {number} 8656 */ 8657 getLength() { 8658 return 1; 8659 } 8660 /** 8661 * @return {Array<any>} 8662 */ 8663 getContent() { 8664 return [this.embed]; 8665 } 8666 /** 8667 * @return {boolean} 8668 */ 8669 isCountable() { 8670 return true; 8671 } 8672 /** 8673 * @return {ContentEmbed} 8674 */ 8675 copy() { 8676 return new _ContentEmbed(this.embed); 8677 } 8678 /** 8679 * @param {number} offset 8680 * @return {ContentEmbed} 8681 */ 8682 splice(offset) { 8683 throw methodUnimplemented(); 8684 } 8685 /** 8686 * @param {ContentEmbed} right 8687 * @return {boolean} 8688 */ 8689 mergeWith(right) { 8690 return false; 8691 } 8692 /** 8693 * @param {Transaction} transaction 8694 * @param {Item} item 8695 */ 8696 integrate(transaction, item) { 8697 } 8698 /** 8699 * @param {Transaction} transaction 8700 */ 8701 delete(transaction) { 8702 } 8703 /** 8704 * @param {StructStore} store 8705 */ 8706 gc(store) { 8707 } 8708 /** 8709 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8710 * @param {number} offset 8711 */ 8712 write(encoder, offset) { 8713 encoder.writeJSON(this.embed); 8714 } 8715 /** 8716 * @return {number} 8717 */ 8718 getRef() { 8719 return 5; 8720 } 8721 }; 8722 var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); 8723 var ContentFormat = class _ContentFormat { 8724 /** 8725 * @param {string} key 8726 * @param {Object} value 8727 */ 8728 constructor(key, value) { 8729 this.key = key; 8730 this.value = value; 8731 } 8732 /** 8733 * @return {number} 8734 */ 8735 getLength() { 8736 return 1; 8737 } 8738 /** 8739 * @return {Array<any>} 8740 */ 8741 getContent() { 8742 return []; 8743 } 8744 /** 8745 * @return {boolean} 8746 */ 8747 isCountable() { 8748 return false; 8749 } 8750 /** 8751 * @return {ContentFormat} 8752 */ 8753 copy() { 8754 return new _ContentFormat(this.key, this.value); 8755 } 8756 /** 8757 * @param {number} _offset 8758 * @return {ContentFormat} 8759 */ 8760 splice(_offset) { 8761 throw methodUnimplemented(); 8762 } 8763 /** 8764 * @param {ContentFormat} _right 8765 * @return {boolean} 8766 */ 8767 mergeWith(_right) { 8768 return false; 8769 } 8770 /** 8771 * @param {Transaction} _transaction 8772 * @param {Item} item 8773 */ 8774 integrate(_transaction, item) { 8775 const p = ( 8776 /** @type {YText} */ 8777 item.parent 8778 ); 8779 p._searchMarker = null; 8780 p._hasFormatting = true; 8781 } 8782 /** 8783 * @param {Transaction} transaction 8784 */ 8785 delete(transaction) { 8786 } 8787 /** 8788 * @param {StructStore} store 8789 */ 8790 gc(store) { 8791 } 8792 /** 8793 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8794 * @param {number} offset 8795 */ 8796 write(encoder, offset) { 8797 encoder.writeKey(this.key); 8798 encoder.writeJSON(this.value); 8799 } 8800 /** 8801 * @return {number} 8802 */ 8803 getRef() { 8804 return 6; 8805 } 8806 }; 8807 var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); 8808 var ContentJSON = class _ContentJSON { 8809 /** 8810 * @param {Array<any>} arr 8811 */ 8812 constructor(arr) { 8813 this.arr = arr; 8814 } 8815 /** 8816 * @return {number} 8817 */ 8818 getLength() { 8819 return this.arr.length; 8820 } 8821 /** 8822 * @return {Array<any>} 8823 */ 8824 getContent() { 8825 return this.arr; 8826 } 8827 /** 8828 * @return {boolean} 8829 */ 8830 isCountable() { 8831 return true; 8832 } 8833 /** 8834 * @return {ContentJSON} 8835 */ 8836 copy() { 8837 return new _ContentJSON(this.arr); 8838 } 8839 /** 8840 * @param {number} offset 8841 * @return {ContentJSON} 8842 */ 8843 splice(offset) { 8844 const right = new _ContentJSON(this.arr.slice(offset)); 8845 this.arr = this.arr.slice(0, offset); 8846 return right; 8847 } 8848 /** 8849 * @param {ContentJSON} right 8850 * @return {boolean} 8851 */ 8852 mergeWith(right) { 8853 this.arr = this.arr.concat(right.arr); 8854 return true; 8855 } 8856 /** 8857 * @param {Transaction} transaction 8858 * @param {Item} item 8859 */ 8860 integrate(transaction, item) { 8861 } 8862 /** 8863 * @param {Transaction} transaction 8864 */ 8865 delete(transaction) { 8866 } 8867 /** 8868 * @param {StructStore} store 8869 */ 8870 gc(store) { 8871 } 8872 /** 8873 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8874 * @param {number} offset 8875 */ 8876 write(encoder, offset) { 8877 const len = this.arr.length; 8878 encoder.writeLen(len - offset); 8879 for (let i = offset; i < len; i++) { 8880 const c = this.arr[i]; 8881 encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); 8882 } 8883 } 8884 /** 8885 * @return {number} 8886 */ 8887 getRef() { 8888 return 2; 8889 } 8890 }; 8891 var readContentJSON = (decoder) => { 8892 const len = decoder.readLen(); 8893 const cs = []; 8894 for (let i = 0; i < len; i++) { 8895 const c = decoder.readString(); 8896 if (c === "undefined") { 8897 cs.push(void 0); 8898 } else { 8899 cs.push(JSON.parse(c)); 8900 } 8901 } 8902 return new ContentJSON(cs); 8903 }; 8904 var isDevMode = getVariable("node_env") === "development"; 8905 var ContentAny = class _ContentAny { 8906 /** 8907 * @param {Array<any>} arr 8908 */ 8909 constructor(arr) { 8910 this.arr = arr; 8911 isDevMode && deepFreeze(arr); 8912 } 8913 /** 8914 * @return {number} 8915 */ 8916 getLength() { 8917 return this.arr.length; 8918 } 8919 /** 8920 * @return {Array<any>} 8921 */ 8922 getContent() { 8923 return this.arr; 8924 } 8925 /** 8926 * @return {boolean} 8927 */ 8928 isCountable() { 8929 return true; 8930 } 8931 /** 8932 * @return {ContentAny} 8933 */ 8934 copy() { 8935 return new _ContentAny(this.arr); 8936 } 8937 /** 8938 * @param {number} offset 8939 * @return {ContentAny} 8940 */ 8941 splice(offset) { 8942 const right = new _ContentAny(this.arr.slice(offset)); 8943 this.arr = this.arr.slice(0, offset); 8944 return right; 8945 } 8946 /** 8947 * @param {ContentAny} right 8948 * @return {boolean} 8949 */ 8950 mergeWith(right) { 8951 this.arr = this.arr.concat(right.arr); 8952 return true; 8953 } 8954 /** 8955 * @param {Transaction} transaction 8956 * @param {Item} item 8957 */ 8958 integrate(transaction, item) { 8959 } 8960 /** 8961 * @param {Transaction} transaction 8962 */ 8963 delete(transaction) { 8964 } 8965 /** 8966 * @param {StructStore} store 8967 */ 8968 gc(store) { 8969 } 8970 /** 8971 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8972 * @param {number} offset 8973 */ 8974 write(encoder, offset) { 8975 const len = this.arr.length; 8976 encoder.writeLen(len - offset); 8977 for (let i = offset; i < len; i++) { 8978 const c = this.arr[i]; 8979 encoder.writeAny(c); 8980 } 8981 } 8982 /** 8983 * @return {number} 8984 */ 8985 getRef() { 8986 return 8; 8987 } 8988 }; 8989 var readContentAny = (decoder) => { 8990 const len = decoder.readLen(); 8991 const cs = []; 8992 for (let i = 0; i < len; i++) { 8993 cs.push(decoder.readAny()); 8994 } 8995 return new ContentAny(cs); 8996 }; 8997 var ContentString = class _ContentString { 8998 /** 8999 * @param {string} str 9000 */ 9001 constructor(str) { 9002 this.str = str; 9003 } 9004 /** 9005 * @return {number} 9006 */ 9007 getLength() { 9008 return this.str.length; 9009 } 9010 /** 9011 * @return {Array<any>} 9012 */ 9013 getContent() { 9014 return this.str.split(""); 9015 } 9016 /** 9017 * @return {boolean} 9018 */ 9019 isCountable() { 9020 return true; 9021 } 9022 /** 9023 * @return {ContentString} 9024 */ 9025 copy() { 9026 return new _ContentString(this.str); 9027 } 9028 /** 9029 * @param {number} offset 9030 * @return {ContentString} 9031 */ 9032 splice(offset) { 9033 const right = new _ContentString(this.str.slice(offset)); 9034 this.str = this.str.slice(0, offset); 9035 const firstCharCode = this.str.charCodeAt(offset - 1); 9036 if (firstCharCode >= 55296 && firstCharCode <= 56319) { 9037 this.str = this.str.slice(0, offset - 1) + "\uFFFD"; 9038 right.str = "\uFFFD" + right.str.slice(1); 9039 } 9040 return right; 9041 } 9042 /** 9043 * @param {ContentString} right 9044 * @return {boolean} 9045 */ 9046 mergeWith(right) { 9047 this.str += right.str; 9048 return true; 9049 } 9050 /** 9051 * @param {Transaction} transaction 9052 * @param {Item} item 9053 */ 9054 integrate(transaction, item) { 9055 } 9056 /** 9057 * @param {Transaction} transaction 9058 */ 9059 delete(transaction) { 9060 } 9061 /** 9062 * @param {StructStore} store 9063 */ 9064 gc(store) { 9065 } 9066 /** 9067 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9068 * @param {number} offset 9069 */ 9070 write(encoder, offset) { 9071 encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); 9072 } 9073 /** 9074 * @return {number} 9075 */ 9076 getRef() { 9077 return 4; 9078 } 9079 }; 9080 var readContentString = (decoder) => new ContentString(decoder.readString()); 9081 var typeRefs = [ 9082 readYArray, 9083 readYMap, 9084 readYText, 9085 readYXmlElement, 9086 readYXmlFragment, 9087 readYXmlHook, 9088 readYXmlText 9089 ]; 9090 var YArrayRefID = 0; 9091 var YMapRefID = 1; 9092 var YTextRefID = 2; 9093 var YXmlElementRefID = 3; 9094 var YXmlFragmentRefID = 4; 9095 var YXmlHookRefID = 5; 9096 var YXmlTextRefID = 6; 9097 var ContentType = class _ContentType { 9098 /** 9099 * @param {AbstractType<any>} type 9100 */ 9101 constructor(type) { 9102 this.type = type; 9103 } 9104 /** 9105 * @return {number} 9106 */ 9107 getLength() { 9108 return 1; 9109 } 9110 /** 9111 * @return {Array<any>} 9112 */ 9113 getContent() { 9114 return [this.type]; 9115 } 9116 /** 9117 * @return {boolean} 9118 */ 9119 isCountable() { 9120 return true; 9121 } 9122 /** 9123 * @return {ContentType} 9124 */ 9125 copy() { 9126 return new _ContentType(this.type._copy()); 9127 } 9128 /** 9129 * @param {number} offset 9130 * @return {ContentType} 9131 */ 9132 splice(offset) { 9133 throw methodUnimplemented(); 9134 } 9135 /** 9136 * @param {ContentType} right 9137 * @return {boolean} 9138 */ 9139 mergeWith(right) { 9140 return false; 9141 } 9142 /** 9143 * @param {Transaction} transaction 9144 * @param {Item} item 9145 */ 9146 integrate(transaction, item) { 9147 this.type._integrate(transaction.doc, item); 9148 } 9149 /** 9150 * @param {Transaction} transaction 9151 */ 9152 delete(transaction) { 9153 let item = this.type._start; 9154 while (item !== null) { 9155 if (!item.deleted) { 9156 item.delete(transaction); 9157 } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { 9158 transaction._mergeStructs.push(item); 9159 } 9160 item = item.right; 9161 } 9162 this.type._map.forEach((item2) => { 9163 if (!item2.deleted) { 9164 item2.delete(transaction); 9165 } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { 9166 transaction._mergeStructs.push(item2); 9167 } 9168 }); 9169 transaction.changed.delete(this.type); 9170 } 9171 /** 9172 * @param {StructStore} store 9173 */ 9174 gc(store) { 9175 let item = this.type._start; 9176 while (item !== null) { 9177 item.gc(store, true); 9178 item = item.right; 9179 } 9180 this.type._start = null; 9181 this.type._map.forEach( 9182 /** @param {Item | null} item */ 9183 (item2) => { 9184 while (item2 !== null) { 9185 item2.gc(store, true); 9186 item2 = item2.left; 9187 } 9188 } 9189 ); 9190 this.type._map = /* @__PURE__ */ new Map(); 9191 } 9192 /** 9193 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9194 * @param {number} offset 9195 */ 9196 write(encoder, offset) { 9197 this.type._write(encoder); 9198 } 9199 /** 9200 * @return {number} 9201 */ 9202 getRef() { 9203 return 7; 9204 } 9205 }; 9206 var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); 9207 var followRedone = (store, id2) => { 9208 let nextID = id2; 9209 let diff = 0; 9210 let item; 9211 do { 9212 if (diff > 0) { 9213 nextID = createID(nextID.client, nextID.clock + diff); 9214 } 9215 item = getItem(store, nextID); 9216 diff = nextID.clock - item.id.clock; 9217 nextID = item.redone; 9218 } while (nextID !== null && item instanceof Item); 9219 return { 9220 item, 9221 diff 9222 }; 9223 }; 9224 var keepItem = (item, keep) => { 9225 while (item !== null && item.keep !== keep) { 9226 item.keep = keep; 9227 item = /** @type {AbstractType<any>} */ 9228 item.parent._item; 9229 } 9230 }; 9231 var splitItem = (transaction, leftItem, diff) => { 9232 const { client, clock } = leftItem.id; 9233 const rightItem = new Item( 9234 createID(client, clock + diff), 9235 leftItem, 9236 createID(client, clock + diff - 1), 9237 leftItem.right, 9238 leftItem.rightOrigin, 9239 leftItem.parent, 9240 leftItem.parentSub, 9241 leftItem.content.splice(diff) 9242 ); 9243 if (leftItem.deleted) { 9244 rightItem.markDeleted(); 9245 } 9246 if (leftItem.keep) { 9247 rightItem.keep = true; 9248 } 9249 if (leftItem.redone !== null) { 9250 rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); 9251 } 9252 leftItem.right = rightItem; 9253 if (rightItem.right !== null) { 9254 rightItem.right.left = rightItem; 9255 } 9256 transaction._mergeStructs.push(rightItem); 9257 if (rightItem.parentSub !== null && rightItem.right === null) { 9258 rightItem.parent._map.set(rightItem.parentSub, rightItem); 9259 } 9260 leftItem.length = diff; 9261 return rightItem; 9262 }; 9263 var isDeletedByUndoStack = (stack, id2) => some( 9264 stack, 9265 /** @param {StackItem} s */ 9266 (s) => isDeleted(s.deletions, id2) 9267 ); 9268 var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { 9269 const doc2 = transaction.doc; 9270 const store = doc2.store; 9271 const ownClientID = doc2.clientID; 9272 const redone = item.redone; 9273 if (redone !== null) { 9274 return getItemCleanStart(transaction, redone); 9275 } 9276 let parentItem = ( 9277 /** @type {AbstractType<any>} */ 9278 item.parent._item 9279 ); 9280 let left = null; 9281 let right; 9282 if (parentItem !== null && parentItem.deleted === true) { 9283 if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { 9284 return null; 9285 } 9286 while (parentItem.redone !== null) { 9287 parentItem = getItemCleanStart(transaction, parentItem.redone); 9288 } 9289 } 9290 const parentType = parentItem === null ? ( 9291 /** @type {AbstractType<any>} */ 9292 item.parent 9293 ) : ( 9294 /** @type {ContentType} */ 9295 parentItem.content.type 9296 ); 9297 if (item.parentSub === null) { 9298 left = item.left; 9299 right = item; 9300 while (left !== null) { 9301 let leftTrace = left; 9302 while (leftTrace !== null && /** @type {AbstractType<any>} */ 9303 leftTrace.parent._item !== parentItem) { 9304 leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); 9305 } 9306 if (leftTrace !== null && /** @type {AbstractType<any>} */ 9307 leftTrace.parent._item === parentItem) { 9308 left = leftTrace; 9309 break; 9310 } 9311 left = left.left; 9312 } 9313 while (right !== null) { 9314 let rightTrace = right; 9315 while (rightTrace !== null && /** @type {AbstractType<any>} */ 9316 rightTrace.parent._item !== parentItem) { 9317 rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); 9318 } 9319 if (rightTrace !== null && /** @type {AbstractType<any>} */ 9320 rightTrace.parent._item === parentItem) { 9321 right = rightTrace; 9322 break; 9323 } 9324 right = right.right; 9325 } 9326 } else { 9327 right = null; 9328 if (item.right && !ignoreRemoteMapChanges) { 9329 left = item; 9330 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))) { 9331 left = left.right; 9332 while (left.redone) left = getItemCleanStart(transaction, left.redone); 9333 } 9334 if (left && left.right !== null) { 9335 return null; 9336 } 9337 } else { 9338 left = parentType._map.get(item.parentSub) || null; 9339 } 9340 } 9341 const nextClock = getState(store, ownClientID); 9342 const nextId = createID(ownClientID, nextClock); 9343 const redoneItem = new Item( 9344 nextId, 9345 left, 9346 left && left.lastId, 9347 right, 9348 right && right.id, 9349 parentType, 9350 item.parentSub, 9351 item.content.copy() 9352 ); 9353 item.redone = nextId; 9354 keepItem(redoneItem, true); 9355 redoneItem.integrate(transaction, 0); 9356 return redoneItem; 9357 }; 9358 var Item = class _Item extends AbstractStruct { 9359 /** 9360 * @param {ID} id 9361 * @param {Item | null} left 9362 * @param {ID | null} origin 9363 * @param {Item | null} right 9364 * @param {ID | null} rightOrigin 9365 * @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. 9366 * @param {string | null} parentSub 9367 * @param {AbstractContent} content 9368 */ 9369 constructor(id2, left, origin2, right, rightOrigin, parent, parentSub, content) { 9370 super(id2, content.getLength()); 9371 this.origin = origin2; 9372 this.left = left; 9373 this.right = right; 9374 this.rightOrigin = rightOrigin; 9375 this.parent = parent; 9376 this.parentSub = parentSub; 9377 this.redone = null; 9378 this.content = content; 9379 this.info = this.content.isCountable() ? BIT2 : 0; 9380 } 9381 /** 9382 * This is used to mark the item as an indexed fast-search marker 9383 * 9384 * @type {boolean} 9385 */ 9386 set marker(isMarked) { 9387 if ((this.info & BIT4) > 0 !== isMarked) { 9388 this.info ^= BIT4; 9389 } 9390 } 9391 get marker() { 9392 return (this.info & BIT4) > 0; 9393 } 9394 /** 9395 * If true, do not garbage collect this Item. 9396 */ 9397 get keep() { 9398 return (this.info & BIT1) > 0; 9399 } 9400 set keep(doKeep) { 9401 if (this.keep !== doKeep) { 9402 this.info ^= BIT1; 9403 } 9404 } 9405 get countable() { 9406 return (this.info & BIT2) > 0; 9407 } 9408 /** 9409 * Whether this item was deleted or not. 9410 * @type {Boolean} 9411 */ 9412 get deleted() { 9413 return (this.info & BIT3) > 0; 9414 } 9415 set deleted(doDelete) { 9416 if (this.deleted !== doDelete) { 9417 this.info ^= BIT3; 9418 } 9419 } 9420 markDeleted() { 9421 this.info |= BIT3; 9422 } 9423 /** 9424 * Return the creator clientID of the missing op or define missing items and return null. 9425 * 9426 * @param {Transaction} transaction 9427 * @param {StructStore} store 9428 * @return {null | number} 9429 */ 9430 getMissing(transaction, store) { 9431 if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store, this.origin.client)) { 9432 return this.origin.client; 9433 } 9434 if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store, this.rightOrigin.client)) { 9435 return this.rightOrigin.client; 9436 } 9437 if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store, this.parent.client)) { 9438 return this.parent.client; 9439 } 9440 if (this.origin) { 9441 this.left = getItemCleanEnd(transaction, store, this.origin); 9442 this.origin = this.left.lastId; 9443 } 9444 if (this.rightOrigin) { 9445 this.right = getItemCleanStart(transaction, this.rightOrigin); 9446 this.rightOrigin = this.right.id; 9447 } 9448 if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { 9449 this.parent = null; 9450 } else if (!this.parent) { 9451 if (this.left && this.left.constructor === _Item) { 9452 this.parent = this.left.parent; 9453 this.parentSub = this.left.parentSub; 9454 } else if (this.right && this.right.constructor === _Item) { 9455 this.parent = this.right.parent; 9456 this.parentSub = this.right.parentSub; 9457 } 9458 } else if (this.parent.constructor === ID) { 9459 const parentItem = getItem(store, this.parent); 9460 if (parentItem.constructor === GC) { 9461 this.parent = null; 9462 } else { 9463 this.parent = /** @type {ContentType} */ 9464 parentItem.content.type; 9465 } 9466 } 9467 return null; 9468 } 9469 /** 9470 * @param {Transaction} transaction 9471 * @param {number} offset 9472 */ 9473 integrate(transaction, offset) { 9474 if (offset > 0) { 9475 this.id.clock += offset; 9476 this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); 9477 this.origin = this.left.lastId; 9478 this.content = this.content.splice(offset); 9479 this.length -= offset; 9480 } 9481 if (this.parent) { 9482 if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { 9483 let left = this.left; 9484 let o; 9485 if (left !== null) { 9486 o = left.right; 9487 } else if (this.parentSub !== null) { 9488 o = /** @type {AbstractType<any>} */ 9489 this.parent._map.get(this.parentSub) || null; 9490 while (o !== null && o.left !== null) { 9491 o = o.left; 9492 } 9493 } else { 9494 o = /** @type {AbstractType<any>} */ 9495 this.parent._start; 9496 } 9497 const conflictingItems = /* @__PURE__ */ new Set(); 9498 const itemsBeforeOrigin = /* @__PURE__ */ new Set(); 9499 while (o !== null && o !== this.right) { 9500 itemsBeforeOrigin.add(o); 9501 conflictingItems.add(o); 9502 if (compareIDs(this.origin, o.origin)) { 9503 if (o.id.client < this.id.client) { 9504 left = o; 9505 conflictingItems.clear(); 9506 } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { 9507 break; 9508 } 9509 } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { 9510 if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { 9511 left = o; 9512 conflictingItems.clear(); 9513 } 9514 } else { 9515 break; 9516 } 9517 o = o.right; 9518 } 9519 this.left = left; 9520 } 9521 if (this.left !== null) { 9522 const right = this.left.right; 9523 this.right = right; 9524 this.left.right = this; 9525 } else { 9526 let r; 9527 if (this.parentSub !== null) { 9528 r = /** @type {AbstractType<any>} */ 9529 this.parent._map.get(this.parentSub) || null; 9530 while (r !== null && r.left !== null) { 9531 r = r.left; 9532 } 9533 } else { 9534 r = /** @type {AbstractType<any>} */ 9535 this.parent._start; 9536 this.parent._start = this; 9537 } 9538 this.right = r; 9539 } 9540 if (this.right !== null) { 9541 this.right.left = this; 9542 } else if (this.parentSub !== null) { 9543 this.parent._map.set(this.parentSub, this); 9544 if (this.left !== null) { 9545 this.left.delete(transaction); 9546 } 9547 } 9548 if (this.parentSub === null && this.countable && !this.deleted) { 9549 this.parent._length += this.length; 9550 } 9551 addStruct(transaction.doc.store, this); 9552 this.content.integrate(transaction, this); 9553 addChangedTypeToTransaction( 9554 transaction, 9555 /** @type {AbstractType<any>} */ 9556 this.parent, 9557 this.parentSub 9558 ); 9559 if ( 9560 /** @type {AbstractType<any>} */ 9561 this.parent._item !== null && /** @type {AbstractType<any>} */ 9562 this.parent._item.deleted || this.parentSub !== null && this.right !== null 9563 ) { 9564 this.delete(transaction); 9565 } 9566 } else { 9567 new GC(this.id, this.length).integrate(transaction, 0); 9568 } 9569 } 9570 /** 9571 * Returns the next non-deleted item 9572 */ 9573 get next() { 9574 let n = this.right; 9575 while (n !== null && n.deleted) { 9576 n = n.right; 9577 } 9578 return n; 9579 } 9580 /** 9581 * Returns the previous non-deleted item 9582 */ 9583 get prev() { 9584 let n = this.left; 9585 while (n !== null && n.deleted) { 9586 n = n.left; 9587 } 9588 return n; 9589 } 9590 /** 9591 * Computes the last content address of this Item. 9592 */ 9593 get lastId() { 9594 return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); 9595 } 9596 /** 9597 * Try to merge two items 9598 * 9599 * @param {Item} right 9600 * @return {boolean} 9601 */ 9602 mergeWith(right) { 9603 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)) { 9604 const searchMarker = ( 9605 /** @type {AbstractType<any>} */ 9606 this.parent._searchMarker 9607 ); 9608 if (searchMarker) { 9609 searchMarker.forEach((marker) => { 9610 if (marker.p === right) { 9611 marker.p = this; 9612 if (!this.deleted && this.countable) { 9613 marker.index -= this.length; 9614 } 9615 } 9616 }); 9617 } 9618 if (right.keep) { 9619 this.keep = true; 9620 } 9621 this.right = right.right; 9622 if (this.right !== null) { 9623 this.right.left = this; 9624 } 9625 this.length += right.length; 9626 return true; 9627 } 9628 return false; 9629 } 9630 /** 9631 * Mark this Item as deleted. 9632 * 9633 * @param {Transaction} transaction 9634 */ 9635 delete(transaction) { 9636 if (!this.deleted) { 9637 const parent = ( 9638 /** @type {AbstractType<any>} */ 9639 this.parent 9640 ); 9641 if (this.countable && this.parentSub === null) { 9642 parent._length -= this.length; 9643 } 9644 this.markDeleted(); 9645 addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); 9646 addChangedTypeToTransaction(transaction, parent, this.parentSub); 9647 this.content.delete(transaction); 9648 } 9649 } 9650 /** 9651 * @param {StructStore} store 9652 * @param {boolean} parentGCd 9653 */ 9654 gc(store, parentGCd) { 9655 if (!this.deleted) { 9656 throw unexpectedCase(); 9657 } 9658 this.content.gc(store); 9659 if (parentGCd) { 9660 replaceStruct(store, this, new GC(this.id, this.length)); 9661 } else { 9662 this.content = new ContentDeleted(this.length); 9663 } 9664 } 9665 /** 9666 * Transform the properties of this type to binary and write it to an 9667 * BinaryEncoder. 9668 * 9669 * This is called when this Item is sent to a remote peer. 9670 * 9671 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 9672 * @param {number} offset 9673 */ 9674 write(encoder, offset) { 9675 const origin2 = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; 9676 const rightOrigin = this.rightOrigin; 9677 const parentSub = this.parentSub; 9678 const info = this.content.getRef() & BITS5 | (origin2 === null ? 0 : BIT8) | // origin is defined 9679 (rightOrigin === null ? 0 : BIT7) | // right origin is defined 9680 (parentSub === null ? 0 : BIT6); 9681 encoder.writeInfo(info); 9682 if (origin2 !== null) { 9683 encoder.writeLeftID(origin2); 9684 } 9685 if (rightOrigin !== null) { 9686 encoder.writeRightID(rightOrigin); 9687 } 9688 if (origin2 === null && rightOrigin === null) { 9689 const parent = ( 9690 /** @type {AbstractType<any>} */ 9691 this.parent 9692 ); 9693 if (parent._item !== void 0) { 9694 const parentItem = parent._item; 9695 if (parentItem === null) { 9696 const ykey = findRootTypeKey(parent); 9697 encoder.writeParentInfo(true); 9698 encoder.writeString(ykey); 9699 } else { 9700 encoder.writeParentInfo(false); 9701 encoder.writeLeftID(parentItem.id); 9702 } 9703 } else if (parent.constructor === String) { 9704 encoder.writeParentInfo(true); 9705 encoder.writeString(parent); 9706 } else if (parent.constructor === ID) { 9707 encoder.writeParentInfo(false); 9708 encoder.writeLeftID(parent); 9709 } else { 9710 unexpectedCase(); 9711 } 9712 if (parentSub !== null) { 9713 encoder.writeString(parentSub); 9714 } 9715 } 9716 this.content.write(encoder, offset); 9717 } 9718 }; 9719 var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); 9720 var contentRefs = [ 9721 () => { 9722 unexpectedCase(); 9723 }, 9724 // GC is not ItemContent 9725 readContentDeleted, 9726 // 1 9727 readContentJSON, 9728 // 2 9729 readContentBinary, 9730 // 3 9731 readContentString, 9732 // 4 9733 readContentEmbed, 9734 // 5 9735 readContentFormat, 9736 // 6 9737 readContentType, 9738 // 7 9739 readContentAny, 9740 // 8 9741 readContentDoc, 9742 // 9 9743 () => { 9744 unexpectedCase(); 9745 } 9746 // 10 - Skip is not ItemContent 9747 ]; 9748 var structSkipRefNumber = 10; 9749 var Skip = class extends AbstractStruct { 9750 get deleted() { 9751 return true; 9752 } 9753 delete() { 9754 } 9755 /** 9756 * @param {Skip} right 9757 * @return {boolean} 9758 */ 9759 mergeWith(right) { 9760 if (this.constructor !== right.constructor) { 9761 return false; 9762 } 9763 this.length += right.length; 9764 return true; 9765 } 9766 /** 9767 * @param {Transaction} transaction 9768 * @param {number} offset 9769 */ 9770 integrate(transaction, offset) { 9771 unexpectedCase(); 9772 } 9773 /** 9774 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9775 * @param {number} offset 9776 */ 9777 write(encoder, offset) { 9778 encoder.writeInfo(structSkipRefNumber); 9779 writeVarUint(encoder.restEncoder, this.length - offset); 9780 } 9781 /** 9782 * @param {Transaction} transaction 9783 * @param {StructStore} store 9784 * @return {null | number} 9785 */ 9786 getMissing(transaction, store) { 9787 return null; 9788 } 9789 }; 9790 var glo = ( 9791 /** @type {any} */ 9792 typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} 9793 ); 9794 var importIdentifier = "__ $YJS$ __"; 9795 if (glo[importIdentifier] === true) { 9796 console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); 9797 } 9798 glo[importIdentifier] = true; 9799 9800 // node_modules/y-protocols/awareness.js 9801 var outdatedTimeout = 3e4; 9802 var Awareness = class extends Observable { 9803 /** 9804 * @param {Y.Doc} doc 9805 */ 9806 constructor(doc2) { 9807 super(); 9808 this.doc = doc2; 9809 this.clientID = doc2.clientID; 9810 this.states = /* @__PURE__ */ new Map(); 9811 this.meta = /* @__PURE__ */ new Map(); 9812 this._checkInterval = /** @type {any} */ 9813 setInterval(() => { 9814 const now = getUnixTime(); 9815 if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ 9816 this.meta.get(this.clientID).lastUpdated) { 9817 this.setLocalState(this.getLocalState()); 9818 } 9819 const remove = []; 9820 this.meta.forEach((meta, clientid) => { 9821 if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { 9822 remove.push(clientid); 9823 } 9824 }); 9825 if (remove.length > 0) { 9826 removeAwarenessStates(this, remove, "timeout"); 9827 } 9828 }, floor(outdatedTimeout / 10)); 9829 doc2.on("destroy", () => { 9830 this.destroy(); 9831 }); 9832 this.setLocalState({}); 9833 } 9834 destroy() { 9835 this.emit("destroy", [this]); 9836 this.setLocalState(null); 9837 super.destroy(); 9838 clearInterval(this._checkInterval); 9839 } 9840 /** 9841 * @return {Object<string,any>|null} 9842 */ 9843 getLocalState() { 9844 return this.states.get(this.clientID) || null; 9845 } 9846 /** 9847 * @param {Object<string,any>|null} state 9848 */ 9849 setLocalState(state) { 9850 const clientID = this.clientID; 9851 const currLocalMeta = this.meta.get(clientID); 9852 const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; 9853 const prevState = this.states.get(clientID); 9854 if (state === null) { 9855 this.states.delete(clientID); 9856 } else { 9857 this.states.set(clientID, state); 9858 } 9859 this.meta.set(clientID, { 9860 clock, 9861 lastUpdated: getUnixTime() 9862 }); 9863 const added = []; 9864 const updated = []; 9865 const filteredUpdated = []; 9866 const removed = []; 9867 if (state === null) { 9868 removed.push(clientID); 9869 } else if (prevState == null) { 9870 if (state != null) { 9871 added.push(clientID); 9872 } 9873 } else { 9874 updated.push(clientID); 9875 if (!equalityDeep(prevState, state)) { 9876 filteredUpdated.push(clientID); 9877 } 9878 } 9879 if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { 9880 this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); 9881 } 9882 this.emit("update", [{ added, updated, removed }, "local"]); 9883 } 9884 /** 9885 * @param {string} field 9886 * @param {any} value 9887 */ 9888 setLocalStateField(field, value) { 9889 const state = this.getLocalState(); 9890 if (state !== null) { 9891 this.setLocalState({ 9892 ...state, 9893 [field]: value 9894 }); 9895 } 9896 } 9897 /** 9898 * @return {Map<number,Object<string,any>>} 9899 */ 9900 getStates() { 9901 return this.states; 9902 } 9903 }; 9904 var removeAwarenessStates = (awareness, clients, origin2) => { 9905 const removed = []; 9906 for (let i = 0; i < clients.length; i++) { 9907 const clientID = clients[i]; 9908 if (awareness.states.has(clientID)) { 9909 awareness.states.delete(clientID); 9910 if (clientID === awareness.clientID) { 9911 const curMeta = ( 9912 /** @type {MetaClientState} */ 9913 awareness.meta.get(clientID) 9914 ); 9915 awareness.meta.set(clientID, { 9916 clock: curMeta.clock + 1, 9917 lastUpdated: getUnixTime() 9918 }); 9919 } 9920 removed.push(clientID); 9921 } 9922 } 9923 if (removed.length > 0) { 9924 awareness.emit("change", [{ added: [], updated: [], removed }, origin2]); 9925 awareness.emit("update", [{ added: [], updated: [], removed }, origin2]); 9926 } 9927 }; 9928 9929 // packages/sync/build-module/config.mjs 9930 var CRDT_DOC_VERSION = 1; 9931 var CRDT_DOC_META_PERSISTENCE_KEY = "fromPersistence"; 9932 var CRDT_RECORD_MAP_KEY = "document"; 9933 var CRDT_STATE_MAP_KEY = "state"; 9934 var CRDT_STATE_MAP_SAVED_AT_KEY = "savedAt"; 9935 var CRDT_STATE_MAP_SAVED_BY_KEY = "savedBy"; 9936 var CRDT_STATE_MAP_VERSION_KEY = "version"; 9937 var LOCAL_EDITOR_ORIGIN = "gutenberg"; 9938 var LOCAL_SYNC_MANAGER_ORIGIN = "syncManager"; 9939 var LOCAL_UNDO_IGNORED_ORIGIN = "gutenberg-undo-ignored"; 9940 9941 // packages/sync/build-module/errors.mjs 9942 var ConnectionErrorCode = /* @__PURE__ */ ((ConnectionErrorCode2) => { 9943 ConnectionErrorCode2["AUTHENTICATION_FAILED"] = "authentication-failed"; 9944 ConnectionErrorCode2["CONNECTION_EXPIRED"] = "connection-expired"; 9945 ConnectionErrorCode2["CONNECTION_LIMIT_EXCEEDED"] = "connection-limit-exceeded"; 9946 ConnectionErrorCode2["DOCUMENT_SIZE_LIMIT_EXCEEDED"] = "document-size-limit-exceeded"; 9947 ConnectionErrorCode2["PROTOCOL_MISMATCH"] = "protocol-mismatch"; 9948 ConnectionErrorCode2["UNKNOWN_ERROR"] = "unknown-error"; 9949 return ConnectionErrorCode2; 9950 })(ConnectionErrorCode || {}); 9951 var ConnectionError = class extends Error { 9952 constructor(code = "unknown-error", message) { 9953 super(message); 9954 this.code = code; 9955 this.name = "ConnectionError"; 9956 } 9957 }; 9958 9959 // packages/sync/build-module/lock-unlock.mjs 9960 var import_private_apis = __toESM(require_private_apis(), 1); 9961 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 9962 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 9963 "@wordpress/sync" 9964 ); 9965 9966 // packages/sync/build-module/performance.mjs 9967 function logPerformanceTiming(fn) { 9968 return function(...args2) { 9969 const start = performance.now(); 9970 const result = fn.apply(this, args2); 9971 const end = performance.now(); 9972 console.log( 9973 `[SyncManager][performance]: $fn.name} took ${(end - start).toFixed(2)} ms` 9974 ); 9975 return result; 9976 }; 9977 } 9978 function passThru(fn) { 9979 return ((...args2) => fn(...args2)); 9980 } 9981 function yieldToEventLoop(fn) { 9982 return function(...args2) { 9983 setTimeout(() => { 9984 fn.apply(this, args2); 9985 }, 0); 9986 }; 9987 } 9988 9989 // packages/sync/build-module/providers/index.mjs 9990 var import_hooks3 = __toESM(require_hooks(), 1); 9991 9992 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 9993 var import_hooks2 = __toESM(require_hooks(), 1); 9994 9995 // node_modules/y-protocols/sync.js 9996 var messageYjsSyncStep1 = 0; 9997 var messageYjsSyncStep2 = 1; 9998 var messageYjsUpdate = 2; 9999 var writeSyncStep1 = (encoder, doc2) => { 10000 writeVarUint(encoder, messageYjsSyncStep1); 10001 const sv = encodeStateVector(doc2); 10002 writeVarUint8Array(encoder, sv); 10003 }; 10004 var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { 10005 writeVarUint(encoder, messageYjsSyncStep2); 10006 writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); 10007 }; 10008 var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); 10009 var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { 10010 try { 10011 applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); 10012 } catch (error) { 10013 if (errorHandler != null) errorHandler( 10014 /** @type {Error} */ 10015 error 10016 ); 10017 console.error("Caught error while handling a Yjs update", error); 10018 } 10019 }; 10020 var readUpdate2 = readSyncStep2; 10021 var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { 10022 const messageType = readVarUint(decoder); 10023 switch (messageType) { 10024 case messageYjsSyncStep1: 10025 readSyncStep1(decoder, encoder, doc2); 10026 break; 10027 case messageYjsSyncStep2: 10028 readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); 10029 break; 10030 case messageYjsUpdate: 10031 readUpdate2(decoder, doc2, transactionOrigin, errorHandler); 10032 break; 10033 default: 10034 throw new Error("Unknown message type"); 10035 } 10036 return messageType; 10037 }; 10038 10039 // packages/sync/build-module/providers/http-polling/config.mjs 10040 var import_hooks = __toESM(require_hooks(), 1); 10041 var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; 10042 var ERROR_RETRY_DELAYS_SOLO_MS = [ 10043 2e3, 10044 4e3, 10045 8e3, 10046 12e3 10047 // Solo: 26s total retry time solo before dialog 10048 ]; 10049 var ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS = [ 10050 1e3, 10051 2e3, 10052 4e3, 10053 8e3 10054 // With collaborators: 15s total retry time before dialog 10055 ]; 10056 var DISCONNECT_DIALOG_RETRY_MS = 3e4; 10057 var MANUAL_RETRY_INTERVAL_MS = 15e3; 10058 var MAX_ENCODED_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; 10059 var MAX_UPDATE_SIZE_IN_BYTES = Math.floor(MAX_ENCODED_UPDATE_SIZE_IN_BYTES / 4) * 3; 10060 var MAX_ROOMS_PER_REQUEST = 50; 10061 var MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES = 15 * 1024 * 1024; 10062 var MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES = 2 * 1024 * 1024; 10063 var DEFAULT_POLLING_INTERVAL_IN_MS = 4e3; 10064 var DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = 1e3; 10065 function getFilteredPollingInterval(hookName, defaultInterval) { 10066 const filteredInterval = (0, import_hooks.applyFilters)(hookName, defaultInterval); 10067 if (typeof filteredInterval !== "number" || !Number.isFinite(filteredInterval) || filteredInterval <= 0) { 10068 return defaultInterval; 10069 } 10070 return Math.min(filteredInterval, defaultInterval); 10071 } 10072 var POLLING_INTERVAL_IN_MS = getFilteredPollingInterval( 10073 "sync.pollingManager.pollingInterval", 10074 DEFAULT_POLLING_INTERVAL_IN_MS 10075 ); 10076 var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = getFilteredPollingInterval( 10077 "sync.pollingManager.pollingIntervalWithCollaborators", 10078 DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS 10079 ); 10080 var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; 10081 10082 // packages/sync/build-module/providers/http-polling/types.mjs 10083 var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { 10084 SyncUpdateType2["COMPACTION"] = "compaction"; 10085 SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; 10086 SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; 10087 SyncUpdateType2["UPDATE"] = "update"; 10088 return SyncUpdateType2; 10089 })(SyncUpdateType || {}); 10090 10091 // packages/sync/build-module/providers/http-polling/utils.mjs 10092 var import_api_fetch = __toESM(require_api_fetch(), 1); 10093 var SYNC_API_PATH = "/wp-sync/v1/updates"; 10094 function uint8ArrayToBase64(data) { 10095 let binary = ""; 10096 const len = data.byteLength; 10097 for (let i = 0; i < len; i++) { 10098 binary += String.fromCharCode(data[i]); 10099 } 10100 return globalThis.btoa(binary); 10101 } 10102 function base64ToUint8Array(base64) { 10103 const binaryString = globalThis.atob(base64); 10104 const len = binaryString.length; 10105 const bytes = new Uint8Array(len); 10106 for (let i = 0; i < len; i++) { 10107 bytes[i] = binaryString.charCodeAt(i); 10108 } 10109 return bytes; 10110 } 10111 function createSyncUpdate(data, type) { 10112 return { 10113 data: uint8ArrayToBase64(data), 10114 type 10115 }; 10116 } 10117 function createUpdateQueue(initial = [], paused = true) { 10118 let isPaused = paused; 10119 const updates = [...initial]; 10120 return { 10121 add(update) { 10122 updates.push(update); 10123 }, 10124 addBulk(bulkUpdates) { 10125 if (0 === bulkUpdates.length) { 10126 return; 10127 } 10128 updates.push(...bulkUpdates); 10129 }, 10130 clear() { 10131 updates.splice(0, updates.length); 10132 }, 10133 get() { 10134 if (isPaused) { 10135 return []; 10136 } 10137 return updates.splice(0, updates.length); 10138 }, 10139 pause() { 10140 isPaused = true; 10141 }, 10142 peek() { 10143 if (isPaused) { 10144 return []; 10145 } 10146 return [...updates]; 10147 }, 10148 restore(restoredUpdates) { 10149 const filtered = restoredUpdates.filter( 10150 (u) => u.type !== SyncUpdateType.COMPACTION 10151 ); 10152 if (0 === filtered.length) { 10153 return; 10154 } 10155 updates.unshift(...filtered); 10156 }, 10157 restoreExact(restoredUpdates) { 10158 if (0 === restoredUpdates.length) { 10159 return; 10160 } 10161 updates.unshift(...restoredUpdates); 10162 }, 10163 resume() { 10164 isPaused = false; 10165 }, 10166 size() { 10167 return updates.length; 10168 }, 10169 take(count) { 10170 if (isPaused || count <= 0) { 10171 return []; 10172 } 10173 return updates.splice(0, count); 10174 } 10175 }; 10176 } 10177 function postSyncUpdate(payload) { 10178 return (0, import_api_fetch.default)({ 10179 method: "POST", 10180 path: SYNC_API_PATH, 10181 data: payload 10182 }); 10183 } 10184 function postSyncUpdateNonBlocking(payload) { 10185 if (payload.rooms.length === 0) { 10186 return; 10187 } 10188 (0, import_api_fetch.default)({ 10189 method: "POST", 10190 path: SYNC_API_PATH, 10191 data: payload, 10192 keepalive: true 10193 }).catch(() => { 10194 }); 10195 } 10196 function intValueOrDefault(value, defaultValue) { 10197 const intValue = parseInt(String(value), 10); 10198 return isNaN(intValue) ? defaultValue : intValue; 10199 } 10200 function rotateWindow(items, offset, size2) { 10201 if (items.length === 0) { 10202 return { window: [], nextOffset: 0 }; 10203 } 10204 const start = (offset % items.length + items.length) % items.length; 10205 const wrapped = [...items.slice(start), ...items.slice(0, start)]; 10206 return { 10207 window: wrapped.slice(0, Math.max(0, size2)), 10208 nextOffset: (start + Math.max(0, size2)) % items.length 10209 }; 10210 } 10211 10212 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 10213 var POLLING_MANAGER_ORIGIN = "polling-manager"; 10214 function isForbiddenError(error) { 10215 return error?.data?.status === 403; 10216 } 10217 function isRequestBodyTooLargeError(error) { 10218 return error?.data?.status === 413 && error?.code === "rest_sync_body_too_large"; 10219 } 10220 function isProtocolMismatchError(error) { 10221 return error?.code === "rest_sync_protocol_mismatch"; 10222 } 10223 function handleForbiddenError(error, requestedRooms) { 10224 const requestedRoomNames = new Set( 10225 requestedRooms.map((room) => room.room) 10226 ); 10227 const forbiddenRooms = Array.isArray(error.data.rooms) ? error.data.rooms.filter((room) => requestedRoomNames.has(room)) : []; 10228 if (forbiddenRooms.length > 0) { 10229 for (const room of forbiddenRooms) { 10230 const state = roomStates.get(room); 10231 if (state) { 10232 state.log( 10233 "Permission denied, unregistering room", 10234 { error }, 10235 "error", 10236 true 10237 // force 10238 ); 10239 unregisterRoom(room, { sendDisconnectSignal: false }); 10240 } 10241 } 10242 for (const room of requestedRooms) { 10243 if (forbiddenRooms.includes(room.room)) { 10244 continue; 10245 } 10246 if (!roomStates.has(room.room)) { 10247 continue; 10248 } 10249 const remainingState = roomStates.get(room.room); 10250 if (room.updates.length > 0) { 10251 remainingState.updateQueue.restore(room.updates); 10252 } 10253 } 10254 } else { 10255 const rooms = [...roomStates.keys()]; 10256 for (const room of rooms) { 10257 const state = roomStates.get(room); 10258 if (state) { 10259 state.log( 10260 "Permission denied, unregistering room", 10261 { error }, 10262 "error", 10263 true 10264 // force 10265 ); 10266 unregisterRoom(room, { sendDisconnectSignal: false }); 10267 } 10268 } 10269 } 10270 } 10271 var roomStates = /* @__PURE__ */ new Map(); 10272 function createDeprecatedCompactionUpdate(updates) { 10273 const mergeable = updates.filter( 10274 (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( 10275 u.type 10276 ) 10277 ).map((u) => base64ToUint8Array(u.data)); 10278 return createSyncUpdate( 10279 mergeUpdatesV2(mergeable), 10280 SyncUpdateType.COMPACTION 10281 ); 10282 } 10283 function createSyncStep1Update(doc2) { 10284 const encoder = createEncoder(); 10285 writeSyncStep1(encoder, doc2); 10286 return createSyncUpdate( 10287 toUint8Array(encoder), 10288 SyncUpdateType.SYNC_STEP_1 10289 ); 10290 } 10291 function createSyncStep2Update(doc2, step1) { 10292 const decoder = createDecoder(step1); 10293 const encoder = createEncoder(); 10294 readSyncMessage( 10295 decoder, 10296 encoder, 10297 doc2, 10298 POLLING_MANAGER_ORIGIN 10299 ); 10300 return createSyncUpdate( 10301 toUint8Array(encoder), 10302 SyncUpdateType.SYNC_STEP_2 10303 ); 10304 } 10305 function processAwarenessUpdate(state, awareness) { 10306 const currentStates = awareness.getStates(); 10307 const added = /* @__PURE__ */ new Set(); 10308 const updated = /* @__PURE__ */ new Set(); 10309 const removed = new Set( 10310 Array.from(currentStates.keys()).filter( 10311 (clientId) => !state[clientId] 10312 ) 10313 ); 10314 Object.entries(state).forEach(([clientIdString, awarenessState]) => { 10315 const clientId = Number(clientIdString); 10316 if (clientId === awareness.clientID) { 10317 return; 10318 } 10319 if (null === awarenessState) { 10320 currentStates.delete(clientId); 10321 removed.add(clientId); 10322 return; 10323 } 10324 if (!currentStates.has(clientId)) { 10325 currentStates.set(clientId, awarenessState); 10326 added.add(clientId); 10327 return; 10328 } 10329 const currentState = currentStates.get(clientId); 10330 if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { 10331 currentStates.set(clientId, awarenessState); 10332 updated.add(clientId); 10333 } 10334 }); 10335 if (added.size + updated.size > 0) { 10336 awareness.emit("change", [ 10337 { 10338 added: Array.from(added), 10339 updated: Array.from(updated), 10340 // Left blank on purpose, as the removal of clients is handled in the if condition below. 10341 removed: [] 10342 } 10343 ]); 10344 } 10345 if (removed.size > 0) { 10346 removeAwarenessStates( 10347 awareness, 10348 Array.from(removed), 10349 POLLING_MANAGER_ORIGIN 10350 ); 10351 } 10352 } 10353 function processDocUpdate(update, doc2, onSync) { 10354 const data = base64ToUint8Array(update.data); 10355 switch (update.type) { 10356 case SyncUpdateType.SYNC_STEP_1: { 10357 return createSyncStep2Update(doc2, data); 10358 } 10359 case SyncUpdateType.SYNC_STEP_2: { 10360 const decoder = createDecoder(data); 10361 const encoder = createEncoder(); 10362 readSyncMessage( 10363 decoder, 10364 encoder, 10365 doc2, 10366 POLLING_MANAGER_ORIGIN 10367 ); 10368 onSync(); 10369 return; 10370 } 10371 case SyncUpdateType.COMPACTION: 10372 case SyncUpdateType.UPDATE: { 10373 applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); 10374 } 10375 } 10376 } 10377 function checkConnectionLimit(awareness, roomState) { 10378 if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { 10379 return false; 10380 } 10381 hasCheckedConnectionLimit = true; 10382 const maxClientsPerRoom = (0, import_hooks2.applyFilters)( 10383 "sync.pollingProvider.maxClientsPerRoom", 10384 DEFAULT_CLIENT_LIMIT_PER_ROOM, 10385 roomState.room 10386 ); 10387 const clientCount = Object.keys(awareness).length; 10388 const validatedLimit = intValueOrDefault( 10389 maxClientsPerRoom, 10390 DEFAULT_CLIENT_LIMIT_PER_ROOM 10391 ); 10392 if (clientCount > validatedLimit) { 10393 roomState.log("Connection limit exceeded", { 10394 clientCount, 10395 maxClientsPerRoom: validatedLimit, 10396 room: roomState.room 10397 }); 10398 return true; 10399 } 10400 return false; 10401 } 10402 var areListenersRegistered = false; 10403 var consecutiveFailures = 0; 10404 var hasCheckedConnectionLimit = false; 10405 var isManualRetry = false; 10406 var hasCollaborators = false; 10407 var isActiveBrowser = "visible" === document.visibilityState; 10408 var isPolling = false; 10409 var isUnloadPending = false; 10410 var pollInterval = POLLING_INTERVAL_IN_MS; 10411 var pollingTimeoutId = null; 10412 var syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10413 var roomOverflowOffset = 0; 10414 function handleBeforeUnload() { 10415 isUnloadPending = true; 10416 } 10417 function handlePageHide() { 10418 const rooms = Array.from(roomStates.entries()).map( 10419 ([room, state]) => ({ 10420 after: 0, 10421 awareness: null, 10422 client_id: state.clientId, 10423 room, 10424 updates: [] 10425 }) 10426 ); 10427 for (let i = 0; i < rooms.length; i += MAX_ROOMS_PER_REQUEST) { 10428 postSyncUpdateNonBlocking({ 10429 rooms: rooms.slice(i, i + MAX_ROOMS_PER_REQUEST) 10430 }); 10431 } 10432 } 10433 function handleVisibilityChange() { 10434 const wasActive = isActiveBrowser; 10435 isActiveBrowser = document.visibilityState === "visible"; 10436 if (isActiveBrowser && !wasActive) { 10437 if (pollingTimeoutId) { 10438 clearTimeout(pollingTimeoutId); 10439 pollingTimeoutId = null; 10440 poll(); 10441 } 10442 } 10443 } 10444 function selectRoomsForRequest() { 10445 const allRooms = Array.from(roomStates.values()); 10446 if (allRooms.length <= MAX_ROOMS_PER_REQUEST) { 10447 return allRooms; 10448 } 10449 const primaryRoom = allRooms.find((state) => state.isPrimaryRoom); 10450 const overflowRooms = allRooms.filter((state) => state !== primaryRoom); 10451 const overflowSlotsPerRequest = MAX_ROOMS_PER_REQUEST - (primaryRoom ? 1 : 0); 10452 const { window: overflowSlice, nextOffset } = rotateWindow( 10453 overflowRooms, 10454 roomOverflowOffset, 10455 overflowSlotsPerRequest 10456 ); 10457 roomOverflowOffset = nextOffset; 10458 if (primaryRoom) { 10459 return [primaryRoom, ...overflowSlice]; 10460 } 10461 return overflowSlice; 10462 } 10463 var textEncoder = new TextEncoder(); 10464 function getJsonByteLength(value) { 10465 return textEncoder.encode(JSON.stringify(value)).byteLength; 10466 } 10467 function createPayloadRoom(state, updates = []) { 10468 return { 10469 after: state.endCursor ?? 0, 10470 awareness: state.localAwarenessState, 10471 client_id: state.clientId, 10472 room: state.room, 10473 updates 10474 }; 10475 } 10476 function getUpdatePayloadSizeDelta(existingUpdateCount, update) { 10477 const commaSize = existingUpdateCount === 0 ? 0 : 1; 10478 return commaSize + getJsonByteLength(update); 10479 } 10480 function buildPayloadForRequest(selectedRoomStates) { 10481 const payload = { rooms: [] }; 10482 const roomsInRequest = []; 10483 for (const state of selectedRoomStates) { 10484 const room = createPayloadRoom(state); 10485 const candidate = { rooms: [...payload.rooms, room] }; 10486 if (payload.rooms.length > 0 && getJsonByteLength(candidate) > syncRequestBodySizeLimit) { 10487 break; 10488 } 10489 payload.rooms.push(room); 10490 roomsInRequest.push(state); 10491 } 10492 const pendingUpdates = roomsInRequest.map( 10493 (state) => state.updateQueue.peek() 10494 ); 10495 const sentUpdateCounts = roomsInRequest.map(() => 0); 10496 let payloadSize = getJsonByteLength(payload); 10497 let addedUpdate = true; 10498 while (addedUpdate) { 10499 addedUpdate = false; 10500 for (let i = 0; i < roomsInRequest.length; i++) { 10501 const update = pendingUpdates[i][sentUpdateCounts[i]]; 10502 if (!update) { 10503 continue; 10504 } 10505 const sizeDelta = getUpdatePayloadSizeDelta( 10506 sentUpdateCounts[i], 10507 update 10508 ); 10509 if (payloadSize + sizeDelta > syncRequestBodySizeLimit) { 10510 continue; 10511 } 10512 sentUpdateCounts[i]++; 10513 payloadSize += sizeDelta; 10514 addedUpdate = true; 10515 } 10516 } 10517 for (let i = 0; i < roomsInRequest.length; i++) { 10518 payload.rooms[i].updates = roomsInRequest[i].updateQueue.take( 10519 sentUpdateCounts[i] 10520 ); 10521 } 10522 return { payload, roomsInRequest }; 10523 } 10524 function restoreExactUpdates(payload) { 10525 for (const room of payload.rooms) { 10526 if (!roomStates.has(room.room) || room.updates.length === 0) { 10527 continue; 10528 } 10529 roomStates.get(room.room).updateQueue.restoreExact(room.updates); 10530 } 10531 } 10532 function poll() { 10533 isPolling = true; 10534 pollingTimeoutId = null; 10535 async function start() { 10536 if (0 === roomStates.size) { 10537 isPolling = false; 10538 return; 10539 } 10540 isUnloadPending = false; 10541 const { payload, roomsInRequest } = buildPayloadForRequest( 10542 selectRoomsForRequest() 10543 ); 10544 roomsInRequest.forEach((state) => { 10545 state.onStatusChange({ status: "connecting" }); 10546 }); 10547 try { 10548 const { rooms } = await postSyncUpdate(payload); 10549 consecutiveFailures = 0; 10550 isManualRetry = false; 10551 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10552 roomsInRequest.forEach((state) => { 10553 if (roomStates.get(state.room) !== state) { 10554 return; 10555 } 10556 state.onStatusChange({ status: "connected" }); 10557 }); 10558 hasCollaborators = false; 10559 rooms.forEach((room) => { 10560 if (!roomStates.has(room.room)) { 10561 return; 10562 } 10563 const roomState = roomStates.get(room.room); 10564 roomState.endCursor = room.end_cursor; 10565 if (checkConnectionLimit(room.awareness, roomState)) { 10566 roomState.onStatusChange({ 10567 status: "disconnected", 10568 error: new ConnectionError( 10569 ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, 10570 "Connection limit exceeded" 10571 ) 10572 }); 10573 unregisterRoom(room.room); 10574 return; 10575 } 10576 roomState.processAwarenessUpdate(room.awareness); 10577 if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { 10578 hasCollaborators = true; 10579 roomStates.forEach((state) => { 10580 state.updateQueue.resume(); 10581 }); 10582 } 10583 const responseUpdates = []; 10584 for (const update of room.updates) { 10585 try { 10586 const response = roomState.processDocUpdate(update); 10587 if (response) { 10588 responseUpdates.push(response); 10589 } 10590 } catch (error) { 10591 roomState.log( 10592 "Failed to apply sync update", 10593 { error, update }, 10594 "error", 10595 true 10596 // force 10597 ); 10598 } 10599 } 10600 roomState.updateQueue.addBulk(responseUpdates); 10601 if (room.should_compact) { 10602 roomState.log("Server requested compaction update"); 10603 roomState.updateQueue.clear(); 10604 roomState.updateQueue.add( 10605 roomState.createCompactionUpdate() 10606 ); 10607 } else if (room.compaction_request) { 10608 roomState.log("Server requested (old) compaction update"); 10609 roomState.updateQueue.add( 10610 createDeprecatedCompactionUpdate( 10611 room.compaction_request 10612 ) 10613 ); 10614 } 10615 }); 10616 if (isActiveBrowser && hasCollaborators) { 10617 pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; 10618 } else if (isActiveBrowser) { 10619 pollInterval = POLLING_INTERVAL_IN_MS; 10620 } else { 10621 pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; 10622 } 10623 } catch (error) { 10624 if (isForbiddenError(error)) { 10625 handleForbiddenError(error, payload.rooms); 10626 if (roomStates.size === 0) { 10627 isPolling = false; 10628 return; 10629 } 10630 } else if (isRequestBodyTooLargeError(error)) { 10631 syncRequestBodySizeLimit = Math.max( 10632 MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES, 10633 Math.floor(syncRequestBodySizeLimit / 2) 10634 ); 10635 pollInterval = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS[0] : ERROR_RETRY_DELAYS_SOLO_MS[0]; 10636 restoreExactUpdates(payload); 10637 for (const room of payload.rooms) { 10638 if (!roomStates.has(room.room)) { 10639 continue; 10640 } 10641 roomStates.get(room.room).log( 10642 "Sync request body too large, retrying with smaller batches", 10643 { 10644 error, 10645 nextPoll: pollInterval, 10646 syncRequestBodySizeLimit 10647 }, 10648 "error", 10649 true 10650 // force 10651 ); 10652 } 10653 } else if (isProtocolMismatchError(error)) { 10654 const affectedRooms = [...roomStates.entries()]; 10655 for (const [, state] of affectedRooms) { 10656 state.onStatusChange({ 10657 status: "disconnected", 10658 error: new ConnectionError( 10659 ConnectionErrorCode.PROTOCOL_MISMATCH, 10660 "Protocol mismatch between client and server" 10661 ) 10662 }); 10663 } 10664 for (const [room] of affectedRooms) { 10665 unregisterRoom(room, { sendDisconnectSignal: false }); 10666 } 10667 isPolling = false; 10668 return; 10669 } else { 10670 consecutiveFailures++; 10671 const retrySchedule = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS : ERROR_RETRY_DELAYS_SOLO_MS; 10672 if (consecutiveFailures <= retrySchedule.length) { 10673 pollInterval = retrySchedule[consecutiveFailures - 1]; 10674 } else { 10675 pollInterval = DISCONNECT_DIALOG_RETRY_MS; 10676 } 10677 if (isManualRetry) { 10678 pollInterval = MANUAL_RETRY_INTERVAL_MS; 10679 isManualRetry = false; 10680 } 10681 for (const room of payload.rooms) { 10682 if (!roomStates.has(room.room)) { 10683 continue; 10684 } 10685 const state = roomStates.get(room.room); 10686 if (room.updates.length > 0 && state.endCursor > 0) { 10687 state.updateQueue.clear(); 10688 state.updateQueue.add(state.createCompactionUpdate()); 10689 } else if (room.updates.length > 0) { 10690 state.updateQueue.restore(room.updates); 10691 } 10692 state.log( 10693 "Error posting sync update, will retry with backoff", 10694 { error, nextPoll: pollInterval }, 10695 "error", 10696 true 10697 // force 10698 ); 10699 } 10700 if (!isUnloadPending) { 10701 const backgroundRetriesFailed = consecutiveFailures > retrySchedule.length; 10702 roomsInRequest.forEach((state) => { 10703 if (roomStates.get(state.room) !== state) { 10704 return; 10705 } 10706 state.onStatusChange({ 10707 status: "disconnected", 10708 canManuallyRetry: true, 10709 consecutiveFailures, 10710 backgroundRetriesFailed, 10711 willAutoRetryInMs: pollInterval 10712 }); 10713 }); 10714 } 10715 } 10716 } 10717 pollingTimeoutId = setTimeout(poll, pollInterval); 10718 } 10719 void start(); 10720 } 10721 function registerRoom({ 10722 room, 10723 doc: doc2, 10724 awareness, 10725 log, 10726 onSync, 10727 onStatusChange 10728 }) { 10729 if (roomStates.has(room)) { 10730 return; 10731 } 10732 const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); 10733 const isPrimaryRoom = 0 === roomStates.size; 10734 function onAwarenessUpdate() { 10735 roomState.localAwarenessState = awareness.getLocalState() ?? {}; 10736 } 10737 function onDocUpdate(update, origin2) { 10738 if (POLLING_MANAGER_ORIGIN === origin2) { 10739 return; 10740 } 10741 if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { 10742 const state = roomStates.get(room); 10743 if (!state) { 10744 return; 10745 } 10746 state.log("Document size limit exceeded", { 10747 maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, 10748 updateSizeInBytes: update.byteLength 10749 }); 10750 state.onStatusChange({ 10751 status: "disconnected", 10752 error: new ConnectionError( 10753 ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, 10754 "Document size limit exceeded" 10755 ) 10756 }); 10757 unregisterRoom(room); 10758 return; 10759 } 10760 updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); 10761 } 10762 function unregister() { 10763 doc2.off("updateV2", onDocUpdate); 10764 awareness.off("change", onAwarenessUpdate); 10765 updateQueue.clear(); 10766 } 10767 const roomState = { 10768 clientId: doc2.clientID, 10769 createCompactionUpdate: () => createSyncUpdate( 10770 encodeStateAsUpdateV2(doc2), 10771 SyncUpdateType.COMPACTION 10772 ), 10773 endCursor: 0, 10774 isPrimaryRoom, 10775 localAwarenessState: awareness.getLocalState() ?? {}, 10776 log, 10777 onStatusChange, 10778 processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), 10779 processDocUpdate: (update) => processDocUpdate(update, doc2, onSync), 10780 room, 10781 unregister, 10782 updateQueue 10783 }; 10784 doc2.on("updateV2", onDocUpdate); 10785 awareness.on("change", onAwarenessUpdate); 10786 roomStates.set(room, roomState); 10787 if (!areListenersRegistered) { 10788 window.addEventListener("beforeunload", handleBeforeUnload); 10789 window.addEventListener("pagehide", handlePageHide); 10790 document.addEventListener("visibilitychange", handleVisibilityChange); 10791 areListenersRegistered = true; 10792 } 10793 if (!isPolling) { 10794 poll(); 10795 } 10796 } 10797 function unregisterRoom(room, { sendDisconnectSignal = true } = {}) { 10798 const state = roomStates.get(room); 10799 if (state) { 10800 if (sendDisconnectSignal) { 10801 const rooms = [ 10802 { 10803 after: 0, 10804 awareness: null, 10805 client_id: state.clientId, 10806 room, 10807 updates: [] 10808 } 10809 ]; 10810 postSyncUpdateNonBlocking({ rooms }); 10811 } 10812 state.unregister(); 10813 roomStates.delete(room); 10814 } 10815 if (0 === roomStates.size && areListenersRegistered) { 10816 window.removeEventListener("beforeunload", handleBeforeUnload); 10817 window.removeEventListener("pagehide", handlePageHide); 10818 document.removeEventListener( 10819 "visibilitychange", 10820 handleVisibilityChange 10821 ); 10822 areListenersRegistered = false; 10823 hasCheckedConnectionLimit = false; 10824 consecutiveFailures = 0; 10825 roomOverflowOffset = 0; 10826 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10827 } 10828 } 10829 function retryNow() { 10830 isManualRetry = true; 10831 if (pollingTimeoutId) { 10832 clearTimeout(pollingTimeoutId); 10833 pollingTimeoutId = null; 10834 poll(); 10835 } 10836 } 10837 var pollingManager = { 10838 registerRoom, 10839 retryNow, 10840 unregisterRoom 10841 }; 10842 10843 // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs 10844 var HttpPollingProvider = class extends ObservableV2 { 10845 constructor(options) { 10846 super(); 10847 this.options = options; 10848 this.log("Initializing", { room: options.room }); 10849 this.awareness = options.awareness ?? new Awareness(options.ydoc); 10850 this.connect(); 10851 } 10852 awareness; 10853 status = "disconnected"; 10854 synced = false; 10855 /** 10856 * Connect to the endpoint and initialize sync. 10857 */ 10858 connect() { 10859 this.log("Connecting"); 10860 pollingManager.registerRoom({ 10861 room: this.options.room, 10862 doc: this.options.ydoc, 10863 awareness: this.awareness, 10864 log: this.log, 10865 onStatusChange: this.emitStatus, 10866 onSync: this.onSync 10867 }); 10868 } 10869 /** 10870 * Destroy the provider and cleanup resources. 10871 */ 10872 destroy() { 10873 this.disconnect(); 10874 super.destroy(); 10875 } 10876 /** 10877 * Disconnect the provider and allow reconnection later. 10878 */ 10879 disconnect() { 10880 this.log("Disconnecting"); 10881 pollingManager.unregisterRoom(this.options.room); 10882 this.emitStatus({ status: "disconnected" }); 10883 } 10884 /** 10885 * Emit connection status, passing the full object through so that 10886 * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. 10887 * 10888 * @param connectionStatus The connection status object 10889 */ 10890 emitStatus = (connectionStatus) => { 10891 const { status } = connectionStatus; 10892 const error = status === "disconnected" ? connectionStatus.error : void 0; 10893 if (this.status === status && !error) { 10894 return; 10895 } 10896 if (status === "connecting" && this.status !== "disconnected") { 10897 return; 10898 } 10899 this.log("Status change", { status, error }); 10900 this.status = status; 10901 this.emit("status", [connectionStatus]); 10902 }; 10903 /** 10904 * Log debug messages if debugging is enabled. 10905 * 10906 * @param message The debug message 10907 * @param debug Additional debug information 10908 * @param errorLevel The console method to use for logging 10909 * @param force Whether to force logging regardless of debug setting 10910 */ 10911 log = (message, debug = {}, errorLevel = "log", force = false) => { 10912 if (!this.options.debug && !force) { 10913 return; 10914 } 10915 const logFn = console[errorLevel] || console.log; 10916 logFn(`[$this.constructor.name}]: $message}`, { 10917 room: this.options.room, 10918 ...debug 10919 }); 10920 }; 10921 /** 10922 * Handle synchronization events from the polling manager. 10923 */ 10924 onSync = () => { 10925 if (!this.synced) { 10926 this.synced = true; 10927 this.log("Synced"); 10928 } 10929 }; 10930 }; 10931 function createHttpPollingProvider() { 10932 return async ({ 10933 awareness, 10934 objectType, 10935 objectId, 10936 ydoc 10937 }) => { 10938 const room = objectId ? `$objectType}:$objectId}` : objectType; 10939 const provider = new HttpPollingProvider({ 10940 awareness, 10941 // debug: true, 10942 room, 10943 ydoc 10944 }); 10945 return { 10946 destroy: () => provider.destroy(), 10947 // Adapter: ObservableV2.on is compatible with ProviderOn 10948 // The callback receives data as the first parameter 10949 on: (event, callback) => { 10950 provider.on(event, callback); 10951 } 10952 }; 10953 }; 10954 } 10955 10956 // packages/sync/build-module/providers/index.mjs 10957 var providerCreators = null; 10958 function getDefaultProviderCreators() { 10959 return [createHttpPollingProvider()]; 10960 } 10961 function isProviderCreator(creator) { 10962 return "function" === typeof creator; 10963 } 10964 function getProviderCreators() { 10965 if (providerCreators) { 10966 return providerCreators; 10967 } 10968 if (!window._wpCollaborationEnabled) { 10969 return []; 10970 } 10971 const filteredProviderCreators = (0, import_hooks3.applyFilters)( 10972 "sync.providers", 10973 getDefaultProviderCreators() 10974 ); 10975 if (!Array.isArray(filteredProviderCreators)) { 10976 providerCreators = []; 10977 return providerCreators; 10978 } 10979 providerCreators = filteredProviderCreators.filter(isProviderCreator); 10980 return providerCreators; 10981 } 10982 10983 // packages/sync/build-module/y-utilities/y-multidoc-undomanager.mjs 10984 var popStackItem2 = (mum, type) => { 10985 const stack = type === "undo" ? mum.undoStack : mum.redoStack; 10986 while (stack.length > 0) { 10987 const um = ( 10988 /** @type {Y.UndoManager} */ 10989 stack.pop() 10990 ); 10991 const prevUmStack = type === "undo" ? um.undoStack : um.redoStack; 10992 const stackItem = ( 10993 /** @type {any} */ 10994 prevUmStack.pop() 10995 ); 10996 let actionPerformed = false; 10997 if (type === "undo") { 10998 um.undoStack = [stackItem]; 10999 actionPerformed = um.undo() !== null; 11000 um.undoStack = prevUmStack; 11001 } else { 11002 um.redoStack = [stackItem]; 11003 actionPerformed = um.redo() !== null; 11004 um.redoStack = prevUmStack; 11005 } 11006 if (actionPerformed) { 11007 return stackItem; 11008 } 11009 } 11010 return null; 11011 }; 11012 var YMultiDocUndoManager = class extends Observable { 11013 /** 11014 * @param {Y.AbstractType<any>|Array<Y.AbstractType<any>>} typeScope Accepts either a single type, or an array of types 11015 * @param {ConstructorParameters<typeof Y.UndoManager>[1]} opts 11016 */ 11017 constructor(typeScope = [], opts = {}) { 11018 super(); 11019 this.docs = /* @__PURE__ */ new Map(); 11020 this.trackedOrigins = opts.trackedOrigins || /* @__PURE__ */ new Set([null]); 11021 opts.trackedOrigins = this.trackedOrigins; 11022 this._defaultOpts = opts; 11023 this.undoStack = []; 11024 this.redoStack = []; 11025 this.addToScope(typeScope); 11026 } 11027 /** 11028 * @param {Array<Y.AbstractType<any>> | Y.AbstractType<any>} ytypes 11029 */ 11030 addToScope(ytypes) { 11031 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 11032 ytypes.forEach((ytype) => { 11033 const ydoc = ( 11034 /** @type {Y.Doc} */ 11035 ytype.doc 11036 ); 11037 const um = setIfUndefined(this.docs, ydoc, () => { 11038 const um2 = new UndoManager([ytype], this._defaultOpts); 11039 um2.on( 11040 "stack-cleared", 11041 /** @param {any} opts */ 11042 ({ 11043 undoStackCleared, 11044 redoStackCleared 11045 }) => { 11046 this.clear(undoStackCleared, redoStackCleared); 11047 } 11048 ); 11049 ydoc.on("destroy", () => { 11050 this.docs.delete(ydoc); 11051 this.undoStack = this.undoStack.filter( 11052 (um3) => um3.doc !== ydoc 11053 ); 11054 this.redoStack = this.redoStack.filter( 11055 (um3) => um3.doc !== ydoc 11056 ); 11057 }); 11058 um2.on( 11059 "stack-item-added", 11060 /** @param {any} change */ 11061 (change) => { 11062 const stack = change.type === "undo" ? this.undoStack : this.redoStack; 11063 stack.push(um2); 11064 this.emit("stack-item-added", [ 11065 { ...change, ydoc }, 11066 this 11067 ]); 11068 } 11069 ); 11070 um2.on( 11071 "stack-item-updated", 11072 /** @param {any} change */ 11073 (change) => { 11074 this.emit("stack-item-updated", [ 11075 { ...change, ydoc }, 11076 this 11077 ]); 11078 } 11079 ); 11080 um2.on( 11081 "stack-item-popped", 11082 /** @param {any} change */ 11083 (change) => { 11084 this.emit("stack-item-popped", [ 11085 { ...change, ydoc }, 11086 this 11087 ]); 11088 } 11089 ); 11090 return um2; 11091 }); 11092 if (um.scope.every((yt) => yt !== ytype)) { 11093 um.scope.push(ytype); 11094 } 11095 }); 11096 } 11097 /** 11098 * @param {any} origin 11099 */ 11100 /* c8 ignore next 3 */ 11101 addTrackedOrigin(origin2) { 11102 this.trackedOrigins.add(origin2); 11103 } 11104 /** 11105 * @param {any} origin 11106 */ 11107 /* c8 ignore next 3 */ 11108 removeTrackedOrigin(origin2) { 11109 this.trackedOrigins.delete(origin2); 11110 } 11111 /** 11112 * Undo last changes on type. 11113 * 11114 * @return {any?} Returns StackItem if a change was applied 11115 */ 11116 undo() { 11117 return popStackItem2(this, "undo"); 11118 } 11119 /** 11120 * Redo last undo operation. 11121 * 11122 * @return {any?} Returns StackItem if a change was applied 11123 */ 11124 redo() { 11125 return popStackItem2(this, "redo"); 11126 } 11127 clear(clearUndoStack = true, clearRedoStack = true) { 11128 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 11129 this.docs.forEach((um) => { 11130 clearUndoStack && (this.undoStack = []); 11131 clearRedoStack && (this.redoStack = []); 11132 um.clear(clearUndoStack, clearRedoStack); 11133 }); 11134 this.emit("stack-cleared", [ 11135 { 11136 undoStackCleared: clearUndoStack, 11137 redoStackCleared: clearRedoStack 11138 } 11139 ]); 11140 } 11141 } 11142 /* c8 ignore next 5 */ 11143 stopCapturing() { 11144 this.docs.forEach((um) => { 11145 um.stopCapturing(); 11146 }); 11147 } 11148 /** 11149 * Are undo steps available? 11150 * 11151 * @return {boolean} `true` if undo is possible 11152 */ 11153 canUndo() { 11154 return this.undoStack.length > 0; 11155 } 11156 /** 11157 * Are redo steps available? 11158 * 11159 * @return {boolean} `true` if redo is possible 11160 */ 11161 canRedo() { 11162 return this.redoStack.length > 0; 11163 } 11164 destroy() { 11165 this.docs.forEach((um) => um.destroy()); 11166 super.destroy(); 11167 } 11168 }; 11169 11170 // packages/sync/build-module/undo-manager.mjs 11171 function createUndoManager() { 11172 const undoMetaHandlers = /* @__PURE__ */ new Map(); 11173 const yUndoManager = new YMultiDocUndoManager([], { 11174 // Throttle undo/redo captures after 500ms of inactivity. 11175 // 500 was selected from subjective local UX testing, shorter timeouts 11176 // may cause mid-word undo stack items. 11177 captureTimeout: 500, 11178 // Ensure that we only scope the undo/redo to the current editor. 11179 // The yjs document's clientID is added once it's available. 11180 trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) 11181 }); 11182 const getUndoStackState = () => ({ 11183 hasRedo: yUndoManager.canRedo(), 11184 hasUndo: yUndoManager.canUndo() 11185 }); 11186 const notifyUndoStackChange = (ydoc) => { 11187 undoMetaHandlers.get(ydoc)?.onUndoStackChange?.(getUndoStackState()); 11188 }; 11189 yUndoManager.on("stack-item-added", (event) => { 11190 const handlers = undoMetaHandlers.get(event.ydoc); 11191 if (!handlers) { 11192 return; 11193 } 11194 handlers.addUndoMeta(event.ydoc, event.stackItem.meta); 11195 notifyUndoStackChange(event.ydoc); 11196 }); 11197 yUndoManager.on("stack-item-updated", (event) => { 11198 notifyUndoStackChange(event.ydoc); 11199 }); 11200 yUndoManager.on("stack-item-popped", (event) => { 11201 const handlers = undoMetaHandlers.get(event.ydoc); 11202 if (!handlers) { 11203 return; 11204 } 11205 handlers.restoreUndoMeta(event.ydoc, event.stackItem.meta); 11206 notifyUndoStackChange(event.ydoc); 11207 }); 11208 yUndoManager.on("stack-cleared", () => { 11209 undoMetaHandlers.forEach((handlers) => { 11210 handlers.onUndoStackChange?.(getUndoStackState()); 11211 }); 11212 }); 11213 return { 11214 /** 11215 * Record changes into the history. 11216 * Since Yjs automatically tracks changes, this method translates the WordPress 11217 * HistoryRecord format into Yjs operations. 11218 * 11219 * @param _record A record of changes to record. 11220 * @param _isStaged Whether to immediately create an undo point or not. 11221 */ 11222 addRecord(_record, _isStaged = false) { 11223 }, 11224 /** 11225 * Add a Yjs map to the scope of the undo manager. 11226 * 11227 * @param {Y.Map< any >} ymap The Yjs map to add to the scope. 11228 * @param handlers Handlers for the scoped document. 11229 * @param handlers.addUndoMeta Handler to add metadata to undo items. 11230 * @param handlers.onUndoStackChange Handler for undo stack changes. 11231 * @param handlers.restoreUndoMeta Handler to restore metadata from undo items. 11232 */ 11233 addToScope(ymap, handlers) { 11234 if (ymap.doc === null) { 11235 return; 11236 } 11237 const ydoc = ymap.doc; 11238 yUndoManager.addToScope(ymap); 11239 if (!undoMetaHandlers.has(ydoc)) { 11240 ydoc.on("destroy", () => undoMetaHandlers.delete(ydoc)); 11241 } 11242 undoMetaHandlers.set(ydoc, handlers); 11243 }, 11244 /** 11245 * Undo the last recorded changes. 11246 * 11247 */ 11248 undo() { 11249 if (!yUndoManager.canUndo()) { 11250 return; 11251 } 11252 yUndoManager.undo(); 11253 return []; 11254 }, 11255 /** 11256 * Redo the last undone changes. 11257 */ 11258 redo() { 11259 if (!yUndoManager.canRedo()) { 11260 return; 11261 } 11262 yUndoManager.redo(); 11263 return []; 11264 }, 11265 /** 11266 * Check if there are changes that can be undone. 11267 * 11268 * @return {boolean} Whether there are changes to undo. 11269 */ 11270 hasUndo() { 11271 return yUndoManager.canUndo(); 11272 }, 11273 /** 11274 * Check if there are changes that can be redone. 11275 * 11276 * @return {boolean} Whether there are changes to redo. 11277 */ 11278 hasRedo() { 11279 return yUndoManager.canRedo(); 11280 }, 11281 /** 11282 * Stop capturing changes into the current undo item. 11283 * The next change will create a new undo item. 11284 */ 11285 stopCapturing() { 11286 yUndoManager.stopCapturing(); 11287 } 11288 }; 11289 } 11290 11291 // packages/sync/build-module/utils.mjs 11292 function createYjsDoc(documentMeta = {}) { 11293 const metaMap = new Map( 11294 Object.entries(documentMeta) 11295 ); 11296 return new Doc({ meta: metaMap }); 11297 } 11298 function initializeYjsDoc(ydoc) { 11299 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11300 stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); 11301 } 11302 function markEntityAsSaved(ydoc) { 11303 const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); 11304 recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); 11305 recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); 11306 } 11307 function pseudoRandomID() { 11308 return Math.floor(Math.random() * 1e9); 11309 } 11310 function serializeCrdtDoc(crdtDoc) { 11311 return JSON.stringify({ 11312 document: toBase64(encodeStateAsUpdateV2(crdtDoc)), 11313 updateId: pseudoRandomID() 11314 // helps with debugging 11315 }); 11316 } 11317 function deserializeCrdtDoc(serializedCrdtDoc) { 11318 try { 11319 const { document: document2 } = JSON.parse(serializedCrdtDoc); 11320 const docMeta = { 11321 [CRDT_DOC_META_PERSISTENCE_KEY]: true 11322 }; 11323 const ydoc = createYjsDoc(docMeta); 11324 const yupdate = fromBase64(document2); 11325 applyUpdateV2(ydoc, yupdate); 11326 ydoc.clientID = pseudoRandomID(); 11327 return ydoc; 11328 } catch { 11329 return null; 11330 } 11331 } 11332 11333 // packages/sync/build-module/manager.mjs 11334 function getEntityId(objectType, objectId) { 11335 return `$objectType}_$objectId}`; 11336 } 11337 function createSyncManager(debug = false) { 11338 const debugWrap = debug ? logPerformanceTiming : passThru; 11339 const collectionStates = /* @__PURE__ */ new Map(); 11340 const entityStates = /* @__PURE__ */ new Map(); 11341 let undoManager; 11342 function log(component, message, entityId, context = {}) { 11343 if (!debug) { 11344 return; 11345 } 11346 console.log(`[SyncManager][$component}]: $message}`, { 11347 ...context, 11348 entityId 11349 }); 11350 } 11351 async function loadEntity(syncConfig, objectType, objectId, record, handlers) { 11352 const providerCreators2 = getProviderCreators(); 11353 const entityId = getEntityId(objectType, objectId); 11354 if (0 === providerCreators2.length) { 11355 log("loadEntity", "no providers, skipping", entityId); 11356 return; 11357 } 11358 if (entityStates.has(entityId)) { 11359 log("loadEntity", "already loaded", entityId); 11360 return; 11361 } 11362 if (false === syncConfig.shouldSync?.(objectType, objectId)) { 11363 log("loadEntity", "shouldSync false, skipping", entityId); 11364 return; 11365 } 11366 log("loadEntity", "loading", entityId); 11367 handlers = { 11368 addUndoMeta: debugWrap(handlers.addUndoMeta), 11369 editRecord: debugWrap(handlers.editRecord), 11370 getEditedRecord: debugWrap(handlers.getEditedRecord), 11371 onStatusChange: debugWrap(handlers.onStatusChange), 11372 persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), 11373 refetchRecord: debugWrap(handlers.refetchRecord), 11374 restoreUndoMeta: debugWrap(handlers.restoreUndoMeta), 11375 onUndoStackChange: handlers.onUndoStackChange ? debugWrap(handlers.onUndoStackChange) : void 0 11376 }; 11377 const ydoc = createYjsDoc({ objectType }); 11378 const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); 11379 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11380 const now = Date.now(); 11381 let hasObserversAttached = false; 11382 let isEntityUnloaded = false; 11383 const unload = () => { 11384 log("loadEntity", "unloading", entityId); 11385 isEntityUnloaded = true; 11386 providerResults?.forEach((result) => result.destroy()); 11387 handlers.onStatusChange(null); 11388 if (hasObserversAttached) { 11389 recordMap.unobserveDeep(onRecordUpdate); 11390 stateMap.unobserve(onStateMapUpdate); 11391 } 11392 ydoc.destroy(); 11393 entityStates.delete(entityId); 11394 }; 11395 const awareness = syncConfig.createAwareness?.(ydoc, objectId); 11396 const onRecordUpdate = (_events, transaction) => { 11397 if (transaction.local && !(transaction.origin instanceof UndoManager)) { 11398 return; 11399 } 11400 void internal.updateEntityRecord(objectType, objectId); 11401 }; 11402 const onStateMapUpdate = (event, transaction) => { 11403 if (transaction.local) { 11404 return; 11405 } 11406 event.keysChanged.forEach((key) => { 11407 switch (key) { 11408 case CRDT_STATE_MAP_SAVED_AT_KEY: 11409 const savedAt = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11410 if ("number" === typeof savedAt && savedAt > now) { 11411 log("loadEntity", "refetching record", entityId); 11412 void handlers.refetchRecord().catch(() => { 11413 }); 11414 } 11415 break; 11416 } 11417 }); 11418 }; 11419 if (!undoManager) { 11420 undoManager = createUndoManager(); 11421 } 11422 const { addUndoMeta, onUndoStackChange, restoreUndoMeta } = handlers; 11423 undoManager.addToScope(recordMap, { 11424 addUndoMeta, 11425 restoreUndoMeta, 11426 onUndoStackChange 11427 }); 11428 let providerResults; 11429 const entityState = { 11430 awareness, 11431 handlers, 11432 objectId, 11433 objectType, 11434 syncConfig, 11435 unload, 11436 ydoc 11437 }; 11438 entityStates.set(entityId, entityState); 11439 log("loadEntity", "connecting", entityId); 11440 providerResults = await Promise.all( 11441 providerCreators2.map(async (create7) => { 11442 const provider = await create7({ 11443 objectType, 11444 objectId, 11445 ydoc, 11446 awareness 11447 }); 11448 provider.on("status", handlers.onStatusChange); 11449 return provider; 11450 }) 11451 ); 11452 if (isEntityUnloaded) { 11453 log("loadEntity", "unloaded during connect, aborting", entityId); 11454 providerResults.forEach((result) => result.destroy()); 11455 return; 11456 } 11457 initializeYjsDoc(ydoc); 11458 internal.applyPersistedCrdtDoc(objectType, objectId, record); 11459 recordMap.observeDeep(onRecordUpdate); 11460 stateMap.observe(onStateMapUpdate); 11461 hasObserversAttached = true; 11462 } 11463 async function loadCollection(syncConfig, objectType, handlers) { 11464 const providerCreators2 = getProviderCreators(); 11465 const entityId = getEntityId(objectType, null); 11466 if (0 === providerCreators2.length) { 11467 log("loadCollection", "no providers, skipping", entityId); 11468 return; 11469 } 11470 if (collectionStates.has(objectType)) { 11471 log("loadCollection", "already loaded", entityId); 11472 return; 11473 } 11474 if (false === syncConfig.shouldSync?.(objectType, null)) { 11475 log("loadCollection", "shouldSync false, skipping", entityId); 11476 return; 11477 } 11478 log("loadCollection", "loading", entityId); 11479 const ydoc = createYjsDoc({ collection: true, objectType }); 11480 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11481 const now = Date.now(); 11482 let hasObserversAttached = false; 11483 let isCollectionUnloaded = false; 11484 const unload = () => { 11485 log("loadCollection", "unloading", entityId); 11486 isCollectionUnloaded = true; 11487 providerResults?.forEach((result) => result.destroy()); 11488 handlers.onStatusChange(null); 11489 if (hasObserversAttached) { 11490 stateMap.unobserve(onStateMapUpdate); 11491 } 11492 ydoc.destroy(); 11493 collectionStates.delete(objectType); 11494 }; 11495 const onStateMapUpdate = (event, transaction) => { 11496 if (transaction.local) { 11497 return; 11498 } 11499 event.keysChanged.forEach((key) => { 11500 switch (key) { 11501 case CRDT_STATE_MAP_SAVED_AT_KEY: 11502 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11503 if ("number" === typeof newValue && newValue > now) { 11504 void handlers.refetchRecords().catch(() => { 11505 }); 11506 } 11507 break; 11508 } 11509 }); 11510 }; 11511 const awareness = syncConfig.createAwareness?.(ydoc); 11512 let providerResults; 11513 const collectionState = { 11514 awareness, 11515 handlers, 11516 syncConfig, 11517 unload, 11518 ydoc 11519 }; 11520 collectionStates.set(objectType, collectionState); 11521 log("loadCollection", "connecting", entityId); 11522 providerResults = await Promise.all( 11523 providerCreators2.map(async (create7) => { 11524 const provider = await create7({ 11525 awareness, 11526 objectType, 11527 objectId: null, 11528 ydoc 11529 }); 11530 provider.on("status", handlers.onStatusChange); 11531 return provider; 11532 }) 11533 ); 11534 if (isCollectionUnloaded) { 11535 log( 11536 "loadCollection", 11537 "unloaded during connect, aborting", 11538 entityId 11539 ); 11540 providerResults.forEach((result) => result.destroy()); 11541 return; 11542 } 11543 stateMap.observe(onStateMapUpdate); 11544 hasObserversAttached = true; 11545 initializeYjsDoc(ydoc); 11546 } 11547 function unloadEntity(objectType, objectId) { 11548 const entityId = getEntityId(objectType, objectId); 11549 log("unloadEntity", "unloading", entityId); 11550 entityStates.get(entityId)?.unload(); 11551 updateCRDTDoc(objectType, null, {}, origin, { 11552 isSave: true 11553 }); 11554 } 11555 function unloadAll() { 11556 log("unloadAll", "unloading all entities", "all"); 11557 for (const [, entityState] of [...entityStates]) { 11558 entityState.unload(); 11559 } 11560 entityStates.clear(); 11561 undoManager = void 0; 11562 for (const [, collectionState] of [...collectionStates]) { 11563 collectionState.unload(); 11564 } 11565 collectionStates.clear(); 11566 } 11567 function getAwareness(objectType, objectId) { 11568 const entityId = getEntityId(objectType, objectId); 11569 const entityState = entityStates.get(entityId); 11570 if (!entityState || !entityState.awareness) { 11571 return void 0; 11572 } 11573 return entityState.awareness; 11574 } 11575 function _applyPersistedCrdtDoc(objectType, objectId, record) { 11576 const entityId = getEntityId(objectType, objectId); 11577 const entityState = entityStates.get(entityId); 11578 if (!entityState) { 11579 log("applyPersistedCrdtDoc", "no entity state", entityId); 11580 return; 11581 } 11582 const { 11583 handlers, 11584 syncConfig: { 11585 applyChangesToCRDTDoc, 11586 getChangesFromCRDTDoc, 11587 getPersistedCRDTDoc 11588 }, 11589 ydoc: targetDoc 11590 } = entityState; 11591 const serialized = getPersistedCRDTDoc?.(record); 11592 const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; 11593 if (!tempDoc) { 11594 log("applyPersistedCrdtDoc", "no persisted doc", entityId); 11595 targetDoc.transact(() => { 11596 applyChangesToCRDTDoc(targetDoc, record); 11597 handlers.persistCRDTDoc(); 11598 }, LOCAL_SYNC_MANAGER_ORIGIN); 11599 return; 11600 } 11601 const update = encodeStateAsUpdateV2(tempDoc); 11602 applyUpdateV2(targetDoc, update); 11603 const invalidations = getChangesFromCRDTDoc(tempDoc, record); 11604 const invalidatedKeys = Object.keys(invalidations); 11605 tempDoc.destroy(); 11606 if (0 === invalidatedKeys.length) { 11607 log("applyPersistedCrdtDoc", "valid persisted doc", entityId); 11608 return; 11609 } 11610 log("applyPersistedCrdtDoc", "invalidated keys", entityId, { 11611 invalidatedKeys 11612 }); 11613 const changes = invalidatedKeys.reduce( 11614 (acc, key) => Object.assign(acc, { 11615 [key]: record[key] 11616 }), 11617 {} 11618 ); 11619 targetDoc.transact(() => { 11620 applyChangesToCRDTDoc(targetDoc, changes); 11621 handlers.persistCRDTDoc(); 11622 }, LOCAL_SYNC_MANAGER_ORIGIN); 11623 } 11624 function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { 11625 const { isSave = false, isNewUndoLevel = false } = options; 11626 const entityId = getEntityId(objectType, objectId); 11627 const entityState = entityStates.get(entityId); 11628 const collectionState = collectionStates.get(objectType); 11629 if (entityState) { 11630 const { syncConfig, ydoc } = entityState; 11631 if (isNewUndoLevel && undoManager) { 11632 undoManager.stopCapturing?.(); 11633 } 11634 ydoc.transact(() => { 11635 log("updateCRDTDoc", "applying changes", entityId, { 11636 changedKeys: Object.keys(changes) 11637 }); 11638 syncConfig.applyChangesToCRDTDoc(ydoc, changes); 11639 if (isSave) { 11640 markEntityAsSaved(ydoc); 11641 } 11642 }, origin2); 11643 } 11644 if (collectionState && isSave) { 11645 collectionState.ydoc.transact(() => { 11646 markEntityAsSaved(collectionState.ydoc); 11647 }, origin2); 11648 } 11649 } 11650 const deferUpdateCRDTDoc = yieldToEventLoop(updateCRDTDoc); 11651 function updateOrDefer(objectType, objectId, changes, origin2, options = {}) { 11652 const hasRemotePeers = (getAwareness(objectType, objectId)?.getStates().size ?? 0) > 1; 11653 const update = hasRemotePeers ? updateCRDTDoc : deferUpdateCRDTDoc; 11654 update(objectType, objectId, changes, origin2, options); 11655 } 11656 async function _updateEntityRecord(objectType, objectId) { 11657 const entityId = getEntityId(objectType, objectId); 11658 const entityState = entityStates.get(entityId); 11659 if (!entityState) { 11660 log("updateEntityRecord", "no entity state", entityId); 11661 return; 11662 } 11663 const { handlers, syncConfig, ydoc } = entityState; 11664 const changes = syncConfig.getChangesFromCRDTDoc( 11665 ydoc, 11666 await handlers.getEditedRecord() 11667 ); 11668 const changedKeys = Object.keys(changes); 11669 if (0 === changedKeys.length) { 11670 return; 11671 } 11672 log("updateEntityRecord", "changes", entityId, { 11673 changedKeys 11674 }); 11675 handlers.editRecord(changes); 11676 } 11677 async function createPersistedCRDTDoc(objectType, objectId) { 11678 const entityId = getEntityId(objectType, objectId); 11679 const entityState = entityStates.get(entityId); 11680 if (!entityState?.ydoc) { 11681 return null; 11682 } 11683 await new Promise((resolve) => setTimeout(resolve, 0)); 11684 return serializeCrdtDoc(entityState.ydoc); 11685 } 11686 const internal = { 11687 applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), 11688 updateEntityRecord: debugWrap(_updateEntityRecord) 11689 }; 11690 return { 11691 createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), 11692 getAwareness, 11693 load: debugWrap(loadEntity), 11694 loadCollection: debugWrap(loadCollection), 11695 // Use getter to ensure we always return the current value of `undoManager`. 11696 get undoManager() { 11697 return undoManager; 11698 }, 11699 unload: debugWrap(unloadEntity), 11700 unloadAll: debugWrap(unloadAll), 11701 update: debugWrap(updateOrDefer) 11702 }; 11703 } 11704 11705 // node_modules/diff/libesm/diff/base.js 11706 var Diff = class { 11707 diff(oldStr, newStr, options = {}) { 11708 let callback; 11709 if (typeof options === "function") { 11710 callback = options; 11711 options = {}; 11712 } else if ("callback" in options) { 11713 callback = options.callback; 11714 } 11715 const oldString = this.castInput(oldStr, options); 11716 const newString = this.castInput(newStr, options); 11717 const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); 11718 const newTokens = this.removeEmpty(this.tokenize(newString, options)); 11719 return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); 11720 } 11721 diffWithOptionsObj(oldTokens, newTokens, options, callback) { 11722 var _a; 11723 const done = (value) => { 11724 value = this.postProcess(value, options); 11725 if (callback) { 11726 setTimeout(function() { 11727 callback(value); 11728 }, 0); 11729 return void 0; 11730 } else { 11731 return value; 11732 } 11733 }; 11734 const newLen = newTokens.length, oldLen = oldTokens.length; 11735 let editLength = 1; 11736 let maxEditLength = newLen + oldLen; 11737 if (options.maxEditLength != null) { 11738 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 11739 } 11740 const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; 11741 const abortAfterTimestamp = Date.now() + maxExecutionTime; 11742 const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; 11743 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); 11744 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11745 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); 11746 } 11747 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; 11748 const execEditLength = () => { 11749 for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 11750 let basePath; 11751 const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; 11752 if (removePath) { 11753 bestPath[diagonalPath - 1] = void 0; 11754 } 11755 let canAdd = false; 11756 if (addPath) { 11757 const addPathNewPos = addPath.oldPos - diagonalPath; 11758 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 11759 } 11760 const canRemove = removePath && removePath.oldPos + 1 < oldLen; 11761 if (!canAdd && !canRemove) { 11762 bestPath[diagonalPath] = void 0; 11763 continue; 11764 } 11765 if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { 11766 basePath = this.addToPath(addPath, true, false, 0, options); 11767 } else { 11768 basePath = this.addToPath(removePath, false, true, 1, options); 11769 } 11770 newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); 11771 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11772 return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; 11773 } else { 11774 bestPath[diagonalPath] = basePath; 11775 if (basePath.oldPos + 1 >= oldLen) { 11776 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 11777 } 11778 if (newPos + 1 >= newLen) { 11779 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 11780 } 11781 } 11782 } 11783 editLength++; 11784 }; 11785 if (callback) { 11786 (function exec() { 11787 setTimeout(function() { 11788 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 11789 return callback(void 0); 11790 } 11791 if (!execEditLength()) { 11792 exec(); 11793 } 11794 }, 0); 11795 })(); 11796 } else { 11797 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 11798 const ret = execEditLength(); 11799 if (ret) { 11800 return ret; 11801 } 11802 } 11803 } 11804 } 11805 addToPath(path, added, removed, oldPosInc, options) { 11806 const last2 = path.lastComponent; 11807 if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { 11808 return { 11809 oldPos: path.oldPos + oldPosInc, 11810 lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } 11811 }; 11812 } else { 11813 return { 11814 oldPos: path.oldPos + oldPosInc, 11815 lastComponent: { count: 1, added, removed, previousComponent: last2 } 11816 }; 11817 } 11818 } 11819 extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { 11820 const newLen = newTokens.length, oldLen = oldTokens.length; 11821 let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; 11822 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { 11823 newPos++; 11824 oldPos++; 11825 commonCount++; 11826 if (options.oneChangePerToken) { 11827 basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; 11828 } 11829 } 11830 if (commonCount && !options.oneChangePerToken) { 11831 basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; 11832 } 11833 basePath.oldPos = oldPos; 11834 return newPos; 11835 } 11836 equals(left, right, options) { 11837 if (options.comparator) { 11838 return options.comparator(left, right); 11839 } else { 11840 return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 11841 } 11842 } 11843 removeEmpty(array) { 11844 const ret = []; 11845 for (let i = 0; i < array.length; i++) { 11846 if (array[i]) { 11847 ret.push(array[i]); 11848 } 11849 } 11850 return ret; 11851 } 11852 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11853 castInput(value, options) { 11854 return value; 11855 } 11856 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11857 tokenize(value, options) { 11858 return Array.from(value); 11859 } 11860 join(chars) { 11861 return chars.join(""); 11862 } 11863 postProcess(changeObjects, options) { 11864 return changeObjects; 11865 } 11866 get useLongestToken() { 11867 return false; 11868 } 11869 buildValues(lastComponent, newTokens, oldTokens) { 11870 const components = []; 11871 let nextComponent; 11872 while (lastComponent) { 11873 components.push(lastComponent); 11874 nextComponent = lastComponent.previousComponent; 11875 delete lastComponent.previousComponent; 11876 lastComponent = nextComponent; 11877 } 11878 components.reverse(); 11879 const componentLen = components.length; 11880 let componentPos = 0, newPos = 0, oldPos = 0; 11881 for (; componentPos < componentLen; componentPos++) { 11882 const component = components[componentPos]; 11883 if (!component.removed) { 11884 if (!component.added && this.useLongestToken) { 11885 let value = newTokens.slice(newPos, newPos + component.count); 11886 value = value.map(function(value2, i) { 11887 const oldValue = oldTokens[oldPos + i]; 11888 return oldValue.length > value2.length ? oldValue : value2; 11889 }); 11890 component.value = this.join(value); 11891 } else { 11892 component.value = this.join(newTokens.slice(newPos, newPos + component.count)); 11893 } 11894 newPos += component.count; 11895 if (!component.added) { 11896 oldPos += component.count; 11897 } 11898 } else { 11899 component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); 11900 oldPos += component.count; 11901 } 11902 } 11903 return components; 11904 } 11905 }; 11906 11907 // node_modules/diff/libesm/diff/character.js 11908 var CharacterDiff = class extends Diff { 11909 }; 11910 var characterDiff = new CharacterDiff(); 11911 function diffChars(oldStr, newStr, options) { 11912 return characterDiff.diff(oldStr, newStr, options); 11913 } 11914 11915 // node_modules/diff/libesm/diff/line.js 11916 var LineDiff = class extends Diff { 11917 constructor() { 11918 super(...arguments); 11919 this.tokenize = tokenize; 11920 } 11921 equals(left, right, options) { 11922 if (options.ignoreWhitespace) { 11923 if (!options.newlineIsToken || !left.includes("\n")) { 11924 left = left.trim(); 11925 } 11926 if (!options.newlineIsToken || !right.includes("\n")) { 11927 right = right.trim(); 11928 } 11929 } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { 11930 if (left.endsWith("\n")) { 11931 left = left.slice(0, -1); 11932 } 11933 if (right.endsWith("\n")) { 11934 right = right.slice(0, -1); 11935 } 11936 } 11937 return super.equals(left, right, options); 11938 } 11939 }; 11940 var lineDiff = new LineDiff(); 11941 function diffLines(oldStr, newStr, options) { 11942 return lineDiff.diff(oldStr, newStr, options); 11943 } 11944 function tokenize(value, options) { 11945 if (options.stripTrailingCr) { 11946 value = value.replace(/\r\n/g, "\n"); 11947 } 11948 const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); 11949 if (!linesAndNewlines[linesAndNewlines.length - 1]) { 11950 linesAndNewlines.pop(); 11951 } 11952 for (let i = 0; i < linesAndNewlines.length; i++) { 11953 const line = linesAndNewlines[i]; 11954 if (i % 2 && !options.newlineIsToken) { 11955 retLines[retLines.length - 1] += line; 11956 } else { 11957 retLines.push(line); 11958 } 11959 } 11960 return retLines; 11961 } 11962 11963 // packages/sync/build-module/quill-delta/Delta.mjs 11964 var import_es62 = __toESM(require_es6(), 1); 11965 11966 // packages/sync/build-module/quill-delta/AttributeMap.mjs 11967 var import_es6 = __toESM(require_es6(), 1); 11968 function cloneDeep(value) { 11969 return JSON.parse(JSON.stringify(value)); 11970 } 11971 var AttributeMap; 11972 ((AttributeMap2) => { 11973 function compose(a = {}, b = {}, keepNull = false) { 11974 if (typeof a !== "object") { 11975 a = {}; 11976 } 11977 if (typeof b !== "object") { 11978 b = {}; 11979 } 11980 let attributes = cloneDeep(b); 11981 if (!keepNull) { 11982 attributes = Object.keys(attributes).reduce( 11983 (copy2, key) => { 11984 if (attributes[key] !== null || attributes[key] !== void 0) { 11985 copy2[key] = attributes[key]; 11986 } 11987 return copy2; 11988 }, 11989 {} 11990 ); 11991 } 11992 for (const key in a) { 11993 if (a[key] !== void 0 && b[key] === void 0) { 11994 attributes[key] = a[key]; 11995 } 11996 } 11997 return Object.keys(attributes).length > 0 ? attributes : void 0; 11998 } 11999 AttributeMap2.compose = compose; 12000 function diff(a = {}, b = {}) { 12001 if (typeof a !== "object") { 12002 a = {}; 12003 } 12004 if (typeof b !== "object") { 12005 b = {}; 12006 } 12007 const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { 12008 if (!(0, import_es6.default)(a[key], b[key])) { 12009 attrs[key] = b[key] === void 0 ? null : b[key]; 12010 } 12011 return attrs; 12012 }, {}); 12013 return Object.keys(attributes).length > 0 ? attributes : void 0; 12014 } 12015 AttributeMap2.diff = diff; 12016 function invert(attr = {}, base = {}) { 12017 attr = attr || {}; 12018 const baseInverted = Object.keys(base).reduce( 12019 (memo, key) => { 12020 if (base[key] !== attr[key] && attr[key] !== void 0) { 12021 memo[key] = base[key]; 12022 } 12023 return memo; 12024 }, 12025 {} 12026 ); 12027 return Object.keys(attr).reduce((memo, key) => { 12028 if (attr[key] !== base[key] && base[key] === void 0) { 12029 memo[key] = null; 12030 } 12031 return memo; 12032 }, baseInverted); 12033 } 12034 AttributeMap2.invert = invert; 12035 function transform(a, b, priority = false) { 12036 if (typeof a !== "object") { 12037 return b; 12038 } 12039 if (typeof b !== "object") { 12040 return void 0; 12041 } 12042 if (!priority) { 12043 return b; 12044 } 12045 const attributes = Object.keys(b).reduce( 12046 (attrs, key) => { 12047 if (a[key] === void 0) { 12048 attrs[key] = b[key]; 12049 } 12050 return attrs; 12051 }, 12052 {} 12053 ); 12054 return Object.keys(attributes).length > 0 ? attributes : void 0; 12055 } 12056 AttributeMap2.transform = transform; 12057 })(AttributeMap || (AttributeMap = {})); 12058 var AttributeMap_default = AttributeMap; 12059 12060 // packages/sync/build-module/quill-delta/Op.mjs 12061 var Op; 12062 ((Op2) => { 12063 function length2(op) { 12064 if (typeof op.delete === "number") { 12065 return op.delete; 12066 } else if (typeof op.retain === "number") { 12067 return op.retain; 12068 } else if (typeof op.retain === "object" && op.retain !== null) { 12069 return 1; 12070 } 12071 return typeof op.insert === "string" ? op.insert.length : 1; 12072 } 12073 Op2.length = length2; 12074 })(Op || (Op = {})); 12075 var Op_default = Op; 12076 12077 // packages/sync/build-module/quill-delta/OpIterator.mjs 12078 var Iterator = class { 12079 ops; 12080 index; 12081 offset; 12082 constructor(ops) { 12083 this.ops = ops; 12084 this.index = 0; 12085 this.offset = 0; 12086 } 12087 hasNext() { 12088 return this.peekLength() < Infinity; 12089 } 12090 next(length2) { 12091 if (!length2) { 12092 length2 = Infinity; 12093 } 12094 const nextOp = this.ops[this.index]; 12095 if (nextOp) { 12096 const offset = this.offset; 12097 const opLength = Op_default.length(nextOp); 12098 if (length2 >= opLength - offset) { 12099 length2 = opLength - offset; 12100 this.index += 1; 12101 this.offset = 0; 12102 } else { 12103 this.offset += length2; 12104 } 12105 if (typeof nextOp.delete === "number") { 12106 return { delete: length2 }; 12107 } 12108 const retOp = {}; 12109 if (nextOp.attributes) { 12110 retOp.attributes = nextOp.attributes; 12111 } 12112 if (typeof nextOp.retain === "number") { 12113 retOp.retain = length2; 12114 } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { 12115 retOp.retain = nextOp.retain; 12116 } else if (typeof nextOp.insert === "string") { 12117 retOp.insert = nextOp.insert.substr(offset, length2); 12118 } else { 12119 retOp.insert = nextOp.insert; 12120 } 12121 return retOp; 12122 } 12123 return { retain: Infinity }; 12124 } 12125 peek() { 12126 return this.ops[this.index]; 12127 } 12128 peekLength() { 12129 if (this.ops[this.index]) { 12130 return Op_default.length(this.ops[this.index]) - this.offset; 12131 } 12132 return Infinity; 12133 } 12134 peekType() { 12135 const op = this.ops[this.index]; 12136 if (op) { 12137 if (typeof op.delete === "number") { 12138 return "delete"; 12139 } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { 12140 return "retain"; 12141 } 12142 return "insert"; 12143 } 12144 return "retain"; 12145 } 12146 rest() { 12147 if (!this.hasNext()) { 12148 return []; 12149 } else if (this.offset === 0) { 12150 return this.ops.slice(this.index); 12151 } 12152 const offset = this.offset; 12153 const index = this.index; 12154 const next = this.next(); 12155 const rest = this.ops.slice(this.index); 12156 this.offset = offset; 12157 this.index = index; 12158 return [next].concat(rest); 12159 } 12160 }; 12161 12162 // packages/sync/build-module/quill-delta/Delta.mjs 12163 function cloneDeep2(value) { 12164 return JSON.parse(JSON.stringify(value)); 12165 } 12166 var NULL_CHARACTER = String.fromCharCode(0); 12167 var STRING_TOO_LARGE_THRESHOLD = 1e4; 12168 function normalizeChangeCounts(changes) { 12169 return changes.map((change) => ({ 12170 ...change, 12171 count: change.value.length 12172 })); 12173 } 12174 var getEmbedTypeAndData = (a, b) => { 12175 if (typeof a !== "object" || a === null) { 12176 throw new Error(`cannot retain a $typeof a}`); 12177 } 12178 if (typeof b !== "object" || b === null) { 12179 throw new Error(`cannot retain a $typeof b}`); 12180 } 12181 const embedType = Object.keys(a)[0]; 12182 if (!embedType || embedType !== Object.keys(b)[0]) { 12183 throw new Error( 12184 `embed types not matched: $embedType} != $Object.keys(b)[0]}` 12185 ); 12186 } 12187 return [embedType, a[embedType], b[embedType]]; 12188 }; 12189 var Delta = class _Delta { 12190 static Op = Op_default; 12191 static OpIterator = Iterator; 12192 static AttributeMap = AttributeMap_default; 12193 static handlers = {}; 12194 static registerEmbed(embedType, handler) { 12195 this.handlers[embedType] = handler; 12196 } 12197 static unregisterEmbed(embedType) { 12198 delete this.handlers[embedType]; 12199 } 12200 static getHandler(embedType) { 12201 const handler = this.handlers[embedType]; 12202 if (!handler) { 12203 throw new Error(`no handlers for embed type "$embedType}"`); 12204 } 12205 return handler; 12206 } 12207 ops; 12208 constructor(ops) { 12209 if (Array.isArray(ops)) { 12210 this.ops = ops; 12211 } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { 12212 this.ops = ops.ops; 12213 } else { 12214 this.ops = []; 12215 } 12216 } 12217 insert(arg, attributes) { 12218 const newOp = {}; 12219 if (typeof arg === "string" && arg.length === 0) { 12220 return this; 12221 } 12222 newOp.insert = arg; 12223 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12224 newOp.attributes = attributes; 12225 } 12226 return this.push(newOp); 12227 } 12228 delete(length2) { 12229 if (length2 <= 0) { 12230 return this; 12231 } 12232 return this.push({ delete: length2 }); 12233 } 12234 retain(length2, attributes) { 12235 if (typeof length2 === "number" && length2 <= 0) { 12236 return this; 12237 } 12238 const newOp = { retain: length2 }; 12239 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12240 newOp.attributes = attributes; 12241 } 12242 return this.push(newOp); 12243 } 12244 push(newOp) { 12245 let index = this.ops.length; 12246 let lastOp = this.ops[index - 1]; 12247 newOp = cloneDeep2(newOp); 12248 if (typeof lastOp === "object") { 12249 if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { 12250 this.ops[index - 1] = { 12251 delete: lastOp.delete + newOp.delete 12252 }; 12253 return this; 12254 } 12255 if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { 12256 index -= 1; 12257 lastOp = this.ops[index - 1]; 12258 if (typeof lastOp !== "object") { 12259 this.ops.unshift(newOp); 12260 return this; 12261 } 12262 } 12263 if ((0, import_es62.default)(newOp.attributes, lastOp.attributes)) { 12264 if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { 12265 this.ops[index - 1] = { 12266 insert: lastOp.insert + newOp.insert 12267 }; 12268 if (typeof newOp.attributes === "object") { 12269 this.ops[index - 1].attributes = newOp.attributes; 12270 } 12271 return this; 12272 } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { 12273 this.ops[index - 1] = { 12274 retain: lastOp.retain + newOp.retain 12275 }; 12276 if (typeof newOp.attributes === "object") { 12277 this.ops[index - 1].attributes = newOp.attributes; 12278 } 12279 return this; 12280 } 12281 } 12282 } 12283 if (index === this.ops.length) { 12284 this.ops.push(newOp); 12285 } else { 12286 this.ops.splice(index, 0, newOp); 12287 } 12288 return this; 12289 } 12290 chop() { 12291 const lastOp = this.ops[this.ops.length - 1]; 12292 if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { 12293 this.ops.pop(); 12294 } 12295 return this; 12296 } 12297 filter(predicate) { 12298 return this.ops.filter(predicate); 12299 } 12300 forEach(predicate) { 12301 this.ops.forEach(predicate); 12302 } 12303 map(predicate) { 12304 return this.ops.map(predicate); 12305 } 12306 partition(predicate) { 12307 const passed = []; 12308 const failed = []; 12309 this.forEach((op) => { 12310 const target = predicate(op) ? passed : failed; 12311 target.push(op); 12312 }); 12313 return [passed, failed]; 12314 } 12315 reduce(predicate, initialValue) { 12316 return this.ops.reduce(predicate, initialValue); 12317 } 12318 changeLength() { 12319 return this.reduce((length2, elem) => { 12320 if (elem.insert) { 12321 return length2 + Op_default.length(elem); 12322 } else if (elem.delete) { 12323 return length2 - elem.delete; 12324 } 12325 return length2; 12326 }, 0); 12327 } 12328 length() { 12329 return this.reduce((length2, elem) => { 12330 return length2 + Op_default.length(elem); 12331 }, 0); 12332 } 12333 slice(start = 0, end = Infinity) { 12334 const ops = []; 12335 const iter = new Iterator(this.ops); 12336 let index = 0; 12337 while (index < end && iter.hasNext()) { 12338 let nextOp; 12339 if (index < start) { 12340 nextOp = iter.next(start - index); 12341 } else { 12342 nextOp = iter.next(end - index); 12343 ops.push(nextOp); 12344 } 12345 index += Op_default.length(nextOp); 12346 } 12347 return new _Delta(ops); 12348 } 12349 compose(other) { 12350 const thisIter = new Iterator(this.ops); 12351 const otherIter = new Iterator(other.ops); 12352 const ops = []; 12353 const firstOther = otherIter.peek(); 12354 if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { 12355 let firstLeft = firstOther.retain; 12356 while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { 12357 firstLeft -= thisIter.peekLength(); 12358 ops.push(thisIter.next()); 12359 } 12360 if (firstOther.retain - firstLeft > 0) { 12361 otherIter.next(firstOther.retain - firstLeft); 12362 } 12363 } 12364 const delta = new _Delta(ops); 12365 while (thisIter.hasNext() || otherIter.hasNext()) { 12366 if (otherIter.peekType() === "insert") { 12367 delta.push(otherIter.next()); 12368 } else if (thisIter.peekType() === "delete") { 12369 delta.push(thisIter.next()); 12370 } else { 12371 const length2 = Math.min( 12372 thisIter.peekLength(), 12373 otherIter.peekLength() 12374 ); 12375 const thisOp = thisIter.next(length2); 12376 const otherOp = otherIter.next(length2); 12377 if (otherOp.retain) { 12378 const newOp = {}; 12379 if (typeof thisOp.retain === "number") { 12380 newOp.retain = typeof otherOp.retain === "number" ? length2 : otherOp.retain; 12381 } else if (typeof otherOp.retain === "number") { 12382 if (thisOp.retain === null || thisOp.retain === void 0) { 12383 newOp.insert = thisOp.insert; 12384 } else { 12385 newOp.retain = thisOp.retain; 12386 } 12387 } else { 12388 const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; 12389 const [embedType, thisData, otherData] = getEmbedTypeAndData( 12390 thisOp[action], 12391 otherOp.retain 12392 ); 12393 const handler = _Delta.getHandler(embedType); 12394 newOp[action] = { 12395 [embedType]: handler.compose( 12396 thisData, 12397 otherData, 12398 action === "retain" 12399 ) 12400 }; 12401 } 12402 const attributes = AttributeMap_default.compose( 12403 thisOp.attributes, 12404 otherOp.attributes, 12405 typeof thisOp.retain === "number" 12406 ); 12407 if (attributes) { 12408 newOp.attributes = attributes; 12409 } 12410 delta.push(newOp); 12411 if (!otherIter.hasNext() && (0, import_es62.default)(delta.ops[delta.ops.length - 1], newOp)) { 12412 const rest = new _Delta(thisIter.rest()); 12413 return delta.concat(rest).chop(); 12414 } 12415 } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { 12416 delta.push(otherOp); 12417 } 12418 } 12419 } 12420 return delta.chop(); 12421 } 12422 concat(other) { 12423 const delta = new _Delta(this.ops.slice()); 12424 if (other.ops.length > 0) { 12425 delta.push(other.ops[0]); 12426 delta.ops = delta.ops.concat(other.ops.slice(1)); 12427 } 12428 return delta; 12429 } 12430 diff(other) { 12431 if (this.ops === other.ops) { 12432 return new _Delta(); 12433 } 12434 const strings = this.deltasToStrings(other); 12435 const diffResult = normalizeChangeCounts( 12436 diffChars(strings[0], strings[1]) 12437 ); 12438 const thisIter = new Iterator(this.ops); 12439 const otherIter = new Iterator(other.ops); 12440 const retDelta = this.convertChangesToDelta( 12441 diffResult, 12442 thisIter, 12443 otherIter 12444 ); 12445 return retDelta.chop(); 12446 } 12447 eachLine(predicate, newline = "\n") { 12448 const iter = new Iterator(this.ops); 12449 let line = new _Delta(); 12450 let i = 0; 12451 while (iter.hasNext()) { 12452 if (iter.peekType() !== "insert") { 12453 return; 12454 } 12455 const thisOp = iter.peek(); 12456 const start = Op_default.length(thisOp) - iter.peekLength(); 12457 const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; 12458 if (index < 0) { 12459 line.push(iter.next()); 12460 } else if (index > 0) { 12461 line.push(iter.next(index)); 12462 } else { 12463 if (predicate(line, iter.next(1).attributes || {}, i) === false) { 12464 return; 12465 } 12466 i += 1; 12467 line = new _Delta(); 12468 } 12469 } 12470 if (line.length() > 0) { 12471 predicate(line, {}, i); 12472 } 12473 } 12474 invert(base) { 12475 const inverted = new _Delta(); 12476 this.reduce((baseIndex, op) => { 12477 if (op.insert) { 12478 inverted.delete(Op_default.length(op)); 12479 } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { 12480 inverted.retain(op.retain); 12481 return baseIndex + op.retain; 12482 } else if (op.delete || typeof op.retain === "number") { 12483 const length2 = op.delete || op.retain; 12484 const slice = base.slice(baseIndex, baseIndex + length2); 12485 slice.forEach((baseOp) => { 12486 if (op.delete) { 12487 inverted.push(baseOp); 12488 } else if (op.retain && op.attributes) { 12489 inverted.retain( 12490 Op_default.length(baseOp), 12491 AttributeMap_default.invert( 12492 op.attributes, 12493 baseOp.attributes 12494 ) 12495 ); 12496 } 12497 }); 12498 return baseIndex + length2; 12499 } else if (typeof op.retain === "object" && op.retain !== null) { 12500 const slice = base.slice(baseIndex, baseIndex + 1); 12501 const baseOp = new Iterator(slice.ops).next(); 12502 const [embedType, opData, baseOpData] = getEmbedTypeAndData( 12503 op.retain, 12504 baseOp.insert 12505 ); 12506 const handler = _Delta.getHandler(embedType); 12507 inverted.retain( 12508 { [embedType]: handler.invert(opData, baseOpData) }, 12509 AttributeMap_default.invert(op.attributes, baseOp.attributes) 12510 ); 12511 return baseIndex + 1; 12512 } 12513 return baseIndex; 12514 }, 0); 12515 return inverted.chop(); 12516 } 12517 transform(arg, priority = false) { 12518 priority = !!priority; 12519 if (typeof arg === "number") { 12520 return this.transformPosition(arg, priority); 12521 } 12522 const other = arg; 12523 const thisIter = new Iterator(this.ops); 12524 const otherIter = new Iterator(other.ops); 12525 const delta = new _Delta(); 12526 while (thisIter.hasNext() || otherIter.hasNext()) { 12527 if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { 12528 delta.retain(Op_default.length(thisIter.next())); 12529 } else if (otherIter.peekType() === "insert") { 12530 delta.push(otherIter.next()); 12531 } else { 12532 const length2 = Math.min( 12533 thisIter.peekLength(), 12534 otherIter.peekLength() 12535 ); 12536 const thisOp = thisIter.next(length2); 12537 const otherOp = otherIter.next(length2); 12538 if (thisOp.delete) { 12539 continue; 12540 } else if (otherOp.delete) { 12541 delta.push(otherOp); 12542 } else { 12543 const thisData = thisOp.retain; 12544 const otherData = otherOp.retain; 12545 let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length2; 12546 if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { 12547 const embedType = Object.keys(thisData)[0]; 12548 if (embedType === Object.keys(otherData)[0]) { 12549 const handler = _Delta.getHandler(embedType); 12550 if (handler) { 12551 transformedData = { 12552 [embedType]: handler.transform( 12553 thisData[embedType], 12554 otherData[embedType], 12555 priority 12556 ) 12557 }; 12558 } 12559 } 12560 } 12561 delta.retain( 12562 transformedData, 12563 AttributeMap_default.transform( 12564 thisOp.attributes, 12565 otherOp.attributes, 12566 priority 12567 ) 12568 ); 12569 } 12570 } 12571 } 12572 return delta.chop(); 12573 } 12574 transformPosition(index, priority = false) { 12575 priority = !!priority; 12576 const thisIter = new Iterator(this.ops); 12577 let offset = 0; 12578 while (thisIter.hasNext() && offset <= index) { 12579 const length2 = thisIter.peekLength(); 12580 const nextType = thisIter.peekType(); 12581 thisIter.next(); 12582 if (nextType === "delete") { 12583 index -= Math.min(length2, index - offset); 12584 continue; 12585 } else if (nextType === "insert" && (offset < index || !priority)) { 12586 index += length2; 12587 } 12588 offset += length2; 12589 } 12590 return index; 12591 } 12592 /** 12593 * Given a Delta and a cursor position, do a diff and attempt to adjust 12594 * the diff to place insertions or deletions at the cursor position. 12595 * 12596 * @todo There are at least a few known cases where this produces a corrupted 12597 * diff. When this is fixed, it should not be necessary to verify that the 12598 * transformed diff applies cleanly. 12599 * 12600 * @see import("@wordpress/core-data/src/utils/crdt-blocks").mergeRichTextUpdate() 12601 * 12602 * @param other - The other Delta to diff against. 12603 * @param cursorAfterChange - The cursor position index after the change. 12604 * @return A Delta that attempts to place insertions or deletions at the cursor position. 12605 */ 12606 diffWithCursor(other, cursorAfterChange) { 12607 if (this.ops === other.ops) { 12608 return new _Delta(); 12609 } 12610 const strings = this.deltasToStrings(other); 12611 const maxStringLength = Math.max( 12612 ...strings.map((str) => str.length) 12613 ); 12614 if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { 12615 const diffResult = normalizeChangeCounts( 12616 diffLines(strings[0], strings[1]) 12617 ); 12618 const thisIterLarge = new Iterator(this.ops); 12619 const otherIterLarge = new Iterator(other.ops); 12620 return this.convertChangesToDelta( 12621 diffResult, 12622 thisIterLarge, 12623 otherIterLarge 12624 ).chop(); 12625 } else if (cursorAfterChange === null) { 12626 return this.diff(other); 12627 } 12628 let diffs = normalizeChangeCounts( 12629 diffChars(strings[0], strings[1]) 12630 ); 12631 let lastDiffPosition = 0; 12632 const adjustedDiffs = []; 12633 for (let i = 0; i < diffs.length; i++) { 12634 const diff = diffs[i]; 12635 const segmentStart = lastDiffPosition; 12636 const segmentEnd = lastDiffPosition + (diff.count ?? 0); 12637 const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; 12638 const isUnchangedSegment = !diff.added && !diff.removed; 12639 const isRemovalSegment = diff.removed && !diff.added; 12640 const nextDiff = diffs[i + 1]; 12641 const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; 12642 if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { 12643 const movedSegments = this.tryMoveInsertionToCursor( 12644 diff, 12645 nextDiff, 12646 cursorAfterChange, 12647 segmentStart 12648 ); 12649 if (movedSegments) { 12650 adjustedDiffs.push(...movedSegments); 12651 i++; 12652 lastDiffPosition = segmentEnd; 12653 continue; 12654 } 12655 } 12656 if (isRemovalSegment) { 12657 const movedSegments = this.tryMoveDeletionToCursor( 12658 diff, 12659 adjustedDiffs, 12660 cursorAfterChange, 12661 lastDiffPosition 12662 ); 12663 if (movedSegments) { 12664 adjustedDiffs.pop(); 12665 adjustedDiffs.push(...movedSegments); 12666 lastDiffPosition += diff.count ?? 0; 12667 continue; 12668 } 12669 } 12670 adjustedDiffs.push(diff); 12671 if (!diff.added) { 12672 lastDiffPosition += diff.count ?? 0; 12673 } 12674 } 12675 diffs = adjustedDiffs; 12676 const thisIter = new Iterator(this.ops); 12677 const otherIter = new Iterator(other.ops); 12678 const retDelta = this.convertChangesToDelta( 12679 diffs, 12680 thisIter, 12681 otherIter 12682 ); 12683 return retDelta.chop(); 12684 } 12685 /** 12686 * Try to move an insertion operation from after an unchanged segment to the cursor position within it. 12687 * This is a "look-ahead" strategy. 12688 * 12689 * @param diff - The current unchanged diff segment. 12690 * @param nextDiff - The next diff segment (expected to be an insertion). 12691 * @param cursorAfterChange - The cursor position after the change. 12692 * @param segmentStart - The start position of the current segment. 12693 * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. 12694 */ 12695 tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { 12696 const nextDiffInsert = nextDiff.value; 12697 const insertLength = nextDiffInsert.length; 12698 const insertOffset = cursorAfterChange - segmentStart - insertLength; 12699 const textAtCursor = diff.value.substring( 12700 insertOffset, 12701 insertOffset + nextDiffInsert.length 12702 ); 12703 const isInsertMoveable = textAtCursor === nextDiffInsert; 12704 if (!isInsertMoveable) { 12705 return null; 12706 } 12707 const beforeCursor = diff.value.substring(0, insertOffset); 12708 const afterCursor = diff.value.substring(insertOffset); 12709 const result = []; 12710 if (beforeCursor.length > 0) { 12711 result.push({ 12712 value: beforeCursor, 12713 count: beforeCursor.length, 12714 added: false, 12715 removed: false 12716 }); 12717 } 12718 result.push(nextDiff); 12719 if (afterCursor.length > 0) { 12720 result.push({ 12721 value: afterCursor, 12722 count: afterCursor.length, 12723 added: false, 12724 removed: false 12725 }); 12726 } 12727 return result; 12728 } 12729 /** 12730 * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. 12731 * This is a "look-back" strategy. 12732 * 12733 * @param diff - The current deletion diff segment. 12734 * @param adjustedDiffs - The array of previously processed diff segments. 12735 * @param cursorAfterChange - The cursor position after the change. 12736 * @param lastDiffPosition - The position in the document up to (but not including) the current diff. 12737 * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. 12738 */ 12739 tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { 12740 const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; 12741 if (!prevDiff || prevDiff.added || prevDiff.removed) { 12742 return null; 12743 } 12744 const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); 12745 const prevSegmentEnd = lastDiffPosition; 12746 if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { 12747 return null; 12748 } 12749 const deletedChars = diff.value; 12750 const deleteOffset = cursorAfterChange - prevSegmentStart; 12751 const textAtCursor = prevDiff.value.substring( 12752 deleteOffset, 12753 deleteOffset + deletedChars.length 12754 ); 12755 const canBePlacedHere = textAtCursor === deletedChars; 12756 if (!canBePlacedHere) { 12757 return null; 12758 } 12759 const beforeCursor = prevDiff.value.substring(0, deleteOffset); 12760 const atAndAfterCursor = prevDiff.value.substring(deleteOffset); 12761 const deletionLength = diff.count ?? 0; 12762 const afterDeletion = atAndAfterCursor.substring(deletionLength); 12763 const result = []; 12764 if (beforeCursor.length > 0) { 12765 result.push({ 12766 value: beforeCursor, 12767 count: beforeCursor.length, 12768 added: false, 12769 removed: false 12770 }); 12771 } 12772 result.push(diff); 12773 if (afterDeletion.length > 0) { 12774 result.push({ 12775 value: afterDeletion, 12776 count: afterDeletion.length, 12777 added: false, 12778 removed: false 12779 }); 12780 } 12781 return result; 12782 } 12783 /** 12784 * Convert two Deltas to string representations for diffing. 12785 * 12786 * @param other - The other Delta to convert. 12787 * @return A tuple of [thisString, otherString]. 12788 */ 12789 deltasToStrings(other) { 12790 return [this, other].map((delta) => { 12791 return delta.map((op) => { 12792 if (op.insert !== null || op.insert !== void 0) { 12793 return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; 12794 } 12795 const prep = delta === other ? "on" : "with"; 12796 throw new Error( 12797 "diff() called " + prep + " non-document" 12798 ); 12799 }).join(""); 12800 }); 12801 } 12802 /** 12803 * Process diff changes and convert them to Delta operations. 12804 * 12805 * @param changes - The array of changes from the diff algorithm. 12806 * @param thisIter - Iterator for this Delta's operations. 12807 * @param otherIter - Iterator for the other Delta's operations. 12808 * @return A Delta containing the processed diff operations. 12809 */ 12810 convertChangesToDelta(changes, thisIter, otherIter) { 12811 const retDelta = new _Delta(); 12812 changes.forEach((component) => { 12813 let length2 = component.count ?? 0; 12814 while (length2 > 0) { 12815 let opLength = 0; 12816 if (component.added) { 12817 opLength = Math.min(otherIter.peekLength(), length2); 12818 retDelta.push(otherIter.next(opLength)); 12819 } else if (component.removed) { 12820 opLength = Math.min(length2, thisIter.peekLength()); 12821 thisIter.next(opLength); 12822 retDelta.delete(opLength); 12823 } else { 12824 opLength = Math.min( 12825 thisIter.peekLength(), 12826 otherIter.peekLength(), 12827 length2 12828 ); 12829 const thisOp = thisIter.next(opLength); 12830 const otherOp = otherIter.next(opLength); 12831 if ((0, import_es62.default)(thisOp.insert, otherOp.insert)) { 12832 retDelta.retain( 12833 opLength, 12834 AttributeMap_default.diff( 12835 thisOp.attributes, 12836 otherOp.attributes 12837 ) 12838 ); 12839 } else { 12840 retDelta.push(otherOp).delete(opLength); 12841 } 12842 } 12843 length2 -= opLength; 12844 } 12845 }); 12846 return retDelta; 12847 } 12848 }; 12849 var Delta_default = Delta; 12850 12851 // packages/sync/build-module/private-apis.mjs 12852 var privateApis = {}; 12853 lock(privateApis, { 12854 ConnectionErrorCode, 12855 createSyncManager, 12856 Delta: Delta_default, 12857 CRDT_DOC_META_PERSISTENCE_KEY, 12858 CRDT_RECORD_MAP_KEY, 12859 LOCAL_EDITOR_ORIGIN, 12860 LOCAL_UNDO_IGNORED_ORIGIN, 12861 retrySyncConnection: () => pollingManager.retryNow() 12862 }); 12863 12864 // packages/sync/build-module/index.mjs 12865 var YJS_VERSION = "13"; 12866 return __toCommonJS(index_exports); 12867 })(); 12868 (window.wp ||= {}).sync = wp.sync; 12869 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Thu Aug 13 08:20:23 2026 | Cross-referenced by PHPXref |