| [ 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 9982 // packages/sync/build-module/providers/index.mjs 9983 var import_hooks3 = __toESM(require_hooks(), 1); 9984 9985 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 9986 var import_hooks2 = __toESM(require_hooks(), 1); 9987 9988 // node_modules/y-protocols/sync.js 9989 var messageYjsSyncStep1 = 0; 9990 var messageYjsSyncStep2 = 1; 9991 var messageYjsUpdate = 2; 9992 var writeSyncStep1 = (encoder, doc2) => { 9993 writeVarUint(encoder, messageYjsSyncStep1); 9994 const sv = encodeStateVector(doc2); 9995 writeVarUint8Array(encoder, sv); 9996 }; 9997 var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { 9998 writeVarUint(encoder, messageYjsSyncStep2); 9999 writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); 10000 }; 10001 var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); 10002 var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { 10003 try { 10004 applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); 10005 } catch (error) { 10006 if (errorHandler != null) errorHandler( 10007 /** @type {Error} */ 10008 error 10009 ); 10010 console.error("Caught error while handling a Yjs update", error); 10011 } 10012 }; 10013 var readUpdate2 = readSyncStep2; 10014 var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { 10015 const messageType = readVarUint(decoder); 10016 switch (messageType) { 10017 case messageYjsSyncStep1: 10018 readSyncStep1(decoder, encoder, doc2); 10019 break; 10020 case messageYjsSyncStep2: 10021 readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); 10022 break; 10023 case messageYjsUpdate: 10024 readUpdate2(decoder, doc2, transactionOrigin, errorHandler); 10025 break; 10026 default: 10027 throw new Error("Unknown message type"); 10028 } 10029 return messageType; 10030 }; 10031 10032 // packages/sync/build-module/providers/http-polling/config.mjs 10033 var import_hooks = __toESM(require_hooks(), 1); 10034 var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; 10035 var ERROR_RETRY_DELAYS_SOLO_MS = [ 10036 2e3, 10037 4e3, 10038 8e3, 10039 12e3 10040 // Solo: 26s total retry time solo before dialog 10041 ]; 10042 var ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS = [ 10043 1e3, 10044 2e3, 10045 4e3, 10046 8e3 10047 // With collaborators: 15s total retry time before dialog 10048 ]; 10049 var DISCONNECT_DIALOG_RETRY_MS = 3e4; 10050 var MANUAL_RETRY_INTERVAL_MS = 15e3; 10051 var MAX_ENCODED_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; 10052 var MAX_UPDATE_SIZE_IN_BYTES = Math.floor(MAX_ENCODED_UPDATE_SIZE_IN_BYTES / 4) * 3; 10053 var MAX_ROOMS_PER_REQUEST = 50; 10054 var MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES = 15 * 1024 * 1024; 10055 var MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES = 2 * 1024 * 1024; 10056 var DEFAULT_POLLING_INTERVAL_IN_MS = 4e3; 10057 var DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = 1e3; 10058 function getFilteredPollingInterval(hookName, defaultInterval) { 10059 const filteredInterval = (0, import_hooks.applyFilters)(hookName, defaultInterval); 10060 if (typeof filteredInterval !== "number" || !Number.isFinite(filteredInterval) || filteredInterval <= 0) { 10061 return defaultInterval; 10062 } 10063 return Math.min(filteredInterval, defaultInterval); 10064 } 10065 var POLLING_INTERVAL_IN_MS = getFilteredPollingInterval( 10066 "sync.pollingManager.pollingInterval", 10067 DEFAULT_POLLING_INTERVAL_IN_MS 10068 ); 10069 var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = getFilteredPollingInterval( 10070 "sync.pollingManager.pollingIntervalWithCollaborators", 10071 DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS 10072 ); 10073 var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; 10074 10075 // packages/sync/build-module/providers/http-polling/types.mjs 10076 var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { 10077 SyncUpdateType2["COMPACTION"] = "compaction"; 10078 SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; 10079 SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; 10080 SyncUpdateType2["UPDATE"] = "update"; 10081 return SyncUpdateType2; 10082 })(SyncUpdateType || {}); 10083 10084 // packages/sync/build-module/providers/http-polling/utils.mjs 10085 var import_api_fetch = __toESM(require_api_fetch(), 1); 10086 var SYNC_API_PATH = "/wp-sync/v1/updates"; 10087 function uint8ArrayToBase64(data) { 10088 let binary = ""; 10089 const len = data.byteLength; 10090 for (let i = 0; i < len; i++) { 10091 binary += String.fromCharCode(data[i]); 10092 } 10093 return globalThis.btoa(binary); 10094 } 10095 function base64ToUint8Array(base64) { 10096 const binaryString = globalThis.atob(base64); 10097 const len = binaryString.length; 10098 const bytes = new Uint8Array(len); 10099 for (let i = 0; i < len; i++) { 10100 bytes[i] = binaryString.charCodeAt(i); 10101 } 10102 return bytes; 10103 } 10104 function createSyncUpdate(data, type) { 10105 return { 10106 data: uint8ArrayToBase64(data), 10107 type 10108 }; 10109 } 10110 function createUpdateQueue(initial = [], paused = true) { 10111 let isPaused = paused; 10112 const updates = [...initial]; 10113 return { 10114 add(update) { 10115 updates.push(update); 10116 }, 10117 addBulk(bulkUpdates) { 10118 if (0 === bulkUpdates.length) { 10119 return; 10120 } 10121 updates.push(...bulkUpdates); 10122 }, 10123 clear() { 10124 updates.splice(0, updates.length); 10125 }, 10126 get() { 10127 if (isPaused) { 10128 return []; 10129 } 10130 return updates.splice(0, updates.length); 10131 }, 10132 pause() { 10133 isPaused = true; 10134 }, 10135 peek() { 10136 if (isPaused) { 10137 return []; 10138 } 10139 return [...updates]; 10140 }, 10141 restore(restoredUpdates) { 10142 const filtered = restoredUpdates.filter( 10143 (u) => u.type !== SyncUpdateType.COMPACTION 10144 ); 10145 if (0 === filtered.length) { 10146 return; 10147 } 10148 updates.unshift(...filtered); 10149 }, 10150 restoreExact(restoredUpdates) { 10151 if (0 === restoredUpdates.length) { 10152 return; 10153 } 10154 updates.unshift(...restoredUpdates); 10155 }, 10156 resume() { 10157 isPaused = false; 10158 }, 10159 size() { 10160 return updates.length; 10161 }, 10162 take(count) { 10163 if (isPaused || count <= 0) { 10164 return []; 10165 } 10166 return updates.splice(0, count); 10167 } 10168 }; 10169 } 10170 function postSyncUpdate(payload) { 10171 return (0, import_api_fetch.default)({ 10172 method: "POST", 10173 path: SYNC_API_PATH, 10174 data: payload 10175 }); 10176 } 10177 function postSyncUpdateNonBlocking(payload) { 10178 if (payload.rooms.length === 0) { 10179 return; 10180 } 10181 (0, import_api_fetch.default)({ 10182 method: "POST", 10183 path: SYNC_API_PATH, 10184 data: payload, 10185 keepalive: true 10186 }).catch(() => { 10187 }); 10188 } 10189 function intValueOrDefault(value, defaultValue) { 10190 const intValue = parseInt(String(value), 10); 10191 return isNaN(intValue) ? defaultValue : intValue; 10192 } 10193 function rotateWindow(items, offset, size2) { 10194 if (items.length === 0) { 10195 return { window: [], nextOffset: 0 }; 10196 } 10197 const start = (offset % items.length + items.length) % items.length; 10198 const wrapped = [...items.slice(start), ...items.slice(0, start)]; 10199 return { 10200 window: wrapped.slice(0, Math.max(0, size2)), 10201 nextOffset: (start + Math.max(0, size2)) % items.length 10202 }; 10203 } 10204 10205 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 10206 var POLLING_MANAGER_ORIGIN = "polling-manager"; 10207 function isForbiddenError(error) { 10208 return error?.data?.status === 403; 10209 } 10210 function isRequestBodyTooLargeError(error) { 10211 return error?.data?.status === 413 && error?.code === "rest_sync_body_too_large"; 10212 } 10213 function isProtocolMismatchError(error) { 10214 return error?.code === "rest_sync_protocol_mismatch"; 10215 } 10216 function handleForbiddenError(error, requestedRooms) { 10217 const requestedRoomNames = new Set( 10218 requestedRooms.map((room) => room.room) 10219 ); 10220 const forbiddenRooms = Array.isArray(error.data.rooms) ? error.data.rooms.filter((room) => requestedRoomNames.has(room)) : []; 10221 if (forbiddenRooms.length > 0) { 10222 for (const room of forbiddenRooms) { 10223 const state = roomStates.get(room); 10224 if (state) { 10225 state.log( 10226 "Permission denied, unregistering room", 10227 { error }, 10228 "error", 10229 true 10230 // force 10231 ); 10232 unregisterRoom(room, { sendDisconnectSignal: false }); 10233 } 10234 } 10235 for (const room of requestedRooms) { 10236 if (forbiddenRooms.includes(room.room)) { 10237 continue; 10238 } 10239 if (!roomStates.has(room.room)) { 10240 continue; 10241 } 10242 const remainingState = roomStates.get(room.room); 10243 if (room.updates.length > 0) { 10244 remainingState.updateQueue.restore(room.updates); 10245 } 10246 } 10247 } else { 10248 const rooms = [...roomStates.keys()]; 10249 for (const room of rooms) { 10250 const state = roomStates.get(room); 10251 if (state) { 10252 state.log( 10253 "Permission denied, unregistering room", 10254 { error }, 10255 "error", 10256 true 10257 // force 10258 ); 10259 unregisterRoom(room, { sendDisconnectSignal: false }); 10260 } 10261 } 10262 } 10263 } 10264 var roomStates = /* @__PURE__ */ new Map(); 10265 function createDeprecatedCompactionUpdate(updates) { 10266 const mergeable = updates.filter( 10267 (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( 10268 u.type 10269 ) 10270 ).map((u) => base64ToUint8Array(u.data)); 10271 return createSyncUpdate( 10272 mergeUpdatesV2(mergeable), 10273 SyncUpdateType.COMPACTION 10274 ); 10275 } 10276 function createSyncStep1Update(doc2) { 10277 const encoder = createEncoder(); 10278 writeSyncStep1(encoder, doc2); 10279 return createSyncUpdate( 10280 toUint8Array(encoder), 10281 SyncUpdateType.SYNC_STEP_1 10282 ); 10283 } 10284 function createSyncStep2Update(doc2, step1) { 10285 const decoder = createDecoder(step1); 10286 const encoder = createEncoder(); 10287 readSyncMessage( 10288 decoder, 10289 encoder, 10290 doc2, 10291 POLLING_MANAGER_ORIGIN 10292 ); 10293 return createSyncUpdate( 10294 toUint8Array(encoder), 10295 SyncUpdateType.SYNC_STEP_2 10296 ); 10297 } 10298 function processAwarenessUpdate(state, awareness) { 10299 const currentStates = awareness.getStates(); 10300 const added = /* @__PURE__ */ new Set(); 10301 const updated = /* @__PURE__ */ new Set(); 10302 const removed = new Set( 10303 Array.from(currentStates.keys()).filter( 10304 (clientId) => !state[clientId] 10305 ) 10306 ); 10307 Object.entries(state).forEach(([clientIdString, awarenessState]) => { 10308 const clientId = Number(clientIdString); 10309 if (clientId === awareness.clientID) { 10310 return; 10311 } 10312 if (null === awarenessState) { 10313 currentStates.delete(clientId); 10314 removed.add(clientId); 10315 return; 10316 } 10317 if (!currentStates.has(clientId)) { 10318 currentStates.set(clientId, awarenessState); 10319 added.add(clientId); 10320 return; 10321 } 10322 const currentState = currentStates.get(clientId); 10323 if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { 10324 currentStates.set(clientId, awarenessState); 10325 updated.add(clientId); 10326 } 10327 }); 10328 if (added.size + updated.size > 0) { 10329 awareness.emit("change", [ 10330 { 10331 added: Array.from(added), 10332 updated: Array.from(updated), 10333 // Left blank on purpose, as the removal of clients is handled in the if condition below. 10334 removed: [] 10335 } 10336 ]); 10337 } 10338 if (removed.size > 0) { 10339 removeAwarenessStates( 10340 awareness, 10341 Array.from(removed), 10342 POLLING_MANAGER_ORIGIN 10343 ); 10344 } 10345 } 10346 function processDocUpdate(update, doc2) { 10347 const data = base64ToUint8Array(update.data); 10348 switch (update.type) { 10349 case SyncUpdateType.SYNC_STEP_1: { 10350 return createSyncStep2Update(doc2, data); 10351 } 10352 case SyncUpdateType.SYNC_STEP_2: { 10353 const decoder = createDecoder(data); 10354 const encoder = createEncoder(); 10355 readSyncMessage( 10356 decoder, 10357 encoder, 10358 doc2, 10359 POLLING_MANAGER_ORIGIN 10360 ); 10361 return; 10362 } 10363 case SyncUpdateType.COMPACTION: 10364 case SyncUpdateType.UPDATE: { 10365 applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); 10366 } 10367 } 10368 } 10369 function checkConnectionLimit(awareness, roomState) { 10370 if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { 10371 return false; 10372 } 10373 hasCheckedConnectionLimit = true; 10374 const maxClientsPerRoom = (0, import_hooks2.applyFilters)( 10375 "sync.pollingProvider.maxClientsPerRoom", 10376 DEFAULT_CLIENT_LIMIT_PER_ROOM, 10377 roomState.room 10378 ); 10379 const clientCount = Object.keys(awareness).length; 10380 const validatedLimit = intValueOrDefault( 10381 maxClientsPerRoom, 10382 DEFAULT_CLIENT_LIMIT_PER_ROOM 10383 ); 10384 if (clientCount > validatedLimit) { 10385 roomState.log("Connection limit exceeded", { 10386 clientCount, 10387 maxClientsPerRoom: validatedLimit, 10388 room: roomState.room 10389 }); 10390 return true; 10391 } 10392 return false; 10393 } 10394 var areListenersRegistered = false; 10395 var consecutiveFailures = 0; 10396 var hasCheckedConnectionLimit = false; 10397 var isManualRetry = false; 10398 var hasCollaborators = false; 10399 var isActiveBrowser = "visible" === document.visibilityState; 10400 var isPolling = false; 10401 var isUnloadPending = false; 10402 var pollInterval = POLLING_INTERVAL_IN_MS; 10403 var pollingTimeoutId = null; 10404 var syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10405 var roomOverflowOffset = 0; 10406 function handleBeforeUnload() { 10407 isUnloadPending = true; 10408 } 10409 function handlePageHide() { 10410 const rooms = Array.from(roomStates.entries()).map( 10411 ([room, state]) => ({ 10412 after: 0, 10413 awareness: null, 10414 client_id: state.clientId, 10415 room, 10416 updates: [] 10417 }) 10418 ); 10419 for (let i = 0; i < rooms.length; i += MAX_ROOMS_PER_REQUEST) { 10420 postSyncUpdateNonBlocking({ 10421 rooms: rooms.slice(i, i + MAX_ROOMS_PER_REQUEST) 10422 }); 10423 } 10424 } 10425 function handleVisibilityChange() { 10426 const wasActive = isActiveBrowser; 10427 isActiveBrowser = document.visibilityState === "visible"; 10428 if (isActiveBrowser && !wasActive) { 10429 if (pollingTimeoutId) { 10430 clearTimeout(pollingTimeoutId); 10431 pollingTimeoutId = null; 10432 poll(); 10433 } 10434 } 10435 } 10436 function selectRoomsForRequest() { 10437 const allRooms = Array.from(roomStates.values()); 10438 if (allRooms.length <= MAX_ROOMS_PER_REQUEST) { 10439 return allRooms; 10440 } 10441 const primaryRoom = allRooms.find((state) => state.isPrimaryRoom); 10442 const overflowRooms = allRooms.filter((state) => state !== primaryRoom); 10443 const overflowSlotsPerRequest = MAX_ROOMS_PER_REQUEST - (primaryRoom ? 1 : 0); 10444 const { window: overflowSlice, nextOffset } = rotateWindow( 10445 overflowRooms, 10446 roomOverflowOffset, 10447 overflowSlotsPerRequest 10448 ); 10449 roomOverflowOffset = nextOffset; 10450 if (primaryRoom) { 10451 return [primaryRoom, ...overflowSlice]; 10452 } 10453 return overflowSlice; 10454 } 10455 var textEncoder = new TextEncoder(); 10456 function getJsonByteLength(value) { 10457 return textEncoder.encode(JSON.stringify(value)).byteLength; 10458 } 10459 function createPayloadRoom(state, updates = []) { 10460 return { 10461 after: state.endCursor ?? 0, 10462 awareness: state.localAwarenessState, 10463 client_id: state.clientId, 10464 room: state.room, 10465 updates 10466 }; 10467 } 10468 function getUpdatePayloadSizeDelta(existingUpdateCount, update) { 10469 const commaSize = existingUpdateCount === 0 ? 0 : 1; 10470 return commaSize + getJsonByteLength(update); 10471 } 10472 function buildPayloadForRequest(selectedRoomStates) { 10473 const payload = { rooms: [] }; 10474 const roomsInRequest = []; 10475 for (const state of selectedRoomStates) { 10476 const room = createPayloadRoom(state); 10477 const candidate = { rooms: [...payload.rooms, room] }; 10478 if (payload.rooms.length > 0 && getJsonByteLength(candidate) > syncRequestBodySizeLimit) { 10479 break; 10480 } 10481 payload.rooms.push(room); 10482 roomsInRequest.push(state); 10483 } 10484 const pendingUpdates = roomsInRequest.map( 10485 (state) => state.updateQueue.peek() 10486 ); 10487 const sentUpdateCounts = roomsInRequest.map(() => 0); 10488 let payloadSize = getJsonByteLength(payload); 10489 let addedUpdate = true; 10490 while (addedUpdate) { 10491 addedUpdate = false; 10492 for (let i = 0; i < roomsInRequest.length; i++) { 10493 const update = pendingUpdates[i][sentUpdateCounts[i]]; 10494 if (!update) { 10495 continue; 10496 } 10497 const sizeDelta = getUpdatePayloadSizeDelta( 10498 sentUpdateCounts[i], 10499 update 10500 ); 10501 if (payloadSize + sizeDelta > syncRequestBodySizeLimit) { 10502 continue; 10503 } 10504 sentUpdateCounts[i]++; 10505 payloadSize += sizeDelta; 10506 addedUpdate = true; 10507 } 10508 } 10509 for (let i = 0; i < roomsInRequest.length; i++) { 10510 payload.rooms[i].updates = roomsInRequest[i].updateQueue.take( 10511 sentUpdateCounts[i] 10512 ); 10513 } 10514 return { payload, roomsInRequest }; 10515 } 10516 function restoreExactUpdates(payload) { 10517 for (const room of payload.rooms) { 10518 if (!roomStates.has(room.room) || room.updates.length === 0) { 10519 continue; 10520 } 10521 roomStates.get(room.room).updateQueue.restoreExact(room.updates); 10522 } 10523 } 10524 function poll() { 10525 isPolling = true; 10526 pollingTimeoutId = null; 10527 async function start() { 10528 if (0 === roomStates.size) { 10529 isPolling = false; 10530 return; 10531 } 10532 isUnloadPending = false; 10533 const { payload, roomsInRequest } = buildPayloadForRequest( 10534 selectRoomsForRequest() 10535 ); 10536 roomsInRequest.forEach((state) => { 10537 state.onStatusChange({ status: "connecting" }); 10538 }); 10539 try { 10540 const { rooms } = await postSyncUpdate(payload); 10541 consecutiveFailures = 0; 10542 isManualRetry = false; 10543 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10544 roomsInRequest.forEach((state) => { 10545 if (roomStates.get(state.room) !== state) { 10546 return; 10547 } 10548 state.onStatusChange({ status: "connected" }); 10549 }); 10550 hasCollaborators = false; 10551 rooms.forEach((room) => { 10552 if (!roomStates.has(room.room)) { 10553 return; 10554 } 10555 const roomState = roomStates.get(room.room); 10556 roomState.endCursor = room.end_cursor; 10557 if (checkConnectionLimit(room.awareness, roomState)) { 10558 roomState.onStatusChange({ 10559 status: "disconnected", 10560 error: new ConnectionError( 10561 ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, 10562 "Connection limit exceeded" 10563 ) 10564 }); 10565 unregisterRoom(room.room); 10566 return; 10567 } 10568 roomState.processAwarenessUpdate(room.awareness); 10569 if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { 10570 hasCollaborators = true; 10571 roomStates.forEach((state) => { 10572 state.updateQueue.resume(); 10573 }); 10574 } 10575 const responseUpdates = []; 10576 for (const update of room.updates) { 10577 try { 10578 const response = roomState.processDocUpdate(update); 10579 if (response) { 10580 responseUpdates.push(response); 10581 } 10582 } catch (error) { 10583 roomState.log( 10584 "Failed to apply sync update", 10585 { error, update }, 10586 "error", 10587 true 10588 // force 10589 ); 10590 } 10591 } 10592 roomState.updateQueue.addBulk(responseUpdates); 10593 if (room.should_compact) { 10594 roomState.log("Server requested compaction update"); 10595 roomState.updateQueue.clear(); 10596 roomState.updateQueue.add( 10597 roomState.createCompactionUpdate() 10598 ); 10599 } else if (room.compaction_request) { 10600 roomState.log("Server requested (old) compaction update"); 10601 roomState.updateQueue.add( 10602 createDeprecatedCompactionUpdate( 10603 room.compaction_request 10604 ) 10605 ); 10606 } 10607 }); 10608 if (isActiveBrowser && hasCollaborators) { 10609 pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; 10610 } else if (isActiveBrowser) { 10611 pollInterval = POLLING_INTERVAL_IN_MS; 10612 } else { 10613 pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; 10614 } 10615 } catch (error) { 10616 if (isForbiddenError(error)) { 10617 handleForbiddenError(error, payload.rooms); 10618 if (roomStates.size === 0) { 10619 isPolling = false; 10620 return; 10621 } 10622 } else if (isRequestBodyTooLargeError(error)) { 10623 syncRequestBodySizeLimit = Math.max( 10624 MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES, 10625 Math.floor(syncRequestBodySizeLimit / 2) 10626 ); 10627 pollInterval = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS[0] : ERROR_RETRY_DELAYS_SOLO_MS[0]; 10628 restoreExactUpdates(payload); 10629 for (const room of payload.rooms) { 10630 if (!roomStates.has(room.room)) { 10631 continue; 10632 } 10633 roomStates.get(room.room).log( 10634 "Sync request body too large, retrying with smaller batches", 10635 { 10636 error, 10637 nextPoll: pollInterval, 10638 syncRequestBodySizeLimit 10639 }, 10640 "error", 10641 true 10642 // force 10643 ); 10644 } 10645 } else if (isProtocolMismatchError(error)) { 10646 const affectedRooms = [...roomStates.entries()]; 10647 for (const [, state] of affectedRooms) { 10648 state.onStatusChange({ 10649 status: "disconnected", 10650 error: new ConnectionError( 10651 ConnectionErrorCode.PROTOCOL_MISMATCH, 10652 "Protocol mismatch between client and server" 10653 ) 10654 }); 10655 } 10656 for (const [room] of affectedRooms) { 10657 unregisterRoom(room, { sendDisconnectSignal: false }); 10658 } 10659 isPolling = false; 10660 return; 10661 } else { 10662 consecutiveFailures++; 10663 const retrySchedule = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS : ERROR_RETRY_DELAYS_SOLO_MS; 10664 if (consecutiveFailures <= retrySchedule.length) { 10665 pollInterval = retrySchedule[consecutiveFailures - 1]; 10666 } else { 10667 pollInterval = DISCONNECT_DIALOG_RETRY_MS; 10668 } 10669 if (isManualRetry) { 10670 pollInterval = MANUAL_RETRY_INTERVAL_MS; 10671 isManualRetry = false; 10672 } 10673 for (const room of payload.rooms) { 10674 if (!roomStates.has(room.room)) { 10675 continue; 10676 } 10677 const state = roomStates.get(room.room); 10678 if (room.updates.length > 0 && state.endCursor > 0) { 10679 state.updateQueue.clear(); 10680 state.updateQueue.add(state.createCompactionUpdate()); 10681 } else if (room.updates.length > 0) { 10682 state.updateQueue.restore(room.updates); 10683 } 10684 state.log( 10685 "Error posting sync update, will retry with backoff", 10686 { error, nextPoll: pollInterval }, 10687 "error", 10688 true 10689 // force 10690 ); 10691 } 10692 if (!isUnloadPending) { 10693 const backgroundRetriesFailed = consecutiveFailures > retrySchedule.length; 10694 roomsInRequest.forEach((state) => { 10695 if (roomStates.get(state.room) !== state) { 10696 return; 10697 } 10698 state.onStatusChange({ 10699 status: "disconnected", 10700 canManuallyRetry: true, 10701 consecutiveFailures, 10702 backgroundRetriesFailed, 10703 willAutoRetryInMs: pollInterval 10704 }); 10705 }); 10706 } 10707 } 10708 } 10709 pollingTimeoutId = setTimeout(poll, pollInterval); 10710 } 10711 void start(); 10712 } 10713 function registerRoom({ 10714 room, 10715 doc: doc2, 10716 awareness, 10717 log, 10718 onStatusChange 10719 }) { 10720 if (roomStates.has(room)) { 10721 return; 10722 } 10723 const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); 10724 const isPrimaryRoom = 0 === roomStates.size; 10725 function onAwarenessUpdate() { 10726 roomState.localAwarenessState = awareness.getLocalState() ?? {}; 10727 } 10728 function onDocUpdate(update, origin2) { 10729 if (POLLING_MANAGER_ORIGIN === origin2) { 10730 return; 10731 } 10732 if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { 10733 const state = roomStates.get(room); 10734 if (!state) { 10735 return; 10736 } 10737 state.log("Document size limit exceeded", { 10738 maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, 10739 updateSizeInBytes: update.byteLength 10740 }); 10741 state.onStatusChange({ 10742 status: "disconnected", 10743 error: new ConnectionError( 10744 ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, 10745 "Document size limit exceeded" 10746 ) 10747 }); 10748 unregisterRoom(room); 10749 return; 10750 } 10751 updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); 10752 } 10753 function unregister() { 10754 doc2.off("updateV2", onDocUpdate); 10755 awareness.off("change", onAwarenessUpdate); 10756 updateQueue.clear(); 10757 } 10758 const roomState = { 10759 clientId: doc2.clientID, 10760 createCompactionUpdate: () => createSyncUpdate( 10761 encodeStateAsUpdateV2(doc2), 10762 SyncUpdateType.COMPACTION 10763 ), 10764 endCursor: 0, 10765 isPrimaryRoom, 10766 localAwarenessState: awareness.getLocalState() ?? {}, 10767 log, 10768 onStatusChange, 10769 processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), 10770 processDocUpdate: (update) => processDocUpdate(update, doc2), 10771 room, 10772 unregister, 10773 updateQueue 10774 }; 10775 doc2.on("updateV2", onDocUpdate); 10776 awareness.on("change", onAwarenessUpdate); 10777 roomStates.set(room, roomState); 10778 if (!areListenersRegistered) { 10779 window.addEventListener("beforeunload", handleBeforeUnload); 10780 window.addEventListener("pagehide", handlePageHide); 10781 document.addEventListener("visibilitychange", handleVisibilityChange); 10782 areListenersRegistered = true; 10783 } 10784 if (!isPolling) { 10785 poll(); 10786 } 10787 } 10788 function unregisterRoom(room, { sendDisconnectSignal = true } = {}) { 10789 const state = roomStates.get(room); 10790 if (state) { 10791 if (sendDisconnectSignal) { 10792 const rooms = [ 10793 { 10794 after: 0, 10795 awareness: null, 10796 client_id: state.clientId, 10797 room, 10798 updates: [] 10799 } 10800 ]; 10801 postSyncUpdateNonBlocking({ rooms }); 10802 } 10803 state.unregister(); 10804 roomStates.delete(room); 10805 } 10806 if (0 === roomStates.size && areListenersRegistered) { 10807 window.removeEventListener("beforeunload", handleBeforeUnload); 10808 window.removeEventListener("pagehide", handlePageHide); 10809 document.removeEventListener( 10810 "visibilitychange", 10811 handleVisibilityChange 10812 ); 10813 areListenersRegistered = false; 10814 hasCheckedConnectionLimit = false; 10815 consecutiveFailures = 0; 10816 roomOverflowOffset = 0; 10817 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10818 } 10819 } 10820 function retryNow() { 10821 isManualRetry = true; 10822 if (pollingTimeoutId) { 10823 clearTimeout(pollingTimeoutId); 10824 pollingTimeoutId = null; 10825 poll(); 10826 } 10827 } 10828 var pollingManager = { 10829 registerRoom, 10830 retryNow, 10831 unregisterRoom 10832 }; 10833 10834 // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs 10835 var HttpPollingProvider = class extends ObservableV2 { 10836 constructor(options) { 10837 super(); 10838 this.options = options; 10839 this.log("Initializing", { room: options.room }); 10840 this.awareness = options.awareness ?? new Awareness(options.ydoc); 10841 this.connect(); 10842 } 10843 awareness; 10844 status = "disconnected"; 10845 /** 10846 * Connect to the endpoint and initialize sync. 10847 */ 10848 connect() { 10849 this.log("Connecting"); 10850 pollingManager.registerRoom({ 10851 room: this.options.room, 10852 doc: this.options.ydoc, 10853 awareness: this.awareness, 10854 log: this.log, 10855 onStatusChange: this.emitStatus 10856 }); 10857 } 10858 /** 10859 * Destroy the provider and cleanup resources. 10860 */ 10861 destroy() { 10862 this.disconnect(); 10863 super.destroy(); 10864 } 10865 /** 10866 * Disconnect the provider and allow reconnection later. 10867 */ 10868 disconnect() { 10869 this.log("Disconnecting"); 10870 pollingManager.unregisterRoom(this.options.room); 10871 this.emitStatus({ status: "disconnected" }); 10872 } 10873 /** 10874 * Emit connection status, passing the full object through so that 10875 * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. 10876 * 10877 * @param connectionStatus The connection status object 10878 */ 10879 emitStatus = (connectionStatus) => { 10880 const { status } = connectionStatus; 10881 const error = status === "disconnected" ? connectionStatus.error : void 0; 10882 if (this.status === status && !error) { 10883 return; 10884 } 10885 if (status === "connecting" && this.status !== "disconnected") { 10886 return; 10887 } 10888 this.log("Status change", { status, error }); 10889 this.status = status; 10890 this.emit("status", [connectionStatus]); 10891 }; 10892 /** 10893 * Log debug messages if debugging is enabled. 10894 * 10895 * @param message The debug message 10896 * @param debug Additional debug information 10897 * @param errorLevel The console method to use for logging 10898 * @param force Whether to force logging regardless of debug setting 10899 */ 10900 log = (message, debug = {}, errorLevel = "log", force = false) => { 10901 if (!this.options.debug && !force) { 10902 return; 10903 } 10904 const logFn = console[errorLevel] || console.log; 10905 logFn(`[$this.constructor.name}]: $message}`, { 10906 room: this.options.room, 10907 ...debug 10908 }); 10909 }; 10910 }; 10911 function createHttpPollingProvider() { 10912 return async ({ 10913 awareness, 10914 objectType, 10915 objectId, 10916 ydoc 10917 }) => { 10918 const room = objectId ? `$objectType}:$objectId}` : objectType; 10919 const provider = new HttpPollingProvider({ 10920 awareness, 10921 // debug: true, 10922 room, 10923 ydoc 10924 }); 10925 return { 10926 destroy: () => provider.destroy(), 10927 // Adapter: ObservableV2.on is compatible with ProviderOn 10928 // The callback receives data as the first parameter 10929 on: (event, callback) => { 10930 provider.on(event, callback); 10931 } 10932 }; 10933 }; 10934 } 10935 10936 // packages/sync/build-module/providers/index.mjs 10937 var providerCreators = null; 10938 function getDefaultProviderCreators() { 10939 return window.__experimentalEnableRealTimeCollaboration ? [createHttpPollingProvider()] : []; 10940 } 10941 function isProviderCreator(creator) { 10942 return "function" === typeof creator; 10943 } 10944 function getProviderCreators() { 10945 if (providerCreators) { 10946 return providerCreators; 10947 } 10948 if (!window.__experimentalEnableRealTimeCollaboration) { 10949 return []; 10950 } 10951 const filteredProviderCreators = (0, import_hooks3.applyFilters)( 10952 "sync.providers", 10953 getDefaultProviderCreators() 10954 ); 10955 if (!Array.isArray(filteredProviderCreators)) { 10956 providerCreators = []; 10957 return providerCreators; 10958 } 10959 providerCreators = filteredProviderCreators.filter(isProviderCreator); 10960 return providerCreators; 10961 } 10962 10963 // packages/sync/build-module/y-utilities/y-multidoc-undomanager.mjs 10964 var popStackItem2 = (mum, type) => { 10965 const stack = type === "undo" ? mum.undoStack : mum.redoStack; 10966 while (stack.length > 0) { 10967 const um = ( 10968 /** @type {Y.UndoManager} */ 10969 stack.pop() 10970 ); 10971 const prevUmStack = type === "undo" ? um.undoStack : um.redoStack; 10972 const stackItem = ( 10973 /** @type {any} */ 10974 prevUmStack.pop() 10975 ); 10976 let actionPerformed = false; 10977 if (type === "undo") { 10978 um.undoStack = [stackItem]; 10979 actionPerformed = um.undo() !== null; 10980 um.undoStack = prevUmStack; 10981 } else { 10982 um.redoStack = [stackItem]; 10983 actionPerformed = um.redo() !== null; 10984 um.redoStack = prevUmStack; 10985 } 10986 if (actionPerformed) { 10987 return stackItem; 10988 } 10989 } 10990 return null; 10991 }; 10992 var YMultiDocUndoManager = class extends Observable { 10993 /** 10994 * @param {Y.AbstractType<any>|Array<Y.AbstractType<any>>} typeScope Accepts either a single type, or an array of types 10995 * @param {ConstructorParameters<typeof Y.UndoManager>[1]} opts 10996 */ 10997 constructor(typeScope = [], opts = {}) { 10998 super(); 10999 this.docs = /* @__PURE__ */ new Map(); 11000 this.trackedOrigins = opts.trackedOrigins || /* @__PURE__ */ new Set([null]); 11001 opts.trackedOrigins = this.trackedOrigins; 11002 this._defaultOpts = opts; 11003 this.undoStack = []; 11004 this.redoStack = []; 11005 this.addToScope(typeScope); 11006 } 11007 /** 11008 * @param {Array<Y.AbstractType<any>> | Y.AbstractType<any>} ytypes 11009 */ 11010 addToScope(ytypes) { 11011 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 11012 ytypes.forEach((ytype) => { 11013 const ydoc = ( 11014 /** @type {Y.Doc} */ 11015 ytype.doc 11016 ); 11017 const um = setIfUndefined(this.docs, ydoc, () => { 11018 const um2 = new UndoManager([ytype], this._defaultOpts); 11019 um2.on( 11020 "stack-cleared", 11021 /** @param {any} opts */ 11022 ({ 11023 undoStackCleared, 11024 redoStackCleared 11025 }) => { 11026 this.clear(undoStackCleared, redoStackCleared); 11027 } 11028 ); 11029 ydoc.on("destroy", () => { 11030 this.docs.delete(ydoc); 11031 this.undoStack = this.undoStack.filter( 11032 (um3) => um3.doc !== ydoc 11033 ); 11034 this.redoStack = this.redoStack.filter( 11035 (um3) => um3.doc !== ydoc 11036 ); 11037 }); 11038 um2.on( 11039 "stack-item-added", 11040 /** @param {any} change */ 11041 (change) => { 11042 const stack = change.type === "undo" ? this.undoStack : this.redoStack; 11043 stack.push(um2); 11044 this.emit("stack-item-added", [ 11045 { ...change, ydoc }, 11046 this 11047 ]); 11048 } 11049 ); 11050 um2.on( 11051 "stack-item-updated", 11052 /** @param {any} change */ 11053 (change) => { 11054 this.emit("stack-item-updated", [ 11055 { ...change, ydoc }, 11056 this 11057 ]); 11058 } 11059 ); 11060 um2.on( 11061 "stack-item-popped", 11062 /** @param {any} change */ 11063 (change) => { 11064 this.emit("stack-item-popped", [ 11065 { ...change, ydoc }, 11066 this 11067 ]); 11068 } 11069 ); 11070 return um2; 11071 }); 11072 if (um.scope.every((yt) => yt !== ytype)) { 11073 um.scope.push(ytype); 11074 } 11075 }); 11076 } 11077 /** 11078 * @param {any} origin 11079 */ 11080 /* c8 ignore next 3 */ 11081 addTrackedOrigin(origin2) { 11082 this.trackedOrigins.add(origin2); 11083 } 11084 /** 11085 * @param {any} origin 11086 */ 11087 /* c8 ignore next 3 */ 11088 removeTrackedOrigin(origin2) { 11089 this.trackedOrigins.delete(origin2); 11090 } 11091 /** 11092 * Undo last changes on type. 11093 * 11094 * @return {any?} Returns StackItem if a change was applied 11095 */ 11096 undo() { 11097 return popStackItem2(this, "undo"); 11098 } 11099 /** 11100 * Redo last undo operation. 11101 * 11102 * @return {any?} Returns StackItem if a change was applied 11103 */ 11104 redo() { 11105 return popStackItem2(this, "redo"); 11106 } 11107 clear(clearUndoStack = true, clearRedoStack = true) { 11108 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 11109 this.docs.forEach((um) => { 11110 clearUndoStack && (this.undoStack = []); 11111 clearRedoStack && (this.redoStack = []); 11112 um.clear(clearUndoStack, clearRedoStack); 11113 }); 11114 this.emit("stack-cleared", [ 11115 { 11116 undoStackCleared: clearUndoStack, 11117 redoStackCleared: clearRedoStack 11118 } 11119 ]); 11120 } 11121 } 11122 /* c8 ignore next 5 */ 11123 stopCapturing() { 11124 this.docs.forEach((um) => { 11125 um.stopCapturing(); 11126 }); 11127 } 11128 /** 11129 * Are undo steps available? 11130 * 11131 * @return {boolean} `true` if undo is possible 11132 */ 11133 canUndo() { 11134 return this.undoStack.length > 0; 11135 } 11136 /** 11137 * Are redo steps available? 11138 * 11139 * @return {boolean} `true` if redo is possible 11140 */ 11141 canRedo() { 11142 return this.redoStack.length > 0; 11143 } 11144 destroy() { 11145 this.docs.forEach((um) => um.destroy()); 11146 super.destroy(); 11147 } 11148 }; 11149 11150 // packages/sync/build-module/undo-manager.mjs 11151 function createUndoManager() { 11152 const undoMetaHandlers = /* @__PURE__ */ new Map(); 11153 const yUndoManager = new YMultiDocUndoManager([], { 11154 // Throttle undo/redo captures after 500ms of inactivity. 11155 // 500 was selected from subjective local UX testing, shorter timeouts 11156 // may cause mid-word undo stack items. 11157 captureTimeout: 500, 11158 // Ensure that we only scope the undo/redo to the current editor. 11159 // The yjs document's clientID is added once it's available. 11160 trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) 11161 }); 11162 const getUndoStackState = () => ({ 11163 hasRedo: yUndoManager.canRedo(), 11164 hasUndo: yUndoManager.canUndo() 11165 }); 11166 const notifyUndoStackChange = (ydoc) => { 11167 undoMetaHandlers.get(ydoc)?.onUndoStackChange?.(getUndoStackState()); 11168 }; 11169 yUndoManager.on("stack-item-added", (event) => { 11170 const handlers = undoMetaHandlers.get(event.ydoc); 11171 if (!handlers) { 11172 return; 11173 } 11174 handlers.addUndoMeta(event.ydoc, event.stackItem.meta); 11175 notifyUndoStackChange(event.ydoc); 11176 }); 11177 yUndoManager.on("stack-item-updated", (event) => { 11178 notifyUndoStackChange(event.ydoc); 11179 }); 11180 yUndoManager.on("stack-item-popped", (event) => { 11181 const handlers = undoMetaHandlers.get(event.ydoc); 11182 if (!handlers) { 11183 return; 11184 } 11185 handlers.restoreUndoMeta(event.ydoc, event.stackItem.meta); 11186 notifyUndoStackChange(event.ydoc); 11187 }); 11188 yUndoManager.on("stack-cleared", () => { 11189 undoMetaHandlers.forEach((handlers) => { 11190 handlers.onUndoStackChange?.(getUndoStackState()); 11191 }); 11192 }); 11193 return { 11194 /** 11195 * Record changes into the history. 11196 * Since Yjs automatically tracks changes, this method translates the WordPress 11197 * HistoryRecord format into Yjs operations. 11198 * 11199 * @param _record A record of changes to record. 11200 * @param _isStaged Whether to immediately create an undo point or not. 11201 */ 11202 addRecord(_record, _isStaged = false) { 11203 }, 11204 /** 11205 * Add a Yjs map to the scope of the undo manager. 11206 * 11207 * @param {Y.Map< any >} ymap The Yjs map to add to the scope. 11208 * @param handlers Handlers for the scoped document. 11209 * @param handlers.addUndoMeta Handler to add metadata to undo items. 11210 * @param handlers.onUndoStackChange Handler for undo stack changes. 11211 * @param handlers.restoreUndoMeta Handler to restore metadata from undo items. 11212 */ 11213 addToScope(ymap, handlers) { 11214 if (ymap.doc === null) { 11215 return; 11216 } 11217 const ydoc = ymap.doc; 11218 yUndoManager.addToScope(ymap); 11219 if (!undoMetaHandlers.has(ydoc)) { 11220 ydoc.on("destroy", () => undoMetaHandlers.delete(ydoc)); 11221 } 11222 undoMetaHandlers.set(ydoc, handlers); 11223 }, 11224 /** 11225 * Undo the last recorded changes. 11226 * 11227 */ 11228 undo() { 11229 if (!yUndoManager.canUndo()) { 11230 return; 11231 } 11232 yUndoManager.undo(); 11233 return []; 11234 }, 11235 /** 11236 * Redo the last undone changes. 11237 */ 11238 redo() { 11239 if (!yUndoManager.canRedo()) { 11240 return; 11241 } 11242 yUndoManager.redo(); 11243 return []; 11244 }, 11245 /** 11246 * Check if there are changes that can be undone. 11247 * 11248 * @return {boolean} Whether there are changes to undo. 11249 */ 11250 hasUndo() { 11251 return yUndoManager.canUndo(); 11252 }, 11253 /** 11254 * Check if there are changes that can be redone. 11255 * 11256 * @return {boolean} Whether there are changes to redo. 11257 */ 11258 hasRedo() { 11259 return yUndoManager.canRedo(); 11260 }, 11261 /** 11262 * Stop capturing changes into the current undo item. 11263 * The next change will create a new undo item. 11264 */ 11265 stopCapturing() { 11266 yUndoManager.stopCapturing(); 11267 } 11268 }; 11269 } 11270 11271 // packages/sync/build-module/crdt-snapshot.mjs 11272 function encodeDocSnapshot(ydoc) { 11273 return toBase64(encodeSnapshotV2(snapshot(ydoc))); 11274 } 11275 function docContainsSnapshot(ydoc, encodedSnapshot) { 11276 let snapshot2; 11277 try { 11278 snapshot2 = decodeSnapshotV2(fromBase64(encodedSnapshot)); 11279 } catch { 11280 return false; 11281 } 11282 const localSnapshot = snapshot(ydoc); 11283 for (const [client, clock] of snapshot2.sv) { 11284 if ((localSnapshot.sv.get(client) ?? 0) < clock) { 11285 return false; 11286 } 11287 } 11288 const copiedDeleteSet = snapshot(ydoc).ds; 11289 const mergedDeleteSet = mergeDeleteSets([ 11290 copiedDeleteSet, 11291 snapshot2.ds 11292 ]); 11293 return equalDeleteSets(localSnapshot.ds, mergedDeleteSet); 11294 } 11295 11296 // packages/sync/build-module/utils.mjs 11297 function createYjsDoc(documentMeta = {}) { 11298 const metaMap = new Map( 11299 Object.entries(documentMeta) 11300 ); 11301 return new Doc({ meta: metaMap }); 11302 } 11303 function initializeYjsDoc(ydoc) { 11304 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11305 stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); 11306 } 11307 function markEntityAsSaved(ydoc) { 11308 const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); 11309 recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); 11310 recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); 11311 } 11312 function pseudoRandomID() { 11313 return Math.floor(Math.random() * 1e9); 11314 } 11315 function serializeCrdtDoc(crdtDoc) { 11316 const tempDoc = createYjsDoc(); 11317 applyUpdateV2(tempDoc, encodeStateAsUpdateV2(crdtDoc)); 11318 const compactedUpdate = encodeStateAsUpdateV2(tempDoc); 11319 tempDoc.destroy(); 11320 return JSON.stringify({ 11321 document: toBase64(compactedUpdate), 11322 updateId: pseudoRandomID() 11323 // helps with debugging 11324 }); 11325 } 11326 function deserializeCrdtDoc(serializedCrdtDoc) { 11327 try { 11328 const { document: document2 } = JSON.parse(serializedCrdtDoc); 11329 const docMeta = { 11330 [CRDT_DOC_META_PERSISTENCE_KEY]: true 11331 }; 11332 const ydoc = createYjsDoc(docMeta); 11333 const yupdate = fromBase64(document2); 11334 applyUpdateV2(ydoc, yupdate); 11335 ydoc.clientID = pseudoRandomID(); 11336 return ydoc; 11337 } catch { 11338 return null; 11339 } 11340 } 11341 11342 // packages/sync/build-module/manager.mjs 11343 function getEntityId(objectType, objectId) { 11344 return `$objectType}_$objectId}`; 11345 } 11346 function createSyncManager(debug = false) { 11347 const debugWrap = debug ? logPerformanceTiming : passThru; 11348 const collectionStates = /* @__PURE__ */ new Map(); 11349 const entityStates = /* @__PURE__ */ new Map(); 11350 let undoManager; 11351 function log(component, message, entityId, context = {}) { 11352 if (!debug) { 11353 return; 11354 } 11355 console.log(`[SyncManager][$component}]: $message}`, { 11356 ...context, 11357 entityId 11358 }); 11359 } 11360 async function loadEntity(syncConfig, objectType, objectId, record, handlers) { 11361 const providerCreators2 = getProviderCreators(); 11362 const entityId = getEntityId(objectType, objectId); 11363 if (0 === providerCreators2.length) { 11364 log("loadEntity", "no providers, skipping", entityId); 11365 return; 11366 } 11367 if (entityStates.has(entityId)) { 11368 log("loadEntity", "already loaded", entityId); 11369 return; 11370 } 11371 if (false === syncConfig.shouldSync?.(objectType, objectId)) { 11372 log("loadEntity", "shouldSync false, skipping", entityId); 11373 return; 11374 } 11375 log("loadEntity", "loading", entityId); 11376 handlers = { 11377 addUndoMeta: debugWrap(handlers.addUndoMeta), 11378 editRecord: debugWrap(handlers.editRecord), 11379 getEditedRecord: debugWrap(handlers.getEditedRecord), 11380 onStatusChange: debugWrap(handlers.onStatusChange), 11381 persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), 11382 refetchRecord: debugWrap(handlers.refetchRecord), 11383 restoreUndoMeta: debugWrap(handlers.restoreUndoMeta), 11384 onUndoStackChange: handlers.onUndoStackChange ? debugWrap(handlers.onUndoStackChange) : void 0 11385 }; 11386 const ydoc = createYjsDoc({ objectType }); 11387 const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); 11388 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11389 const now = Date.now(); 11390 let hasObserversAttached = false; 11391 let isEntityUnloaded = false; 11392 const unload = () => { 11393 log("loadEntity", "unloading", entityId); 11394 isEntityUnloaded = true; 11395 providerResults?.forEach((result) => result.destroy()); 11396 handlers.onStatusChange(null); 11397 if (hasObserversAttached) { 11398 recordMap.unobserveDeep(onRecordUpdate); 11399 stateMap.unobserve(onStateMapUpdate); 11400 } 11401 ydoc.destroy(); 11402 entityStates.delete(entityId); 11403 }; 11404 const awareness = syncConfig.createAwareness?.(ydoc, objectId); 11405 const onRecordUpdate = (_events, transaction) => { 11406 if (transaction.local && !(transaction.origin instanceof UndoManager)) { 11407 return; 11408 } 11409 void internal.updateEntityRecord(objectType, objectId); 11410 }; 11411 const onStateMapUpdate = (event, transaction) => { 11412 if (transaction.local) { 11413 return; 11414 } 11415 event.keysChanged.forEach((key) => { 11416 switch (key) { 11417 case CRDT_STATE_MAP_SAVED_AT_KEY: 11418 const savedAt = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11419 if ("number" === typeof savedAt && savedAt > now) { 11420 log("loadEntity", "refetching record", entityId); 11421 void handlers.refetchRecord().catch(() => { 11422 }); 11423 } 11424 break; 11425 } 11426 }); 11427 }; 11428 if (!undoManager) { 11429 undoManager = createUndoManager(); 11430 } 11431 const { addUndoMeta, onUndoStackChange, restoreUndoMeta } = handlers; 11432 undoManager.addToScope(recordMap, { 11433 addUndoMeta, 11434 restoreUndoMeta, 11435 onUndoStackChange 11436 }); 11437 let providerResults; 11438 const entityState = { 11439 awareness, 11440 handlers, 11441 objectId, 11442 objectType, 11443 syncConfig, 11444 unload, 11445 ydoc 11446 }; 11447 entityStates.set(entityId, entityState); 11448 log("loadEntity", "connecting", entityId); 11449 providerResults = await Promise.all( 11450 providerCreators2.map(async (create7) => { 11451 const provider = await create7({ 11452 objectType, 11453 objectId, 11454 ydoc, 11455 awareness 11456 }); 11457 provider.on("status", handlers.onStatusChange); 11458 return provider; 11459 }) 11460 ); 11461 if (isEntityUnloaded) { 11462 log("loadEntity", "unloaded during connect, aborting", entityId); 11463 providerResults.forEach((result) => result.destroy()); 11464 return; 11465 } 11466 initializeYjsDoc(ydoc); 11467 internal.applyPersistedCrdtDoc(objectType, objectId, record); 11468 recordMap.observeDeep(onRecordUpdate); 11469 stateMap.observe(onStateMapUpdate); 11470 hasObserversAttached = true; 11471 } 11472 async function loadCollection(syncConfig, objectType, handlers) { 11473 const providerCreators2 = getProviderCreators(); 11474 const entityId = getEntityId(objectType, null); 11475 if (0 === providerCreators2.length) { 11476 log("loadCollection", "no providers, skipping", entityId); 11477 return; 11478 } 11479 if (collectionStates.has(objectType)) { 11480 log("loadCollection", "already loaded", entityId); 11481 return; 11482 } 11483 if (false === syncConfig.shouldSync?.(objectType, null)) { 11484 log("loadCollection", "shouldSync false, skipping", entityId); 11485 return; 11486 } 11487 log("loadCollection", "loading", entityId); 11488 const ydoc = createYjsDoc({ collection: true, objectType }); 11489 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11490 const now = Date.now(); 11491 let hasObserversAttached = false; 11492 let isCollectionUnloaded = false; 11493 const unload = () => { 11494 log("loadCollection", "unloading", entityId); 11495 isCollectionUnloaded = true; 11496 providerResults?.forEach((result) => result.destroy()); 11497 handlers.onStatusChange(null); 11498 if (hasObserversAttached) { 11499 stateMap.unobserve(onStateMapUpdate); 11500 } 11501 ydoc.destroy(); 11502 collectionStates.delete(objectType); 11503 }; 11504 const onStateMapUpdate = (event, transaction) => { 11505 if (transaction.local) { 11506 return; 11507 } 11508 event.keysChanged.forEach((key) => { 11509 switch (key) { 11510 case CRDT_STATE_MAP_SAVED_AT_KEY: 11511 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11512 if ("number" === typeof newValue && newValue > now) { 11513 void handlers.refetchRecords().catch(() => { 11514 }); 11515 } 11516 break; 11517 } 11518 }); 11519 }; 11520 const awareness = syncConfig.createAwareness?.(ydoc); 11521 let providerResults; 11522 const collectionState = { 11523 awareness, 11524 handlers, 11525 syncConfig, 11526 unload, 11527 ydoc 11528 }; 11529 collectionStates.set(objectType, collectionState); 11530 log("loadCollection", "connecting", entityId); 11531 providerResults = await Promise.all( 11532 providerCreators2.map(async (create7) => { 11533 const provider = await create7({ 11534 awareness, 11535 objectType, 11536 objectId: null, 11537 ydoc 11538 }); 11539 provider.on("status", handlers.onStatusChange); 11540 return provider; 11541 }) 11542 ); 11543 if (isCollectionUnloaded) { 11544 log( 11545 "loadCollection", 11546 "unloaded during connect, aborting", 11547 entityId 11548 ); 11549 providerResults.forEach((result) => result.destroy()); 11550 return; 11551 } 11552 stateMap.observe(onStateMapUpdate); 11553 hasObserversAttached = true; 11554 initializeYjsDoc(ydoc); 11555 } 11556 function unloadEntity(objectType, objectId) { 11557 const entityId = getEntityId(objectType, objectId); 11558 log("unloadEntity", "unloading", entityId); 11559 entityStates.get(entityId)?.unload(); 11560 updateCRDTDoc(objectType, null, {}, origin, { 11561 isSave: true 11562 }); 11563 } 11564 function unloadAll() { 11565 log("unloadAll", "unloading all entities", "all"); 11566 for (const [, entityState] of [...entityStates]) { 11567 entityState.unload(); 11568 } 11569 entityStates.clear(); 11570 undoManager = void 0; 11571 for (const [, collectionState] of [...collectionStates]) { 11572 collectionState.unload(); 11573 } 11574 collectionStates.clear(); 11575 } 11576 function getAwareness(objectType, objectId) { 11577 const entityId = getEntityId(objectType, objectId); 11578 const entityState = entityStates.get(entityId); 11579 if (!entityState || !entityState.awareness) { 11580 return void 0; 11581 } 11582 return entityState.awareness; 11583 } 11584 function _applyPersistedCrdtDoc(objectType, objectId, record) { 11585 const entityId = getEntityId(objectType, objectId); 11586 const entityState = entityStates.get(entityId); 11587 if (!entityState) { 11588 log("applyPersistedCrdtDoc", "no entity state", entityId); 11589 return; 11590 } 11591 const { 11592 handlers, 11593 syncConfig: { 11594 applyChangesToCRDTDoc, 11595 getChangesFromCRDTDoc, 11596 getPersistedCRDTDoc 11597 }, 11598 ydoc: targetDoc 11599 } = entityState; 11600 const serialized = getPersistedCRDTDoc?.(record); 11601 const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; 11602 if (!tempDoc) { 11603 log("applyPersistedCrdtDoc", "no persisted doc", entityId); 11604 targetDoc.transact(() => { 11605 applyChangesToCRDTDoc(targetDoc, record); 11606 handlers.persistCRDTDoc(); 11607 }, LOCAL_SYNC_MANAGER_ORIGIN); 11608 return; 11609 } 11610 const update = encodeStateAsUpdateV2(tempDoc); 11611 applyUpdateV2(targetDoc, update); 11612 const invalidations = getChangesFromCRDTDoc(tempDoc, record); 11613 const invalidatedKeys = Object.keys(invalidations); 11614 tempDoc.destroy(); 11615 if (0 === invalidatedKeys.length) { 11616 log("applyPersistedCrdtDoc", "valid persisted doc", entityId); 11617 return; 11618 } 11619 log("applyPersistedCrdtDoc", "invalidated keys", entityId, { 11620 invalidatedKeys 11621 }); 11622 const changes = invalidatedKeys.reduce( 11623 (acc, key) => Object.assign(acc, { 11624 [key]: record[key] 11625 }), 11626 {} 11627 ); 11628 targetDoc.transact(() => { 11629 applyChangesToCRDTDoc(targetDoc, changes); 11630 handlers.persistCRDTDoc(); 11631 }, LOCAL_SYNC_MANAGER_ORIGIN); 11632 } 11633 function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { 11634 const { isSave = false, isNewUndoLevel = false } = options; 11635 const entityId = getEntityId(objectType, objectId); 11636 const entityState = entityStates.get(entityId); 11637 const collectionState = collectionStates.get(objectType); 11638 if (entityState) { 11639 const { syncConfig, ydoc } = entityState; 11640 if (isNewUndoLevel && undoManager) { 11641 undoManager.stopCapturing?.(); 11642 } 11643 ydoc.transact(() => { 11644 log("updateCRDTDoc", "applying changes", entityId, { 11645 changedKeys: Object.keys(changes) 11646 }); 11647 syncConfig.applyChangesToCRDTDoc(ydoc, changes); 11648 if (isSave) { 11649 markEntityAsSaved(ydoc); 11650 } 11651 }, origin2); 11652 } 11653 if (collectionState && isSave) { 11654 collectionState.ydoc.transact(() => { 11655 markEntityAsSaved(collectionState.ydoc); 11656 }, origin2); 11657 } 11658 } 11659 const pendingCRDTDocUpdates = []; 11660 function flushPendingCRDTDocUpdates() { 11661 while (pendingCRDTDocUpdates.length > 0) { 11662 const args2 = pendingCRDTDocUpdates.shift(); 11663 if (args2) { 11664 updateCRDTDoc(...args2); 11665 } 11666 } 11667 } 11668 function deferUpdateCRDTDoc(...args2) { 11669 pendingCRDTDocUpdates.push(args2); 11670 setTimeout(flushPendingCRDTDocUpdates, 0); 11671 } 11672 function updateOrDefer(objectType, objectId, changes, origin2, options = {}) { 11673 const hasRemotePeers = (getAwareness(objectType, objectId)?.getStates().size ?? 0) > 1; 11674 if (hasRemotePeers) { 11675 flushPendingCRDTDocUpdates(); 11676 updateCRDTDoc(objectType, objectId, changes, origin2, options); 11677 return; 11678 } 11679 deferUpdateCRDTDoc(objectType, objectId, changes, origin2, options); 11680 } 11681 function getEntitySnapshot(objectType, objectId) { 11682 const entityId = getEntityId(objectType, objectId); 11683 const entityState = entityStates.get(entityId); 11684 if (!entityState) { 11685 log("getEntitySnapshot", "no entity state", entityId); 11686 return void 0; 11687 } 11688 flushPendingCRDTDocUpdates(); 11689 return encodeDocSnapshot(entityState.ydoc); 11690 } 11691 function entityContainsSnapshot(objectType, objectId, encodedSnapshot) { 11692 const entityId = getEntityId(objectType, objectId); 11693 const entityState = entityStates.get(entityId); 11694 if (!entityState) { 11695 return false; 11696 } 11697 flushPendingCRDTDocUpdates(); 11698 return docContainsSnapshot(entityState.ydoc, encodedSnapshot); 11699 } 11700 async function _updateEntityRecord(objectType, objectId) { 11701 const entityId = getEntityId(objectType, objectId); 11702 const entityState = entityStates.get(entityId); 11703 if (!entityState) { 11704 log("updateEntityRecord", "no entity state", entityId); 11705 return; 11706 } 11707 const { handlers, syncConfig, ydoc } = entityState; 11708 const changes = syncConfig.getChangesFromCRDTDoc( 11709 ydoc, 11710 await handlers.getEditedRecord() 11711 ); 11712 const changedKeys = Object.keys(changes); 11713 if (0 === changedKeys.length) { 11714 return; 11715 } 11716 log("updateEntityRecord", "changes", entityId, { 11717 changedKeys 11718 }); 11719 handlers.editRecord(changes); 11720 } 11721 async function createPersistedCRDTDoc(objectType, objectId) { 11722 const entityId = getEntityId(objectType, objectId); 11723 const entityState = entityStates.get(entityId); 11724 if (!entityState?.ydoc) { 11725 return null; 11726 } 11727 flushPendingCRDTDocUpdates(); 11728 return serializeCrdtDoc(entityState.ydoc); 11729 } 11730 const internal = { 11731 applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), 11732 updateEntityRecord: debugWrap(_updateEntityRecord) 11733 }; 11734 return { 11735 createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), 11736 entityContainsSnapshot: debugWrap(entityContainsSnapshot), 11737 getAwareness, 11738 getEntitySnapshot: debugWrap(getEntitySnapshot), 11739 load: debugWrap(loadEntity), 11740 loadCollection: debugWrap(loadCollection), 11741 // Use getter to ensure we always return the current value of `undoManager`. 11742 get undoManager() { 11743 return undoManager; 11744 }, 11745 unload: debugWrap(unloadEntity), 11746 unloadAll: debugWrap(unloadAll), 11747 update: debugWrap(updateOrDefer) 11748 }; 11749 } 11750 11751 // node_modules/diff/libesm/diff/base.js 11752 var Diff = class { 11753 diff(oldStr, newStr, options = {}) { 11754 let callback; 11755 if (typeof options === "function") { 11756 callback = options; 11757 options = {}; 11758 } else if ("callback" in options) { 11759 callback = options.callback; 11760 } 11761 const oldString = this.castInput(oldStr, options); 11762 const newString = this.castInput(newStr, options); 11763 const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); 11764 const newTokens = this.removeEmpty(this.tokenize(newString, options)); 11765 return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); 11766 } 11767 diffWithOptionsObj(oldTokens, newTokens, options, callback) { 11768 var _a; 11769 const done = (value) => { 11770 value = this.postProcess(value, options); 11771 if (callback) { 11772 setTimeout(function() { 11773 callback(value); 11774 }, 0); 11775 return void 0; 11776 } else { 11777 return value; 11778 } 11779 }; 11780 const newLen = newTokens.length, oldLen = oldTokens.length; 11781 let editLength = 1; 11782 let maxEditLength = newLen + oldLen; 11783 if (options.maxEditLength != null) { 11784 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 11785 } 11786 const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; 11787 const abortAfterTimestamp = Date.now() + maxExecutionTime; 11788 const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; 11789 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); 11790 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11791 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); 11792 } 11793 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; 11794 const execEditLength = () => { 11795 for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 11796 let basePath; 11797 const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; 11798 if (removePath) { 11799 bestPath[diagonalPath - 1] = void 0; 11800 } 11801 let canAdd = false; 11802 if (addPath) { 11803 const addPathNewPos = addPath.oldPos - diagonalPath; 11804 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 11805 } 11806 const canRemove = removePath && removePath.oldPos + 1 < oldLen; 11807 if (!canAdd && !canRemove) { 11808 bestPath[diagonalPath] = void 0; 11809 continue; 11810 } 11811 if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { 11812 basePath = this.addToPath(addPath, true, false, 0, options); 11813 } else { 11814 basePath = this.addToPath(removePath, false, true, 1, options); 11815 } 11816 newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); 11817 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11818 return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; 11819 } else { 11820 bestPath[diagonalPath] = basePath; 11821 if (basePath.oldPos + 1 >= oldLen) { 11822 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 11823 } 11824 if (newPos + 1 >= newLen) { 11825 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 11826 } 11827 } 11828 } 11829 editLength++; 11830 }; 11831 if (callback) { 11832 (function exec() { 11833 setTimeout(function() { 11834 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 11835 return callback(void 0); 11836 } 11837 if (!execEditLength()) { 11838 exec(); 11839 } 11840 }, 0); 11841 })(); 11842 } else { 11843 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 11844 const ret = execEditLength(); 11845 if (ret) { 11846 return ret; 11847 } 11848 } 11849 } 11850 } 11851 addToPath(path, added, removed, oldPosInc, options) { 11852 const last2 = path.lastComponent; 11853 if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { 11854 return { 11855 oldPos: path.oldPos + oldPosInc, 11856 lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } 11857 }; 11858 } else { 11859 return { 11860 oldPos: path.oldPos + oldPosInc, 11861 lastComponent: { count: 1, added, removed, previousComponent: last2 } 11862 }; 11863 } 11864 } 11865 extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { 11866 const newLen = newTokens.length, oldLen = oldTokens.length; 11867 let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; 11868 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { 11869 newPos++; 11870 oldPos++; 11871 commonCount++; 11872 if (options.oneChangePerToken) { 11873 basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; 11874 } 11875 } 11876 if (commonCount && !options.oneChangePerToken) { 11877 basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; 11878 } 11879 basePath.oldPos = oldPos; 11880 return newPos; 11881 } 11882 equals(left, right, options) { 11883 if (options.comparator) { 11884 return options.comparator(left, right); 11885 } else { 11886 return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 11887 } 11888 } 11889 removeEmpty(array) { 11890 const ret = []; 11891 for (let i = 0; i < array.length; i++) { 11892 if (array[i]) { 11893 ret.push(array[i]); 11894 } 11895 } 11896 return ret; 11897 } 11898 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11899 castInput(value, options) { 11900 return value; 11901 } 11902 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11903 tokenize(value, options) { 11904 return Array.from(value); 11905 } 11906 join(chars) { 11907 return chars.join(""); 11908 } 11909 postProcess(changeObjects, options) { 11910 return changeObjects; 11911 } 11912 get useLongestToken() { 11913 return false; 11914 } 11915 buildValues(lastComponent, newTokens, oldTokens) { 11916 const components = []; 11917 let nextComponent; 11918 while (lastComponent) { 11919 components.push(lastComponent); 11920 nextComponent = lastComponent.previousComponent; 11921 delete lastComponent.previousComponent; 11922 lastComponent = nextComponent; 11923 } 11924 components.reverse(); 11925 const componentLen = components.length; 11926 let componentPos = 0, newPos = 0, oldPos = 0; 11927 for (; componentPos < componentLen; componentPos++) { 11928 const component = components[componentPos]; 11929 if (!component.removed) { 11930 if (!component.added && this.useLongestToken) { 11931 let value = newTokens.slice(newPos, newPos + component.count); 11932 value = value.map(function(value2, i) { 11933 const oldValue = oldTokens[oldPos + i]; 11934 return oldValue.length > value2.length ? oldValue : value2; 11935 }); 11936 component.value = this.join(value); 11937 } else { 11938 component.value = this.join(newTokens.slice(newPos, newPos + component.count)); 11939 } 11940 newPos += component.count; 11941 if (!component.added) { 11942 oldPos += component.count; 11943 } 11944 } else { 11945 component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); 11946 oldPos += component.count; 11947 } 11948 } 11949 return components; 11950 } 11951 }; 11952 11953 // node_modules/diff/libesm/diff/character.js 11954 var CharacterDiff = class extends Diff { 11955 }; 11956 var characterDiff = new CharacterDiff(); 11957 function diffChars(oldStr, newStr, options) { 11958 return characterDiff.diff(oldStr, newStr, options); 11959 } 11960 11961 // node_modules/diff/libesm/diff/line.js 11962 var LineDiff = class extends Diff { 11963 constructor() { 11964 super(...arguments); 11965 this.tokenize = tokenize; 11966 } 11967 equals(left, right, options) { 11968 if (options.ignoreWhitespace) { 11969 if (!options.newlineIsToken || !left.includes("\n")) { 11970 left = left.trim(); 11971 } 11972 if (!options.newlineIsToken || !right.includes("\n")) { 11973 right = right.trim(); 11974 } 11975 } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { 11976 if (left.endsWith("\n")) { 11977 left = left.slice(0, -1); 11978 } 11979 if (right.endsWith("\n")) { 11980 right = right.slice(0, -1); 11981 } 11982 } 11983 return super.equals(left, right, options); 11984 } 11985 }; 11986 var lineDiff = new LineDiff(); 11987 function diffLines(oldStr, newStr, options) { 11988 return lineDiff.diff(oldStr, newStr, options); 11989 } 11990 function tokenize(value, options) { 11991 if (options.stripTrailingCr) { 11992 value = value.replace(/\r\n/g, "\n"); 11993 } 11994 const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); 11995 if (!linesAndNewlines[linesAndNewlines.length - 1]) { 11996 linesAndNewlines.pop(); 11997 } 11998 for (let i = 0; i < linesAndNewlines.length; i++) { 11999 const line = linesAndNewlines[i]; 12000 if (i % 2 && !options.newlineIsToken) { 12001 retLines[retLines.length - 1] += line; 12002 } else { 12003 retLines.push(line); 12004 } 12005 } 12006 return retLines; 12007 } 12008 12009 // packages/sync/build-module/quill-delta/Delta.mjs 12010 var import_es62 = __toESM(require_es6(), 1); 12011 12012 // packages/sync/build-module/quill-delta/AttributeMap.mjs 12013 var import_es6 = __toESM(require_es6(), 1); 12014 function cloneDeep(value) { 12015 return JSON.parse(JSON.stringify(value)); 12016 } 12017 var AttributeMap; 12018 ((AttributeMap2) => { 12019 function compose(a = {}, b = {}, keepNull = false) { 12020 if (typeof a !== "object") { 12021 a = {}; 12022 } 12023 if (typeof b !== "object") { 12024 b = {}; 12025 } 12026 let attributes = cloneDeep(b); 12027 if (!keepNull) { 12028 attributes = Object.keys(attributes).reduce( 12029 (copy2, key) => { 12030 if (attributes[key] !== null || attributes[key] !== void 0) { 12031 copy2[key] = attributes[key]; 12032 } 12033 return copy2; 12034 }, 12035 {} 12036 ); 12037 } 12038 for (const key in a) { 12039 if (a[key] !== void 0 && b[key] === void 0) { 12040 attributes[key] = a[key]; 12041 } 12042 } 12043 return Object.keys(attributes).length > 0 ? attributes : void 0; 12044 } 12045 AttributeMap2.compose = compose; 12046 function diff(a = {}, b = {}) { 12047 if (typeof a !== "object") { 12048 a = {}; 12049 } 12050 if (typeof b !== "object") { 12051 b = {}; 12052 } 12053 const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { 12054 if (!(0, import_es6.default)(a[key], b[key])) { 12055 attrs[key] = b[key] === void 0 ? null : b[key]; 12056 } 12057 return attrs; 12058 }, {}); 12059 return Object.keys(attributes).length > 0 ? attributes : void 0; 12060 } 12061 AttributeMap2.diff = diff; 12062 function invert(attr = {}, base = {}) { 12063 attr = attr || {}; 12064 const baseInverted = Object.keys(base).reduce( 12065 (memo, key) => { 12066 if (base[key] !== attr[key] && attr[key] !== void 0) { 12067 memo[key] = base[key]; 12068 } 12069 return memo; 12070 }, 12071 {} 12072 ); 12073 return Object.keys(attr).reduce((memo, key) => { 12074 if (attr[key] !== base[key] && base[key] === void 0) { 12075 memo[key] = null; 12076 } 12077 return memo; 12078 }, baseInverted); 12079 } 12080 AttributeMap2.invert = invert; 12081 function transform(a, b, priority = false) { 12082 if (typeof a !== "object") { 12083 return b; 12084 } 12085 if (typeof b !== "object") { 12086 return void 0; 12087 } 12088 if (!priority) { 12089 return b; 12090 } 12091 const attributes = Object.keys(b).reduce( 12092 (attrs, key) => { 12093 if (a[key] === void 0) { 12094 attrs[key] = b[key]; 12095 } 12096 return attrs; 12097 }, 12098 {} 12099 ); 12100 return Object.keys(attributes).length > 0 ? attributes : void 0; 12101 } 12102 AttributeMap2.transform = transform; 12103 })(AttributeMap || (AttributeMap = {})); 12104 var AttributeMap_default = AttributeMap; 12105 12106 // packages/sync/build-module/quill-delta/Op.mjs 12107 var Op; 12108 ((Op2) => { 12109 function length2(op) { 12110 if (typeof op.delete === "number") { 12111 return op.delete; 12112 } else if (typeof op.retain === "number") { 12113 return op.retain; 12114 } else if (typeof op.retain === "object" && op.retain !== null) { 12115 return 1; 12116 } 12117 return typeof op.insert === "string" ? op.insert.length : 1; 12118 } 12119 Op2.length = length2; 12120 })(Op || (Op = {})); 12121 var Op_default = Op; 12122 12123 // packages/sync/build-module/quill-delta/OpIterator.mjs 12124 var Iterator = class { 12125 ops; 12126 index; 12127 offset; 12128 constructor(ops) { 12129 this.ops = ops; 12130 this.index = 0; 12131 this.offset = 0; 12132 } 12133 hasNext() { 12134 return this.peekLength() < Infinity; 12135 } 12136 next(length2) { 12137 if (!length2) { 12138 length2 = Infinity; 12139 } 12140 const nextOp = this.ops[this.index]; 12141 if (nextOp) { 12142 const offset = this.offset; 12143 const opLength = Op_default.length(nextOp); 12144 if (length2 >= opLength - offset) { 12145 length2 = opLength - offset; 12146 this.index += 1; 12147 this.offset = 0; 12148 } else { 12149 this.offset += length2; 12150 } 12151 if (typeof nextOp.delete === "number") { 12152 return { delete: length2 }; 12153 } 12154 const retOp = {}; 12155 if (nextOp.attributes) { 12156 retOp.attributes = nextOp.attributes; 12157 } 12158 if (typeof nextOp.retain === "number") { 12159 retOp.retain = length2; 12160 } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { 12161 retOp.retain = nextOp.retain; 12162 } else if (typeof nextOp.insert === "string") { 12163 retOp.insert = nextOp.insert.substr(offset, length2); 12164 } else { 12165 retOp.insert = nextOp.insert; 12166 } 12167 return retOp; 12168 } 12169 return { retain: Infinity }; 12170 } 12171 peek() { 12172 return this.ops[this.index]; 12173 } 12174 peekLength() { 12175 if (this.ops[this.index]) { 12176 return Op_default.length(this.ops[this.index]) - this.offset; 12177 } 12178 return Infinity; 12179 } 12180 peekType() { 12181 const op = this.ops[this.index]; 12182 if (op) { 12183 if (typeof op.delete === "number") { 12184 return "delete"; 12185 } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { 12186 return "retain"; 12187 } 12188 return "insert"; 12189 } 12190 return "retain"; 12191 } 12192 rest() { 12193 if (!this.hasNext()) { 12194 return []; 12195 } else if (this.offset === 0) { 12196 return this.ops.slice(this.index); 12197 } 12198 const offset = this.offset; 12199 const index = this.index; 12200 const next = this.next(); 12201 const rest = this.ops.slice(this.index); 12202 this.offset = offset; 12203 this.index = index; 12204 return [next].concat(rest); 12205 } 12206 }; 12207 12208 // packages/sync/build-module/quill-delta/Delta.mjs 12209 function cloneDeep2(value) { 12210 return JSON.parse(JSON.stringify(value)); 12211 } 12212 var NULL_CHARACTER = String.fromCharCode(0); 12213 var STRING_TOO_LARGE_THRESHOLD = 1e4; 12214 function normalizeChangeCounts(changes) { 12215 return changes.map((change) => ({ 12216 ...change, 12217 count: change.value.length 12218 })); 12219 } 12220 var getEmbedTypeAndData = (a, b) => { 12221 if (typeof a !== "object" || a === null) { 12222 throw new Error(`cannot retain a $typeof a}`); 12223 } 12224 if (typeof b !== "object" || b === null) { 12225 throw new Error(`cannot retain a $typeof b}`); 12226 } 12227 const embedType = Object.keys(a)[0]; 12228 if (!embedType || embedType !== Object.keys(b)[0]) { 12229 throw new Error( 12230 `embed types not matched: $embedType} != $Object.keys(b)[0]}` 12231 ); 12232 } 12233 return [embedType, a[embedType], b[embedType]]; 12234 }; 12235 var Delta = class _Delta { 12236 static Op = Op_default; 12237 static OpIterator = Iterator; 12238 static AttributeMap = AttributeMap_default; 12239 static handlers = {}; 12240 static registerEmbed(embedType, handler) { 12241 this.handlers[embedType] = handler; 12242 } 12243 static unregisterEmbed(embedType) { 12244 delete this.handlers[embedType]; 12245 } 12246 static getHandler(embedType) { 12247 const handler = this.handlers[embedType]; 12248 if (!handler) { 12249 throw new Error(`no handlers for embed type "$embedType}"`); 12250 } 12251 return handler; 12252 } 12253 ops; 12254 constructor(ops) { 12255 if (Array.isArray(ops)) { 12256 this.ops = ops; 12257 } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { 12258 this.ops = ops.ops; 12259 } else { 12260 this.ops = []; 12261 } 12262 } 12263 insert(arg, attributes) { 12264 const newOp = {}; 12265 if (typeof arg === "string" && arg.length === 0) { 12266 return this; 12267 } 12268 newOp.insert = arg; 12269 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12270 newOp.attributes = attributes; 12271 } 12272 return this.push(newOp); 12273 } 12274 delete(length2) { 12275 if (length2 <= 0) { 12276 return this; 12277 } 12278 return this.push({ delete: length2 }); 12279 } 12280 retain(length2, attributes) { 12281 if (typeof length2 === "number" && length2 <= 0) { 12282 return this; 12283 } 12284 const newOp = { retain: length2 }; 12285 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12286 newOp.attributes = attributes; 12287 } 12288 return this.push(newOp); 12289 } 12290 push(newOp) { 12291 let index = this.ops.length; 12292 let lastOp = this.ops[index - 1]; 12293 newOp = cloneDeep2(newOp); 12294 if (typeof lastOp === "object") { 12295 if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { 12296 this.ops[index - 1] = { 12297 delete: lastOp.delete + newOp.delete 12298 }; 12299 return this; 12300 } 12301 if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { 12302 index -= 1; 12303 lastOp = this.ops[index - 1]; 12304 if (typeof lastOp !== "object") { 12305 this.ops.unshift(newOp); 12306 return this; 12307 } 12308 } 12309 if ((0, import_es62.default)(newOp.attributes, lastOp.attributes)) { 12310 if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { 12311 this.ops[index - 1] = { 12312 insert: lastOp.insert + newOp.insert 12313 }; 12314 if (typeof newOp.attributes === "object") { 12315 this.ops[index - 1].attributes = newOp.attributes; 12316 } 12317 return this; 12318 } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { 12319 this.ops[index - 1] = { 12320 retain: lastOp.retain + newOp.retain 12321 }; 12322 if (typeof newOp.attributes === "object") { 12323 this.ops[index - 1].attributes = newOp.attributes; 12324 } 12325 return this; 12326 } 12327 } 12328 } 12329 if (index === this.ops.length) { 12330 this.ops.push(newOp); 12331 } else { 12332 this.ops.splice(index, 0, newOp); 12333 } 12334 return this; 12335 } 12336 chop() { 12337 const lastOp = this.ops[this.ops.length - 1]; 12338 if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { 12339 this.ops.pop(); 12340 } 12341 return this; 12342 } 12343 filter(predicate) { 12344 return this.ops.filter(predicate); 12345 } 12346 forEach(predicate) { 12347 this.ops.forEach(predicate); 12348 } 12349 map(predicate) { 12350 return this.ops.map(predicate); 12351 } 12352 partition(predicate) { 12353 const passed = []; 12354 const failed = []; 12355 this.forEach((op) => { 12356 const target = predicate(op) ? passed : failed; 12357 target.push(op); 12358 }); 12359 return [passed, failed]; 12360 } 12361 reduce(predicate, initialValue) { 12362 return this.ops.reduce(predicate, initialValue); 12363 } 12364 changeLength() { 12365 return this.reduce((length2, elem) => { 12366 if (elem.insert) { 12367 return length2 + Op_default.length(elem); 12368 } else if (elem.delete) { 12369 return length2 - elem.delete; 12370 } 12371 return length2; 12372 }, 0); 12373 } 12374 length() { 12375 return this.reduce((length2, elem) => { 12376 return length2 + Op_default.length(elem); 12377 }, 0); 12378 } 12379 slice(start = 0, end = Infinity) { 12380 const ops = []; 12381 const iter = new Iterator(this.ops); 12382 let index = 0; 12383 while (index < end && iter.hasNext()) { 12384 let nextOp; 12385 if (index < start) { 12386 nextOp = iter.next(start - index); 12387 } else { 12388 nextOp = iter.next(end - index); 12389 ops.push(nextOp); 12390 } 12391 index += Op_default.length(nextOp); 12392 } 12393 return new _Delta(ops); 12394 } 12395 compose(other) { 12396 const thisIter = new Iterator(this.ops); 12397 const otherIter = new Iterator(other.ops); 12398 const ops = []; 12399 const firstOther = otherIter.peek(); 12400 if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { 12401 let firstLeft = firstOther.retain; 12402 while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { 12403 firstLeft -= thisIter.peekLength(); 12404 ops.push(thisIter.next()); 12405 } 12406 if (firstOther.retain - firstLeft > 0) { 12407 otherIter.next(firstOther.retain - firstLeft); 12408 } 12409 } 12410 const delta = new _Delta(ops); 12411 while (thisIter.hasNext() || otherIter.hasNext()) { 12412 if (otherIter.peekType() === "insert") { 12413 delta.push(otherIter.next()); 12414 } else if (thisIter.peekType() === "delete") { 12415 delta.push(thisIter.next()); 12416 } else { 12417 const length2 = Math.min( 12418 thisIter.peekLength(), 12419 otherIter.peekLength() 12420 ); 12421 const thisOp = thisIter.next(length2); 12422 const otherOp = otherIter.next(length2); 12423 if (otherOp.retain) { 12424 const newOp = {}; 12425 if (typeof thisOp.retain === "number") { 12426 newOp.retain = typeof otherOp.retain === "number" ? length2 : otherOp.retain; 12427 } else if (typeof otherOp.retain === "number") { 12428 if (thisOp.retain === null || thisOp.retain === void 0) { 12429 newOp.insert = thisOp.insert; 12430 } else { 12431 newOp.retain = thisOp.retain; 12432 } 12433 } else { 12434 const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; 12435 const [embedType, thisData, otherData] = getEmbedTypeAndData( 12436 thisOp[action], 12437 otherOp.retain 12438 ); 12439 const handler = _Delta.getHandler(embedType); 12440 newOp[action] = { 12441 [embedType]: handler.compose( 12442 thisData, 12443 otherData, 12444 action === "retain" 12445 ) 12446 }; 12447 } 12448 const attributes = AttributeMap_default.compose( 12449 thisOp.attributes, 12450 otherOp.attributes, 12451 typeof thisOp.retain === "number" 12452 ); 12453 if (attributes) { 12454 newOp.attributes = attributes; 12455 } 12456 delta.push(newOp); 12457 if (!otherIter.hasNext() && (0, import_es62.default)(delta.ops[delta.ops.length - 1], newOp)) { 12458 const rest = new _Delta(thisIter.rest()); 12459 return delta.concat(rest).chop(); 12460 } 12461 } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { 12462 delta.push(otherOp); 12463 } 12464 } 12465 } 12466 return delta.chop(); 12467 } 12468 concat(other) { 12469 const delta = new _Delta(this.ops.slice()); 12470 if (other.ops.length > 0) { 12471 delta.push(other.ops[0]); 12472 delta.ops = delta.ops.concat(other.ops.slice(1)); 12473 } 12474 return delta; 12475 } 12476 diff(other) { 12477 if (this.ops === other.ops) { 12478 return new _Delta(); 12479 } 12480 const strings = this.deltasToStrings(other); 12481 const diffResult = normalizeChangeCounts( 12482 diffChars(strings[0], strings[1]) 12483 ); 12484 const thisIter = new Iterator(this.ops); 12485 const otherIter = new Iterator(other.ops); 12486 const retDelta = this.convertChangesToDelta( 12487 diffResult, 12488 thisIter, 12489 otherIter 12490 ); 12491 return retDelta.chop(); 12492 } 12493 eachLine(predicate, newline = "\n") { 12494 const iter = new Iterator(this.ops); 12495 let line = new _Delta(); 12496 let i = 0; 12497 while (iter.hasNext()) { 12498 if (iter.peekType() !== "insert") { 12499 return; 12500 } 12501 const thisOp = iter.peek(); 12502 const start = Op_default.length(thisOp) - iter.peekLength(); 12503 const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; 12504 if (index < 0) { 12505 line.push(iter.next()); 12506 } else if (index > 0) { 12507 line.push(iter.next(index)); 12508 } else { 12509 if (predicate(line, iter.next(1).attributes || {}, i) === false) { 12510 return; 12511 } 12512 i += 1; 12513 line = new _Delta(); 12514 } 12515 } 12516 if (line.length() > 0) { 12517 predicate(line, {}, i); 12518 } 12519 } 12520 invert(base) { 12521 const inverted = new _Delta(); 12522 this.reduce((baseIndex, op) => { 12523 if (op.insert) { 12524 inverted.delete(Op_default.length(op)); 12525 } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { 12526 inverted.retain(op.retain); 12527 return baseIndex + op.retain; 12528 } else if (op.delete || typeof op.retain === "number") { 12529 const length2 = op.delete || op.retain; 12530 const slice = base.slice(baseIndex, baseIndex + length2); 12531 slice.forEach((baseOp) => { 12532 if (op.delete) { 12533 inverted.push(baseOp); 12534 } else if (op.retain && op.attributes) { 12535 inverted.retain( 12536 Op_default.length(baseOp), 12537 AttributeMap_default.invert( 12538 op.attributes, 12539 baseOp.attributes 12540 ) 12541 ); 12542 } 12543 }); 12544 return baseIndex + length2; 12545 } else if (typeof op.retain === "object" && op.retain !== null) { 12546 const slice = base.slice(baseIndex, baseIndex + 1); 12547 const baseOp = new Iterator(slice.ops).next(); 12548 const [embedType, opData, baseOpData] = getEmbedTypeAndData( 12549 op.retain, 12550 baseOp.insert 12551 ); 12552 const handler = _Delta.getHandler(embedType); 12553 inverted.retain( 12554 { [embedType]: handler.invert(opData, baseOpData) }, 12555 AttributeMap_default.invert(op.attributes, baseOp.attributes) 12556 ); 12557 return baseIndex + 1; 12558 } 12559 return baseIndex; 12560 }, 0); 12561 return inverted.chop(); 12562 } 12563 transform(arg, priority = false) { 12564 priority = !!priority; 12565 if (typeof arg === "number") { 12566 return this.transformPosition(arg, priority); 12567 } 12568 const other = arg; 12569 const thisIter = new Iterator(this.ops); 12570 const otherIter = new Iterator(other.ops); 12571 const delta = new _Delta(); 12572 while (thisIter.hasNext() || otherIter.hasNext()) { 12573 if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { 12574 delta.retain(Op_default.length(thisIter.next())); 12575 } else if (otherIter.peekType() === "insert") { 12576 delta.push(otherIter.next()); 12577 } else { 12578 const length2 = Math.min( 12579 thisIter.peekLength(), 12580 otherIter.peekLength() 12581 ); 12582 const thisOp = thisIter.next(length2); 12583 const otherOp = otherIter.next(length2); 12584 if (thisOp.delete) { 12585 continue; 12586 } else if (otherOp.delete) { 12587 delta.push(otherOp); 12588 } else { 12589 const thisData = thisOp.retain; 12590 const otherData = otherOp.retain; 12591 let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length2; 12592 if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { 12593 const embedType = Object.keys(thisData)[0]; 12594 if (embedType === Object.keys(otherData)[0]) { 12595 const handler = _Delta.getHandler(embedType); 12596 if (handler) { 12597 transformedData = { 12598 [embedType]: handler.transform( 12599 thisData[embedType], 12600 otherData[embedType], 12601 priority 12602 ) 12603 }; 12604 } 12605 } 12606 } 12607 delta.retain( 12608 transformedData, 12609 AttributeMap_default.transform( 12610 thisOp.attributes, 12611 otherOp.attributes, 12612 priority 12613 ) 12614 ); 12615 } 12616 } 12617 } 12618 return delta.chop(); 12619 } 12620 transformPosition(index, priority = false) { 12621 priority = !!priority; 12622 const thisIter = new Iterator(this.ops); 12623 let offset = 0; 12624 while (thisIter.hasNext() && offset <= index) { 12625 const length2 = thisIter.peekLength(); 12626 const nextType = thisIter.peekType(); 12627 thisIter.next(); 12628 if (nextType === "delete") { 12629 index -= Math.min(length2, index - offset); 12630 continue; 12631 } else if (nextType === "insert" && (offset < index || !priority)) { 12632 index += length2; 12633 } 12634 offset += length2; 12635 } 12636 return index; 12637 } 12638 /** 12639 * Given a Delta and a cursor position, do a diff and attempt to adjust 12640 * the diff to place insertions or deletions at the cursor position. 12641 * 12642 * @todo There are at least a few known cases where this produces a corrupted 12643 * diff. When this is fixed, it should not be necessary to verify that the 12644 * transformed diff applies cleanly. 12645 * 12646 * @see import("@wordpress/core-data/src/utils/crdt-blocks").mergeRichTextUpdate() 12647 * 12648 * @param other - The other Delta to diff against. 12649 * @param cursorAfterChange - The cursor position index after the change. 12650 * @return A Delta that attempts to place insertions or deletions at the cursor position. 12651 */ 12652 diffWithCursor(other, cursorAfterChange) { 12653 if (this.ops === other.ops) { 12654 return new _Delta(); 12655 } 12656 const strings = this.deltasToStrings(other); 12657 const maxStringLength = Math.max( 12658 ...strings.map((str) => str.length) 12659 ); 12660 if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { 12661 const diffResult = normalizeChangeCounts( 12662 diffLines(strings[0], strings[1]) 12663 ); 12664 const thisIterLarge = new Iterator(this.ops); 12665 const otherIterLarge = new Iterator(other.ops); 12666 return this.convertChangesToDelta( 12667 diffResult, 12668 thisIterLarge, 12669 otherIterLarge 12670 ).chop(); 12671 } else if (cursorAfterChange === null) { 12672 return this.diff(other); 12673 } 12674 let diffs = normalizeChangeCounts( 12675 diffChars(strings[0], strings[1]) 12676 ); 12677 let lastDiffPosition = 0; 12678 const adjustedDiffs = []; 12679 for (let i = 0; i < diffs.length; i++) { 12680 const diff = diffs[i]; 12681 const segmentStart = lastDiffPosition; 12682 const segmentEnd = lastDiffPosition + (diff.count ?? 0); 12683 const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; 12684 const isUnchangedSegment = !diff.added && !diff.removed; 12685 const isRemovalSegment = diff.removed && !diff.added; 12686 const nextDiff = diffs[i + 1]; 12687 const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; 12688 if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { 12689 const movedSegments = this.tryMoveInsertionToCursor( 12690 diff, 12691 nextDiff, 12692 cursorAfterChange, 12693 segmentStart 12694 ); 12695 if (movedSegments) { 12696 adjustedDiffs.push(...movedSegments); 12697 i++; 12698 lastDiffPosition = segmentEnd; 12699 continue; 12700 } 12701 } 12702 if (isRemovalSegment) { 12703 const movedSegments = this.tryMoveDeletionToCursor( 12704 diff, 12705 adjustedDiffs, 12706 cursorAfterChange, 12707 lastDiffPosition 12708 ); 12709 if (movedSegments) { 12710 adjustedDiffs.pop(); 12711 adjustedDiffs.push(...movedSegments); 12712 lastDiffPosition += diff.count ?? 0; 12713 continue; 12714 } 12715 } 12716 adjustedDiffs.push(diff); 12717 if (!diff.added) { 12718 lastDiffPosition += diff.count ?? 0; 12719 } 12720 } 12721 diffs = adjustedDiffs; 12722 const thisIter = new Iterator(this.ops); 12723 const otherIter = new Iterator(other.ops); 12724 const retDelta = this.convertChangesToDelta( 12725 diffs, 12726 thisIter, 12727 otherIter 12728 ); 12729 return retDelta.chop(); 12730 } 12731 /** 12732 * Try to move an insertion operation from after an unchanged segment to the cursor position within it. 12733 * This is a "look-ahead" strategy. 12734 * 12735 * @param diff - The current unchanged diff segment. 12736 * @param nextDiff - The next diff segment (expected to be an insertion). 12737 * @param cursorAfterChange - The cursor position after the change. 12738 * @param segmentStart - The start position of the current segment. 12739 * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. 12740 */ 12741 tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { 12742 const nextDiffInsert = nextDiff.value; 12743 const insertLength = nextDiffInsert.length; 12744 const insertOffset = cursorAfterChange - segmentStart - insertLength; 12745 const textAtCursor = diff.value.substring( 12746 insertOffset, 12747 insertOffset + nextDiffInsert.length 12748 ); 12749 const isInsertMoveable = textAtCursor === nextDiffInsert; 12750 if (!isInsertMoveable) { 12751 return null; 12752 } 12753 const beforeCursor = diff.value.substring(0, insertOffset); 12754 const afterCursor = diff.value.substring(insertOffset); 12755 const result = []; 12756 if (beforeCursor.length > 0) { 12757 result.push({ 12758 value: beforeCursor, 12759 count: beforeCursor.length, 12760 added: false, 12761 removed: false 12762 }); 12763 } 12764 result.push(nextDiff); 12765 if (afterCursor.length > 0) { 12766 result.push({ 12767 value: afterCursor, 12768 count: afterCursor.length, 12769 added: false, 12770 removed: false 12771 }); 12772 } 12773 return result; 12774 } 12775 /** 12776 * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. 12777 * This is a "look-back" strategy. 12778 * 12779 * @param diff - The current deletion diff segment. 12780 * @param adjustedDiffs - The array of previously processed diff segments. 12781 * @param cursorAfterChange - The cursor position after the change. 12782 * @param lastDiffPosition - The position in the document up to (but not including) the current diff. 12783 * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. 12784 */ 12785 tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { 12786 const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; 12787 if (!prevDiff || prevDiff.added || prevDiff.removed) { 12788 return null; 12789 } 12790 const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); 12791 const prevSegmentEnd = lastDiffPosition; 12792 if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { 12793 return null; 12794 } 12795 const deletedChars = diff.value; 12796 const deleteOffset = cursorAfterChange - prevSegmentStart; 12797 const textAtCursor = prevDiff.value.substring( 12798 deleteOffset, 12799 deleteOffset + deletedChars.length 12800 ); 12801 const canBePlacedHere = textAtCursor === deletedChars; 12802 if (!canBePlacedHere) { 12803 return null; 12804 } 12805 const beforeCursor = prevDiff.value.substring(0, deleteOffset); 12806 const atAndAfterCursor = prevDiff.value.substring(deleteOffset); 12807 const deletionLength = diff.count ?? 0; 12808 const afterDeletion = atAndAfterCursor.substring(deletionLength); 12809 const result = []; 12810 if (beforeCursor.length > 0) { 12811 result.push({ 12812 value: beforeCursor, 12813 count: beforeCursor.length, 12814 added: false, 12815 removed: false 12816 }); 12817 } 12818 result.push(diff); 12819 if (afterDeletion.length > 0) { 12820 result.push({ 12821 value: afterDeletion, 12822 count: afterDeletion.length, 12823 added: false, 12824 removed: false 12825 }); 12826 } 12827 return result; 12828 } 12829 /** 12830 * Convert two Deltas to string representations for diffing. 12831 * 12832 * @param other - The other Delta to convert. 12833 * @return A tuple of [thisString, otherString]. 12834 */ 12835 deltasToStrings(other) { 12836 return [this, other].map((delta) => { 12837 return delta.map((op) => { 12838 if (op.insert !== null || op.insert !== void 0) { 12839 return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; 12840 } 12841 const prep = delta === other ? "on" : "with"; 12842 throw new Error( 12843 "diff() called " + prep + " non-document" 12844 ); 12845 }).join(""); 12846 }); 12847 } 12848 /** 12849 * Process diff changes and convert them to Delta operations. 12850 * 12851 * @param changes - The array of changes from the diff algorithm. 12852 * @param thisIter - Iterator for this Delta's operations. 12853 * @param otherIter - Iterator for the other Delta's operations. 12854 * @return A Delta containing the processed diff operations. 12855 */ 12856 convertChangesToDelta(changes, thisIter, otherIter) { 12857 const retDelta = new _Delta(); 12858 changes.forEach((component) => { 12859 let length2 = component.count ?? 0; 12860 while (length2 > 0) { 12861 let opLength = 0; 12862 if (component.added) { 12863 opLength = Math.min(otherIter.peekLength(), length2); 12864 retDelta.push(otherIter.next(opLength)); 12865 } else if (component.removed) { 12866 opLength = Math.min(length2, thisIter.peekLength()); 12867 thisIter.next(opLength); 12868 retDelta.delete(opLength); 12869 } else { 12870 opLength = Math.min( 12871 thisIter.peekLength(), 12872 otherIter.peekLength(), 12873 length2 12874 ); 12875 const thisOp = thisIter.next(opLength); 12876 const otherOp = otherIter.next(opLength); 12877 if ((0, import_es62.default)(thisOp.insert, otherOp.insert)) { 12878 retDelta.retain( 12879 opLength, 12880 AttributeMap_default.diff( 12881 thisOp.attributes, 12882 otherOp.attributes 12883 ) 12884 ); 12885 } else { 12886 retDelta.push(otherOp).delete(opLength); 12887 } 12888 } 12889 length2 -= opLength; 12890 } 12891 }); 12892 return retDelta; 12893 } 12894 }; 12895 var Delta_default = Delta; 12896 12897 // packages/sync/build-module/private-apis.mjs 12898 var privateApis = {}; 12899 lock(privateApis, { 12900 ConnectionErrorCode, 12901 createSyncManager, 12902 Delta: Delta_default, 12903 CRDT_DOC_META_PERSISTENCE_KEY, 12904 CRDT_RECORD_MAP_KEY, 12905 LOCAL_EDITOR_ORIGIN, 12906 LOCAL_UNDO_IGNORED_ORIGIN, 12907 retrySyncConnection: () => pollingManager.retryNow() 12908 }); 12909 12910 // packages/sync/build-module/index.mjs 12911 var YJS_VERSION = "13"; 12912 return __toCommonJS(index_exports); 12913 })(); 12914 (window.wp ||= {}).sync = wp.sync; 12915 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Tue Sep 22 08:20:31 2026 | Cross-referenced by PHPXref |