| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 "use strict"; 2 var wp; 3 (wp ||= {}).sync = (() => { 4 var __create = Object.create; 5 var __defProp = Object.defineProperty; 6 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 7 var __getOwnPropNames = Object.getOwnPropertyNames; 8 var __getProtoOf = Object.getPrototypeOf; 9 var __hasOwnProp = Object.prototype.hasOwnProperty; 10 var __commonJS = (cb, mod) => function __require() { 11 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 12 }; 13 var __export = (target, all2) => { 14 for (var name in all2) 15 __defProp(target, name, { get: all2[name], enumerable: true }); 16 }; 17 var __copyProps = (to, from2, except, desc) => { 18 if (from2 && typeof from2 === "object" || typeof from2 === "function") { 19 for (let key of __getOwnPropNames(from2)) 20 if (!__hasOwnProp.call(to, key) && key !== except) 21 __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable }); 22 } 23 return to; 24 }; 25 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 26 // If the importer is in node compatibility mode or this is not an ESM 27 // file that has been converted to a CommonJS file using a Babel- 28 // compatible transform (i.e. "__esModule" has not been set), then set 29 // "default" to the CommonJS "module.exports" for node compatibility. 30 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 31 mod 32 )); 33 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 34 35 // package-external:@wordpress/private-apis 36 var require_private_apis = __commonJS({ 37 "package-external:@wordpress/private-apis"(exports, module) { 38 module.exports = window.wp.privateApis; 39 } 40 }); 41 42 // package-external:@wordpress/hooks 43 var require_hooks = __commonJS({ 44 "package-external:@wordpress/hooks"(exports, module) { 45 module.exports = window.wp.hooks; 46 } 47 }); 48 49 // package-external:@wordpress/api-fetch 50 var require_api_fetch = __commonJS({ 51 "package-external:@wordpress/api-fetch"(exports, module) { 52 module.exports = window.wp.apiFetch; 53 } 54 }); 55 56 // node_modules/fast-deep-equal/es6/index.js 57 var require_es6 = __commonJS({ 58 "node_modules/fast-deep-equal/es6/index.js"(exports, module) { 59 "use strict"; 60 module.exports = function equal(a, b) { 61 if (a === b) return true; 62 if (a && b && typeof a == "object" && typeof b == "object") { 63 if (a.constructor !== b.constructor) return false; 64 var length2, i, keys2; 65 if (Array.isArray(a)) { 66 length2 = a.length; 67 if (length2 != b.length) return false; 68 for (i = length2; i-- !== 0; ) 69 if (!equal(a[i], b[i])) return false; 70 return true; 71 } 72 if (a instanceof Map && b instanceof Map) { 73 if (a.size !== b.size) return false; 74 for (i of a.entries()) 75 if (!b.has(i[0])) return false; 76 for (i of a.entries()) 77 if (!equal(i[1], b.get(i[0]))) return false; 78 return true; 79 } 80 if (a instanceof Set && b instanceof Set) { 81 if (a.size !== b.size) return false; 82 for (i of a.entries()) 83 if (!b.has(i[0])) return false; 84 return true; 85 } 86 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 87 length2 = a.length; 88 if (length2 != b.length) return false; 89 for (i = length2; i-- !== 0; ) 90 if (a[i] !== b[i]) return false; 91 return true; 92 } 93 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 94 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 95 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 96 keys2 = Object.keys(a); 97 length2 = keys2.length; 98 if (length2 !== Object.keys(b).length) return false; 99 for (i = length2; i-- !== 0; ) 100 if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false; 101 for (i = length2; i-- !== 0; ) { 102 var key = keys2[i]; 103 if (!equal(a[key], b[key])) return false; 104 } 105 return true; 106 } 107 return a !== a && b !== b; 108 }; 109 } 110 }); 111 112 // packages/sync/build-module/index.mjs 113 var index_exports = {}; 114 __export(index_exports, { 115 Awareness: () => Awareness, 116 Y: () => yjs_exports, 117 YJS_VERSION: () => YJS_VERSION, 118 privateApis: () => privateApis 119 }); 120 121 // node_modules/yjs/dist/yjs.mjs 122 var yjs_exports = {}; 123 __export(yjs_exports, { 124 AbsolutePosition: () => AbsolutePosition, 125 AbstractConnector: () => AbstractConnector, 126 AbstractStruct: () => AbstractStruct, 127 AbstractType: () => AbstractType, 128 Array: () => YArray, 129 ContentAny: () => ContentAny, 130 ContentBinary: () => ContentBinary, 131 ContentDeleted: () => ContentDeleted, 132 ContentDoc: () => ContentDoc, 133 ContentEmbed: () => ContentEmbed, 134 ContentFormat: () => ContentFormat, 135 ContentJSON: () => ContentJSON, 136 ContentString: () => ContentString, 137 ContentType: () => ContentType, 138 Doc: () => Doc, 139 GC: () => GC, 140 ID: () => ID, 141 Item: () => Item, 142 Map: () => YMap, 143 PermanentUserData: () => PermanentUserData, 144 RelativePosition: () => RelativePosition, 145 Skip: () => Skip, 146 Snapshot: () => Snapshot, 147 Text: () => YText, 148 Transaction: () => Transaction, 149 UndoManager: () => UndoManager, 150 UpdateDecoderV1: () => UpdateDecoderV1, 151 UpdateDecoderV2: () => UpdateDecoderV2, 152 UpdateEncoderV1: () => UpdateEncoderV1, 153 UpdateEncoderV2: () => UpdateEncoderV2, 154 XmlElement: () => YXmlElement, 155 XmlFragment: () => YXmlFragment, 156 XmlHook: () => YXmlHook, 157 XmlText: () => YXmlText, 158 YArrayEvent: () => YArrayEvent, 159 YEvent: () => YEvent, 160 YMapEvent: () => YMapEvent, 161 YTextEvent: () => YTextEvent, 162 YXmlEvent: () => YXmlEvent, 163 applyUpdate: () => applyUpdate, 164 applyUpdateV2: () => applyUpdateV2, 165 cleanupYTextFormatting: () => cleanupYTextFormatting, 166 compareIDs: () => compareIDs, 167 compareRelativePositions: () => compareRelativePositions, 168 convertUpdateFormatV1ToV2: () => convertUpdateFormatV1ToV2, 169 convertUpdateFormatV2ToV1: () => convertUpdateFormatV2ToV1, 170 createAbsolutePositionFromRelativePosition: () => createAbsolutePositionFromRelativePosition, 171 createDeleteSet: () => createDeleteSet, 172 createDeleteSetFromStructStore: () => createDeleteSetFromStructStore, 173 createDocFromSnapshot: () => createDocFromSnapshot, 174 createID: () => createID, 175 createRelativePositionFromJSON: () => createRelativePositionFromJSON, 176 createRelativePositionFromTypeIndex: () => createRelativePositionFromTypeIndex, 177 createSnapshot: () => createSnapshot, 178 decodeRelativePosition: () => decodeRelativePosition, 179 decodeSnapshot: () => decodeSnapshot, 180 decodeSnapshotV2: () => decodeSnapshotV2, 181 decodeStateVector: () => decodeStateVector, 182 decodeUpdate: () => decodeUpdate, 183 decodeUpdateV2: () => decodeUpdateV2, 184 diffUpdate: () => diffUpdate, 185 diffUpdateV2: () => diffUpdateV2, 186 emptySnapshot: () => emptySnapshot, 187 encodeRelativePosition: () => encodeRelativePosition, 188 encodeSnapshot: () => encodeSnapshot, 189 encodeSnapshotV2: () => encodeSnapshotV2, 190 encodeStateAsUpdate: () => encodeStateAsUpdate, 191 encodeStateAsUpdateV2: () => encodeStateAsUpdateV2, 192 encodeStateVector: () => encodeStateVector, 193 encodeStateVectorFromUpdate: () => encodeStateVectorFromUpdate, 194 encodeStateVectorFromUpdateV2: () => encodeStateVectorFromUpdateV2, 195 equalDeleteSets: () => equalDeleteSets, 196 equalSnapshots: () => equalSnapshots, 197 findIndexSS: () => findIndexSS, 198 findRootTypeKey: () => findRootTypeKey, 199 getItem: () => getItem, 200 getItemCleanEnd: () => getItemCleanEnd, 201 getItemCleanStart: () => getItemCleanStart, 202 getState: () => getState, 203 getTypeChildren: () => getTypeChildren, 204 isDeleted: () => isDeleted, 205 isParentOf: () => isParentOf, 206 iterateDeletedStructs: () => iterateDeletedStructs, 207 logType: () => logType, 208 logUpdate: () => logUpdate, 209 logUpdateV2: () => logUpdateV2, 210 mergeDeleteSets: () => mergeDeleteSets, 211 mergeUpdates: () => mergeUpdates, 212 mergeUpdatesV2: () => mergeUpdatesV2, 213 obfuscateUpdate: () => obfuscateUpdate, 214 obfuscateUpdateV2: () => obfuscateUpdateV2, 215 parseUpdateMeta: () => parseUpdateMeta, 216 parseUpdateMetaV2: () => parseUpdateMetaV2, 217 readUpdate: () => readUpdate, 218 readUpdateV2: () => readUpdateV2, 219 relativePositionToJSON: () => relativePositionToJSON, 220 snapshot: () => snapshot, 221 snapshotContainsUpdate: () => snapshotContainsUpdate, 222 transact: () => transact, 223 tryGc: () => tryGc, 224 typeListToArraySnapshot: () => typeListToArraySnapshot, 225 typeMapGetAllSnapshot: () => typeMapGetAllSnapshot, 226 typeMapGetSnapshot: () => typeMapGetSnapshot 227 }); 228 229 // node_modules/lib0/map.js 230 var create = () => /* @__PURE__ */ new Map(); 231 var copy = (m) => { 232 const r = create(); 233 m.forEach((v, k) => { 234 r.set(k, v); 235 }); 236 return r; 237 }; 238 var setIfUndefined = (map2, key, createT) => { 239 let set = map2.get(key); 240 if (set === void 0) { 241 map2.set(key, set = createT()); 242 } 243 return set; 244 }; 245 var map = (m, f) => { 246 const res = []; 247 for (const [key, value] of m) { 248 res.push(f(value, key)); 249 } 250 return res; 251 }; 252 var any = (m, f) => { 253 for (const [key, value] of m) { 254 if (f(value, key)) { 255 return true; 256 } 257 } 258 return false; 259 }; 260 261 // node_modules/lib0/set.js 262 var create2 = () => /* @__PURE__ */ new Set(); 263 264 // node_modules/lib0/array.js 265 var last = (arr) => arr[arr.length - 1]; 266 var appendTo = (dest, src) => { 267 for (let i = 0; i < src.length; i++) { 268 dest.push(src[i]); 269 } 270 }; 271 var from = Array.from; 272 var every = (arr, f) => { 273 for (let i = 0; i < arr.length; i++) { 274 if (!f(arr[i], i, arr)) { 275 return false; 276 } 277 } 278 return true; 279 }; 280 var some = (arr, f) => { 281 for (let i = 0; i < arr.length; i++) { 282 if (f(arr[i], i, arr)) { 283 return true; 284 } 285 } 286 return false; 287 }; 288 var unfold = (len, f) => { 289 const array = new Array(len); 290 for (let i = 0; i < len; i++) { 291 array[i] = f(i, array); 292 } 293 return array; 294 }; 295 var isArray = Array.isArray; 296 297 // node_modules/lib0/observable.js 298 var ObservableV2 = class { 299 constructor() { 300 this._observers = create(); 301 } 302 /** 303 * @template {keyof EVENTS & string} NAME 304 * @param {NAME} name 305 * @param {EVENTS[NAME]} f 306 */ 307 on(name, f) { 308 setIfUndefined( 309 this._observers, 310 /** @type {string} */ 311 name, 312 create2 313 ).add(f); 314 return f; 315 } 316 /** 317 * @template {keyof EVENTS & string} NAME 318 * @param {NAME} name 319 * @param {EVENTS[NAME]} f 320 */ 321 once(name, f) { 322 const _f = (...args2) => { 323 this.off( 324 name, 325 /** @type {any} */ 326 _f 327 ); 328 f(...args2); 329 }; 330 this.on( 331 name, 332 /** @type {any} */ 333 _f 334 ); 335 } 336 /** 337 * @template {keyof EVENTS & string} NAME 338 * @param {NAME} name 339 * @param {EVENTS[NAME]} f 340 */ 341 off(name, f) { 342 const observers = this._observers.get(name); 343 if (observers !== void 0) { 344 observers.delete(f); 345 if (observers.size === 0) { 346 this._observers.delete(name); 347 } 348 } 349 } 350 /** 351 * Emit a named event. All registered event listeners that listen to the 352 * specified name will receive the event. 353 * 354 * @todo This should catch exceptions 355 * 356 * @template {keyof EVENTS & string} NAME 357 * @param {NAME} name The event name. 358 * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. 359 */ 360 emit(name, args2) { 361 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 362 } 363 destroy() { 364 this._observers = create(); 365 } 366 }; 367 var Observable = class { 368 constructor() { 369 this._observers = create(); 370 } 371 /** 372 * @param {N} name 373 * @param {function} f 374 */ 375 on(name, f) { 376 setIfUndefined(this._observers, name, create2).add(f); 377 } 378 /** 379 * @param {N} name 380 * @param {function} f 381 */ 382 once(name, f) { 383 const _f = (...args2) => { 384 this.off(name, _f); 385 f(...args2); 386 }; 387 this.on(name, _f); 388 } 389 /** 390 * @param {N} name 391 * @param {function} f 392 */ 393 off(name, f) { 394 const observers = this._observers.get(name); 395 if (observers !== void 0) { 396 observers.delete(f); 397 if (observers.size === 0) { 398 this._observers.delete(name); 399 } 400 } 401 } 402 /** 403 * Emit a named event. All registered event listeners that listen to the 404 * specified name will receive the event. 405 * 406 * @todo This should catch exceptions 407 * 408 * @param {N} name The event name. 409 * @param {Array<any>} args The arguments that are applied to the event listener. 410 */ 411 emit(name, args2) { 412 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 413 } 414 destroy() { 415 this._observers = create(); 416 } 417 }; 418 419 // node_modules/lib0/math.js 420 var floor = Math.floor; 421 var abs = Math.abs; 422 var min = (a, b) => a < b ? a : b; 423 var max = (a, b) => a > b ? a : b; 424 var isNaN2 = Number.isNaN; 425 var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; 426 427 // node_modules/lib0/binary.js 428 var BIT1 = 1; 429 var BIT2 = 2; 430 var BIT3 = 4; 431 var BIT4 = 8; 432 var BIT6 = 32; 433 var BIT7 = 64; 434 var BIT8 = 128; 435 var BIT18 = 1 << 17; 436 var BIT19 = 1 << 18; 437 var BIT20 = 1 << 19; 438 var BIT21 = 1 << 20; 439 var BIT22 = 1 << 21; 440 var BIT23 = 1 << 22; 441 var BIT24 = 1 << 23; 442 var BIT25 = 1 << 24; 443 var BIT26 = 1 << 25; 444 var BIT27 = 1 << 26; 445 var BIT28 = 1 << 27; 446 var BIT29 = 1 << 28; 447 var BIT30 = 1 << 29; 448 var BIT31 = 1 << 30; 449 var BIT32 = 1 << 31; 450 var BITS5 = 31; 451 var BITS6 = 63; 452 var BITS7 = 127; 453 var BITS17 = BIT18 - 1; 454 var BITS18 = BIT19 - 1; 455 var BITS19 = BIT20 - 1; 456 var BITS20 = BIT21 - 1; 457 var BITS21 = BIT22 - 1; 458 var BITS22 = BIT23 - 1; 459 var BITS23 = BIT24 - 1; 460 var BITS24 = BIT25 - 1; 461 var BITS25 = BIT26 - 1; 462 var BITS26 = BIT27 - 1; 463 var BITS27 = BIT28 - 1; 464 var BITS28 = BIT29 - 1; 465 var BITS29 = BIT30 - 1; 466 var BITS30 = BIT31 - 1; 467 var BITS31 = 2147483647; 468 469 // node_modules/lib0/number.js 470 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; 471 var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; 472 var LOWEST_INT32 = 1 << 31; 473 var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); 474 var isNaN3 = Number.isNaN; 475 var parseInt2 = Number.parseInt; 476 477 // node_modules/lib0/string.js 478 var fromCharCode = String.fromCharCode; 479 var fromCodePoint = String.fromCodePoint; 480 var MAX_UTF16_CHARACTER = fromCharCode(65535); 481 var toLowerCase = (s) => s.toLowerCase(); 482 var trimLeftRegex = /^\s*/g; 483 var trimLeft = (s) => s.replace(trimLeftRegex, ""); 484 var fromCamelCaseRegex = /([A-Z])/g; 485 var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match2) => `$separator}$toLowerCase(match2)}`)); 486 var _encodeUtf8Polyfill = (str) => { 487 const encodedString = unescape(encodeURIComponent(str)); 488 const len = encodedString.length; 489 const buf = new Uint8Array(len); 490 for (let i = 0; i < len; i++) { 491 buf[i] = /** @type {number} */ 492 encodedString.codePointAt(i); 493 } 494 return buf; 495 }; 496 var utf8TextEncoder = ( 497 /** @type {TextEncoder} */ 498 typeof TextEncoder !== "undefined" ? new TextEncoder() : null 499 ); 500 var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); 501 var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; 502 var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); 503 if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { 504 utf8TextDecoder = null; 505 } 506 var repeat = (source, n) => unfold(n, () => source).join(""); 507 508 // node_modules/lib0/encoding.js 509 var Encoder = class { 510 constructor() { 511 this.cpos = 0; 512 this.cbuf = new Uint8Array(100); 513 this.bufs = []; 514 } 515 }; 516 var createEncoder = () => new Encoder(); 517 var length = (encoder) => { 518 let len = encoder.cpos; 519 for (let i = 0; i < encoder.bufs.length; i++) { 520 len += encoder.bufs[i].length; 521 } 522 return len; 523 }; 524 var toUint8Array = (encoder) => { 525 const uint8arr = new Uint8Array(length(encoder)); 526 let curPos = 0; 527 for (let i = 0; i < encoder.bufs.length; i++) { 528 const d = encoder.bufs[i]; 529 uint8arr.set(d, curPos); 530 curPos += d.length; 531 } 532 uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); 533 return uint8arr; 534 }; 535 var verifyLen = (encoder, len) => { 536 const bufferLen = encoder.cbuf.length; 537 if (bufferLen - encoder.cpos < len) { 538 encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); 539 encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); 540 encoder.cpos = 0; 541 } 542 }; 543 var write = (encoder, num) => { 544 const bufferLen = encoder.cbuf.length; 545 if (encoder.cpos === bufferLen) { 546 encoder.bufs.push(encoder.cbuf); 547 encoder.cbuf = new Uint8Array(bufferLen * 2); 548 encoder.cpos = 0; 549 } 550 encoder.cbuf[encoder.cpos++] = num; 551 }; 552 var writeUint8 = write; 553 var writeVarUint = (encoder, num) => { 554 while (num > BITS7) { 555 write(encoder, BIT8 | BITS7 & num); 556 num = floor(num / 128); 557 } 558 write(encoder, BITS7 & num); 559 }; 560 var writeVarInt = (encoder, num) => { 561 const isNegative = isNegativeZero(num); 562 if (isNegative) { 563 num = -num; 564 } 565 write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); 566 num = floor(num / 64); 567 while (num > 0) { 568 write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); 569 num = floor(num / 128); 570 } 571 }; 572 var _strBuffer = new Uint8Array(3e4); 573 var _maxStrBSize = _strBuffer.length / 3; 574 var _writeVarStringNative = (encoder, str) => { 575 if (str.length < _maxStrBSize) { 576 const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; 577 writeVarUint(encoder, written); 578 for (let i = 0; i < written; i++) { 579 write(encoder, _strBuffer[i]); 580 } 581 } else { 582 writeVarUint8Array(encoder, encodeUtf8(str)); 583 } 584 }; 585 var _writeVarStringPolyfill = (encoder, str) => { 586 const encodedString = unescape(encodeURIComponent(str)); 587 const len = encodedString.length; 588 writeVarUint(encoder, len); 589 for (let i = 0; i < len; i++) { 590 write( 591 encoder, 592 /** @type {number} */ 593 encodedString.codePointAt(i) 594 ); 595 } 596 }; 597 var writeVarString = utf8TextEncoder && /** @type {any} */ 598 utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; 599 var writeBinaryEncoder = (encoder, append2) => writeUint8Array(encoder, toUint8Array(append2)); 600 var writeUint8Array = (encoder, uint8Array) => { 601 const bufferLen = encoder.cbuf.length; 602 const cpos = encoder.cpos; 603 const leftCopyLen = min(bufferLen - cpos, uint8Array.length); 604 const rightCopyLen = uint8Array.length - leftCopyLen; 605 encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); 606 encoder.cpos += leftCopyLen; 607 if (rightCopyLen > 0) { 608 encoder.bufs.push(encoder.cbuf); 609 encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); 610 encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); 611 encoder.cpos = rightCopyLen; 612 } 613 }; 614 var writeVarUint8Array = (encoder, uint8Array) => { 615 writeVarUint(encoder, uint8Array.byteLength); 616 writeUint8Array(encoder, uint8Array); 617 }; 618 var writeOnDataView = (encoder, len) => { 619 verifyLen(encoder, len); 620 const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); 621 encoder.cpos += len; 622 return dview; 623 }; 624 var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); 625 var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); 626 var writeBigInt64 = (encoder, num) => ( 627 /** @type {any} */ 628 writeOnDataView(encoder, 8).setBigInt64(0, num, false) 629 ); 630 var floatTestBed = new DataView(new ArrayBuffer(4)); 631 var isFloat32 = (num) => { 632 floatTestBed.setFloat32(0, num); 633 return floatTestBed.getFloat32(0) === num; 634 }; 635 var writeAny = (encoder, data) => { 636 switch (typeof data) { 637 case "string": 638 write(encoder, 119); 639 writeVarString(encoder, data); 640 break; 641 case "number": 642 if (isInteger(data) && abs(data) <= BITS31) { 643 write(encoder, 125); 644 writeVarInt(encoder, data); 645 } else if (isFloat32(data)) { 646 write(encoder, 124); 647 writeFloat32(encoder, data); 648 } else { 649 write(encoder, 123); 650 writeFloat64(encoder, data); 651 } 652 break; 653 case "bigint": 654 write(encoder, 122); 655 writeBigInt64(encoder, data); 656 break; 657 case "object": 658 if (data === null) { 659 write(encoder, 126); 660 } else if (isArray(data)) { 661 write(encoder, 117); 662 writeVarUint(encoder, data.length); 663 for (let i = 0; i < data.length; i++) { 664 writeAny(encoder, data[i]); 665 } 666 } else if (data instanceof Uint8Array) { 667 write(encoder, 116); 668 writeVarUint8Array(encoder, data); 669 } else { 670 write(encoder, 118); 671 const keys2 = Object.keys(data); 672 writeVarUint(encoder, keys2.length); 673 for (let i = 0; i < keys2.length; i++) { 674 const key = keys2[i]; 675 writeVarString(encoder, key); 676 writeAny(encoder, data[key]); 677 } 678 } 679 break; 680 case "boolean": 681 write(encoder, data ? 120 : 121); 682 break; 683 default: 684 write(encoder, 127); 685 } 686 }; 687 var RleEncoder = class extends Encoder { 688 /** 689 * @param {function(Encoder, T):void} writer 690 */ 691 constructor(writer) { 692 super(); 693 this.w = writer; 694 this.s = null; 695 this.count = 0; 696 } 697 /** 698 * @param {T} v 699 */ 700 write(v) { 701 if (this.s === v) { 702 this.count++; 703 } else { 704 if (this.count > 0) { 705 writeVarUint(this, this.count - 1); 706 } 707 this.count = 1; 708 this.w(this, v); 709 this.s = v; 710 } 711 } 712 }; 713 var flushUintOptRleEncoder = (encoder) => { 714 if (encoder.count > 0) { 715 writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); 716 if (encoder.count > 1) { 717 writeVarUint(encoder.encoder, encoder.count - 2); 718 } 719 } 720 }; 721 var UintOptRleEncoder = class { 722 constructor() { 723 this.encoder = new Encoder(); 724 this.s = 0; 725 this.count = 0; 726 } 727 /** 728 * @param {number} v 729 */ 730 write(v) { 731 if (this.s === v) { 732 this.count++; 733 } else { 734 flushUintOptRleEncoder(this); 735 this.count = 1; 736 this.s = v; 737 } 738 } 739 /** 740 * Flush the encoded state and transform this to a Uint8Array. 741 * 742 * Note that this should only be called once. 743 */ 744 toUint8Array() { 745 flushUintOptRleEncoder(this); 746 return toUint8Array(this.encoder); 747 } 748 }; 749 var flushIntDiffOptRleEncoder = (encoder) => { 750 if (encoder.count > 0) { 751 const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); 752 writeVarInt(encoder.encoder, encodedDiff); 753 if (encoder.count > 1) { 754 writeVarUint(encoder.encoder, encoder.count - 2); 755 } 756 } 757 }; 758 var IntDiffOptRleEncoder = class { 759 constructor() { 760 this.encoder = new Encoder(); 761 this.s = 0; 762 this.count = 0; 763 this.diff = 0; 764 } 765 /** 766 * @param {number} v 767 */ 768 write(v) { 769 if (this.diff === v - this.s) { 770 this.s = v; 771 this.count++; 772 } else { 773 flushIntDiffOptRleEncoder(this); 774 this.count = 1; 775 this.diff = v - this.s; 776 this.s = v; 777 } 778 } 779 /** 780 * Flush the encoded state and transform this to a Uint8Array. 781 * 782 * Note that this should only be called once. 783 */ 784 toUint8Array() { 785 flushIntDiffOptRleEncoder(this); 786 return toUint8Array(this.encoder); 787 } 788 }; 789 var StringEncoder = class { 790 constructor() { 791 this.sarr = []; 792 this.s = ""; 793 this.lensE = new UintOptRleEncoder(); 794 } 795 /** 796 * @param {string} string 797 */ 798 write(string) { 799 this.s += string; 800 if (this.s.length > 19) { 801 this.sarr.push(this.s); 802 this.s = ""; 803 } 804 this.lensE.write(string.length); 805 } 806 toUint8Array() { 807 const encoder = new Encoder(); 808 this.sarr.push(this.s); 809 this.s = ""; 810 writeVarString(encoder, this.sarr.join("")); 811 writeUint8Array(encoder, this.lensE.toUint8Array()); 812 return toUint8Array(encoder); 813 } 814 }; 815 816 // node_modules/lib0/error.js 817 var create3 = (s) => new Error(s); 818 var methodUnimplemented = () => { 819 throw create3("Method unimplemented"); 820 }; 821 var unexpectedCase = () => { 822 throw create3("Unexpected case"); 823 }; 824 825 // node_modules/lib0/decoding.js 826 var errorUnexpectedEndOfArray = create3("Unexpected end of array"); 827 var errorIntegerOutOfRange = create3("Integer out of Range"); 828 var Decoder = class { 829 /** 830 * @param {Uint8Array<Buf>} uint8Array Binary data to decode 831 */ 832 constructor(uint8Array) { 833 this.arr = uint8Array; 834 this.pos = 0; 835 } 836 }; 837 var createDecoder = (uint8Array) => new Decoder(uint8Array); 838 var hasContent = (decoder) => decoder.pos !== decoder.arr.length; 839 var readUint8Array = (decoder, len) => { 840 const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); 841 decoder.pos += len; 842 return view; 843 }; 844 var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); 845 var readUint8 = (decoder) => decoder.arr[decoder.pos++]; 846 var readVarUint = (decoder) => { 847 let num = 0; 848 let mult = 1; 849 const len = decoder.arr.length; 850 while (decoder.pos < len) { 851 const r = decoder.arr[decoder.pos++]; 852 num = num + (r & BITS7) * mult; 853 mult *= 128; 854 if (r < BIT8) { 855 return num; 856 } 857 if (num > MAX_SAFE_INTEGER) { 858 throw errorIntegerOutOfRange; 859 } 860 } 861 throw errorUnexpectedEndOfArray; 862 }; 863 var readVarInt = (decoder) => { 864 let r = decoder.arr[decoder.pos++]; 865 let num = r & BITS6; 866 let mult = 64; 867 const sign = (r & BIT7) > 0 ? -1 : 1; 868 if ((r & BIT8) === 0) { 869 return sign * num; 870 } 871 const len = decoder.arr.length; 872 while (decoder.pos < len) { 873 r = decoder.arr[decoder.pos++]; 874 num = num + (r & BITS7) * mult; 875 mult *= 128; 876 if (r < BIT8) { 877 return sign * num; 878 } 879 if (num > MAX_SAFE_INTEGER) { 880 throw errorIntegerOutOfRange; 881 } 882 } 883 throw errorUnexpectedEndOfArray; 884 }; 885 var _readVarStringPolyfill = (decoder) => { 886 let remainingLen = readVarUint(decoder); 887 if (remainingLen === 0) { 888 return ""; 889 } else { 890 let encodedString = String.fromCodePoint(readUint8(decoder)); 891 if (--remainingLen < 100) { 892 while (remainingLen--) { 893 encodedString += String.fromCodePoint(readUint8(decoder)); 894 } 895 } else { 896 while (remainingLen > 0) { 897 const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; 898 const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); 899 decoder.pos += nextLen; 900 encodedString += String.fromCodePoint.apply( 901 null, 902 /** @type {any} */ 903 bytes 904 ); 905 remainingLen -= nextLen; 906 } 907 } 908 return decodeURIComponent(escape(encodedString)); 909 } 910 }; 911 var _readVarStringNative = (decoder) => ( 912 /** @type any */ 913 utf8TextDecoder.decode(readVarUint8Array(decoder)) 914 ); 915 var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; 916 var readFromDataView = (decoder, len) => { 917 const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); 918 decoder.pos += len; 919 return dv; 920 }; 921 var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); 922 var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); 923 var readBigInt64 = (decoder) => ( 924 /** @type {any} */ 925 readFromDataView(decoder, 8).getBigInt64(0, false) 926 ); 927 var readAnyLookupTable = [ 928 (decoder) => void 0, 929 // CASE 127: undefined 930 (decoder) => null, 931 // CASE 126: null 932 readVarInt, 933 // CASE 125: integer 934 readFloat32, 935 // CASE 124: float32 936 readFloat64, 937 // CASE 123: float64 938 readBigInt64, 939 // CASE 122: bigint 940 (decoder) => false, 941 // CASE 121: boolean (false) 942 (decoder) => true, 943 // CASE 120: boolean (true) 944 readVarString, 945 // CASE 119: string 946 (decoder) => { 947 const len = readVarUint(decoder); 948 const obj = {}; 949 for (let i = 0; i < len; i++) { 950 const key = readVarString(decoder); 951 obj[key] = readAny(decoder); 952 } 953 return obj; 954 }, 955 (decoder) => { 956 const len = readVarUint(decoder); 957 const arr = []; 958 for (let i = 0; i < len; i++) { 959 arr.push(readAny(decoder)); 960 } 961 return arr; 962 }, 963 readVarUint8Array 964 // CASE 116: Uint8Array 965 ]; 966 var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); 967 var RleDecoder = class extends Decoder { 968 /** 969 * @param {Uint8Array} uint8Array 970 * @param {function(Decoder):T} reader 971 */ 972 constructor(uint8Array, reader) { 973 super(uint8Array); 974 this.reader = reader; 975 this.s = null; 976 this.count = 0; 977 } 978 read() { 979 if (this.count === 0) { 980 this.s = this.reader(this); 981 if (hasContent(this)) { 982 this.count = readVarUint(this) + 1; 983 } else { 984 this.count = -1; 985 } 986 } 987 this.count--; 988 return ( 989 /** @type {T} */ 990 this.s 991 ); 992 } 993 }; 994 var UintOptRleDecoder = class extends Decoder { 995 /** 996 * @param {Uint8Array} uint8Array 997 */ 998 constructor(uint8Array) { 999 super(uint8Array); 1000 this.s = 0; 1001 this.count = 0; 1002 } 1003 read() { 1004 if (this.count === 0) { 1005 this.s = readVarInt(this); 1006 const isNegative = isNegativeZero(this.s); 1007 this.count = 1; 1008 if (isNegative) { 1009 this.s = -this.s; 1010 this.count = readVarUint(this) + 2; 1011 } 1012 } 1013 this.count--; 1014 return ( 1015 /** @type {number} */ 1016 this.s 1017 ); 1018 } 1019 }; 1020 var IntDiffOptRleDecoder = class extends Decoder { 1021 /** 1022 * @param {Uint8Array} uint8Array 1023 */ 1024 constructor(uint8Array) { 1025 super(uint8Array); 1026 this.s = 0; 1027 this.count = 0; 1028 this.diff = 0; 1029 } 1030 /** 1031 * @return {number} 1032 */ 1033 read() { 1034 if (this.count === 0) { 1035 const diff = readVarInt(this); 1036 const hasCount = diff & 1; 1037 this.diff = floor(diff / 2); 1038 this.count = 1; 1039 if (hasCount) { 1040 this.count = readVarUint(this) + 2; 1041 } 1042 } 1043 this.s += this.diff; 1044 this.count--; 1045 return this.s; 1046 } 1047 }; 1048 var StringDecoder = class { 1049 /** 1050 * @param {Uint8Array} uint8Array 1051 */ 1052 constructor(uint8Array) { 1053 this.decoder = new UintOptRleDecoder(uint8Array); 1054 this.str = readVarString(this.decoder); 1055 this.spos = 0; 1056 } 1057 /** 1058 * @return {string} 1059 */ 1060 read() { 1061 const end = this.spos + this.decoder.read(); 1062 const res = this.str.slice(this.spos, end); 1063 this.spos = end; 1064 return res; 1065 } 1066 }; 1067 1068 // node_modules/lib0/webcrypto.js 1069 var subtle = crypto.subtle; 1070 var getRandomValues = crypto.getRandomValues.bind(crypto); 1071 1072 // node_modules/lib0/random.js 1073 var uint32 = () => getRandomValues(new Uint32Array(1))[0]; 1074 var uuidv4Template = "10000000-1000-4000-8000" + -1e11; 1075 var uuidv4 = () => uuidv4Template.replace( 1076 /[018]/g, 1077 /** @param {number} c */ 1078 (c) => (c ^ uint32() & 15 >> c / 4).toString(16) 1079 ); 1080 1081 // node_modules/lib0/time.js 1082 var getUnixTime = Date.now; 1083 1084 // node_modules/lib0/promise.js 1085 var create4 = (f) => ( 1086 /** @type {Promise<T>} */ 1087 new Promise(f) 1088 ); 1089 var all = Promise.all.bind(Promise); 1090 1091 // node_modules/lib0/conditions.js 1092 var undefinedToNull = (v) => v === void 0 ? null : v; 1093 1094 // node_modules/lib0/storage.js 1095 var VarStoragePolyfill = class { 1096 constructor() { 1097 this.map = /* @__PURE__ */ new Map(); 1098 } 1099 /** 1100 * @param {string} key 1101 * @param {any} newValue 1102 */ 1103 setItem(key, newValue) { 1104 this.map.set(key, newValue); 1105 } 1106 /** 1107 * @param {string} key 1108 */ 1109 getItem(key) { 1110 return this.map.get(key); 1111 } 1112 }; 1113 var _localStorage = new VarStoragePolyfill(); 1114 var usePolyfill = true; 1115 try { 1116 if (typeof localStorage !== "undefined" && localStorage) { 1117 _localStorage = localStorage; 1118 usePolyfill = false; 1119 } 1120 } catch (e) { 1121 } 1122 var varStorage = _localStorage; 1123 1124 // node_modules/lib0/trait/equality.js 1125 var EqualityTraitSymbol = /* @__PURE__ */ Symbol("Equality"); 1126 var equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false; 1127 1128 // node_modules/lib0/object.js 1129 var isObject = (o) => typeof o === "object"; 1130 var assign = Object.assign; 1131 var keys = Object.keys; 1132 var forEach = (obj, f) => { 1133 for (const key in obj) { 1134 f(obj[key], key); 1135 } 1136 }; 1137 var size = (obj) => keys(obj).length; 1138 var isEmpty = (obj) => { 1139 for (const _k in obj) { 1140 return false; 1141 } 1142 return true; 1143 }; 1144 var every2 = (obj, f) => { 1145 for (const key in obj) { 1146 if (!f(obj[key], key)) { 1147 return false; 1148 } 1149 } 1150 return true; 1151 }; 1152 var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); 1153 var equalFlat = (a, b) => a === b || size(a) === size(b) && every2(a, (val, key) => (val !== void 0 || hasProperty(b, key)) && equals(b[key], val)); 1154 var freeze = Object.freeze; 1155 var deepFreeze = (o) => { 1156 for (const key in o) { 1157 const c = o[key]; 1158 if (typeof c === "object" || typeof c === "function") { 1159 deepFreeze(o[key]); 1160 } 1161 } 1162 return freeze(o); 1163 }; 1164 1165 // node_modules/lib0/function.js 1166 var callAll = (fs, args2, i = 0) => { 1167 try { 1168 for (; i < fs.length; i++) { 1169 fs[i](...args2); 1170 } 1171 } finally { 1172 if (i < fs.length) { 1173 callAll(fs, args2, i + 1); 1174 } 1175 } 1176 }; 1177 var id = (a) => a; 1178 var equalityDeep = (a, b) => { 1179 if (a === b) { 1180 return true; 1181 } 1182 if (a == null || b == null || a.constructor !== b.constructor && (a.constructor || Object) !== (b.constructor || Object)) { 1183 return false; 1184 } 1185 if (a[EqualityTraitSymbol] != null) { 1186 return a[EqualityTraitSymbol](b); 1187 } 1188 switch (a.constructor) { 1189 case ArrayBuffer: 1190 a = new Uint8Array(a); 1191 b = new Uint8Array(b); 1192 // eslint-disable-next-line no-fallthrough 1193 case Uint8Array: { 1194 if (a.byteLength !== b.byteLength) { 1195 return false; 1196 } 1197 for (let i = 0; i < a.length; i++) { 1198 if (a[i] !== b[i]) { 1199 return false; 1200 } 1201 } 1202 break; 1203 } 1204 case Set: { 1205 if (a.size !== b.size) { 1206 return false; 1207 } 1208 for (const value of a) { 1209 if (!b.has(value)) { 1210 return false; 1211 } 1212 } 1213 break; 1214 } 1215 case Map: { 1216 if (a.size !== b.size) { 1217 return false; 1218 } 1219 for (const key of a.keys()) { 1220 if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) { 1221 return false; 1222 } 1223 } 1224 break; 1225 } 1226 case void 0: 1227 case Object: 1228 if (size(a) !== size(b)) { 1229 return false; 1230 } 1231 for (const key in a) { 1232 if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) { 1233 return false; 1234 } 1235 } 1236 break; 1237 case Array: 1238 if (a.length !== b.length) { 1239 return false; 1240 } 1241 for (let i = 0; i < a.length; i++) { 1242 if (!equalityDeep(a[i], b[i])) { 1243 return false; 1244 } 1245 } 1246 break; 1247 default: 1248 return false; 1249 } 1250 return true; 1251 }; 1252 var isOneOf = (value, options) => options.includes(value); 1253 1254 // node_modules/lib0/environment.js 1255 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]"; 1256 var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; 1257 var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; 1258 var params; 1259 var args = []; 1260 var computeParams = () => { 1261 if (params === void 0) { 1262 if (isNode) { 1263 params = create(); 1264 const pargs = process.argv; 1265 let currParamName = null; 1266 for (let i = 0; i < pargs.length; i++) { 1267 const parg = pargs[i]; 1268 if (parg[0] === "-") { 1269 if (currParamName !== null) { 1270 params.set(currParamName, ""); 1271 } 1272 currParamName = parg; 1273 } else { 1274 if (currParamName !== null) { 1275 params.set(currParamName, parg); 1276 currParamName = null; 1277 } else { 1278 args.push(parg); 1279 } 1280 } 1281 } 1282 if (currParamName !== null) { 1283 params.set(currParamName, ""); 1284 } 1285 } else if (typeof location === "object") { 1286 params = create(); 1287 (location.search || "?").slice(1).split("&").forEach((kv) => { 1288 if (kv.length !== 0) { 1289 const [key, value] = kv.split("="); 1290 params.set(`--$fromCamelCase(key, "-")}`, value); 1291 params.set(`-$fromCamelCase(key, "-")}`, value); 1292 } 1293 }); 1294 } else { 1295 params = create(); 1296 } 1297 } 1298 return params; 1299 }; 1300 var hasParam = (name) => computeParams().has(name); 1301 var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); 1302 var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; 1303 var production = hasConf("production"); 1304 var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); 1305 var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors 1306 !hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); 1307 1308 // node_modules/lib0/buffer.js 1309 var createUint8ArrayFromLen = (len) => new Uint8Array(len); 1310 var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length2) => new Uint8Array(buffer, byteOffset, length2); 1311 var toBase64Browser = (bytes) => { 1312 let s = ""; 1313 for (let i = 0; i < bytes.byteLength; i++) { 1314 s += fromCharCode(bytes[i]); 1315 } 1316 return btoa(s); 1317 }; 1318 var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); 1319 var fromBase64Browser = (s) => { 1320 const a = atob(s); 1321 const bytes = createUint8ArrayFromLen(a.length); 1322 for (let i = 0; i < a.length; i++) { 1323 bytes[i] = a.charCodeAt(i); 1324 } 1325 return bytes; 1326 }; 1327 var fromBase64Node = (s) => { 1328 const buf = Buffer.from(s, "base64"); 1329 return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); 1330 }; 1331 var toBase64 = isBrowser ? toBase64Browser : toBase64Node; 1332 var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; 1333 var copyUint8Array = (uint8Array) => { 1334 const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); 1335 newBuf.set(uint8Array); 1336 return newBuf; 1337 }; 1338 1339 // node_modules/lib0/pair.js 1340 var Pair = class { 1341 /** 1342 * @param {L} left 1343 * @param {R} right 1344 */ 1345 constructor(left, right) { 1346 this.left = left; 1347 this.right = right; 1348 } 1349 }; 1350 var create5 = (left, right) => new Pair(left, right); 1351 1352 // node_modules/lib0/prng.js 1353 var bool = (gen) => gen.next() >= 0.5; 1354 var int53 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); 1355 var int32 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); 1356 var int31 = (gen, min2, max2) => int32(gen, min2, max2); 1357 var letter = (gen) => fromCharCode(int31(gen, 97, 122)); 1358 var word = (gen, minLen = 0, maxLen = 20) => { 1359 const len = int31(gen, minLen, maxLen); 1360 let str = ""; 1361 for (let i = 0; i < len; i++) { 1362 str += letter(gen); 1363 } 1364 return str; 1365 }; 1366 var oneOf = (gen, array) => array[int31(gen, 0, array.length - 1)]; 1367 1368 // node_modules/lib0/schema.js 1369 var schemaSymbol = /* @__PURE__ */ Symbol("0schema"); 1370 var ValidationError = class { 1371 constructor() { 1372 this._rerrs = []; 1373 } 1374 /** 1375 * @param {string?} path 1376 * @param {string} expected 1377 * @param {string} has 1378 * @param {string?} message 1379 */ 1380 extend(path, expected, has, message = null) { 1381 this._rerrs.push({ path, expected, has, message }); 1382 } 1383 toString() { 1384 const s = []; 1385 for (let i = this._rerrs.length - 1; i > 0; i--) { 1386 const r = this._rerrs[i]; 1387 s.push(repeat(" ", (this._rerrs.length - i) * 2) + `$r.path != null ? `[$r.path}] ` : ""}$r.has} doesn't match $r.expected}. $r.message}`); 1388 } 1389 return s.join("\n"); 1390 } 1391 }; 1392 var shapeExtends = (a, b) => { 1393 if (a === b) return true; 1394 if (a == null || b == null || a.constructor !== b.constructor) return false; 1395 if (a[EqualityTraitSymbol]) return equals(a, b); 1396 if (isArray(a)) { 1397 return every( 1398 a, 1399 (aitem) => some(b, (bitem) => shapeExtends(aitem, bitem)) 1400 ); 1401 } else if (isObject(a)) { 1402 return every2( 1403 a, 1404 (aitem, akey) => shapeExtends(aitem, b[akey]) 1405 ); 1406 } 1407 return false; 1408 }; 1409 var Schema = class { 1410 // this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore 1411 /** 1412 * If true, the more things are added to the shape the more objects this schema will accept (e.g. 1413 * union). By default, the more objects are added, the the fewer objects this schema will accept. 1414 * @protected 1415 */ 1416 static _dilutes = false; 1417 /** 1418 * @param {Schema<any>} other 1419 */ 1420 extends(other) { 1421 let [a, b] = [ 1422 /** @type {any} */ 1423 this.shape, 1424 /** @type {any} */ 1425 other.shape 1426 ]; 1427 if ( 1428 /** @type {typeof Schema<any>} */ 1429 this.constructor._dilutes 1430 ) [b, a] = [a, b]; 1431 return shapeExtends(a, b); 1432 } 1433 /** 1434 * Overwrite this when necessary. By default, we only check the `shape` property which every shape 1435 * should have. 1436 * @param {Schema<any>} other 1437 */ 1438 equals(other) { 1439 return this.constructor === other.constructor && equalityDeep(this.shape, other.shape); 1440 } 1441 [schemaSymbol]() { 1442 return true; 1443 } 1444 /** 1445 * @param {object} other 1446 */ 1447 [EqualityTraitSymbol](other) { 1448 return this.equals( 1449 /** @type {any} */ 1450 other 1451 ); 1452 } 1453 /** 1454 * Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of 1455 * Schema. Validate will check the structure of the parameter and return true iff the instance 1456 * really is an instance of Schema. 1457 * 1458 * @param {T} o 1459 * @return {boolean} 1460 */ 1461 validate(o) { 1462 return this.check(o); 1463 } 1464 /* c8 ignore start */ 1465 /** 1466 * Similar to validate, but this method accepts untyped parameters. 1467 * 1468 * @param {any} _o 1469 * @param {ValidationError} [_err] 1470 * @return {_o is T} 1471 */ 1472 check(_o, _err) { 1473 methodUnimplemented(); 1474 } 1475 /* c8 ignore stop */ 1476 /** 1477 * @type {Schema<T?>} 1478 */ 1479 get nullable() { 1480 return $union(this, $null); 1481 } 1482 /** 1483 * @type {$Optional<Schema<T>>} 1484 */ 1485 get optional() { 1486 return new $Optional( 1487 /** @type {Schema<T>} */ 1488 this 1489 ); 1490 } 1491 /** 1492 * Cast a variable to a specific type. Returns the casted value, or throws an exception otherwise. 1493 * Use this if you know that the type is of a specific type and you just want to convince the type 1494 * system. 1495 * 1496 * **Do not rely on these error messages!** 1497 * Performs an assertion check only if not in a production environment. 1498 * 1499 * @template OO 1500 * @param {OO} o 1501 * @return {Extract<OO, T> extends never ? T : (OO extends Array<never> ? T : Extract<OO,T>)} 1502 */ 1503 cast(o) { 1504 assert(o, this); 1505 return ( 1506 /** @type {any} */ 1507 o 1508 ); 1509 } 1510 /** 1511 * EXPECTO PATRONUM!! 🪄 1512 * This function protects against type errors. Though it may not work in the real world. 1513 * 1514 * "After all this time?" 1515 * "Always." - Snape, talking about type safety 1516 * 1517 * Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed. 1518 * Use this if you know that the type is of a specific type and you just want to convince the type 1519 * system. 1520 * 1521 * Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).expect((n) => n + 1)` 1522 * 1523 * **Do not rely on these error messages!** 1524 * Performs an assertion check if not in a production environment. 1525 * 1526 * @param {T} o 1527 * @return {o extends T ? T : never} 1528 */ 1529 expect(o) { 1530 assert(o, this); 1531 return o; 1532 } 1533 }; 1534 var $ConstructedBy = class extends Schema { 1535 /** 1536 * @param {C} c 1537 * @param {((o:Instance<C>)=>boolean)|null} check 1538 */ 1539 constructor(c, check) { 1540 super(); 1541 this.shape = c; 1542 this._c = check; 1543 } 1544 /** 1545 * @param {any} o 1546 * @param {ValidationError} [err] 1547 * @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o 1548 */ 1549 check(o, err = void 0) { 1550 const c = o?.constructor === this.shape && (this._c == null || this._c(o)); 1551 !c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? "Constructor match failed" : "Check failed"); 1552 return c; 1553 } 1554 }; 1555 var $constructedBy = (c, check = null) => new $ConstructedBy(c, check); 1556 var $$constructedBy = $constructedBy($ConstructedBy); 1557 var $Custom = class extends Schema { 1558 /** 1559 * @param {(o:any) => boolean} check 1560 */ 1561 constructor(check) { 1562 super(); 1563 this.shape = check; 1564 } 1565 /** 1566 * @param {any} o 1567 * @param {ValidationError} err 1568 * @return {o is any} 1569 */ 1570 check(o, err) { 1571 const c = this.shape(o); 1572 !c && err?.extend(null, "custom prop", o?.constructor.name, "failed to check custom prop"); 1573 return c; 1574 } 1575 }; 1576 var $custom = (check) => new $Custom(check); 1577 var $$custom = $constructedBy($Custom); 1578 var $Literal = class extends Schema { 1579 /** 1580 * @param {Array<T>} literals 1581 */ 1582 constructor(literals) { 1583 super(); 1584 this.shape = literals; 1585 } 1586 /** 1587 * 1588 * @param {any} o 1589 * @param {ValidationError} [err] 1590 * @return {o is T} 1591 */ 1592 check(o, err) { 1593 const c = this.shape.some((a) => a === o); 1594 !c && err?.extend(null, this.shape.join(" | "), o.toString()); 1595 return c; 1596 } 1597 }; 1598 var $literal = (...literals) => new $Literal(literals); 1599 var $$literal = $constructedBy($Literal); 1600 var _regexEscape = ( 1601 /** @type {any} */ 1602 RegExp.escape || /** @type {(str:string) => string} */ 1603 ((str) => str.replace(/[().|&,$^[\]]/g, (s) => "\\" + s)) 1604 ); 1605 var _schemaStringTemplateToRegex = (s) => { 1606 if ($string.check(s)) { 1607 return [_regexEscape(s)]; 1608 } 1609 if ($$literal.check(s)) { 1610 return ( 1611 /** @type {Array<string|number>} */ 1612 s.shape.map((v) => v + "") 1613 ); 1614 } 1615 if ($$number.check(s)) { 1616 return ["[+-]?\\d+.?\\d*"]; 1617 } 1618 if ($$string.check(s)) { 1619 return [".*"]; 1620 } 1621 if ($$union.check(s)) { 1622 return s.shape.map(_schemaStringTemplateToRegex).flat(1); 1623 } 1624 unexpectedCase(); 1625 }; 1626 var $StringTemplate = class extends Schema { 1627 /** 1628 * @param {T} shape 1629 */ 1630 constructor(shape) { 1631 super(); 1632 this.shape = shape; 1633 this._r = new RegExp("^" + shape.map(_schemaStringTemplateToRegex).map((opts) => `($opts.join("|")})`).join("") + "$"); 1634 } 1635 /** 1636 * @param {any} o 1637 * @param {ValidationError} [err] 1638 * @return {o is CastStringTemplateArgsToTemplate<T>} 1639 */ 1640 check(o, err) { 1641 const c = this._r.exec(o) != null; 1642 !c && err?.extend(null, this._r.toString(), o.toString(), "String doesn't match string template."); 1643 return c; 1644 } 1645 }; 1646 var $$stringTemplate = $constructedBy($StringTemplate); 1647 var isOptionalSymbol = /* @__PURE__ */ Symbol("optional"); 1648 var $Optional = class extends Schema { 1649 /** 1650 * @param {S} shape 1651 */ 1652 constructor(shape) { 1653 super(); 1654 this.shape = shape; 1655 } 1656 /** 1657 * @param {any} o 1658 * @param {ValidationError} [err] 1659 * @return {o is (Unwrap<S>|undefined)} 1660 */ 1661 check(o, err) { 1662 const c = o === void 0 || this.shape.check(o); 1663 !c && err?.extend(null, "undefined (optional)", "()"); 1664 return c; 1665 } 1666 get [isOptionalSymbol]() { 1667 return true; 1668 } 1669 }; 1670 var $$optional = $constructedBy($Optional); 1671 var $Never = class extends Schema { 1672 /** 1673 * @param {any} _o 1674 * @param {ValidationError} [err] 1675 * @return {_o is never} 1676 */ 1677 check(_o, err) { 1678 err?.extend(null, "never", typeof _o); 1679 return false; 1680 } 1681 }; 1682 var $never = new $Never(); 1683 var $$never = $constructedBy($Never); 1684 var $Object = class _$Object extends Schema { 1685 /** 1686 * @param {S} shape 1687 * @param {boolean} partial 1688 */ 1689 constructor(shape, partial = false) { 1690 super(); 1691 this.shape = shape; 1692 this._isPartial = partial; 1693 } 1694 static _dilutes = true; 1695 /** 1696 * @type {Schema<Partial<$ObjectToType<S>>>} 1697 */ 1698 get partial() { 1699 return new _$Object(this.shape, true); 1700 } 1701 /** 1702 * @param {any} o 1703 * @param {ValidationError} err 1704 * @return {o is $ObjectToType<S>} 1705 */ 1706 check(o, err) { 1707 if (o == null) { 1708 err?.extend(null, "object", "null"); 1709 return false; 1710 } 1711 return every2(this.shape, (vv, vk) => { 1712 const c = this._isPartial && !hasProperty(o, vk) || vv.check(o[vk], err); 1713 !c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], "Object property does not match"); 1714 return c; 1715 }); 1716 } 1717 }; 1718 var $object = (def) => ( 1719 /** @type {any} */ 1720 new $Object(def) 1721 ); 1722 var $$object = $constructedBy($Object); 1723 var $objectAny = $custom((o) => o != null && (o.constructor === Object || o.constructor == null)); 1724 var $Record = class extends Schema { 1725 /** 1726 * @param {Keys} keys 1727 * @param {Values} values 1728 */ 1729 constructor(keys2, values) { 1730 super(); 1731 this.shape = { 1732 keys: keys2, 1733 values 1734 }; 1735 } 1736 /** 1737 * @param {any} o 1738 * @param {ValidationError} err 1739 * @return {o is { [key in Unwrap<Keys>]: Unwrap<Values> }} 1740 */ 1741 check(o, err) { 1742 return o != null && every2(o, (vv, vk) => { 1743 const ck = this.shape.keys.check(vk, err); 1744 !ck && err?.extend(vk + "", "Record", typeof o, ck ? "Key doesn't match schema" : "Value doesn't match value"); 1745 return ck && this.shape.values.check(vv, err); 1746 }); 1747 } 1748 }; 1749 var $record = (keys2, values) => new $Record(keys2, values); 1750 var $$record = $constructedBy($Record); 1751 var $Tuple = class extends Schema { 1752 /** 1753 * @param {S} shape 1754 */ 1755 constructor(shape) { 1756 super(); 1757 this.shape = shape; 1758 } 1759 /** 1760 * @param {any} o 1761 * @param {ValidationError} err 1762 * @return {o is { [K in keyof S]: S[K] extends Schema<infer Type> ? Type : never }} 1763 */ 1764 check(o, err) { 1765 return o != null && every2(this.shape, (vv, vk) => { 1766 const c = ( 1767 /** @type {Schema<any>} */ 1768 vv.check(o[vk], err) 1769 ); 1770 !c && err?.extend(vk.toString(), "Tuple", typeof vv); 1771 return c; 1772 }); 1773 } 1774 }; 1775 var $tuple = (...def) => new $Tuple(def); 1776 var $$tuple = $constructedBy($Tuple); 1777 var $Array = class extends Schema { 1778 /** 1779 * @param {Array<S>} v 1780 */ 1781 constructor(v) { 1782 super(); 1783 this.shape = v.length === 1 ? v[0] : new $Union(v); 1784 } 1785 /** 1786 * @param {any} o 1787 * @param {ValidationError} [err] 1788 * @return {o is Array<S extends Schema<infer T> ? T : never>} o 1789 */ 1790 check(o, err) { 1791 const c = isArray(o) && every(o, (oi) => this.shape.check(oi)); 1792 !c && err?.extend(null, "Array", ""); 1793 return c; 1794 } 1795 }; 1796 var $array = (...def) => new $Array(def); 1797 var $$array = $constructedBy($Array); 1798 var $arrayAny = $custom((o) => isArray(o)); 1799 var $InstanceOf = class extends Schema { 1800 /** 1801 * @param {new (...args:any) => T} constructor 1802 * @param {((o:T) => boolean)|null} check 1803 */ 1804 constructor(constructor, check) { 1805 super(); 1806 this.shape = constructor; 1807 this._c = check; 1808 } 1809 /** 1810 * @param {any} o 1811 * @param {ValidationError} err 1812 * @return {o is T} 1813 */ 1814 check(o, err) { 1815 const c = o instanceof this.shape && (this._c == null || this._c(o)); 1816 !c && err?.extend(null, this.shape.name, o?.constructor.name); 1817 return c; 1818 } 1819 }; 1820 var $instanceOf = (c, check = null) => new $InstanceOf(c, check); 1821 var $$instanceOf = $constructedBy($InstanceOf); 1822 var $$schema = $instanceOf(Schema); 1823 var $Lambda = class extends Schema { 1824 /** 1825 * @param {Args} args 1826 */ 1827 constructor(args2) { 1828 super(); 1829 this.len = args2.length - 1; 1830 this.args = $tuple(...args2.slice(-1)); 1831 this.res = args2[this.len]; 1832 } 1833 /** 1834 * @param {any} f 1835 * @param {ValidationError} err 1836 * @return {f is _LArgsToLambdaDef<Args>} 1837 */ 1838 check(f, err) { 1839 const c = f.constructor === Function && f.length <= this.len; 1840 !c && err?.extend(null, "function", typeof f); 1841 return c; 1842 } 1843 }; 1844 var $$lambda = $constructedBy($Lambda); 1845 var $function = $custom((o) => typeof o === "function"); 1846 var $Intersection = class extends Schema { 1847 /** 1848 * @param {T} v 1849 */ 1850 constructor(v) { 1851 super(); 1852 this.shape = v; 1853 } 1854 /** 1855 * @param {any} o 1856 * @param {ValidationError} [err] 1857 * @return {o is Intersect<UnwrapArray<T>>} 1858 */ 1859 check(o, err) { 1860 const c = every(this.shape, (check) => check.check(o, err)); 1861 !c && err?.extend(null, "Intersectinon", typeof o); 1862 return c; 1863 } 1864 }; 1865 var $$intersect = $constructedBy($Intersection, (o) => o.shape.length > 0); 1866 var $Union = class extends Schema { 1867 static _dilutes = true; 1868 /** 1869 * @param {Array<Schema<S>>} v 1870 */ 1871 constructor(v) { 1872 super(); 1873 this.shape = v; 1874 } 1875 /** 1876 * @param {any} o 1877 * @param {ValidationError} [err] 1878 * @return {o is S} 1879 */ 1880 check(o, err) { 1881 const c = some(this.shape, (vv) => vv.check(o, err)); 1882 err?.extend(null, "Union", typeof o); 1883 return c; 1884 } 1885 }; 1886 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); 1887 var $$union = ( 1888 /** @type {Schema<$Union<any>>} */ 1889 $constructedBy($Union) 1890 ); 1891 var _t = () => true; 1892 var $any = $custom(_t); 1893 var $$any = ( 1894 /** @type {Schema<Schema<any>>} */ 1895 $constructedBy($Custom, (o) => o.shape === _t) 1896 ); 1897 var $bigint = $custom((o) => typeof o === "bigint"); 1898 var $$bigint = ( 1899 /** @type {Schema<Schema<BigInt>>} */ 1900 $custom((o) => o === $bigint) 1901 ); 1902 var $symbol = $custom((o) => typeof o === "symbol"); 1903 var $$symbol = ( 1904 /** @type {Schema<Schema<Symbol>>} */ 1905 $custom((o) => o === $symbol) 1906 ); 1907 var $number = $custom((o) => typeof o === "number"); 1908 var $$number = ( 1909 /** @type {Schema<Schema<number>>} */ 1910 $custom((o) => o === $number) 1911 ); 1912 var $string = $custom((o) => typeof o === "string"); 1913 var $$string = ( 1914 /** @type {Schema<Schema<string>>} */ 1915 $custom((o) => o === $string) 1916 ); 1917 var $boolean = $custom((o) => typeof o === "boolean"); 1918 var $$boolean = ( 1919 /** @type {Schema<Schema<Boolean>>} */ 1920 $custom((o) => o === $boolean) 1921 ); 1922 var $undefined = $literal(void 0); 1923 var $$undefined = ( 1924 /** @type {Schema<Schema<undefined>>} */ 1925 $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === void 0) 1926 ); 1927 var $void = $literal(void 0); 1928 var $null = $literal(null); 1929 var $$null = ( 1930 /** @type {Schema<Schema<null>>} */ 1931 $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === null) 1932 ); 1933 var $uint8Array = $constructedBy(Uint8Array); 1934 var $$uint8Array = ( 1935 /** @type {Schema<Schema<Uint8Array>>} */ 1936 $constructedBy($ConstructedBy, (o) => o.shape === Uint8Array) 1937 ); 1938 var $primitive = $union($number, $string, $null, $undefined, $bigint, $boolean, $symbol); 1939 var $json = (() => { 1940 const $jsonArr = ( 1941 /** @type {$Array<$any>} */ 1942 $array($any) 1943 ); 1944 const $jsonRecord = ( 1945 /** @type {$Record<$string,$any>} */ 1946 $record($string, $any) 1947 ); 1948 const $json2 = $union($number, $string, $null, $boolean, $jsonArr, $jsonRecord); 1949 $jsonArr.shape = $json2; 1950 $jsonRecord.shape.values = $json2; 1951 return $json2; 1952 })(); 1953 var $ = (o) => { 1954 if ($$schema.check(o)) { 1955 return ( 1956 /** @type {any} */ 1957 o 1958 ); 1959 } else if ($objectAny.check(o)) { 1960 const o2 = {}; 1961 for (const k in o) { 1962 o2[k] = $(o[k]); 1963 } 1964 return ( 1965 /** @type {any} */ 1966 $object(o2) 1967 ); 1968 } else if ($arrayAny.check(o)) { 1969 return ( 1970 /** @type {any} */ 1971 $union(...o.map($)) 1972 ); 1973 } else if ($primitive.check(o)) { 1974 return ( 1975 /** @type {any} */ 1976 $literal(o) 1977 ); 1978 } else if ($function.check(o)) { 1979 return ( 1980 /** @type {any} */ 1981 $constructedBy( 1982 /** @type {any} */ 1983 o 1984 ) 1985 ); 1986 } 1987 unexpectedCase(); 1988 }; 1989 var assert = production ? () => { 1990 } : (o, schema) => { 1991 const err = new ValidationError(); 1992 if (!schema.check(o, err)) { 1993 throw create3(`Expected value to be of type $schema.constructor.name}. 1994 $err.toString()}`); 1995 } 1996 }; 1997 var PatternMatcher = class { 1998 /** 1999 * @param {Schema<State>} [$state] 2000 */ 2001 constructor($state) { 2002 this.patterns = []; 2003 this.$state = $state; 2004 } 2005 /** 2006 * @template P 2007 * @template R 2008 * @param {P} pattern 2009 * @param {(o:NoInfer<Unwrap<ReadSchema<P>>>,s:State)=>R} handler 2010 * @return {PatternMatcher<State,Patterns|Pattern<Unwrap<ReadSchema<P>>,R>>} 2011 */ 2012 if(pattern, handler) { 2013 this.patterns.push({ if: $(pattern), h: handler }); 2014 return this; 2015 } 2016 /** 2017 * @template R 2018 * @param {(o:any,s:State)=>R} h 2019 */ 2020 else(h) { 2021 return this.if($any, h); 2022 } 2023 /** 2024 * @return {State extends undefined 2025 * ? <In extends Unwrap<Patterns['if']>>(o:In,state?:undefined)=>PatternMatchResult<Patterns,In> 2026 * : <In extends Unwrap<Patterns['if']>>(o:In,state:State)=>PatternMatchResult<Patterns,In>} 2027 */ 2028 done() { 2029 return ( 2030 /** @type {any} */ 2031 (o, s) => { 2032 for (let i = 0; i < this.patterns.length; i++) { 2033 const p = this.patterns[i]; 2034 if (p.if.check(o)) { 2035 return p.h(o, s); 2036 } 2037 } 2038 throw create3("Unhandled pattern"); 2039 } 2040 ); 2041 } 2042 }; 2043 var match = (state) => new PatternMatcher( 2044 /** @type {any} */ 2045 state 2046 ); 2047 var _random = ( 2048 /** @type {any} */ 2049 match( 2050 /** @type {Schema<prng.PRNG>} */ 2051 $any 2052 ).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) => { 2053 const res = {}; 2054 for (const k in o.shape) { 2055 let prop = o.shape[k]; 2056 if ($$optional.check(prop)) { 2057 if (bool(gen)) { 2058 continue; 2059 } 2060 prop = prop.shape; 2061 } 2062 res[k] = _random(prop, gen); 2063 } 2064 return res; 2065 }).if($$array, (o, gen) => { 2066 const arr = []; 2067 const n = int32(gen, 0, 42); 2068 for (let i = 0; i < n; i++) { 2069 arr.push(random(gen, o.shape)); 2070 } 2071 return arr; 2072 }).if($$literal, (o, gen) => { 2073 return oneOf(gen, o.shape); 2074 }).if($$null, (o, gen) => { 2075 return null; 2076 }).if($$lambda, (o, gen) => { 2077 const res = random(gen, o.res); 2078 return () => res; 2079 }).if($$any, (o, gen) => random(gen, oneOf(gen, [ 2080 $number, 2081 $string, 2082 $null, 2083 $undefined, 2084 $bigint, 2085 $boolean, 2086 $array($number), 2087 $record($union("a", "b", "c"), $number) 2088 ]))).if($$record, (o, gen) => { 2089 const res = {}; 2090 const keysN = int53(gen, 0, 3); 2091 for (let i = 0; i < keysN; i++) { 2092 const key = random(gen, o.shape.keys); 2093 const val = random(gen, o.shape.values); 2094 res[key] = val; 2095 } 2096 return res; 2097 }).done() 2098 ); 2099 var random = (gen, schema) => ( 2100 /** @type {any} */ 2101 _random($(schema), gen) 2102 ); 2103 2104 // node_modules/lib0/dom.js 2105 var doc = ( 2106 /** @type {Document} */ 2107 typeof document !== "undefined" ? document : {} 2108 ); 2109 var $fragment = $custom((el) => el.nodeType === DOCUMENT_FRAGMENT_NODE); 2110 var domParser = ( 2111 /** @type {DOMParser} */ 2112 typeof DOMParser !== "undefined" ? new DOMParser() : null 2113 ); 2114 var $element = $custom((el) => el.nodeType === ELEMENT_NODE); 2115 var $text = $custom((el) => el.nodeType === TEXT_NODE); 2116 var mapToStyleString = (m) => map(m, (value, key) => `$key}:$value};`).join(""); 2117 var ELEMENT_NODE = doc.ELEMENT_NODE; 2118 var TEXT_NODE = doc.TEXT_NODE; 2119 var CDATA_SECTION_NODE = doc.CDATA_SECTION_NODE; 2120 var COMMENT_NODE = doc.COMMENT_NODE; 2121 var DOCUMENT_NODE = doc.DOCUMENT_NODE; 2122 var DOCUMENT_TYPE_NODE = doc.DOCUMENT_TYPE_NODE; 2123 var DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE; 2124 var $node = $custom((el) => el.nodeType === DOCUMENT_NODE); 2125 2126 // node_modules/lib0/symbol.js 2127 var create6 = Symbol; 2128 2129 // node_modules/lib0/logging.common.js 2130 var BOLD = create6(); 2131 var UNBOLD = create6(); 2132 var BLUE = create6(); 2133 var GREY = create6(); 2134 var GREEN = create6(); 2135 var RED = create6(); 2136 var PURPLE = create6(); 2137 var ORANGE = create6(); 2138 var UNCOLOR = create6(); 2139 var computeNoColorLoggingArgs = (args2) => { 2140 if (args2.length === 1 && args2[0]?.constructor === Function) { 2141 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2142 /** @type {[function]} */ 2143 args2[0](); 2144 } 2145 const strBuilder = []; 2146 const logArgs = []; 2147 let i = 0; 2148 for (; i < args2.length; i++) { 2149 const arg = args2[i]; 2150 if (arg === void 0) { 2151 break; 2152 } else if (arg.constructor === String || arg.constructor === Number) { 2153 strBuilder.push(arg); 2154 } else if (arg.constructor === Object) { 2155 break; 2156 } 2157 } 2158 if (i > 0) { 2159 logArgs.push(strBuilder.join("")); 2160 } 2161 for (; i < args2.length; i++) { 2162 const arg = args2[i]; 2163 if (!(arg instanceof Symbol)) { 2164 logArgs.push(arg); 2165 } 2166 } 2167 return logArgs; 2168 }; 2169 var lastLoggingTime = getUnixTime(); 2170 2171 // node_modules/lib0/logging.js 2172 var _browserStyleMap = { 2173 [BOLD]: create5("font-weight", "bold"), 2174 [UNBOLD]: create5("font-weight", "normal"), 2175 [BLUE]: create5("color", "blue"), 2176 [GREEN]: create5("color", "green"), 2177 [GREY]: create5("color", "grey"), 2178 [RED]: create5("color", "red"), 2179 [PURPLE]: create5("color", "purple"), 2180 [ORANGE]: create5("color", "orange"), 2181 // not well supported in chrome when debugging node with inspector - TODO: deprecate 2182 [UNCOLOR]: create5("color", "black") 2183 }; 2184 var computeBrowserLoggingArgs = (args2) => { 2185 if (args2.length === 1 && args2[0]?.constructor === Function) { 2186 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2187 /** @type {[function]} */ 2188 args2[0](); 2189 } 2190 const strBuilder = []; 2191 const styles = []; 2192 const currentStyle = create(); 2193 let logArgs = []; 2194 let i = 0; 2195 for (; i < args2.length; i++) { 2196 const arg = args2[i]; 2197 const style = _browserStyleMap[arg]; 2198 if (style !== void 0) { 2199 currentStyle.set(style.left, style.right); 2200 } else { 2201 if (arg === void 0) { 2202 break; 2203 } 2204 if (arg.constructor === String || arg.constructor === Number) { 2205 const style2 = mapToStyleString(currentStyle); 2206 if (i > 0 || style2.length > 0) { 2207 strBuilder.push("%c" + arg); 2208 styles.push(style2); 2209 } else { 2210 strBuilder.push(arg); 2211 } 2212 } else { 2213 break; 2214 } 2215 } 2216 } 2217 if (i > 0) { 2218 logArgs = styles; 2219 logArgs.unshift(strBuilder.join("")); 2220 } 2221 for (; i < args2.length; i++) { 2222 const arg = args2[i]; 2223 if (!(arg instanceof Symbol)) { 2224 logArgs.push(arg); 2225 } 2226 } 2227 return logArgs; 2228 }; 2229 var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; 2230 var print = (...args2) => { 2231 console.log(...computeLoggingArgs(args2)); 2232 vconsoles.forEach((vc) => vc.print(args2)); 2233 }; 2234 var warn = (...args2) => { 2235 console.warn(...computeLoggingArgs(args2)); 2236 args2.unshift(ORANGE); 2237 vconsoles.forEach((vc) => vc.print(args2)); 2238 }; 2239 var vconsoles = create2(); 2240 2241 // node_modules/lib0/iterator.js 2242 var createIterator = (next) => ({ 2243 /** 2244 * @return {IterableIterator<T>} 2245 */ 2246 [Symbol.iterator]() { 2247 return this; 2248 }, 2249 // @ts-ignore 2250 next 2251 }); 2252 var iteratorFilter = (iterator, filter) => createIterator(() => { 2253 let res; 2254 do { 2255 res = iterator.next(); 2256 } while (!res.done && !filter(res.value)); 2257 return res; 2258 }); 2259 var iteratorMap = (iterator, fmap) => createIterator(() => { 2260 const { done, value } = iterator.next(); 2261 return { done, value: done ? void 0 : fmap(value) }; 2262 }); 2263 2264 // node_modules/yjs/dist/yjs.mjs 2265 var AbstractConnector = class extends ObservableV2 { 2266 /** 2267 * @param {Doc} ydoc 2268 * @param {any} awareness 2269 */ 2270 constructor(ydoc, awareness) { 2271 super(); 2272 this.doc = ydoc; 2273 this.awareness = awareness; 2274 } 2275 }; 2276 var DeleteItem = class { 2277 /** 2278 * @param {number} clock 2279 * @param {number} len 2280 */ 2281 constructor(clock, len) { 2282 this.clock = clock; 2283 this.len = len; 2284 } 2285 }; 2286 var DeleteSet = class { 2287 constructor() { 2288 this.clients = /* @__PURE__ */ new Map(); 2289 } 2290 }; 2291 var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { 2292 const structs = ( 2293 /** @type {Array<GC|Item>} */ 2294 transaction.doc.store.clients.get(clientid) 2295 ); 2296 if (structs != null) { 2297 const lastStruct = structs[structs.length - 1]; 2298 const clockState = lastStruct.id.clock + lastStruct.length; 2299 for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) { 2300 iterateStructs(transaction, structs, del.clock, del.len, f); 2301 } 2302 } 2303 }); 2304 var findIndexDS = (dis, clock) => { 2305 let left = 0; 2306 let right = dis.length - 1; 2307 while (left <= right) { 2308 const midindex = floor((left + right) / 2); 2309 const mid = dis[midindex]; 2310 const midclock = mid.clock; 2311 if (midclock <= clock) { 2312 if (clock < midclock + mid.len) { 2313 return midindex; 2314 } 2315 left = midindex + 1; 2316 } else { 2317 right = midindex - 1; 2318 } 2319 } 2320 return null; 2321 }; 2322 var isDeleted = (ds, id2) => { 2323 const dis = ds.clients.get(id2.client); 2324 return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; 2325 }; 2326 var sortAndMergeDeleteSet = (ds) => { 2327 ds.clients.forEach((dels) => { 2328 dels.sort((a, b) => a.clock - b.clock); 2329 let i, j; 2330 for (i = 1, j = 1; i < dels.length; i++) { 2331 const left = dels[j - 1]; 2332 const right = dels[i]; 2333 if (left.clock + left.len >= right.clock) { 2334 left.len = max(left.len, right.clock + right.len - left.clock); 2335 } else { 2336 if (j < i) { 2337 dels[j] = right; 2338 } 2339 j++; 2340 } 2341 } 2342 dels.length = j; 2343 }); 2344 }; 2345 var mergeDeleteSets = (dss) => { 2346 const merged = new DeleteSet(); 2347 for (let dssI = 0; dssI < dss.length; dssI++) { 2348 dss[dssI].clients.forEach((delsLeft, client) => { 2349 if (!merged.clients.has(client)) { 2350 const dels = delsLeft.slice(); 2351 for (let i = dssI + 1; i < dss.length; i++) { 2352 appendTo(dels, dss[i].clients.get(client) || []); 2353 } 2354 merged.clients.set(client, dels); 2355 } 2356 }); 2357 } 2358 sortAndMergeDeleteSet(merged); 2359 return merged; 2360 }; 2361 var addToDeleteSet = (ds, client, clock, length2) => { 2362 setIfUndefined(ds.clients, client, () => ( 2363 /** @type {Array<DeleteItem>} */ 2364 [] 2365 )).push(new DeleteItem(clock, length2)); 2366 }; 2367 var createDeleteSet = () => new DeleteSet(); 2368 var createDeleteSetFromStructStore = (ss) => { 2369 const ds = createDeleteSet(); 2370 ss.clients.forEach((structs, client) => { 2371 const dsitems = []; 2372 for (let i = 0; i < structs.length; i++) { 2373 const struct = structs[i]; 2374 if (struct.deleted) { 2375 const clock = struct.id.clock; 2376 let len = struct.length; 2377 if (i + 1 < structs.length) { 2378 for (let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1]) { 2379 len += next.length; 2380 } 2381 } 2382 dsitems.push(new DeleteItem(clock, len)); 2383 } 2384 } 2385 if (dsitems.length > 0) { 2386 ds.clients.set(client, dsitems); 2387 } 2388 }); 2389 return ds; 2390 }; 2391 var writeDeleteSet = (encoder, ds) => { 2392 writeVarUint(encoder.restEncoder, ds.clients.size); 2393 from(ds.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, dsitems]) => { 2394 encoder.resetDsCurVal(); 2395 writeVarUint(encoder.restEncoder, client); 2396 const len = dsitems.length; 2397 writeVarUint(encoder.restEncoder, len); 2398 for (let i = 0; i < len; i++) { 2399 const item = dsitems[i]; 2400 encoder.writeDsClock(item.clock); 2401 encoder.writeDsLen(item.len); 2402 } 2403 }); 2404 }; 2405 var readDeleteSet = (decoder) => { 2406 const ds = new DeleteSet(); 2407 const numClients = readVarUint(decoder.restDecoder); 2408 for (let i = 0; i < numClients; i++) { 2409 decoder.resetDsCurVal(); 2410 const client = readVarUint(decoder.restDecoder); 2411 const numberOfDeletes = readVarUint(decoder.restDecoder); 2412 if (numberOfDeletes > 0) { 2413 const dsField = setIfUndefined(ds.clients, client, () => ( 2414 /** @type {Array<DeleteItem>} */ 2415 [] 2416 )); 2417 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2418 dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); 2419 } 2420 } 2421 } 2422 return ds; 2423 }; 2424 var readAndApplyDeleteSet = (decoder, transaction, store) => { 2425 const unappliedDS = new DeleteSet(); 2426 const numClients = readVarUint(decoder.restDecoder); 2427 for (let i = 0; i < numClients; i++) { 2428 decoder.resetDsCurVal(); 2429 const client = readVarUint(decoder.restDecoder); 2430 const numberOfDeletes = readVarUint(decoder.restDecoder); 2431 const structs = store.clients.get(client) || []; 2432 const state = getState(store, client); 2433 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2434 const clock = decoder.readDsClock(); 2435 const clockEnd = clock + decoder.readDsLen(); 2436 if (clock < state) { 2437 if (state < clockEnd) { 2438 addToDeleteSet(unappliedDS, client, state, clockEnd - state); 2439 } 2440 let index = findIndexSS(structs, clock); 2441 let struct = structs[index]; 2442 if (!struct.deleted && struct.id.clock < clock) { 2443 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 2444 index++; 2445 } 2446 while (index < structs.length) { 2447 struct = structs[index++]; 2448 if (struct.id.clock < clockEnd) { 2449 if (!struct.deleted) { 2450 if (clockEnd < struct.id.clock + struct.length) { 2451 structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); 2452 } 2453 struct.delete(transaction); 2454 } 2455 } else { 2456 break; 2457 } 2458 } 2459 } else { 2460 addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); 2461 } 2462 } 2463 } 2464 if (unappliedDS.clients.size > 0) { 2465 const ds = new UpdateEncoderV2(); 2466 writeVarUint(ds.restEncoder, 0); 2467 writeDeleteSet(ds, unappliedDS); 2468 return ds.toUint8Array(); 2469 } 2470 return null; 2471 }; 2472 var equalDeleteSets = (ds1, ds2) => { 2473 if (ds1.clients.size !== ds2.clients.size) return false; 2474 for (const [client, deleteItems1] of ds1.clients.entries()) { 2475 const deleteItems2 = ( 2476 /** @type {Array<import('../internals.js').DeleteItem>} */ 2477 ds2.clients.get(client) 2478 ); 2479 if (deleteItems2 === void 0 || deleteItems1.length !== deleteItems2.length) return false; 2480 for (let i = 0; i < deleteItems1.length; i++) { 2481 const di1 = deleteItems1[i]; 2482 const di2 = deleteItems2[i]; 2483 if (di1.clock !== di2.clock || di1.len !== di2.len) { 2484 return false; 2485 } 2486 } 2487 } 2488 return true; 2489 }; 2490 var generateNewClientId = uint32; 2491 var Doc = class _Doc extends ObservableV2 { 2492 /** 2493 * @param {DocOpts} opts configuration 2494 */ 2495 constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { 2496 super(); 2497 this.gc = gc; 2498 this.gcFilter = gcFilter; 2499 this.clientID = generateNewClientId(); 2500 this.guid = guid; 2501 this.collectionid = collectionid; 2502 this.share = /* @__PURE__ */ new Map(); 2503 this.store = new StructStore(); 2504 this._transaction = null; 2505 this._transactionCleanups = []; 2506 this.subdocs = /* @__PURE__ */ new Set(); 2507 this._item = null; 2508 this.shouldLoad = shouldLoad; 2509 this.autoLoad = autoLoad; 2510 this.meta = meta; 2511 this.isLoaded = false; 2512 this.isSynced = false; 2513 this.isDestroyed = false; 2514 this.whenLoaded = create4((resolve) => { 2515 this.on("load", () => { 2516 this.isLoaded = true; 2517 resolve(this); 2518 }); 2519 }); 2520 const provideSyncedPromise = () => create4((resolve) => { 2521 const eventHandler = (isSynced) => { 2522 if (isSynced === void 0 || isSynced === true) { 2523 this.off("sync", eventHandler); 2524 resolve(); 2525 } 2526 }; 2527 this.on("sync", eventHandler); 2528 }); 2529 this.on("sync", (isSynced) => { 2530 if (isSynced === false && this.isSynced) { 2531 this.whenSynced = provideSyncedPromise(); 2532 } 2533 this.isSynced = isSynced === void 0 || isSynced === true; 2534 if (this.isSynced && !this.isLoaded) { 2535 this.emit("load", [this]); 2536 } 2537 }); 2538 this.whenSynced = provideSyncedPromise(); 2539 } 2540 /** 2541 * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). 2542 * 2543 * `load()` might be used in the future to request any provider to load the most current data. 2544 * 2545 * It is safe to call `load()` multiple times. 2546 */ 2547 load() { 2548 const item = this._item; 2549 if (item !== null && !this.shouldLoad) { 2550 transact( 2551 /** @type {any} */ 2552 item.parent.doc, 2553 (transaction) => { 2554 transaction.subdocsLoaded.add(this); 2555 }, 2556 null, 2557 true 2558 ); 2559 } 2560 this.shouldLoad = true; 2561 } 2562 getSubdocs() { 2563 return this.subdocs; 2564 } 2565 getSubdocGuids() { 2566 return new Set(from(this.subdocs).map((doc2) => doc2.guid)); 2567 } 2568 /** 2569 * Changes that happen inside of a transaction are bundled. This means that 2570 * the observer fires _after_ the transaction is finished and that all changes 2571 * that happened inside of the transaction are sent as one message to the 2572 * other peers. 2573 * 2574 * @template T 2575 * @param {function(Transaction):T} f The function that should be executed as a transaction 2576 * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin 2577 * @return T 2578 * 2579 * @public 2580 */ 2581 transact(f, origin2 = null) { 2582 return transact(this, f, origin2); 2583 } 2584 /** 2585 * Define a shared data type. 2586 * 2587 * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result 2588 * and do not overwrite each other. I.e. 2589 * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` 2590 * 2591 * After this method is called, the type is also available on `ydoc.share.get(name)`. 2592 * 2593 * *Best Practices:* 2594 * Define all types right after the Y.Doc instance is created and store them in a separate object. 2595 * Also use the typed methods `getText(name)`, `getArray(name)`, .. 2596 * 2597 * @template {typeof AbstractType<any>} Type 2598 * @example 2599 * const ydoc = new Y.Doc(..) 2600 * const appState = { 2601 * document: ydoc.getText('document') 2602 * comments: ydoc.getArray('comments') 2603 * } 2604 * 2605 * @param {string} name 2606 * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... 2607 * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor 2608 * 2609 * @public 2610 */ 2611 get(name, TypeConstructor = ( 2612 /** @type {any} */ 2613 AbstractType 2614 )) { 2615 const type = setIfUndefined(this.share, name, () => { 2616 const t = new TypeConstructor(); 2617 t._integrate(this, null); 2618 return t; 2619 }); 2620 const Constr = type.constructor; 2621 if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { 2622 if (Constr === AbstractType) { 2623 const t = new TypeConstructor(); 2624 t._map = type._map; 2625 type._map.forEach( 2626 /** @param {Item?} n */ 2627 (n) => { 2628 for (; n !== null; n = n.left) { 2629 n.parent = t; 2630 } 2631 } 2632 ); 2633 t._start = type._start; 2634 for (let n = t._start; n !== null; n = n.right) { 2635 n.parent = t; 2636 } 2637 t._length = type._length; 2638 this.share.set(name, t); 2639 t._integrate(this, null); 2640 return ( 2641 /** @type {InstanceType<Type>} */ 2642 t 2643 ); 2644 } else { 2645 throw new Error(`Type with the name $name} has already been defined with a different constructor`); 2646 } 2647 } 2648 return ( 2649 /** @type {InstanceType<Type>} */ 2650 type 2651 ); 2652 } 2653 /** 2654 * @template T 2655 * @param {string} [name] 2656 * @return {YArray<T>} 2657 * 2658 * @public 2659 */ 2660 getArray(name = "") { 2661 return ( 2662 /** @type {YArray<T>} */ 2663 this.get(name, YArray) 2664 ); 2665 } 2666 /** 2667 * @param {string} [name] 2668 * @return {YText} 2669 * 2670 * @public 2671 */ 2672 getText(name = "") { 2673 return this.get(name, YText); 2674 } 2675 /** 2676 * @template T 2677 * @param {string} [name] 2678 * @return {YMap<T>} 2679 * 2680 * @public 2681 */ 2682 getMap(name = "") { 2683 return ( 2684 /** @type {YMap<T>} */ 2685 this.get(name, YMap) 2686 ); 2687 } 2688 /** 2689 * @param {string} [name] 2690 * @return {YXmlElement} 2691 * 2692 * @public 2693 */ 2694 getXmlElement(name = "") { 2695 return ( 2696 /** @type {YXmlElement<{[key:string]:string}>} */ 2697 this.get(name, YXmlElement) 2698 ); 2699 } 2700 /** 2701 * @param {string} [name] 2702 * @return {YXmlFragment} 2703 * 2704 * @public 2705 */ 2706 getXmlFragment(name = "") { 2707 return this.get(name, YXmlFragment); 2708 } 2709 /** 2710 * Converts the entire document into a js object, recursively traversing each yjs type 2711 * Doesn't log types that have not been defined (using ydoc.getType(..)). 2712 * 2713 * @deprecated Do not use this method and rather call toJSON directly on the shared types. 2714 * 2715 * @return {Object<string, any>} 2716 */ 2717 toJSON() { 2718 const doc2 = {}; 2719 this.share.forEach((value, key) => { 2720 doc2[key] = value.toJSON(); 2721 }); 2722 return doc2; 2723 } 2724 /** 2725 * Emit `destroy` event and unregister all event handlers. 2726 */ 2727 destroy() { 2728 this.isDestroyed = true; 2729 from(this.subdocs).forEach((subdoc) => subdoc.destroy()); 2730 const item = this._item; 2731 if (item !== null) { 2732 this._item = null; 2733 const content = ( 2734 /** @type {ContentDoc} */ 2735 item.content 2736 ); 2737 content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); 2738 content.doc._item = item; 2739 transact( 2740 /** @type {any} */ 2741 item.parent.doc, 2742 (transaction) => { 2743 const doc2 = content.doc; 2744 if (!item.deleted) { 2745 transaction.subdocsAdded.add(doc2); 2746 } 2747 transaction.subdocsRemoved.add(this); 2748 }, 2749 null, 2750 true 2751 ); 2752 } 2753 this.emit("destroyed", [true]); 2754 this.emit("destroy", [this]); 2755 super.destroy(); 2756 } 2757 }; 2758 var DSDecoderV1 = class { 2759 /** 2760 * @param {decoding.Decoder} decoder 2761 */ 2762 constructor(decoder) { 2763 this.restDecoder = decoder; 2764 } 2765 resetDsCurVal() { 2766 } 2767 /** 2768 * @return {number} 2769 */ 2770 readDsClock() { 2771 return readVarUint(this.restDecoder); 2772 } 2773 /** 2774 * @return {number} 2775 */ 2776 readDsLen() { 2777 return readVarUint(this.restDecoder); 2778 } 2779 }; 2780 var UpdateDecoderV1 = class extends DSDecoderV1 { 2781 /** 2782 * @return {ID} 2783 */ 2784 readLeftID() { 2785 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2786 } 2787 /** 2788 * @return {ID} 2789 */ 2790 readRightID() { 2791 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2792 } 2793 /** 2794 * Read the next client id. 2795 * Use this in favor of readID whenever possible to reduce the number of objects created. 2796 */ 2797 readClient() { 2798 return readVarUint(this.restDecoder); 2799 } 2800 /** 2801 * @return {number} info An unsigned 8-bit integer 2802 */ 2803 readInfo() { 2804 return readUint8(this.restDecoder); 2805 } 2806 /** 2807 * @return {string} 2808 */ 2809 readString() { 2810 return readVarString(this.restDecoder); 2811 } 2812 /** 2813 * @return {boolean} isKey 2814 */ 2815 readParentInfo() { 2816 return readVarUint(this.restDecoder) === 1; 2817 } 2818 /** 2819 * @return {number} info An unsigned 8-bit integer 2820 */ 2821 readTypeRef() { 2822 return readVarUint(this.restDecoder); 2823 } 2824 /** 2825 * Write len of a struct - well suited for Opt RLE encoder. 2826 * 2827 * @return {number} len 2828 */ 2829 readLen() { 2830 return readVarUint(this.restDecoder); 2831 } 2832 /** 2833 * @return {any} 2834 */ 2835 readAny() { 2836 return readAny(this.restDecoder); 2837 } 2838 /** 2839 * @return {Uint8Array} 2840 */ 2841 readBuf() { 2842 return copyUint8Array(readVarUint8Array(this.restDecoder)); 2843 } 2844 /** 2845 * Legacy implementation uses JSON parse. We use any-decoding in v2. 2846 * 2847 * @return {any} 2848 */ 2849 readJSON() { 2850 return JSON.parse(readVarString(this.restDecoder)); 2851 } 2852 /** 2853 * @return {string} 2854 */ 2855 readKey() { 2856 return readVarString(this.restDecoder); 2857 } 2858 }; 2859 var DSDecoderV2 = class { 2860 /** 2861 * @param {decoding.Decoder} decoder 2862 */ 2863 constructor(decoder) { 2864 this.dsCurrVal = 0; 2865 this.restDecoder = decoder; 2866 } 2867 resetDsCurVal() { 2868 this.dsCurrVal = 0; 2869 } 2870 /** 2871 * @return {number} 2872 */ 2873 readDsClock() { 2874 this.dsCurrVal += readVarUint(this.restDecoder); 2875 return this.dsCurrVal; 2876 } 2877 /** 2878 * @return {number} 2879 */ 2880 readDsLen() { 2881 const diff = readVarUint(this.restDecoder) + 1; 2882 this.dsCurrVal += diff; 2883 return diff; 2884 } 2885 }; 2886 var UpdateDecoderV2 = class extends DSDecoderV2 { 2887 /** 2888 * @param {decoding.Decoder} decoder 2889 */ 2890 constructor(decoder) { 2891 super(decoder); 2892 this.keys = []; 2893 readVarUint(decoder); 2894 this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2895 this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2896 this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2897 this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2898 this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2899 this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); 2900 this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2901 this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2902 this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2903 } 2904 /** 2905 * @return {ID} 2906 */ 2907 readLeftID() { 2908 return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); 2909 } 2910 /** 2911 * @return {ID} 2912 */ 2913 readRightID() { 2914 return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); 2915 } 2916 /** 2917 * Read the next client id. 2918 * Use this in favor of readID whenever possible to reduce the number of objects created. 2919 */ 2920 readClient() { 2921 return this.clientDecoder.read(); 2922 } 2923 /** 2924 * @return {number} info An unsigned 8-bit integer 2925 */ 2926 readInfo() { 2927 return ( 2928 /** @type {number} */ 2929 this.infoDecoder.read() 2930 ); 2931 } 2932 /** 2933 * @return {string} 2934 */ 2935 readString() { 2936 return this.stringDecoder.read(); 2937 } 2938 /** 2939 * @return {boolean} 2940 */ 2941 readParentInfo() { 2942 return this.parentInfoDecoder.read() === 1; 2943 } 2944 /** 2945 * @return {number} An unsigned 8-bit integer 2946 */ 2947 readTypeRef() { 2948 return this.typeRefDecoder.read(); 2949 } 2950 /** 2951 * Write len of a struct - well suited for Opt RLE encoder. 2952 * 2953 * @return {number} 2954 */ 2955 readLen() { 2956 return this.lenDecoder.read(); 2957 } 2958 /** 2959 * @return {any} 2960 */ 2961 readAny() { 2962 return readAny(this.restDecoder); 2963 } 2964 /** 2965 * @return {Uint8Array} 2966 */ 2967 readBuf() { 2968 return readVarUint8Array(this.restDecoder); 2969 } 2970 /** 2971 * This is mainly here for legacy purposes. 2972 * 2973 * 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. 2974 * 2975 * @return {any} 2976 */ 2977 readJSON() { 2978 return readAny(this.restDecoder); 2979 } 2980 /** 2981 * @return {string} 2982 */ 2983 readKey() { 2984 const keyClock = this.keyClockDecoder.read(); 2985 if (keyClock < this.keys.length) { 2986 return this.keys[keyClock]; 2987 } else { 2988 const key = this.stringDecoder.read(); 2989 this.keys.push(key); 2990 return key; 2991 } 2992 } 2993 }; 2994 var DSEncoderV1 = class { 2995 constructor() { 2996 this.restEncoder = createEncoder(); 2997 } 2998 toUint8Array() { 2999 return toUint8Array(this.restEncoder); 3000 } 3001 resetDsCurVal() { 3002 } 3003 /** 3004 * @param {number} clock 3005 */ 3006 writeDsClock(clock) { 3007 writeVarUint(this.restEncoder, clock); 3008 } 3009 /** 3010 * @param {number} len 3011 */ 3012 writeDsLen(len) { 3013 writeVarUint(this.restEncoder, len); 3014 } 3015 }; 3016 var UpdateEncoderV1 = class extends DSEncoderV1 { 3017 /** 3018 * @param {ID} id 3019 */ 3020 writeLeftID(id2) { 3021 writeVarUint(this.restEncoder, id2.client); 3022 writeVarUint(this.restEncoder, id2.clock); 3023 } 3024 /** 3025 * @param {ID} id 3026 */ 3027 writeRightID(id2) { 3028 writeVarUint(this.restEncoder, id2.client); 3029 writeVarUint(this.restEncoder, id2.clock); 3030 } 3031 /** 3032 * Use writeClient and writeClock instead of writeID if possible. 3033 * @param {number} client 3034 */ 3035 writeClient(client) { 3036 writeVarUint(this.restEncoder, client); 3037 } 3038 /** 3039 * @param {number} info An unsigned 8-bit integer 3040 */ 3041 writeInfo(info) { 3042 writeUint8(this.restEncoder, info); 3043 } 3044 /** 3045 * @param {string} s 3046 */ 3047 writeString(s) { 3048 writeVarString(this.restEncoder, s); 3049 } 3050 /** 3051 * @param {boolean} isYKey 3052 */ 3053 writeParentInfo(isYKey) { 3054 writeVarUint(this.restEncoder, isYKey ? 1 : 0); 3055 } 3056 /** 3057 * @param {number} info An unsigned 8-bit integer 3058 */ 3059 writeTypeRef(info) { 3060 writeVarUint(this.restEncoder, info); 3061 } 3062 /** 3063 * Write len of a struct - well suited for Opt RLE encoder. 3064 * 3065 * @param {number} len 3066 */ 3067 writeLen(len) { 3068 writeVarUint(this.restEncoder, len); 3069 } 3070 /** 3071 * @param {any} any 3072 */ 3073 writeAny(any2) { 3074 writeAny(this.restEncoder, any2); 3075 } 3076 /** 3077 * @param {Uint8Array} buf 3078 */ 3079 writeBuf(buf) { 3080 writeVarUint8Array(this.restEncoder, buf); 3081 } 3082 /** 3083 * @param {any} embed 3084 */ 3085 writeJSON(embed) { 3086 writeVarString(this.restEncoder, JSON.stringify(embed)); 3087 } 3088 /** 3089 * @param {string} key 3090 */ 3091 writeKey(key) { 3092 writeVarString(this.restEncoder, key); 3093 } 3094 }; 3095 var DSEncoderV2 = class { 3096 constructor() { 3097 this.restEncoder = createEncoder(); 3098 this.dsCurrVal = 0; 3099 } 3100 toUint8Array() { 3101 return toUint8Array(this.restEncoder); 3102 } 3103 resetDsCurVal() { 3104 this.dsCurrVal = 0; 3105 } 3106 /** 3107 * @param {number} clock 3108 */ 3109 writeDsClock(clock) { 3110 const diff = clock - this.dsCurrVal; 3111 this.dsCurrVal = clock; 3112 writeVarUint(this.restEncoder, diff); 3113 } 3114 /** 3115 * @param {number} len 3116 */ 3117 writeDsLen(len) { 3118 if (len === 0) { 3119 unexpectedCase(); 3120 } 3121 writeVarUint(this.restEncoder, len - 1); 3122 this.dsCurrVal += len; 3123 } 3124 }; 3125 var UpdateEncoderV2 = class extends DSEncoderV2 { 3126 constructor() { 3127 super(); 3128 this.keyMap = /* @__PURE__ */ new Map(); 3129 this.keyClock = 0; 3130 this.keyClockEncoder = new IntDiffOptRleEncoder(); 3131 this.clientEncoder = new UintOptRleEncoder(); 3132 this.leftClockEncoder = new IntDiffOptRleEncoder(); 3133 this.rightClockEncoder = new IntDiffOptRleEncoder(); 3134 this.infoEncoder = new RleEncoder(writeUint8); 3135 this.stringEncoder = new StringEncoder(); 3136 this.parentInfoEncoder = new RleEncoder(writeUint8); 3137 this.typeRefEncoder = new UintOptRleEncoder(); 3138 this.lenEncoder = new UintOptRleEncoder(); 3139 } 3140 toUint8Array() { 3141 const encoder = createEncoder(); 3142 writeVarUint(encoder, 0); 3143 writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); 3144 writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); 3145 writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); 3146 writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); 3147 writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); 3148 writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); 3149 writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); 3150 writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); 3151 writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); 3152 writeUint8Array(encoder, toUint8Array(this.restEncoder)); 3153 return toUint8Array(encoder); 3154 } 3155 /** 3156 * @param {ID} id 3157 */ 3158 writeLeftID(id2) { 3159 this.clientEncoder.write(id2.client); 3160 this.leftClockEncoder.write(id2.clock); 3161 } 3162 /** 3163 * @param {ID} id 3164 */ 3165 writeRightID(id2) { 3166 this.clientEncoder.write(id2.client); 3167 this.rightClockEncoder.write(id2.clock); 3168 } 3169 /** 3170 * @param {number} client 3171 */ 3172 writeClient(client) { 3173 this.clientEncoder.write(client); 3174 } 3175 /** 3176 * @param {number} info An unsigned 8-bit integer 3177 */ 3178 writeInfo(info) { 3179 this.infoEncoder.write(info); 3180 } 3181 /** 3182 * @param {string} s 3183 */ 3184 writeString(s) { 3185 this.stringEncoder.write(s); 3186 } 3187 /** 3188 * @param {boolean} isYKey 3189 */ 3190 writeParentInfo(isYKey) { 3191 this.parentInfoEncoder.write(isYKey ? 1 : 0); 3192 } 3193 /** 3194 * @param {number} info An unsigned 8-bit integer 3195 */ 3196 writeTypeRef(info) { 3197 this.typeRefEncoder.write(info); 3198 } 3199 /** 3200 * Write len of a struct - well suited for Opt RLE encoder. 3201 * 3202 * @param {number} len 3203 */ 3204 writeLen(len) { 3205 this.lenEncoder.write(len); 3206 } 3207 /** 3208 * @param {any} any 3209 */ 3210 writeAny(any2) { 3211 writeAny(this.restEncoder, any2); 3212 } 3213 /** 3214 * @param {Uint8Array} buf 3215 */ 3216 writeBuf(buf) { 3217 writeVarUint8Array(this.restEncoder, buf); 3218 } 3219 /** 3220 * This is mainly here for legacy purposes. 3221 * 3222 * 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. 3223 * 3224 * @param {any} embed 3225 */ 3226 writeJSON(embed) { 3227 writeAny(this.restEncoder, embed); 3228 } 3229 /** 3230 * Property keys are often reused. For example, in y-prosemirror the key `bold` might 3231 * occur very often. For a 3d application, the key `position` might occur very often. 3232 * 3233 * We cache these keys in a Map and refer to them via a unique number. 3234 * 3235 * @param {string} key 3236 */ 3237 writeKey(key) { 3238 const clock = this.keyMap.get(key); 3239 if (clock === void 0) { 3240 this.keyClockEncoder.write(this.keyClock++); 3241 this.stringEncoder.write(key); 3242 } else { 3243 this.keyClockEncoder.write(clock); 3244 } 3245 } 3246 }; 3247 var writeStructs = (encoder, structs, client, clock) => { 3248 clock = max(clock, structs[0].id.clock); 3249 const startNewStructs = findIndexSS(structs, clock); 3250 writeVarUint(encoder.restEncoder, structs.length - startNewStructs); 3251 encoder.writeClient(client); 3252 writeVarUint(encoder.restEncoder, clock); 3253 const firstStruct = structs[startNewStructs]; 3254 firstStruct.write(encoder, clock - firstStruct.id.clock); 3255 for (let i = startNewStructs + 1; i < structs.length; i++) { 3256 structs[i].write(encoder, 0); 3257 } 3258 }; 3259 var writeClientsStructs = (encoder, store, _sm) => { 3260 const sm = /* @__PURE__ */ new Map(); 3261 _sm.forEach((clock, client) => { 3262 if (getState(store, client) > clock) { 3263 sm.set(client, clock); 3264 } 3265 }); 3266 getStateVector(store).forEach((_clock, client) => { 3267 if (!_sm.has(client)) { 3268 sm.set(client, 0); 3269 } 3270 }); 3271 writeVarUint(encoder.restEncoder, sm.size); 3272 from(sm.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3273 writeStructs( 3274 encoder, 3275 /** @type {Array<GC|Item>} */ 3276 store.clients.get(client), 3277 client, 3278 clock 3279 ); 3280 }); 3281 }; 3282 var readClientsStructRefs = (decoder, doc2) => { 3283 const clientRefs = create(); 3284 const numOfStateUpdates = readVarUint(decoder.restDecoder); 3285 for (let i = 0; i < numOfStateUpdates; i++) { 3286 const numberOfStructs = readVarUint(decoder.restDecoder); 3287 const refs = new Array(numberOfStructs); 3288 const client = decoder.readClient(); 3289 let clock = readVarUint(decoder.restDecoder); 3290 clientRefs.set(client, { i: 0, refs }); 3291 for (let i2 = 0; i2 < numberOfStructs; i2++) { 3292 const info = decoder.readInfo(); 3293 switch (BITS5 & info) { 3294 case 0: { 3295 const len = decoder.readLen(); 3296 refs[i2] = new GC(createID(client, clock), len); 3297 clock += len; 3298 break; 3299 } 3300 case 10: { 3301 const len = readVarUint(decoder.restDecoder); 3302 refs[i2] = new Skip(createID(client, clock), len); 3303 clock += len; 3304 break; 3305 } 3306 default: { 3307 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 3308 const struct = new Item( 3309 createID(client, clock), 3310 null, 3311 // left 3312 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 3313 // origin 3314 null, 3315 // right 3316 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 3317 // right origin 3318 cantCopyParentInfo ? decoder.readParentInfo() ? doc2.get(decoder.readString()) : decoder.readLeftID() : null, 3319 // parent 3320 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 3321 // parentSub 3322 readItemContent(decoder, info) 3323 // item content 3324 ); 3325 refs[i2] = struct; 3326 clock += struct.length; 3327 } 3328 } 3329 } 3330 } 3331 return clientRefs; 3332 }; 3333 var integrateStructs = (transaction, store, clientsStructRefs) => { 3334 const stack = []; 3335 let clientsStructRefsIds = from(clientsStructRefs.keys()).sort((a, b) => a - b); 3336 if (clientsStructRefsIds.length === 0) { 3337 return null; 3338 } 3339 const getNextStructTarget = () => { 3340 if (clientsStructRefsIds.length === 0) { 3341 return null; 3342 } 3343 let nextStructsTarget = ( 3344 /** @type {{i:number,refs:Array<GC|Item>}} */ 3345 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) 3346 ); 3347 while (nextStructsTarget.refs.length === nextStructsTarget.i) { 3348 clientsStructRefsIds.pop(); 3349 if (clientsStructRefsIds.length > 0) { 3350 nextStructsTarget = /** @type {{i:number,refs:Array<GC|Item>}} */ 3351 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); 3352 } else { 3353 return null; 3354 } 3355 } 3356 return nextStructsTarget; 3357 }; 3358 let curStructsTarget = getNextStructTarget(); 3359 if (curStructsTarget === null) { 3360 return null; 3361 } 3362 const restStructs = new StructStore(); 3363 const missingSV = /* @__PURE__ */ new Map(); 3364 const updateMissingSv = (client, clock) => { 3365 const mclock = missingSV.get(client); 3366 if (mclock == null || mclock > clock) { 3367 missingSV.set(client, clock); 3368 } 3369 }; 3370 let stackHead = ( 3371 /** @type {any} */ 3372 curStructsTarget.refs[ 3373 /** @type {any} */ 3374 curStructsTarget.i++ 3375 ] 3376 ); 3377 const state = /* @__PURE__ */ new Map(); 3378 const addStackToRestSS = () => { 3379 for (const item of stack) { 3380 const client = item.id.client; 3381 const inapplicableItems = clientsStructRefs.get(client); 3382 if (inapplicableItems) { 3383 inapplicableItems.i--; 3384 restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); 3385 clientsStructRefs.delete(client); 3386 inapplicableItems.i = 0; 3387 inapplicableItems.refs = []; 3388 } else { 3389 restStructs.clients.set(client, [item]); 3390 } 3391 clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); 3392 } 3393 stack.length = 0; 3394 }; 3395 while (true) { 3396 if (stackHead.constructor !== Skip) { 3397 const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store, stackHead.id.client)); 3398 const offset = localClock - stackHead.id.clock; 3399 if (offset < 0) { 3400 stack.push(stackHead); 3401 updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); 3402 addStackToRestSS(); 3403 } else { 3404 const missing = stackHead.getMissing(transaction, store); 3405 if (missing !== null) { 3406 stack.push(stackHead); 3407 const structRefs = clientsStructRefs.get( 3408 /** @type {number} */ 3409 missing 3410 ) || { refs: [], i: 0 }; 3411 if (structRefs.refs.length === structRefs.i) { 3412 updateMissingSv( 3413 /** @type {number} */ 3414 missing, 3415 getState(store, missing) 3416 ); 3417 addStackToRestSS(); 3418 } else { 3419 stackHead = structRefs.refs[structRefs.i++]; 3420 continue; 3421 } 3422 } else if (offset === 0 || offset < stackHead.length) { 3423 stackHead.integrate(transaction, offset); 3424 state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); 3425 } 3426 } 3427 } 3428 if (stack.length > 0) { 3429 stackHead = /** @type {GC|Item} */ 3430 stack.pop(); 3431 } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { 3432 stackHead = /** @type {GC|Item} */ 3433 curStructsTarget.refs[curStructsTarget.i++]; 3434 } else { 3435 curStructsTarget = getNextStructTarget(); 3436 if (curStructsTarget === null) { 3437 break; 3438 } else { 3439 stackHead = /** @type {GC|Item} */ 3440 curStructsTarget.refs[curStructsTarget.i++]; 3441 } 3442 } 3443 } 3444 if (restStructs.clients.size > 0) { 3445 const encoder = new UpdateEncoderV2(); 3446 writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); 3447 writeVarUint(encoder.restEncoder, 0); 3448 return { missing: missingSV, update: encoder.toUint8Array() }; 3449 } 3450 return null; 3451 }; 3452 var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); 3453 var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { 3454 transaction.local = false; 3455 let retry = false; 3456 const doc2 = transaction.doc; 3457 const store = doc2.store; 3458 const ss = readClientsStructRefs(structDecoder, doc2); 3459 const restStructs = integrateStructs(transaction, store, ss); 3460 const pending = store.pendingStructs; 3461 if (pending) { 3462 for (const [client, clock] of pending.missing) { 3463 if (clock < getState(store, client)) { 3464 retry = true; 3465 break; 3466 } 3467 } 3468 if (restStructs) { 3469 for (const [client, clock] of restStructs.missing) { 3470 const mclock = pending.missing.get(client); 3471 if (mclock == null || mclock > clock) { 3472 pending.missing.set(client, clock); 3473 } 3474 } 3475 pending.update = mergeUpdatesV2([pending.update, restStructs.update]); 3476 } 3477 } else { 3478 store.pendingStructs = restStructs; 3479 } 3480 const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store); 3481 if (store.pendingDs) { 3482 const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store.pendingDs)); 3483 readVarUint(pendingDSUpdate.restDecoder); 3484 const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store); 3485 if (dsRest && dsRest2) { 3486 store.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); 3487 } else { 3488 store.pendingDs = dsRest || dsRest2; 3489 } 3490 } else { 3491 store.pendingDs = dsRest; 3492 } 3493 if (retry) { 3494 const update = ( 3495 /** @type {{update: Uint8Array}} */ 3496 store.pendingStructs.update 3497 ); 3498 store.pendingStructs = null; 3499 applyUpdateV2(transaction.doc, update); 3500 } 3501 }, transactionOrigin, false); 3502 var readUpdate = (decoder, ydoc, transactionOrigin) => readUpdateV2(decoder, ydoc, transactionOrigin, new UpdateDecoderV1(decoder)); 3503 var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { 3504 const decoder = createDecoder(update); 3505 readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); 3506 }; 3507 var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); 3508 var writeStateAsUpdate = (encoder, doc2, targetStateVector = /* @__PURE__ */ new Map()) => { 3509 writeClientsStructs(encoder, doc2.store, targetStateVector); 3510 writeDeleteSet(encoder, createDeleteSetFromStructStore(doc2.store)); 3511 }; 3512 var encodeStateAsUpdateV2 = (doc2, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { 3513 const targetStateVector = decodeStateVector(encodedTargetStateVector); 3514 writeStateAsUpdate(encoder, doc2, targetStateVector); 3515 const updates = [encoder.toUint8Array()]; 3516 if (doc2.store.pendingDs) { 3517 updates.push(doc2.store.pendingDs); 3518 } 3519 if (doc2.store.pendingStructs) { 3520 updates.push(diffUpdateV2(doc2.store.pendingStructs.update, encodedTargetStateVector)); 3521 } 3522 if (updates.length > 1) { 3523 if (encoder.constructor === UpdateEncoderV1) { 3524 return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); 3525 } else if (encoder.constructor === UpdateEncoderV2) { 3526 return mergeUpdatesV2(updates); 3527 } 3528 } 3529 return updates[0]; 3530 }; 3531 var encodeStateAsUpdate = (doc2, encodedTargetStateVector) => encodeStateAsUpdateV2(doc2, encodedTargetStateVector, new UpdateEncoderV1()); 3532 var readStateVector = (decoder) => { 3533 const ss = /* @__PURE__ */ new Map(); 3534 const ssLength = readVarUint(decoder.restDecoder); 3535 for (let i = 0; i < ssLength; i++) { 3536 const client = readVarUint(decoder.restDecoder); 3537 const clock = readVarUint(decoder.restDecoder); 3538 ss.set(client, clock); 3539 } 3540 return ss; 3541 }; 3542 var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); 3543 var writeStateVector = (encoder, sv) => { 3544 writeVarUint(encoder.restEncoder, sv.size); 3545 from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3546 writeVarUint(encoder.restEncoder, client); 3547 writeVarUint(encoder.restEncoder, clock); 3548 }); 3549 return encoder; 3550 }; 3551 var writeDocumentStateVector = (encoder, doc2) => writeStateVector(encoder, getStateVector(doc2.store)); 3552 var encodeStateVectorV2 = (doc2, encoder = new DSEncoderV2()) => { 3553 if (doc2 instanceof Map) { 3554 writeStateVector(encoder, doc2); 3555 } else { 3556 writeDocumentStateVector(encoder, doc2); 3557 } 3558 return encoder.toUint8Array(); 3559 }; 3560 var encodeStateVector = (doc2) => encodeStateVectorV2(doc2, new DSEncoderV1()); 3561 var EventHandler = class { 3562 constructor() { 3563 this.l = []; 3564 } 3565 }; 3566 var createEventHandler = () => new EventHandler(); 3567 var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); 3568 var removeEventHandlerListener = (eventHandler, f) => { 3569 const l = eventHandler.l; 3570 const len = l.length; 3571 eventHandler.l = l.filter((g) => f !== g); 3572 if (len === eventHandler.l.length) { 3573 console.error("[yjs] Tried to remove event handler that doesn't exist."); 3574 } 3575 }; 3576 var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); 3577 var ID = class { 3578 /** 3579 * @param {number} client client id 3580 * @param {number} clock unique per client id, continuous number 3581 */ 3582 constructor(client, clock) { 3583 this.client = client; 3584 this.clock = clock; 3585 } 3586 }; 3587 var compareIDs = (a, b) => a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock; 3588 var createID = (client, clock) => new ID(client, clock); 3589 var writeID = (encoder, id2) => { 3590 writeVarUint(encoder, id2.client); 3591 writeVarUint(encoder, id2.clock); 3592 }; 3593 var readID = (decoder) => createID(readVarUint(decoder), readVarUint(decoder)); 3594 var findRootTypeKey = (type) => { 3595 for (const [key, value] of type.doc.share.entries()) { 3596 if (value === type) { 3597 return key; 3598 } 3599 } 3600 throw unexpectedCase(); 3601 }; 3602 var isParentOf = (parent, child) => { 3603 while (child !== null) { 3604 if (child.parent === parent) { 3605 return true; 3606 } 3607 child = /** @type {AbstractType<any>} */ 3608 child.parent._item; 3609 } 3610 return false; 3611 }; 3612 var logType = (type) => { 3613 const res = []; 3614 let n = type._start; 3615 while (n) { 3616 res.push(n); 3617 n = n.right; 3618 } 3619 console.log("Children: ", res); 3620 console.log("Children content: ", res.filter((m) => !m.deleted).map((m) => m.content)); 3621 }; 3622 var PermanentUserData = class { 3623 /** 3624 * @param {Doc} doc 3625 * @param {YMap<any>} [storeType] 3626 */ 3627 constructor(doc2, storeType = doc2.getMap("users")) { 3628 const dss = /* @__PURE__ */ new Map(); 3629 this.yusers = storeType; 3630 this.doc = doc2; 3631 this.clients = /* @__PURE__ */ new Map(); 3632 this.dss = dss; 3633 const initUser = (user, userDescription) => { 3634 const ds = user.get("ds"); 3635 const ids = user.get("ids"); 3636 const addClientId = ( 3637 /** @param {number} clientid */ 3638 (clientid) => this.clients.set(clientid, userDescription) 3639 ); 3640 ds.observe( 3641 /** @param {YArrayEvent<any>} event */ 3642 (event) => { 3643 event.changes.added.forEach((item) => { 3644 item.content.getContent().forEach((encodedDs) => { 3645 if (encodedDs instanceof Uint8Array) { 3646 this.dss.set(userDescription, mergeDeleteSets([this.dss.get(userDescription) || createDeleteSet(), readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))])); 3647 } 3648 }); 3649 }); 3650 } 3651 ); 3652 this.dss.set(userDescription, mergeDeleteSets(ds.map((encodedDs) => readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))))); 3653 ids.observe( 3654 /** @param {YArrayEvent<any>} event */ 3655 (event) => event.changes.added.forEach((item) => item.content.getContent().forEach(addClientId)) 3656 ); 3657 ids.forEach(addClientId); 3658 }; 3659 storeType.observe((event) => { 3660 event.keysChanged.forEach( 3661 (userDescription) => initUser(storeType.get(userDescription), userDescription) 3662 ); 3663 }); 3664 storeType.forEach(initUser); 3665 } 3666 /** 3667 * @param {Doc} doc 3668 * @param {number} clientid 3669 * @param {string} userDescription 3670 * @param {Object} conf 3671 * @param {function(Transaction, DeleteSet):boolean} [conf.filter] 3672 */ 3673 setUserMapping(doc2, clientid, userDescription, { filter = () => true } = {}) { 3674 const users = this.yusers; 3675 let user = users.get(userDescription); 3676 if (!user) { 3677 user = new YMap(); 3678 user.set("ids", new YArray()); 3679 user.set("ds", new YArray()); 3680 users.set(userDescription, user); 3681 } 3682 user.get("ids").push([clientid]); 3683 users.observe((_event) => { 3684 setTimeout(() => { 3685 const userOverwrite = users.get(userDescription); 3686 if (userOverwrite !== user) { 3687 user = userOverwrite; 3688 this.clients.forEach((_userDescription, clientid2) => { 3689 if (userDescription === _userDescription) { 3690 user.get("ids").push([clientid2]); 3691 } 3692 }); 3693 const encoder = new DSEncoderV1(); 3694 const ds = this.dss.get(userDescription); 3695 if (ds) { 3696 writeDeleteSet(encoder, ds); 3697 user.get("ds").push([encoder.toUint8Array()]); 3698 } 3699 } 3700 }, 0); 3701 }); 3702 doc2.on( 3703 "afterTransaction", 3704 /** @param {Transaction} transaction */ 3705 (transaction) => { 3706 setTimeout(() => { 3707 const yds = user.get("ds"); 3708 const ds = transaction.deleteSet; 3709 if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) { 3710 const encoder = new DSEncoderV1(); 3711 writeDeleteSet(encoder, ds); 3712 yds.push([encoder.toUint8Array()]); 3713 } 3714 }); 3715 } 3716 ); 3717 } 3718 /** 3719 * @param {number} clientid 3720 * @return {any} 3721 */ 3722 getUserByClientId(clientid) { 3723 return this.clients.get(clientid) || null; 3724 } 3725 /** 3726 * @param {ID} id 3727 * @return {string | null} 3728 */ 3729 getUserByDeletedId(id2) { 3730 for (const [userDescription, ds] of this.dss.entries()) { 3731 if (isDeleted(ds, id2)) { 3732 return userDescription; 3733 } 3734 } 3735 return null; 3736 } 3737 }; 3738 var RelativePosition = class { 3739 /** 3740 * @param {ID|null} type 3741 * @param {string|null} tname 3742 * @param {ID|null} item 3743 * @param {number} assoc 3744 */ 3745 constructor(type, tname, item, assoc = 0) { 3746 this.type = type; 3747 this.tname = tname; 3748 this.item = item; 3749 this.assoc = assoc; 3750 } 3751 }; 3752 var relativePositionToJSON = (rpos) => { 3753 const json = {}; 3754 if (rpos.type) { 3755 json.type = rpos.type; 3756 } 3757 if (rpos.tname) { 3758 json.tname = rpos.tname; 3759 } 3760 if (rpos.item) { 3761 json.item = rpos.item; 3762 } 3763 if (rpos.assoc != null) { 3764 json.assoc = rpos.assoc; 3765 } 3766 return json; 3767 }; 3768 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); 3769 var AbsolutePosition = class { 3770 /** 3771 * @param {AbstractType<any>} type 3772 * @param {number} index 3773 * @param {number} [assoc] 3774 */ 3775 constructor(type, index, assoc = 0) { 3776 this.type = type; 3777 this.index = index; 3778 this.assoc = assoc; 3779 } 3780 }; 3781 var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); 3782 var createRelativePosition = (type, item, assoc) => { 3783 let typeid = null; 3784 let tname = null; 3785 if (type._item === null) { 3786 tname = findRootTypeKey(type); 3787 } else { 3788 typeid = createID(type._item.id.client, type._item.id.clock); 3789 } 3790 return new RelativePosition(typeid, tname, item, assoc); 3791 }; 3792 var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { 3793 let t = type._start; 3794 if (assoc < 0) { 3795 if (index === 0) { 3796 return createRelativePosition(type, null, assoc); 3797 } 3798 index--; 3799 } 3800 while (t !== null) { 3801 if (!t.deleted && t.countable) { 3802 if (t.length > index) { 3803 return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); 3804 } 3805 index -= t.length; 3806 } 3807 if (t.right === null && assoc < 0) { 3808 return createRelativePosition(type, t.lastId, assoc); 3809 } 3810 t = t.right; 3811 } 3812 return createRelativePosition(type, null, assoc); 3813 }; 3814 var writeRelativePosition = (encoder, rpos) => { 3815 const { type, tname, item, assoc } = rpos; 3816 if (item !== null) { 3817 writeVarUint(encoder, 0); 3818 writeID(encoder, item); 3819 } else if (tname !== null) { 3820 writeUint8(encoder, 1); 3821 writeVarString(encoder, tname); 3822 } else if (type !== null) { 3823 writeUint8(encoder, 2); 3824 writeID(encoder, type); 3825 } else { 3826 throw unexpectedCase(); 3827 } 3828 writeVarInt(encoder, assoc); 3829 return encoder; 3830 }; 3831 var encodeRelativePosition = (rpos) => { 3832 const encoder = createEncoder(); 3833 writeRelativePosition(encoder, rpos); 3834 return toUint8Array(encoder); 3835 }; 3836 var readRelativePosition = (decoder) => { 3837 let type = null; 3838 let tname = null; 3839 let itemID = null; 3840 switch (readVarUint(decoder)) { 3841 case 0: 3842 itemID = readID(decoder); 3843 break; 3844 case 1: 3845 tname = readVarString(decoder); 3846 break; 3847 case 2: { 3848 type = readID(decoder); 3849 } 3850 } 3851 const assoc = hasContent(decoder) ? readVarInt(decoder) : 0; 3852 return new RelativePosition(type, tname, itemID, assoc); 3853 }; 3854 var decodeRelativePosition = (uint8Array) => readRelativePosition(createDecoder(uint8Array)); 3855 var getItemWithOffset = (store, id2) => { 3856 const item = getItem(store, id2); 3857 const diff = id2.clock - item.id.clock; 3858 return { 3859 item, 3860 diff 3861 }; 3862 }; 3863 var createAbsolutePositionFromRelativePosition = (rpos, doc2, followUndoneDeletions = true) => { 3864 const store = doc2.store; 3865 const rightID = rpos.item; 3866 const typeID = rpos.type; 3867 const tname = rpos.tname; 3868 const assoc = rpos.assoc; 3869 let type = null; 3870 let index = 0; 3871 if (rightID !== null) { 3872 if (getState(store, rightID.client) <= rightID.clock) { 3873 return null; 3874 } 3875 const res = followUndoneDeletions ? followRedone(store, rightID) : getItemWithOffset(store, rightID); 3876 const right = res.item; 3877 if (!(right instanceof Item)) { 3878 return null; 3879 } 3880 type = /** @type {AbstractType<any>} */ 3881 right.parent; 3882 if (type._item === null || !type._item.deleted) { 3883 index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); 3884 let n = right.left; 3885 while (n !== null) { 3886 if (!n.deleted && n.countable) { 3887 index += n.length; 3888 } 3889 n = n.left; 3890 } 3891 } 3892 } else { 3893 if (tname !== null) { 3894 type = doc2.get(tname); 3895 } else if (typeID !== null) { 3896 if (getState(store, typeID.client) <= typeID.clock) { 3897 return null; 3898 } 3899 const { item } = followUndoneDeletions ? followRedone(store, typeID) : { item: getItem(store, typeID) }; 3900 if (item instanceof Item && item.content instanceof ContentType) { 3901 type = item.content.type; 3902 } else { 3903 return null; 3904 } 3905 } else { 3906 throw unexpectedCase(); 3907 } 3908 if (assoc >= 0) { 3909 index = type._length; 3910 } else { 3911 index = 0; 3912 } 3913 } 3914 return createAbsolutePosition(type, index, rpos.assoc); 3915 }; 3916 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; 3917 var Snapshot = class { 3918 /** 3919 * @param {DeleteSet} ds 3920 * @param {Map<number,number>} sv state map 3921 */ 3922 constructor(ds, sv) { 3923 this.ds = ds; 3924 this.sv = sv; 3925 } 3926 }; 3927 var equalSnapshots = (snap1, snap2) => { 3928 const ds1 = snap1.ds.clients; 3929 const ds2 = snap2.ds.clients; 3930 const sv1 = snap1.sv; 3931 const sv2 = snap2.sv; 3932 if (sv1.size !== sv2.size || ds1.size !== ds2.size) { 3933 return false; 3934 } 3935 for (const [key, value] of sv1.entries()) { 3936 if (sv2.get(key) !== value) { 3937 return false; 3938 } 3939 } 3940 for (const [client, dsitems1] of ds1.entries()) { 3941 const dsitems2 = ds2.get(client) || []; 3942 if (dsitems1.length !== dsitems2.length) { 3943 return false; 3944 } 3945 for (let i = 0; i < dsitems1.length; i++) { 3946 const dsitem1 = dsitems1[i]; 3947 const dsitem2 = dsitems2[i]; 3948 if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) { 3949 return false; 3950 } 3951 } 3952 } 3953 return true; 3954 }; 3955 var encodeSnapshotV2 = (snapshot2, encoder = new DSEncoderV2()) => { 3956 writeDeleteSet(encoder, snapshot2.ds); 3957 writeStateVector(encoder, snapshot2.sv); 3958 return encoder.toUint8Array(); 3959 }; 3960 var encodeSnapshot = (snapshot2) => encodeSnapshotV2(snapshot2, new DSEncoderV1()); 3961 var decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(createDecoder(buf))) => { 3962 return new Snapshot(readDeleteSet(decoder), readStateVector(decoder)); 3963 }; 3964 var decodeSnapshot = (buf) => decodeSnapshotV2(buf, new DSDecoderV1(createDecoder(buf))); 3965 var createSnapshot = (ds, sm) => new Snapshot(ds, sm); 3966 var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); 3967 var snapshot = (doc2) => createSnapshot(createDeleteSetFromStructStore(doc2.store), getStateVector(doc2.store)); 3968 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); 3969 var splitSnapshotAffectedStructs = (transaction, snapshot2) => { 3970 const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); 3971 const store = transaction.doc.store; 3972 if (!meta.has(snapshot2)) { 3973 snapshot2.sv.forEach((clock, client) => { 3974 if (clock < getState(store, client)) { 3975 getItemCleanStart(transaction, createID(client, clock)); 3976 } 3977 }); 3978 iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { 3979 }); 3980 meta.add(snapshot2); 3981 } 3982 }; 3983 var createDocFromSnapshot = (originDoc, snapshot2, newDoc = new Doc()) => { 3984 if (originDoc.gc) { 3985 throw new Error("Garbage-collection must be disabled in `originDoc`!"); 3986 } 3987 const { sv, ds } = snapshot2; 3988 const encoder = new UpdateEncoderV2(); 3989 originDoc.transact((transaction) => { 3990 let size2 = 0; 3991 sv.forEach((clock) => { 3992 if (clock > 0) { 3993 size2++; 3994 } 3995 }); 3996 writeVarUint(encoder.restEncoder, size2); 3997 for (const [client, clock] of sv) { 3998 if (clock === 0) { 3999 continue; 4000 } 4001 if (clock < getState(originDoc.store, client)) { 4002 getItemCleanStart(transaction, createID(client, clock)); 4003 } 4004 const structs = originDoc.store.clients.get(client) || []; 4005 const lastStructIndex = findIndexSS(structs, clock - 1); 4006 writeVarUint(encoder.restEncoder, lastStructIndex + 1); 4007 encoder.writeClient(client); 4008 writeVarUint(encoder.restEncoder, 0); 4009 for (let i = 0; i <= lastStructIndex; i++) { 4010 structs[i].write(encoder, 0); 4011 } 4012 } 4013 writeDeleteSet(encoder, ds); 4014 }); 4015 applyUpdateV2(newDoc, encoder.toUint8Array(), "snapshot"); 4016 return newDoc; 4017 }; 4018 var snapshotContainsUpdateV2 = (snapshot2, update, YDecoder = UpdateDecoderV2) => { 4019 const updateDecoder = new YDecoder(createDecoder(update)); 4020 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4021 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4022 if ((snapshot2.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) { 4023 return false; 4024 } 4025 } 4026 const mergedDS = mergeDeleteSets([snapshot2.ds, readDeleteSet(updateDecoder)]); 4027 return equalDeleteSets(snapshot2.ds, mergedDS); 4028 }; 4029 var snapshotContainsUpdate = (snapshot2, update) => snapshotContainsUpdateV2(snapshot2, update, UpdateDecoderV1); 4030 var StructStore = class { 4031 constructor() { 4032 this.clients = /* @__PURE__ */ new Map(); 4033 this.pendingStructs = null; 4034 this.pendingDs = null; 4035 } 4036 }; 4037 var getStateVector = (store) => { 4038 const sm = /* @__PURE__ */ new Map(); 4039 store.clients.forEach((structs, client) => { 4040 const struct = structs[structs.length - 1]; 4041 sm.set(client, struct.id.clock + struct.length); 4042 }); 4043 return sm; 4044 }; 4045 var getState = (store, client) => { 4046 const structs = store.clients.get(client); 4047 if (structs === void 0) { 4048 return 0; 4049 } 4050 const lastStruct = structs[structs.length - 1]; 4051 return lastStruct.id.clock + lastStruct.length; 4052 }; 4053 var addStruct = (store, struct) => { 4054 let structs = store.clients.get(struct.id.client); 4055 if (structs === void 0) { 4056 structs = []; 4057 store.clients.set(struct.id.client, structs); 4058 } else { 4059 const lastStruct = structs[structs.length - 1]; 4060 if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { 4061 throw unexpectedCase(); 4062 } 4063 } 4064 structs.push(struct); 4065 }; 4066 var findIndexSS = (structs, clock) => { 4067 let left = 0; 4068 let right = structs.length - 1; 4069 let mid = structs[right]; 4070 let midclock = mid.id.clock; 4071 if (midclock === clock) { 4072 return right; 4073 } 4074 let midindex = floor(clock / (midclock + mid.length - 1) * right); 4075 while (left <= right) { 4076 mid = structs[midindex]; 4077 midclock = mid.id.clock; 4078 if (midclock <= clock) { 4079 if (clock < midclock + mid.length) { 4080 return midindex; 4081 } 4082 left = midindex + 1; 4083 } else { 4084 right = midindex - 1; 4085 } 4086 midindex = floor((left + right) / 2); 4087 } 4088 throw unexpectedCase(); 4089 }; 4090 var find = (store, id2) => { 4091 const structs = store.clients.get(id2.client); 4092 return structs[findIndexSS(structs, id2.clock)]; 4093 }; 4094 var getItem = ( 4095 /** @type {function(StructStore,ID):Item} */ 4096 find 4097 ); 4098 var findIndexCleanStart = (transaction, structs, clock) => { 4099 const index = findIndexSS(structs, clock); 4100 const struct = structs[index]; 4101 if (struct.id.clock < clock && struct instanceof Item) { 4102 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 4103 return index + 1; 4104 } 4105 return index; 4106 }; 4107 var getItemCleanStart = (transaction, id2) => { 4108 const structs = ( 4109 /** @type {Array<Item>} */ 4110 transaction.doc.store.clients.get(id2.client) 4111 ); 4112 return structs[findIndexCleanStart(transaction, structs, id2.clock)]; 4113 }; 4114 var getItemCleanEnd = (transaction, store, id2) => { 4115 const structs = store.clients.get(id2.client); 4116 const index = findIndexSS(structs, id2.clock); 4117 const struct = structs[index]; 4118 if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { 4119 structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); 4120 } 4121 return struct; 4122 }; 4123 var replaceStruct = (store, struct, newStruct) => { 4124 const structs = ( 4125 /** @type {Array<GC|Item>} */ 4126 store.clients.get(struct.id.client) 4127 ); 4128 structs[findIndexSS(structs, struct.id.clock)] = newStruct; 4129 }; 4130 var iterateStructs = (transaction, structs, clockStart, len, f) => { 4131 if (len === 0) { 4132 return; 4133 } 4134 const clockEnd = clockStart + len; 4135 let index = findIndexCleanStart(transaction, structs, clockStart); 4136 let struct; 4137 do { 4138 struct = structs[index++]; 4139 if (clockEnd < struct.id.clock + struct.length) { 4140 findIndexCleanStart(transaction, structs, clockEnd); 4141 } 4142 f(struct); 4143 } while (index < structs.length && structs[index].id.clock < clockEnd); 4144 }; 4145 var Transaction = class { 4146 /** 4147 * @param {Doc} doc 4148 * @param {any} origin 4149 * @param {boolean} local 4150 */ 4151 constructor(doc2, origin2, local) { 4152 this.doc = doc2; 4153 this.deleteSet = new DeleteSet(); 4154 this.beforeState = getStateVector(doc2.store); 4155 this.afterState = /* @__PURE__ */ new Map(); 4156 this.changed = /* @__PURE__ */ new Map(); 4157 this.changedParentTypes = /* @__PURE__ */ new Map(); 4158 this._mergeStructs = []; 4159 this.origin = origin2; 4160 this.meta = /* @__PURE__ */ new Map(); 4161 this.local = local; 4162 this.subdocsAdded = /* @__PURE__ */ new Set(); 4163 this.subdocsRemoved = /* @__PURE__ */ new Set(); 4164 this.subdocsLoaded = /* @__PURE__ */ new Set(); 4165 this._needFormattingCleanup = false; 4166 } 4167 }; 4168 var writeUpdateMessageFromTransaction = (encoder, transaction) => { 4169 if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { 4170 return false; 4171 } 4172 sortAndMergeDeleteSet(transaction.deleteSet); 4173 writeStructsFromTransaction(encoder, transaction); 4174 writeDeleteSet(encoder, transaction.deleteSet); 4175 return true; 4176 }; 4177 var addChangedTypeToTransaction = (transaction, type, parentSub) => { 4178 const item = type._item; 4179 if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { 4180 setIfUndefined(transaction.changed, type, create2).add(parentSub); 4181 } 4182 }; 4183 var tryToMergeWithLefts = (structs, pos) => { 4184 let right = structs[pos]; 4185 let left = structs[pos - 1]; 4186 let i = pos; 4187 for (; i > 0; right = left, left = structs[--i - 1]) { 4188 if (left.deleted === right.deleted && left.constructor === right.constructor) { 4189 if (left.mergeWith(right)) { 4190 if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ 4191 right.parent._map.get(right.parentSub) === right) { 4192 right.parent._map.set( 4193 right.parentSub, 4194 /** @type {Item} */ 4195 left 4196 ); 4197 } 4198 continue; 4199 } 4200 } 4201 break; 4202 } 4203 const merged = pos - i; 4204 if (merged) { 4205 structs.splice(pos + 1 - merged, merged); 4206 } 4207 return merged; 4208 }; 4209 var tryGcDeleteSet = (ds, store, gcFilter) => { 4210 for (const [client, deleteItems] of ds.clients.entries()) { 4211 const structs = ( 4212 /** @type {Array<GC|Item>} */ 4213 store.clients.get(client) 4214 ); 4215 for (let di = deleteItems.length - 1; di >= 0; di--) { 4216 const deleteItem = deleteItems[di]; 4217 const endDeleteItemClock = deleteItem.clock + deleteItem.len; 4218 for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { 4219 const struct2 = structs[si]; 4220 if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { 4221 break; 4222 } 4223 if (struct2 instanceof Item && struct2.deleted && !struct2.keep && gcFilter(struct2)) { 4224 struct2.gc(store, false); 4225 } 4226 } 4227 } 4228 } 4229 }; 4230 var tryMergeDeleteSet = (ds, store) => { 4231 ds.clients.forEach((deleteItems, client) => { 4232 const structs = ( 4233 /** @type {Array<GC|Item>} */ 4234 store.clients.get(client) 4235 ); 4236 for (let di = deleteItems.length - 1; di >= 0; di--) { 4237 const deleteItem = deleteItems[di]; 4238 const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); 4239 for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { 4240 si -= 1 + tryToMergeWithLefts(structs, si); 4241 } 4242 } 4243 }); 4244 }; 4245 var tryGc = (ds, store, gcFilter) => { 4246 tryGcDeleteSet(ds, store, gcFilter); 4247 tryMergeDeleteSet(ds, store); 4248 }; 4249 var cleanupTransactions = (transactionCleanups, i) => { 4250 if (i < transactionCleanups.length) { 4251 const transaction = transactionCleanups[i]; 4252 const doc2 = transaction.doc; 4253 const store = doc2.store; 4254 const ds = transaction.deleteSet; 4255 const mergeStructs = transaction._mergeStructs; 4256 try { 4257 sortAndMergeDeleteSet(ds); 4258 transaction.afterState = getStateVector(transaction.doc.store); 4259 doc2.emit("beforeObserverCalls", [transaction, doc2]); 4260 const fs = []; 4261 transaction.changed.forEach( 4262 (subs, itemtype) => fs.push(() => { 4263 if (itemtype._item === null || !itemtype._item.deleted) { 4264 itemtype._callObserver(transaction, subs); 4265 } 4266 }) 4267 ); 4268 fs.push(() => { 4269 transaction.changedParentTypes.forEach((events, type) => { 4270 if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { 4271 events = events.filter( 4272 (event) => event.target._item === null || !event.target._item.deleted 4273 ); 4274 events.forEach((event) => { 4275 event.currentTarget = type; 4276 event._path = null; 4277 }); 4278 events.sort((event1, event2) => event1.path.length - event2.path.length); 4279 fs.push(() => { 4280 callEventHandlerListeners(type._dEH, events, transaction); 4281 }); 4282 } 4283 }); 4284 fs.push(() => doc2.emit("afterTransaction", [transaction, doc2])); 4285 fs.push(() => { 4286 if (transaction._needFormattingCleanup) { 4287 cleanupYTextAfterTransaction(transaction); 4288 } 4289 }); 4290 }); 4291 callAll(fs, []); 4292 } finally { 4293 if (doc2.gc) { 4294 tryGcDeleteSet(ds, store, doc2.gcFilter); 4295 } 4296 tryMergeDeleteSet(ds, store); 4297 transaction.afterState.forEach((clock, client) => { 4298 const beforeClock = transaction.beforeState.get(client) || 0; 4299 if (beforeClock !== clock) { 4300 const structs = ( 4301 /** @type {Array<GC|Item>} */ 4302 store.clients.get(client) 4303 ); 4304 const firstChangePos = max(findIndexSS(structs, beforeClock), 1); 4305 for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { 4306 i2 -= 1 + tryToMergeWithLefts(structs, i2); 4307 } 4308 } 4309 }); 4310 for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { 4311 const { client, clock } = mergeStructs[i2].id; 4312 const structs = ( 4313 /** @type {Array<GC|Item>} */ 4314 store.clients.get(client) 4315 ); 4316 const replacedStructPos = findIndexSS(structs, clock); 4317 if (replacedStructPos + 1 < structs.length) { 4318 if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { 4319 continue; 4320 } 4321 } 4322 if (replacedStructPos > 0) { 4323 tryToMergeWithLefts(structs, replacedStructPos); 4324 } 4325 } 4326 if (!transaction.local && transaction.afterState.get(doc2.clientID) !== transaction.beforeState.get(doc2.clientID)) { 4327 print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); 4328 doc2.clientID = generateNewClientId(); 4329 } 4330 doc2.emit("afterTransactionCleanup", [transaction, doc2]); 4331 if (doc2._observers.has("update")) { 4332 const encoder = new UpdateEncoderV1(); 4333 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4334 if (hasContent2) { 4335 doc2.emit("update", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4336 } 4337 } 4338 if (doc2._observers.has("updateV2")) { 4339 const encoder = new UpdateEncoderV2(); 4340 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4341 if (hasContent2) { 4342 doc2.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4343 } 4344 } 4345 const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; 4346 if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { 4347 subdocsAdded.forEach((subdoc) => { 4348 subdoc.clientID = doc2.clientID; 4349 if (subdoc.collectionid == null) { 4350 subdoc.collectionid = doc2.collectionid; 4351 } 4352 doc2.subdocs.add(subdoc); 4353 }); 4354 subdocsRemoved.forEach((subdoc) => doc2.subdocs.delete(subdoc)); 4355 doc2.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc2, transaction]); 4356 subdocsRemoved.forEach((subdoc) => subdoc.destroy()); 4357 } 4358 if (transactionCleanups.length <= i + 1) { 4359 doc2._transactionCleanups = []; 4360 doc2.emit("afterAllTransactions", [doc2, transactionCleanups]); 4361 } else { 4362 cleanupTransactions(transactionCleanups, i + 1); 4363 } 4364 } 4365 } 4366 }; 4367 var transact = (doc2, f, origin2 = null, local = true) => { 4368 const transactionCleanups = doc2._transactionCleanups; 4369 let initialCall = false; 4370 let result = null; 4371 if (doc2._transaction === null) { 4372 initialCall = true; 4373 doc2._transaction = new Transaction(doc2, origin2, local); 4374 transactionCleanups.push(doc2._transaction); 4375 if (transactionCleanups.length === 1) { 4376 doc2.emit("beforeAllTransactions", [doc2]); 4377 } 4378 doc2.emit("beforeTransaction", [doc2._transaction, doc2]); 4379 } 4380 try { 4381 result = f(doc2._transaction); 4382 } finally { 4383 if (initialCall) { 4384 const finishCleanup = doc2._transaction === transactionCleanups[0]; 4385 doc2._transaction = null; 4386 if (finishCleanup) { 4387 cleanupTransactions(transactionCleanups, 0); 4388 } 4389 } 4390 } 4391 return result; 4392 }; 4393 var StackItem = class { 4394 /** 4395 * @param {DeleteSet} deletions 4396 * @param {DeleteSet} insertions 4397 */ 4398 constructor(deletions, insertions) { 4399 this.insertions = insertions; 4400 this.deletions = deletions; 4401 this.meta = /* @__PURE__ */ new Map(); 4402 } 4403 }; 4404 var clearUndoManagerStackItem = (tr, um, stackItem) => { 4405 iterateDeletedStructs(tr, stackItem.deletions, (item) => { 4406 if (item instanceof Item && um.scope.some((type) => type === tr.doc || isParentOf( 4407 /** @type {AbstractType<any>} */ 4408 type, 4409 item 4410 ))) { 4411 keepItem(item, false); 4412 } 4413 }); 4414 }; 4415 var popStackItem = (undoManager, stack, eventType) => { 4416 let _tr = null; 4417 const doc2 = undoManager.doc; 4418 const scope = undoManager.scope; 4419 transact(doc2, (transaction) => { 4420 while (stack.length > 0 && undoManager.currStackItem === null) { 4421 const store = doc2.store; 4422 const stackItem = ( 4423 /** @type {StackItem} */ 4424 stack.pop() 4425 ); 4426 const itemsToRedo = /* @__PURE__ */ new Set(); 4427 const itemsToDelete = []; 4428 let performedChange = false; 4429 iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { 4430 if (struct instanceof Item) { 4431 if (struct.redone !== null) { 4432 let { item, diff } = followRedone(store, struct.id); 4433 if (diff > 0) { 4434 item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); 4435 } 4436 struct = item; 4437 } 4438 if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( 4439 /** @type {AbstractType<any>} */ 4440 type, 4441 /** @type {Item} */ 4442 struct 4443 ))) { 4444 itemsToDelete.push(struct); 4445 } 4446 } 4447 }); 4448 iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { 4449 if (struct instanceof Item && scope.some((type) => type === transaction.doc || isParentOf( 4450 /** @type {AbstractType<any>} */ 4451 type, 4452 struct 4453 )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. 4454 !isDeleted(stackItem.insertions, struct.id)) { 4455 itemsToRedo.add(struct); 4456 } 4457 }); 4458 itemsToRedo.forEach((struct) => { 4459 performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange; 4460 }); 4461 for (let i = itemsToDelete.length - 1; i >= 0; i--) { 4462 const item = itemsToDelete[i]; 4463 if (undoManager.deleteFilter(item)) { 4464 item.delete(transaction); 4465 performedChange = true; 4466 } 4467 } 4468 undoManager.currStackItem = performedChange ? stackItem : null; 4469 } 4470 transaction.changed.forEach((subProps, type) => { 4471 if (subProps.has(null) && type._searchMarker) { 4472 type._searchMarker.length = 0; 4473 } 4474 }); 4475 _tr = transaction; 4476 }, undoManager); 4477 const res = undoManager.currStackItem; 4478 if (res != null) { 4479 const changedParentTypes = _tr.changedParentTypes; 4480 undoManager.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager }, undoManager]); 4481 undoManager.currStackItem = null; 4482 } 4483 return res; 4484 }; 4485 var UndoManager = class extends ObservableV2 { 4486 /** 4487 * @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. 4488 * @param {UndoManagerOptions} options 4489 */ 4490 constructor(typeScope, { 4491 captureTimeout = 500, 4492 captureTransaction = (_tr) => true, 4493 deleteFilter = () => true, 4494 trackedOrigins = /* @__PURE__ */ new Set([null]), 4495 ignoreRemoteMapChanges = false, 4496 doc: doc2 = ( 4497 /** @type {Doc} */ 4498 isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc 4499 ) 4500 } = {}) { 4501 super(); 4502 this.scope = []; 4503 this.doc = doc2; 4504 this.addToScope(typeScope); 4505 this.deleteFilter = deleteFilter; 4506 trackedOrigins.add(this); 4507 this.trackedOrigins = trackedOrigins; 4508 this.captureTransaction = captureTransaction; 4509 this.undoStack = []; 4510 this.redoStack = []; 4511 this.undoing = false; 4512 this.redoing = false; 4513 this.currStackItem = null; 4514 this.lastChange = 0; 4515 this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; 4516 this.captureTimeout = captureTimeout; 4517 this.afterTransactionHandler = (transaction) => { 4518 if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( 4519 /** @type {AbstractType<any>} */ 4520 type 4521 ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { 4522 return; 4523 } 4524 const undoing = this.undoing; 4525 const redoing = this.redoing; 4526 const stack = undoing ? this.redoStack : this.undoStack; 4527 if (undoing) { 4528 this.stopCapturing(); 4529 } else if (!redoing) { 4530 this.clear(false, true); 4531 } 4532 const insertions = new DeleteSet(); 4533 transaction.afterState.forEach((endClock, client) => { 4534 const startClock = transaction.beforeState.get(client) || 0; 4535 const len = endClock - startClock; 4536 if (len > 0) { 4537 addToDeleteSet(insertions, client, startClock, len); 4538 } 4539 }); 4540 const now = getUnixTime(); 4541 let didAdd = false; 4542 if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { 4543 const lastOp = stack[stack.length - 1]; 4544 lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); 4545 lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); 4546 } else { 4547 stack.push(new StackItem(transaction.deleteSet, insertions)); 4548 didAdd = true; 4549 } 4550 if (!undoing && !redoing) { 4551 this.lastChange = now; 4552 } 4553 iterateDeletedStructs( 4554 transaction, 4555 transaction.deleteSet, 4556 /** @param {Item|GC} item */ 4557 (item) => { 4558 if (item instanceof Item && this.scope.some((type) => type === transaction.doc || isParentOf( 4559 /** @type {AbstractType<any>} */ 4560 type, 4561 item 4562 ))) { 4563 keepItem(item, true); 4564 } 4565 } 4566 ); 4567 const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; 4568 if (didAdd) { 4569 this.emit("stack-item-added", changeEvent); 4570 } else { 4571 this.emit("stack-item-updated", changeEvent); 4572 } 4573 }; 4574 this.doc.on("afterTransaction", this.afterTransactionHandler); 4575 this.doc.on("destroy", () => { 4576 this.destroy(); 4577 }); 4578 } 4579 /** 4580 * Extend the scope. 4581 * 4582 * @param {Array<AbstractType<any> | Doc> | AbstractType<any> | Doc} ytypes 4583 */ 4584 addToScope(ytypes) { 4585 const tmpSet = new Set(this.scope); 4586 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 4587 ytypes.forEach((ytype) => { 4588 if (!tmpSet.has(ytype)) { 4589 tmpSet.add(ytype); 4590 if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn("[yjs#509] Not same Y.Doc"); 4591 this.scope.push(ytype); 4592 } 4593 }); 4594 } 4595 /** 4596 * @param {any} origin 4597 */ 4598 addTrackedOrigin(origin2) { 4599 this.trackedOrigins.add(origin2); 4600 } 4601 /** 4602 * @param {any} origin 4603 */ 4604 removeTrackedOrigin(origin2) { 4605 this.trackedOrigins.delete(origin2); 4606 } 4607 clear(clearUndoStack = true, clearRedoStack = true) { 4608 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 4609 this.doc.transact((tr) => { 4610 if (clearUndoStack) { 4611 this.undoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 4612 this.undoStack = []; 4613 } 4614 if (clearRedoStack) { 4615 this.redoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 4616 this.redoStack = []; 4617 } 4618 this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); 4619 }); 4620 } 4621 } 4622 /** 4623 * UndoManager merges Undo-StackItem if they are created within time-gap 4624 * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next 4625 * StackItem won't be merged. 4626 * 4627 * 4628 * @example 4629 * // without stopCapturing 4630 * ytext.insert(0, 'a') 4631 * ytext.insert(1, 'b') 4632 * um.undo() 4633 * ytext.toString() // => '' (note that 'ab' was removed) 4634 * // with stopCapturing 4635 * ytext.insert(0, 'a') 4636 * um.stopCapturing() 4637 * ytext.insert(0, 'b') 4638 * um.undo() 4639 * ytext.toString() // => 'a' (note that only 'b' was removed) 4640 * 4641 */ 4642 stopCapturing() { 4643 this.lastChange = 0; 4644 } 4645 /** 4646 * Undo last changes on type. 4647 * 4648 * @return {StackItem?} Returns StackItem if a change was applied 4649 */ 4650 undo() { 4651 this.undoing = true; 4652 let res; 4653 try { 4654 res = popStackItem(this, this.undoStack, "undo"); 4655 } finally { 4656 this.undoing = false; 4657 } 4658 return res; 4659 } 4660 /** 4661 * Redo last undo operation. 4662 * 4663 * @return {StackItem?} Returns StackItem if a change was applied 4664 */ 4665 redo() { 4666 this.redoing = true; 4667 let res; 4668 try { 4669 res = popStackItem(this, this.redoStack, "redo"); 4670 } finally { 4671 this.redoing = false; 4672 } 4673 return res; 4674 } 4675 /** 4676 * Are undo steps available? 4677 * 4678 * @return {boolean} `true` if undo is possible 4679 */ 4680 canUndo() { 4681 return this.undoStack.length > 0; 4682 } 4683 /** 4684 * Are redo steps available? 4685 * 4686 * @return {boolean} `true` if redo is possible 4687 */ 4688 canRedo() { 4689 return this.redoStack.length > 0; 4690 } 4691 destroy() { 4692 this.trackedOrigins.delete(this); 4693 this.doc.off("afterTransaction", this.afterTransactionHandler); 4694 super.destroy(); 4695 } 4696 }; 4697 function* lazyStructReaderGenerator(decoder) { 4698 const numOfStateUpdates = readVarUint(decoder.restDecoder); 4699 for (let i = 0; i < numOfStateUpdates; i++) { 4700 const numberOfStructs = readVarUint(decoder.restDecoder); 4701 const client = decoder.readClient(); 4702 let clock = readVarUint(decoder.restDecoder); 4703 for (let i2 = 0; i2 < numberOfStructs; i2++) { 4704 const info = decoder.readInfo(); 4705 if (info === 10) { 4706 const len = readVarUint(decoder.restDecoder); 4707 yield new Skip(createID(client, clock), len); 4708 clock += len; 4709 } else if ((BITS5 & info) !== 0) { 4710 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 4711 const struct = new Item( 4712 createID(client, clock), 4713 null, 4714 // left 4715 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 4716 // origin 4717 null, 4718 // right 4719 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 4720 // right origin 4721 // @ts-ignore Force writing a string here. 4722 cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, 4723 // parent 4724 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 4725 // parentSub 4726 readItemContent(decoder, info) 4727 // item content 4728 ); 4729 yield struct; 4730 clock += struct.length; 4731 } else { 4732 const len = decoder.readLen(); 4733 yield new GC(createID(client, clock), len); 4734 clock += len; 4735 } 4736 } 4737 } 4738 } 4739 var LazyStructReader = class { 4740 /** 4741 * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder 4742 * @param {boolean} filterSkips 4743 */ 4744 constructor(decoder, filterSkips) { 4745 this.gen = lazyStructReaderGenerator(decoder); 4746 this.curr = null; 4747 this.done = false; 4748 this.filterSkips = filterSkips; 4749 this.next(); 4750 } 4751 /** 4752 * @return {Item | GC | Skip |null} 4753 */ 4754 next() { 4755 do { 4756 this.curr = this.gen.next().value || null; 4757 } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); 4758 return this.curr; 4759 } 4760 }; 4761 var logUpdate = (update) => logUpdateV2(update, UpdateDecoderV1); 4762 var logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4763 const structs = []; 4764 const updateDecoder = new YDecoder(createDecoder(update)); 4765 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4766 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4767 structs.push(curr); 4768 } 4769 print("Structs: ", structs); 4770 const ds = readDeleteSet(updateDecoder); 4771 print("DeleteSet: ", ds); 4772 }; 4773 var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1); 4774 var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4775 const structs = []; 4776 const updateDecoder = new YDecoder(createDecoder(update)); 4777 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4778 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4779 structs.push(curr); 4780 } 4781 return { 4782 structs, 4783 ds: readDeleteSet(updateDecoder) 4784 }; 4785 }; 4786 var LazyStructWriter = class { 4787 /** 4788 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 4789 */ 4790 constructor(encoder) { 4791 this.currClient = 0; 4792 this.startClock = 0; 4793 this.written = 0; 4794 this.encoder = encoder; 4795 this.clientStructs = []; 4796 } 4797 }; 4798 var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); 4799 var encodeStateVectorFromUpdateV2 = (update, YEncoder = DSEncoderV2, YDecoder = UpdateDecoderV2) => { 4800 const encoder = new YEncoder(); 4801 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4802 let curr = updateDecoder.curr; 4803 if (curr !== null) { 4804 let size2 = 0; 4805 let currClient = curr.id.client; 4806 let stopCounting = curr.id.clock !== 0; 4807 let currClock = stopCounting ? 0 : curr.id.clock + curr.length; 4808 for (; curr !== null; curr = updateDecoder.next()) { 4809 if (currClient !== curr.id.client) { 4810 if (currClock !== 0) { 4811 size2++; 4812 writeVarUint(encoder.restEncoder, currClient); 4813 writeVarUint(encoder.restEncoder, currClock); 4814 } 4815 currClient = curr.id.client; 4816 currClock = 0; 4817 stopCounting = curr.id.clock !== 0; 4818 } 4819 if (curr.constructor === Skip) { 4820 stopCounting = true; 4821 } 4822 if (!stopCounting) { 4823 currClock = curr.id.clock + curr.length; 4824 } 4825 } 4826 if (currClock !== 0) { 4827 size2++; 4828 writeVarUint(encoder.restEncoder, currClient); 4829 writeVarUint(encoder.restEncoder, currClock); 4830 } 4831 const enc = createEncoder(); 4832 writeVarUint(enc, size2); 4833 writeBinaryEncoder(enc, encoder.restEncoder); 4834 encoder.restEncoder = enc; 4835 return encoder.toUint8Array(); 4836 } else { 4837 writeVarUint(encoder.restEncoder, 0); 4838 return encoder.toUint8Array(); 4839 } 4840 }; 4841 var encodeStateVectorFromUpdate = (update) => encodeStateVectorFromUpdateV2(update, DSEncoderV1, UpdateDecoderV1); 4842 var parseUpdateMetaV2 = (update, YDecoder = UpdateDecoderV2) => { 4843 const from2 = /* @__PURE__ */ new Map(); 4844 const to = /* @__PURE__ */ new Map(); 4845 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4846 let curr = updateDecoder.curr; 4847 if (curr !== null) { 4848 let currClient = curr.id.client; 4849 let currClock = curr.id.clock; 4850 from2.set(currClient, currClock); 4851 for (; curr !== null; curr = updateDecoder.next()) { 4852 if (currClient !== curr.id.client) { 4853 to.set(currClient, currClock); 4854 from2.set(curr.id.client, curr.id.clock); 4855 currClient = curr.id.client; 4856 } 4857 currClock = curr.id.clock + curr.length; 4858 } 4859 to.set(currClient, currClock); 4860 } 4861 return { from: from2, to }; 4862 }; 4863 var parseUpdateMeta = (update) => parseUpdateMetaV2(update, UpdateDecoderV1); 4864 var sliceStruct = (left, diff) => { 4865 if (left.constructor === GC) { 4866 const { client, clock } = left.id; 4867 return new GC(createID(client, clock + diff), left.length - diff); 4868 } else if (left.constructor === Skip) { 4869 const { client, clock } = left.id; 4870 return new Skip(createID(client, clock + diff), left.length - diff); 4871 } else { 4872 const leftItem = ( 4873 /** @type {Item} */ 4874 left 4875 ); 4876 const { client, clock } = leftItem.id; 4877 return new Item( 4878 createID(client, clock + diff), 4879 null, 4880 createID(client, clock + diff - 1), 4881 null, 4882 leftItem.rightOrigin, 4883 leftItem.parent, 4884 leftItem.parentSub, 4885 leftItem.content.splice(diff) 4886 ); 4887 } 4888 }; 4889 var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4890 if (updates.length === 1) { 4891 return updates[0]; 4892 } 4893 const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); 4894 let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); 4895 let currWrite = null; 4896 const updateEncoder = new YEncoder(); 4897 const lazyStructEncoder = new LazyStructWriter(updateEncoder); 4898 while (true) { 4899 lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); 4900 lazyStructDecoders.sort( 4901 /** @type {function(any,any):number} */ 4902 (dec1, dec2) => { 4903 if (dec1.curr.id.client === dec2.curr.id.client) { 4904 const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; 4905 if (clockDiff === 0) { 4906 return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; 4907 } else { 4908 return clockDiff; 4909 } 4910 } else { 4911 return dec2.curr.id.client - dec1.curr.id.client; 4912 } 4913 } 4914 ); 4915 if (lazyStructDecoders.length === 0) { 4916 break; 4917 } 4918 const currDecoder = lazyStructDecoders[0]; 4919 const firstClient = ( 4920 /** @type {Item | GC} */ 4921 currDecoder.curr.id.client 4922 ); 4923 if (currWrite !== null) { 4924 let curr = ( 4925 /** @type {Item | GC | null} */ 4926 currDecoder.curr 4927 ); 4928 let iterated = false; 4929 while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { 4930 curr = currDecoder.next(); 4931 iterated = true; 4932 } 4933 if (curr === null || // current decoder is empty 4934 curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` 4935 iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { 4936 continue; 4937 } 4938 if (firstClient !== currWrite.struct.id.client) { 4939 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4940 currWrite = { struct: curr, offset: 0 }; 4941 currDecoder.next(); 4942 } else { 4943 if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { 4944 if (currWrite.struct.constructor === Skip) { 4945 currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; 4946 } else { 4947 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4948 const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; 4949 const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); 4950 currWrite = { struct, offset: 0 }; 4951 } 4952 } else { 4953 const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; 4954 if (diff > 0) { 4955 if (currWrite.struct.constructor === Skip) { 4956 currWrite.struct.length -= diff; 4957 } else { 4958 curr = sliceStruct(curr, diff); 4959 } 4960 } 4961 if (!currWrite.struct.mergeWith( 4962 /** @type {any} */ 4963 curr 4964 )) { 4965 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4966 currWrite = { struct: curr, offset: 0 }; 4967 currDecoder.next(); 4968 } 4969 } 4970 } 4971 } else { 4972 currWrite = { struct: ( 4973 /** @type {Item | GC} */ 4974 currDecoder.curr 4975 ), offset: 0 }; 4976 currDecoder.next(); 4977 } 4978 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()) { 4979 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4980 currWrite = { struct: next, offset: 0 }; 4981 } 4982 } 4983 if (currWrite !== null) { 4984 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4985 currWrite = null; 4986 } 4987 finishLazyStructWriting(lazyStructEncoder); 4988 const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); 4989 const ds = mergeDeleteSets(dss); 4990 writeDeleteSet(updateEncoder, ds); 4991 return updateEncoder.toUint8Array(); 4992 }; 4993 var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4994 const state = decodeStateVector(sv); 4995 const encoder = new YEncoder(); 4996 const lazyStructWriter = new LazyStructWriter(encoder); 4997 const decoder = new YDecoder(createDecoder(update)); 4998 const reader = new LazyStructReader(decoder, false); 4999 while (reader.curr) { 5000 const curr = reader.curr; 5001 const currClient = curr.id.client; 5002 const svClock = state.get(currClient) || 0; 5003 if (reader.curr.constructor === Skip) { 5004 reader.next(); 5005 continue; 5006 } 5007 if (curr.id.clock + curr.length > svClock) { 5008 writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); 5009 reader.next(); 5010 while (reader.curr && reader.curr.id.client === currClient) { 5011 writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); 5012 reader.next(); 5013 } 5014 } else { 5015 while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { 5016 reader.next(); 5017 } 5018 } 5019 } 5020 finishLazyStructWriting(lazyStructWriter); 5021 const ds = readDeleteSet(decoder); 5022 writeDeleteSet(encoder, ds); 5023 return encoder.toUint8Array(); 5024 }; 5025 var diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1); 5026 var flushLazyStructWriter = (lazyWriter) => { 5027 if (lazyWriter.written > 0) { 5028 lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); 5029 lazyWriter.encoder.restEncoder = createEncoder(); 5030 lazyWriter.written = 0; 5031 } 5032 }; 5033 var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { 5034 if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { 5035 flushLazyStructWriter(lazyWriter); 5036 } 5037 if (lazyWriter.written === 0) { 5038 lazyWriter.currClient = struct.id.client; 5039 lazyWriter.encoder.writeClient(struct.id.client); 5040 writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); 5041 } 5042 struct.write(lazyWriter.encoder, offset); 5043 lazyWriter.written++; 5044 }; 5045 var finishLazyStructWriting = (lazyWriter) => { 5046 flushLazyStructWriter(lazyWriter); 5047 const restEncoder = lazyWriter.encoder.restEncoder; 5048 writeVarUint(restEncoder, lazyWriter.clientStructs.length); 5049 for (let i = 0; i < lazyWriter.clientStructs.length; i++) { 5050 const partStructs = lazyWriter.clientStructs[i]; 5051 writeVarUint(restEncoder, partStructs.written); 5052 writeUint8Array(restEncoder, partStructs.restEncoder); 5053 } 5054 }; 5055 var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { 5056 const updateDecoder = new YDecoder(createDecoder(update)); 5057 const lazyDecoder = new LazyStructReader(updateDecoder, false); 5058 const updateEncoder = new YEncoder(); 5059 const lazyWriter = new LazyStructWriter(updateEncoder); 5060 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 5061 writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); 5062 } 5063 finishLazyStructWriting(lazyWriter); 5064 const ds = readDeleteSet(updateDecoder); 5065 writeDeleteSet(updateEncoder, ds); 5066 return updateEncoder.toUint8Array(); 5067 }; 5068 var createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {}) => { 5069 let i = 0; 5070 const mapKeyCache = create(); 5071 const nodeNameCache = create(); 5072 const formattingKeyCache = create(); 5073 const formattingValueCache = create(); 5074 formattingValueCache.set(null, null); 5075 return (block) => { 5076 switch (block.constructor) { 5077 case GC: 5078 case Skip: 5079 return block; 5080 case Item: { 5081 const item = ( 5082 /** @type {Item} */ 5083 block 5084 ); 5085 const content = item.content; 5086 switch (content.constructor) { 5087 case ContentDeleted: 5088 break; 5089 case ContentType: { 5090 if (yxml) { 5091 const type = ( 5092 /** @type {ContentType} */ 5093 content.type 5094 ); 5095 if (type instanceof YXmlElement) { 5096 type.nodeName = setIfUndefined(nodeNameCache, type.nodeName, () => "node-" + i); 5097 } 5098 if (type instanceof YXmlHook) { 5099 type.hookName = setIfUndefined(nodeNameCache, type.hookName, () => "hook-" + i); 5100 } 5101 } 5102 break; 5103 } 5104 case ContentAny: { 5105 const c = ( 5106 /** @type {ContentAny} */ 5107 content 5108 ); 5109 c.arr = c.arr.map(() => i); 5110 break; 5111 } 5112 case ContentBinary: { 5113 const c = ( 5114 /** @type {ContentBinary} */ 5115 content 5116 ); 5117 c.content = new Uint8Array([i]); 5118 break; 5119 } 5120 case ContentDoc: { 5121 const c = ( 5122 /** @type {ContentDoc} */ 5123 content 5124 ); 5125 if (subdocs) { 5126 c.opts = {}; 5127 c.doc.guid = i + ""; 5128 } 5129 break; 5130 } 5131 case ContentEmbed: { 5132 const c = ( 5133 /** @type {ContentEmbed} */ 5134 content 5135 ); 5136 c.embed = {}; 5137 break; 5138 } 5139 case ContentFormat: { 5140 const c = ( 5141 /** @type {ContentFormat} */ 5142 content 5143 ); 5144 if (formatting) { 5145 c.key = setIfUndefined(formattingKeyCache, c.key, () => i + ""); 5146 c.value = setIfUndefined(formattingValueCache, c.value, () => ({ i })); 5147 } 5148 break; 5149 } 5150 case ContentJSON: { 5151 const c = ( 5152 /** @type {ContentJSON} */ 5153 content 5154 ); 5155 c.arr = c.arr.map(() => i); 5156 break; 5157 } 5158 case ContentString: { 5159 const c = ( 5160 /** @type {ContentString} */ 5161 content 5162 ); 5163 c.str = repeat(i % 10 + "", c.str.length); 5164 break; 5165 } 5166 default: 5167 unexpectedCase(); 5168 } 5169 if (item.parentSub) { 5170 item.parentSub = setIfUndefined(mapKeyCache, item.parentSub, () => i + ""); 5171 } 5172 i++; 5173 return block; 5174 } 5175 default: 5176 unexpectedCase(); 5177 } 5178 }; 5179 }; 5180 var obfuscateUpdate = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV1, UpdateEncoderV1); 5181 var obfuscateUpdateV2 = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV2, UpdateEncoderV2); 5182 var convertUpdateFormatV1ToV2 = (update) => convertUpdateFormat(update, id, UpdateDecoderV1, UpdateEncoderV2); 5183 var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); 5184 var errorComputeChanges = "You must not compute changes after the event-handler fired."; 5185 var YEvent = class { 5186 /** 5187 * @param {T} target The changed type. 5188 * @param {Transaction} transaction 5189 */ 5190 constructor(target, transaction) { 5191 this.target = target; 5192 this.currentTarget = target; 5193 this.transaction = transaction; 5194 this._changes = null; 5195 this._keys = null; 5196 this._delta = null; 5197 this._path = null; 5198 } 5199 /** 5200 * Computes the path from `y` to the changed type. 5201 * 5202 * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. 5203 * 5204 * The following property holds: 5205 * @example 5206 * let type = y 5207 * event.path.forEach(dir => { 5208 * type = type.get(dir) 5209 * }) 5210 * type === event.target // => true 5211 */ 5212 get path() { 5213 return this._path || (this._path = getPathTo(this.currentTarget, this.target)); 5214 } 5215 /** 5216 * Check if a struct is deleted by this event. 5217 * 5218 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5219 * 5220 * @param {AbstractStruct} struct 5221 * @return {boolean} 5222 */ 5223 deletes(struct) { 5224 return isDeleted(this.transaction.deleteSet, struct.id); 5225 } 5226 /** 5227 * @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>} 5228 */ 5229 get keys() { 5230 if (this._keys === null) { 5231 if (this.transaction.doc._transactionCleanups.length === 0) { 5232 throw create3(errorComputeChanges); 5233 } 5234 const keys2 = /* @__PURE__ */ new Map(); 5235 const target = this.target; 5236 const changed = ( 5237 /** @type Set<string|null> */ 5238 this.transaction.changed.get(target) 5239 ); 5240 changed.forEach((key) => { 5241 if (key !== null) { 5242 const item = ( 5243 /** @type {Item} */ 5244 target._map.get(key) 5245 ); 5246 let action; 5247 let oldValue; 5248 if (this.adds(item)) { 5249 let prev = item.left; 5250 while (prev !== null && this.adds(prev)) { 5251 prev = prev.left; 5252 } 5253 if (this.deletes(item)) { 5254 if (prev !== null && this.deletes(prev)) { 5255 action = "delete"; 5256 oldValue = last(prev.content.getContent()); 5257 } else { 5258 return; 5259 } 5260 } else { 5261 if (prev !== null && this.deletes(prev)) { 5262 action = "update"; 5263 oldValue = last(prev.content.getContent()); 5264 } else { 5265 action = "add"; 5266 oldValue = void 0; 5267 } 5268 } 5269 } else { 5270 if (this.deletes(item)) { 5271 action = "delete"; 5272 oldValue = last( 5273 /** @type {Item} */ 5274 item.content.getContent() 5275 ); 5276 } else { 5277 return; 5278 } 5279 } 5280 keys2.set(key, { action, oldValue }); 5281 } 5282 }); 5283 this._keys = keys2; 5284 } 5285 return this._keys; 5286 } 5287 /** 5288 * This is a computed property. Note that this can only be safely computed during the 5289 * event call. Computing this property after other changes happened might result in 5290 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5291 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5292 * 5293 * @type {Array<{insert?: string | Array<any> | object | AbstractType<any>, retain?: number, delete?: number, attributes?: Object<string, any>}>} 5294 */ 5295 get delta() { 5296 return this.changes.delta; 5297 } 5298 /** 5299 * Check if a struct is added by this event. 5300 * 5301 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5302 * 5303 * @param {AbstractStruct} struct 5304 * @return {boolean} 5305 */ 5306 adds(struct) { 5307 return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); 5308 } 5309 /** 5310 * This is a computed property. Note that this can only be safely computed during the 5311 * event call. Computing this property after other changes happened might result in 5312 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5313 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5314 * 5315 * @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}>}} 5316 */ 5317 get changes() { 5318 let changes = this._changes; 5319 if (changes === null) { 5320 if (this.transaction.doc._transactionCleanups.length === 0) { 5321 throw create3(errorComputeChanges); 5322 } 5323 const target = this.target; 5324 const added = create2(); 5325 const deleted = create2(); 5326 const delta = []; 5327 changes = { 5328 added, 5329 deleted, 5330 delta, 5331 keys: this.keys 5332 }; 5333 const changed = ( 5334 /** @type Set<string|null> */ 5335 this.transaction.changed.get(target) 5336 ); 5337 if (changed.has(null)) { 5338 let lastOp = null; 5339 const packOp = () => { 5340 if (lastOp) { 5341 delta.push(lastOp); 5342 } 5343 }; 5344 for (let item = target._start; item !== null; item = item.right) { 5345 if (item.deleted) { 5346 if (this.deletes(item) && !this.adds(item)) { 5347 if (lastOp === null || lastOp.delete === void 0) { 5348 packOp(); 5349 lastOp = { delete: 0 }; 5350 } 5351 lastOp.delete += item.length; 5352 deleted.add(item); 5353 } 5354 } else { 5355 if (this.adds(item)) { 5356 if (lastOp === null || lastOp.insert === void 0) { 5357 packOp(); 5358 lastOp = { insert: [] }; 5359 } 5360 lastOp.insert = lastOp.insert.concat(item.content.getContent()); 5361 added.add(item); 5362 } else { 5363 if (lastOp === null || lastOp.retain === void 0) { 5364 packOp(); 5365 lastOp = { retain: 0 }; 5366 } 5367 lastOp.retain += item.length; 5368 } 5369 } 5370 } 5371 if (lastOp !== null && lastOp.retain === void 0) { 5372 packOp(); 5373 } 5374 } 5375 this._changes = changes; 5376 } 5377 return ( 5378 /** @type {any} */ 5379 changes 5380 ); 5381 } 5382 }; 5383 var getPathTo = (parent, child) => { 5384 const path = []; 5385 while (child._item !== null && child !== parent) { 5386 if (child._item.parentSub !== null) { 5387 path.unshift(child._item.parentSub); 5388 } else { 5389 let i = 0; 5390 let c = ( 5391 /** @type {AbstractType<any>} */ 5392 child._item.parent._start 5393 ); 5394 while (c !== child._item && c !== null) { 5395 if (!c.deleted && c.countable) { 5396 i += c.length; 5397 } 5398 c = c.right; 5399 } 5400 path.unshift(i); 5401 } 5402 child = /** @type {AbstractType<any>} */ 5403 child._item.parent; 5404 } 5405 return path; 5406 }; 5407 var warnPrematureAccess = () => { 5408 warn("Invalid access: Add Yjs type to a document before reading data."); 5409 }; 5410 var maxSearchMarker = 80; 5411 var globalSearchMarkerTimestamp = 0; 5412 var ArraySearchMarker = class { 5413 /** 5414 * @param {Item} p 5415 * @param {number} index 5416 */ 5417 constructor(p, index) { 5418 p.marker = true; 5419 this.p = p; 5420 this.index = index; 5421 this.timestamp = globalSearchMarkerTimestamp++; 5422 } 5423 }; 5424 var refreshMarkerTimestamp = (marker) => { 5425 marker.timestamp = globalSearchMarkerTimestamp++; 5426 }; 5427 var overwriteMarker = (marker, p, index) => { 5428 marker.p.marker = false; 5429 marker.p = p; 5430 p.marker = true; 5431 marker.index = index; 5432 marker.timestamp = globalSearchMarkerTimestamp++; 5433 }; 5434 var markPosition = (searchMarker, p, index) => { 5435 if (searchMarker.length >= maxSearchMarker) { 5436 const marker = searchMarker.reduce((a, b) => a.timestamp < b.timestamp ? a : b); 5437 overwriteMarker(marker, p, index); 5438 return marker; 5439 } else { 5440 const pm = new ArraySearchMarker(p, index); 5441 searchMarker.push(pm); 5442 return pm; 5443 } 5444 }; 5445 var findMarker = (yarray, index) => { 5446 if (yarray._start === null || index === 0 || yarray._searchMarker === null) { 5447 return null; 5448 } 5449 const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b) => abs(index - a.index) < abs(index - b.index) ? a : b); 5450 let p = yarray._start; 5451 let pindex = 0; 5452 if (marker !== null) { 5453 p = marker.p; 5454 pindex = marker.index; 5455 refreshMarkerTimestamp(marker); 5456 } 5457 while (p.right !== null && pindex < index) { 5458 if (!p.deleted && p.countable) { 5459 if (index < pindex + p.length) { 5460 break; 5461 } 5462 pindex += p.length; 5463 } 5464 p = p.right; 5465 } 5466 while (p.left !== null && pindex > index) { 5467 p = p.left; 5468 if (!p.deleted && p.countable) { 5469 pindex -= p.length; 5470 } 5471 } 5472 while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { 5473 p = p.left; 5474 if (!p.deleted && p.countable) { 5475 pindex -= p.length; 5476 } 5477 } 5478 if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray<any>} */ 5479 p.parent.length / maxSearchMarker) { 5480 overwriteMarker(marker, p, pindex); 5481 return marker; 5482 } else { 5483 return markPosition(yarray._searchMarker, p, pindex); 5484 } 5485 }; 5486 var updateMarkerChanges = (searchMarker, index, len) => { 5487 for (let i = searchMarker.length - 1; i >= 0; i--) { 5488 const m = searchMarker[i]; 5489 if (len > 0) { 5490 let p = m.p; 5491 p.marker = false; 5492 while (p && (p.deleted || !p.countable)) { 5493 p = p.left; 5494 if (p && !p.deleted && p.countable) { 5495 m.index -= p.length; 5496 } 5497 } 5498 if (p === null || p.marker === true) { 5499 searchMarker.splice(i, 1); 5500 continue; 5501 } 5502 m.p = p; 5503 p.marker = true; 5504 } 5505 if (index < m.index || len > 0 && index === m.index) { 5506 m.index = max(index, m.index + len); 5507 } 5508 } 5509 }; 5510 var getTypeChildren = (t) => { 5511 t.doc ?? warnPrematureAccess(); 5512 let s = t._start; 5513 const arr = []; 5514 while (s) { 5515 arr.push(s); 5516 s = s.right; 5517 } 5518 return arr; 5519 }; 5520 var callTypeObservers = (type, transaction, event) => { 5521 const changedType = type; 5522 const changedParentTypes = transaction.changedParentTypes; 5523 while (true) { 5524 setIfUndefined(changedParentTypes, type, () => []).push(event); 5525 if (type._item === null) { 5526 break; 5527 } 5528 type = /** @type {AbstractType<any>} */ 5529 type._item.parent; 5530 } 5531 callEventHandlerListeners(changedType._eH, event, transaction); 5532 }; 5533 var AbstractType = class { 5534 constructor() { 5535 this._item = null; 5536 this._map = /* @__PURE__ */ new Map(); 5537 this._start = null; 5538 this.doc = null; 5539 this._length = 0; 5540 this._eH = createEventHandler(); 5541 this._dEH = createEventHandler(); 5542 this._searchMarker = null; 5543 } 5544 /** 5545 * @return {AbstractType<any>|null} 5546 */ 5547 get parent() { 5548 return this._item ? ( 5549 /** @type {AbstractType<any>} */ 5550 this._item.parent 5551 ) : null; 5552 } 5553 /** 5554 * Integrate this type into the Yjs instance. 5555 * 5556 * * Save this struct in the os 5557 * * This type is sent to other client 5558 * * Observer functions are fired 5559 * 5560 * @param {Doc} y The Yjs instance 5561 * @param {Item|null} item 5562 */ 5563 _integrate(y, item) { 5564 this.doc = y; 5565 this._item = item; 5566 } 5567 /** 5568 * @return {AbstractType<EventType>} 5569 */ 5570 _copy() { 5571 throw methodUnimplemented(); 5572 } 5573 /** 5574 * Makes a copy of this data type that can be included somewhere else. 5575 * 5576 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 5577 * 5578 * @return {AbstractType<EventType>} 5579 */ 5580 clone() { 5581 throw methodUnimplemented(); 5582 } 5583 /** 5584 * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder 5585 */ 5586 _write(_encoder) { 5587 } 5588 /** 5589 * The first non-deleted item 5590 */ 5591 get _first() { 5592 let n = this._start; 5593 while (n !== null && n.deleted) { 5594 n = n.right; 5595 } 5596 return n; 5597 } 5598 /** 5599 * Creates YEvent and calls all type observers. 5600 * Must be implemented by each type. 5601 * 5602 * @param {Transaction} transaction 5603 * @param {Set<null|string>} _parentSubs Keys changed on this type. `null` if list was modified. 5604 */ 5605 _callObserver(transaction, _parentSubs) { 5606 if (!transaction.local && this._searchMarker) { 5607 this._searchMarker.length = 0; 5608 } 5609 } 5610 /** 5611 * Observe all events that are created on this type. 5612 * 5613 * @param {function(EventType, Transaction):void} f Observer function 5614 */ 5615 observe(f) { 5616 addEventHandlerListener(this._eH, f); 5617 } 5618 /** 5619 * Observe all events that are created by this type and its children. 5620 * 5621 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 5622 */ 5623 observeDeep(f) { 5624 addEventHandlerListener(this._dEH, f); 5625 } 5626 /** 5627 * Unregister an observer function. 5628 * 5629 * @param {function(EventType,Transaction):void} f Observer function 5630 */ 5631 unobserve(f) { 5632 removeEventHandlerListener(this._eH, f); 5633 } 5634 /** 5635 * Unregister an observer function. 5636 * 5637 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 5638 */ 5639 unobserveDeep(f) { 5640 removeEventHandlerListener(this._dEH, f); 5641 } 5642 /** 5643 * @abstract 5644 * @return {any} 5645 */ 5646 toJSON() { 5647 } 5648 }; 5649 var typeListSlice = (type, start, end) => { 5650 type.doc ?? warnPrematureAccess(); 5651 if (start < 0) { 5652 start = type._length + start; 5653 } 5654 if (end < 0) { 5655 end = type._length + end; 5656 } 5657 let len = end - start; 5658 const cs = []; 5659 let n = type._start; 5660 while (n !== null && len > 0) { 5661 if (n.countable && !n.deleted) { 5662 const c = n.content.getContent(); 5663 if (c.length <= start) { 5664 start -= c.length; 5665 } else { 5666 for (let i = start; i < c.length && len > 0; i++) { 5667 cs.push(c[i]); 5668 len--; 5669 } 5670 start = 0; 5671 } 5672 } 5673 n = n.right; 5674 } 5675 return cs; 5676 }; 5677 var typeListToArray = (type) => { 5678 type.doc ?? warnPrematureAccess(); 5679 const cs = []; 5680 let n = type._start; 5681 while (n !== null) { 5682 if (n.countable && !n.deleted) { 5683 const c = n.content.getContent(); 5684 for (let i = 0; i < c.length; i++) { 5685 cs.push(c[i]); 5686 } 5687 } 5688 n = n.right; 5689 } 5690 return cs; 5691 }; 5692 var typeListToArraySnapshot = (type, snapshot2) => { 5693 const cs = []; 5694 let n = type._start; 5695 while (n !== null) { 5696 if (n.countable && isVisible(n, snapshot2)) { 5697 const c = n.content.getContent(); 5698 for (let i = 0; i < c.length; i++) { 5699 cs.push(c[i]); 5700 } 5701 } 5702 n = n.right; 5703 } 5704 return cs; 5705 }; 5706 var typeListForEach = (type, f) => { 5707 let index = 0; 5708 let n = type._start; 5709 type.doc ?? warnPrematureAccess(); 5710 while (n !== null) { 5711 if (n.countable && !n.deleted) { 5712 const c = n.content.getContent(); 5713 for (let i = 0; i < c.length; i++) { 5714 f(c[i], index++, type); 5715 } 5716 } 5717 n = n.right; 5718 } 5719 }; 5720 var typeListMap = (type, f) => { 5721 const result = []; 5722 typeListForEach(type, (c, i) => { 5723 result.push(f(c, i, type)); 5724 }); 5725 return result; 5726 }; 5727 var typeListCreateIterator = (type) => { 5728 let n = type._start; 5729 let currentContent = null; 5730 let currentContentIndex = 0; 5731 return { 5732 [Symbol.iterator]() { 5733 return this; 5734 }, 5735 next: () => { 5736 if (currentContent === null) { 5737 while (n !== null && n.deleted) { 5738 n = n.right; 5739 } 5740 if (n === null) { 5741 return { 5742 done: true, 5743 value: void 0 5744 }; 5745 } 5746 currentContent = n.content.getContent(); 5747 currentContentIndex = 0; 5748 n = n.right; 5749 } 5750 const value = currentContent[currentContentIndex++]; 5751 if (currentContent.length <= currentContentIndex) { 5752 currentContent = null; 5753 } 5754 return { 5755 done: false, 5756 value 5757 }; 5758 } 5759 }; 5760 }; 5761 var typeListGet = (type, index) => { 5762 type.doc ?? warnPrematureAccess(); 5763 const marker = findMarker(type, index); 5764 let n = type._start; 5765 if (marker !== null) { 5766 n = marker.p; 5767 index -= marker.index; 5768 } 5769 for (; n !== null; n = n.right) { 5770 if (!n.deleted && n.countable) { 5771 if (index < n.length) { 5772 return n.content.getContent()[index]; 5773 } 5774 index -= n.length; 5775 } 5776 } 5777 }; 5778 var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { 5779 let left = referenceItem; 5780 const doc2 = transaction.doc; 5781 const ownClientId = doc2.clientID; 5782 const store = doc2.store; 5783 const right = referenceItem === null ? parent._start : referenceItem.right; 5784 let jsonContent = []; 5785 const packJsonContent = () => { 5786 if (jsonContent.length > 0) { 5787 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); 5788 left.integrate(transaction, 0); 5789 jsonContent = []; 5790 } 5791 }; 5792 content.forEach((c) => { 5793 if (c === null) { 5794 jsonContent.push(c); 5795 } else { 5796 switch (c.constructor) { 5797 case Number: 5798 case Object: 5799 case Boolean: 5800 case Array: 5801 case String: 5802 jsonContent.push(c); 5803 break; 5804 default: 5805 packJsonContent(); 5806 switch (c.constructor) { 5807 case Uint8Array: 5808 case ArrayBuffer: 5809 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( 5810 /** @type {Uint8Array} */ 5811 c 5812 ))); 5813 left.integrate(transaction, 0); 5814 break; 5815 case Doc: 5816 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( 5817 /** @type {Doc} */ 5818 c 5819 )); 5820 left.integrate(transaction, 0); 5821 break; 5822 default: 5823 if (c instanceof AbstractType) { 5824 left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); 5825 left.integrate(transaction, 0); 5826 } else { 5827 throw new Error("Unexpected content type in insert operation"); 5828 } 5829 } 5830 } 5831 } 5832 }); 5833 packJsonContent(); 5834 }; 5835 var lengthExceeded = () => create3("Length exceeded!"); 5836 var typeListInsertGenerics = (transaction, parent, index, content) => { 5837 if (index > parent._length) { 5838 throw lengthExceeded(); 5839 } 5840 if (index === 0) { 5841 if (parent._searchMarker) { 5842 updateMarkerChanges(parent._searchMarker, index, content.length); 5843 } 5844 return typeListInsertGenericsAfter(transaction, parent, null, content); 5845 } 5846 const startIndex = index; 5847 const marker = findMarker(parent, index); 5848 let n = parent._start; 5849 if (marker !== null) { 5850 n = marker.p; 5851 index -= marker.index; 5852 if (index === 0) { 5853 n = n.prev; 5854 index += n && n.countable && !n.deleted ? n.length : 0; 5855 } 5856 } 5857 for (; n !== null; n = n.right) { 5858 if (!n.deleted && n.countable) { 5859 if (index <= n.length) { 5860 if (index < n.length) { 5861 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5862 } 5863 break; 5864 } 5865 index -= n.length; 5866 } 5867 } 5868 if (parent._searchMarker) { 5869 updateMarkerChanges(parent._searchMarker, startIndex, content.length); 5870 } 5871 return typeListInsertGenericsAfter(transaction, parent, n, content); 5872 }; 5873 var typeListPushGenerics = (transaction, parent, content) => { 5874 const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); 5875 let n = marker.p; 5876 if (n) { 5877 while (n.right) { 5878 n = n.right; 5879 } 5880 } 5881 return typeListInsertGenericsAfter(transaction, parent, n, content); 5882 }; 5883 var typeListDelete = (transaction, parent, index, length2) => { 5884 if (length2 === 0) { 5885 return; 5886 } 5887 const startIndex = index; 5888 const startLength = length2; 5889 const marker = findMarker(parent, index); 5890 let n = parent._start; 5891 if (marker !== null) { 5892 n = marker.p; 5893 index -= marker.index; 5894 } 5895 for (; n !== null && index > 0; n = n.right) { 5896 if (!n.deleted && n.countable) { 5897 if (index < n.length) { 5898 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5899 } 5900 index -= n.length; 5901 } 5902 } 5903 while (length2 > 0 && n !== null) { 5904 if (!n.deleted) { 5905 if (length2 < n.length) { 5906 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length2)); 5907 } 5908 n.delete(transaction); 5909 length2 -= n.length; 5910 } 5911 n = n.right; 5912 } 5913 if (length2 > 0) { 5914 throw lengthExceeded(); 5915 } 5916 if (parent._searchMarker) { 5917 updateMarkerChanges( 5918 parent._searchMarker, 5919 startIndex, 5920 -startLength + length2 5921 /* in case we remove the above exception */ 5922 ); 5923 } 5924 }; 5925 var typeMapDelete = (transaction, parent, key) => { 5926 const c = parent._map.get(key); 5927 if (c !== void 0) { 5928 c.delete(transaction); 5929 } 5930 }; 5931 var typeMapSet = (transaction, parent, key, value) => { 5932 const left = parent._map.get(key) || null; 5933 const doc2 = transaction.doc; 5934 const ownClientId = doc2.clientID; 5935 let content; 5936 if (value == null) { 5937 content = new ContentAny([value]); 5938 } else { 5939 switch (value.constructor) { 5940 case Number: 5941 case Object: 5942 case Boolean: 5943 case Array: 5944 case String: 5945 case Date: 5946 case BigInt: 5947 content = new ContentAny([value]); 5948 break; 5949 case Uint8Array: 5950 content = new ContentBinary( 5951 /** @type {Uint8Array} */ 5952 value 5953 ); 5954 break; 5955 case Doc: 5956 content = new ContentDoc( 5957 /** @type {Doc} */ 5958 value 5959 ); 5960 break; 5961 default: 5962 if (value instanceof AbstractType) { 5963 content = new ContentType(value); 5964 } else { 5965 throw new Error("Unexpected content type"); 5966 } 5967 } 5968 } 5969 new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); 5970 }; 5971 var typeMapGet = (parent, key) => { 5972 parent.doc ?? warnPrematureAccess(); 5973 const val = parent._map.get(key); 5974 return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; 5975 }; 5976 var typeMapGetAll = (parent) => { 5977 const res = {}; 5978 parent.doc ?? warnPrematureAccess(); 5979 parent._map.forEach((value, key) => { 5980 if (!value.deleted) { 5981 res[key] = value.content.getContent()[value.length - 1]; 5982 } 5983 }); 5984 return res; 5985 }; 5986 var typeMapHas = (parent, key) => { 5987 parent.doc ?? warnPrematureAccess(); 5988 const val = parent._map.get(key); 5989 return val !== void 0 && !val.deleted; 5990 }; 5991 var typeMapGetSnapshot = (parent, key, snapshot2) => { 5992 let v = parent._map.get(key) || null; 5993 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 5994 v = v.left; 5995 } 5996 return v !== null && isVisible(v, snapshot2) ? v.content.getContent()[v.length - 1] : void 0; 5997 }; 5998 var typeMapGetAllSnapshot = (parent, snapshot2) => { 5999 const res = {}; 6000 parent._map.forEach((value, key) => { 6001 let v = value; 6002 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 6003 v = v.left; 6004 } 6005 if (v !== null && isVisible(v, snapshot2)) { 6006 res[key] = v.content.getContent()[v.length - 1]; 6007 } 6008 }); 6009 return res; 6010 }; 6011 var createMapIterator = (type) => { 6012 type.doc ?? warnPrematureAccess(); 6013 return iteratorFilter( 6014 type._map.entries(), 6015 /** @param {any} entry */ 6016 (entry) => !entry[1].deleted 6017 ); 6018 }; 6019 var YArrayEvent = class extends YEvent { 6020 }; 6021 var YArray = class _YArray extends AbstractType { 6022 constructor() { 6023 super(); 6024 this._prelimContent = []; 6025 this._searchMarker = []; 6026 } 6027 /** 6028 * Construct a new YArray containing the specified items. 6029 * @template {Object<string,any>|Array<any>|number|null|string|Uint8Array} T 6030 * @param {Array<T>} items 6031 * @return {YArray<T>} 6032 */ 6033 static from(items) { 6034 const a = new _YArray(); 6035 a.push(items); 6036 return a; 6037 } 6038 /** 6039 * Integrate this type into the Yjs instance. 6040 * 6041 * * Save this struct in the os 6042 * * This type is sent to other client 6043 * * Observer functions are fired 6044 * 6045 * @param {Doc} y The Yjs instance 6046 * @param {Item} item 6047 */ 6048 _integrate(y, item) { 6049 super._integrate(y, item); 6050 this.insert( 6051 0, 6052 /** @type {Array<any>} */ 6053 this._prelimContent 6054 ); 6055 this._prelimContent = null; 6056 } 6057 /** 6058 * @return {YArray<T>} 6059 */ 6060 _copy() { 6061 return new _YArray(); 6062 } 6063 /** 6064 * Makes a copy of this data type that can be included somewhere else. 6065 * 6066 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6067 * 6068 * @return {YArray<T>} 6069 */ 6070 clone() { 6071 const arr = new _YArray(); 6072 arr.insert(0, this.toArray().map( 6073 (el) => el instanceof AbstractType ? ( 6074 /** @type {typeof el} */ 6075 el.clone() 6076 ) : el 6077 )); 6078 return arr; 6079 } 6080 get length() { 6081 this.doc ?? warnPrematureAccess(); 6082 return this._length; 6083 } 6084 /** 6085 * Creates YArrayEvent and calls observers. 6086 * 6087 * @param {Transaction} transaction 6088 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6089 */ 6090 _callObserver(transaction, parentSubs) { 6091 super._callObserver(transaction, parentSubs); 6092 callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); 6093 } 6094 /** 6095 * Inserts new content at an index. 6096 * 6097 * Important: This function expects an array of content. Not just a content 6098 * object. The reason for this "weirdness" is that inserting several elements 6099 * is very efficient when it is done as a single operation. 6100 * 6101 * @example 6102 * // Insert character 'a' at position 0 6103 * yarray.insert(0, ['a']) 6104 * // Insert numbers 1, 2 at position 1 6105 * yarray.insert(1, [1, 2]) 6106 * 6107 * @param {number} index The index to insert content at. 6108 * @param {Array<T>} content The array of content 6109 */ 6110 insert(index, content) { 6111 if (this.doc !== null) { 6112 transact(this.doc, (transaction) => { 6113 typeListInsertGenerics( 6114 transaction, 6115 this, 6116 index, 6117 /** @type {any} */ 6118 content 6119 ); 6120 }); 6121 } else { 6122 this._prelimContent.splice(index, 0, ...content); 6123 } 6124 } 6125 /** 6126 * Appends content to this YArray. 6127 * 6128 * @param {Array<T>} content Array of content to append. 6129 * 6130 * @todo Use the following implementation in all types. 6131 */ 6132 push(content) { 6133 if (this.doc !== null) { 6134 transact(this.doc, (transaction) => { 6135 typeListPushGenerics( 6136 transaction, 6137 this, 6138 /** @type {any} */ 6139 content 6140 ); 6141 }); 6142 } else { 6143 this._prelimContent.push(...content); 6144 } 6145 } 6146 /** 6147 * Prepends content to this YArray. 6148 * 6149 * @param {Array<T>} content Array of content to prepend. 6150 */ 6151 unshift(content) { 6152 this.insert(0, content); 6153 } 6154 /** 6155 * Deletes elements starting from an index. 6156 * 6157 * @param {number} index Index at which to start deleting elements 6158 * @param {number} length The number of elements to remove. Defaults to 1. 6159 */ 6160 delete(index, length2 = 1) { 6161 if (this.doc !== null) { 6162 transact(this.doc, (transaction) => { 6163 typeListDelete(transaction, this, index, length2); 6164 }); 6165 } else { 6166 this._prelimContent.splice(index, length2); 6167 } 6168 } 6169 /** 6170 * Returns the i-th element from a YArray. 6171 * 6172 * @param {number} index The index of the element to return from the YArray 6173 * @return {T} 6174 */ 6175 get(index) { 6176 return typeListGet(this, index); 6177 } 6178 /** 6179 * Transforms this YArray to a JavaScript Array. 6180 * 6181 * @return {Array<T>} 6182 */ 6183 toArray() { 6184 return typeListToArray(this); 6185 } 6186 /** 6187 * Returns a portion of this YArray into a JavaScript Array selected 6188 * from start to end (end not included). 6189 * 6190 * @param {number} [start] 6191 * @param {number} [end] 6192 * @return {Array<T>} 6193 */ 6194 slice(start = 0, end = this.length) { 6195 return typeListSlice(this, start, end); 6196 } 6197 /** 6198 * Transforms this Shared Type to a JSON object. 6199 * 6200 * @return {Array<any>} 6201 */ 6202 toJSON() { 6203 return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); 6204 } 6205 /** 6206 * Returns an Array with the result of calling a provided function on every 6207 * element of this YArray. 6208 * 6209 * @template M 6210 * @param {function(T,number,YArray<T>):M} f Function that produces an element of the new Array 6211 * @return {Array<M>} A new array with each element being the result of the 6212 * callback function 6213 */ 6214 map(f) { 6215 return typeListMap( 6216 this, 6217 /** @type {any} */ 6218 f 6219 ); 6220 } 6221 /** 6222 * Executes a provided function once on every element of this YArray. 6223 * 6224 * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray. 6225 */ 6226 forEach(f) { 6227 typeListForEach(this, f); 6228 } 6229 /** 6230 * @return {IterableIterator<T>} 6231 */ 6232 [Symbol.iterator]() { 6233 return typeListCreateIterator(this); 6234 } 6235 /** 6236 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6237 */ 6238 _write(encoder) { 6239 encoder.writeTypeRef(YArrayRefID); 6240 } 6241 }; 6242 var readYArray = (_decoder) => new YArray(); 6243 var YMapEvent = class extends YEvent { 6244 /** 6245 * @param {YMap<T>} ymap The YArray that changed. 6246 * @param {Transaction} transaction 6247 * @param {Set<any>} subs The keys that changed. 6248 */ 6249 constructor(ymap, transaction, subs) { 6250 super(ymap, transaction); 6251 this.keysChanged = subs; 6252 } 6253 }; 6254 var YMap = class _YMap extends AbstractType { 6255 /** 6256 * 6257 * @param {Iterable<readonly [string, any]>=} entries - an optional iterable to initialize the YMap 6258 */ 6259 constructor(entries) { 6260 super(); 6261 this._prelimContent = null; 6262 if (entries === void 0) { 6263 this._prelimContent = /* @__PURE__ */ new Map(); 6264 } else { 6265 this._prelimContent = new Map(entries); 6266 } 6267 } 6268 /** 6269 * Integrate this type into the Yjs instance. 6270 * 6271 * * Save this struct in the os 6272 * * This type is sent to other client 6273 * * Observer functions are fired 6274 * 6275 * @param {Doc} y The Yjs instance 6276 * @param {Item} item 6277 */ 6278 _integrate(y, item) { 6279 super._integrate(y, item); 6280 this._prelimContent.forEach((value, key) => { 6281 this.set(key, value); 6282 }); 6283 this._prelimContent = null; 6284 } 6285 /** 6286 * @return {YMap<MapType>} 6287 */ 6288 _copy() { 6289 return new _YMap(); 6290 } 6291 /** 6292 * Makes a copy of this data type that can be included somewhere else. 6293 * 6294 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6295 * 6296 * @return {YMap<MapType>} 6297 */ 6298 clone() { 6299 const map2 = new _YMap(); 6300 this.forEach((value, key) => { 6301 map2.set(key, value instanceof AbstractType ? ( 6302 /** @type {typeof value} */ 6303 value.clone() 6304 ) : value); 6305 }); 6306 return map2; 6307 } 6308 /** 6309 * Creates YMapEvent and calls observers. 6310 * 6311 * @param {Transaction} transaction 6312 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6313 */ 6314 _callObserver(transaction, parentSubs) { 6315 callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); 6316 } 6317 /** 6318 * Transforms this Shared Type to a JSON object. 6319 * 6320 * @return {Object<string,any>} 6321 */ 6322 toJSON() { 6323 this.doc ?? warnPrematureAccess(); 6324 const map2 = {}; 6325 this._map.forEach((item, key) => { 6326 if (!item.deleted) { 6327 const v = item.content.getContent()[item.length - 1]; 6328 map2[key] = v instanceof AbstractType ? v.toJSON() : v; 6329 } 6330 }); 6331 return map2; 6332 } 6333 /** 6334 * Returns the size of the YMap (count of key/value pairs) 6335 * 6336 * @return {number} 6337 */ 6338 get size() { 6339 return [...createMapIterator(this)].length; 6340 } 6341 /** 6342 * Returns the keys for each element in the YMap Type. 6343 * 6344 * @return {IterableIterator<string>} 6345 */ 6346 keys() { 6347 return iteratorMap( 6348 createMapIterator(this), 6349 /** @param {any} v */ 6350 (v) => v[0] 6351 ); 6352 } 6353 /** 6354 * Returns the values for each element in the YMap Type. 6355 * 6356 * @return {IterableIterator<MapType>} 6357 */ 6358 values() { 6359 return iteratorMap( 6360 createMapIterator(this), 6361 /** @param {any} v */ 6362 (v) => v[1].content.getContent()[v[1].length - 1] 6363 ); 6364 } 6365 /** 6366 * Returns an Iterator of [key, value] pairs 6367 * 6368 * @return {IterableIterator<[string, MapType]>} 6369 */ 6370 entries() { 6371 return iteratorMap( 6372 createMapIterator(this), 6373 /** @param {any} v */ 6374 (v) => ( 6375 /** @type {any} */ 6376 [v[0], v[1].content.getContent()[v[1].length - 1]] 6377 ) 6378 ); 6379 } 6380 /** 6381 * Executes a provided function on once on every key-value pair. 6382 * 6383 * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray. 6384 */ 6385 forEach(f) { 6386 this.doc ?? warnPrematureAccess(); 6387 this._map.forEach((item, key) => { 6388 if (!item.deleted) { 6389 f(item.content.getContent()[item.length - 1], key, this); 6390 } 6391 }); 6392 } 6393 /** 6394 * Returns an Iterator of [key, value] pairs 6395 * 6396 * @return {IterableIterator<[string, MapType]>} 6397 */ 6398 [Symbol.iterator]() { 6399 return this.entries(); 6400 } 6401 /** 6402 * Remove a specified element from this YMap. 6403 * 6404 * @param {string} key The key of the element to remove. 6405 */ 6406 delete(key) { 6407 if (this.doc !== null) { 6408 transact(this.doc, (transaction) => { 6409 typeMapDelete(transaction, this, key); 6410 }); 6411 } else { 6412 this._prelimContent.delete(key); 6413 } 6414 } 6415 /** 6416 * Adds or updates an element with a specified key and value. 6417 * @template {MapType} VAL 6418 * 6419 * @param {string} key The key of the element to add to this YMap 6420 * @param {VAL} value The value of the element to add 6421 * @return {VAL} 6422 */ 6423 set(key, value) { 6424 if (this.doc !== null) { 6425 transact(this.doc, (transaction) => { 6426 typeMapSet( 6427 transaction, 6428 this, 6429 key, 6430 /** @type {any} */ 6431 value 6432 ); 6433 }); 6434 } else { 6435 this._prelimContent.set(key, value); 6436 } 6437 return value; 6438 } 6439 /** 6440 * Returns a specified element from this YMap. 6441 * 6442 * @param {string} key 6443 * @return {MapType|undefined} 6444 */ 6445 get(key) { 6446 return ( 6447 /** @type {any} */ 6448 typeMapGet(this, key) 6449 ); 6450 } 6451 /** 6452 * Returns a boolean indicating whether the specified key exists or not. 6453 * 6454 * @param {string} key The key to test. 6455 * @return {boolean} 6456 */ 6457 has(key) { 6458 return typeMapHas(this, key); 6459 } 6460 /** 6461 * Removes all elements from this YMap. 6462 */ 6463 clear() { 6464 if (this.doc !== null) { 6465 transact(this.doc, (transaction) => { 6466 this.forEach(function(_value, key, map2) { 6467 typeMapDelete(transaction, map2, key); 6468 }); 6469 }); 6470 } else { 6471 this._prelimContent.clear(); 6472 } 6473 } 6474 /** 6475 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6476 */ 6477 _write(encoder) { 6478 encoder.writeTypeRef(YMapRefID); 6479 } 6480 }; 6481 var readYMap = (_decoder) => new YMap(); 6482 var equalAttrs = (a, b) => a === b || typeof a === "object" && typeof b === "object" && a && b && equalFlat(a, b); 6483 var ItemTextListPosition = class { 6484 /** 6485 * @param {Item|null} left 6486 * @param {Item|null} right 6487 * @param {number} index 6488 * @param {Map<string,any>} currentAttributes 6489 */ 6490 constructor(left, right, index, currentAttributes) { 6491 this.left = left; 6492 this.right = right; 6493 this.index = index; 6494 this.currentAttributes = currentAttributes; 6495 } 6496 /** 6497 * Only call this if you know that this.right is defined 6498 */ 6499 forward() { 6500 if (this.right === null) { 6501 unexpectedCase(); 6502 } 6503 switch (this.right.content.constructor) { 6504 case ContentFormat: 6505 if (!this.right.deleted) { 6506 updateCurrentAttributes( 6507 this.currentAttributes, 6508 /** @type {ContentFormat} */ 6509 this.right.content 6510 ); 6511 } 6512 break; 6513 default: 6514 if (!this.right.deleted) { 6515 this.index += this.right.length; 6516 } 6517 break; 6518 } 6519 this.left = this.right; 6520 this.right = this.right.right; 6521 } 6522 }; 6523 var findNextPosition = (transaction, pos, count) => { 6524 while (pos.right !== null && count > 0) { 6525 switch (pos.right.content.constructor) { 6526 case ContentFormat: 6527 if (!pos.right.deleted) { 6528 updateCurrentAttributes( 6529 pos.currentAttributes, 6530 /** @type {ContentFormat} */ 6531 pos.right.content 6532 ); 6533 } 6534 break; 6535 default: 6536 if (!pos.right.deleted) { 6537 if (count < pos.right.length) { 6538 getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); 6539 } 6540 pos.index += pos.right.length; 6541 count -= pos.right.length; 6542 } 6543 break; 6544 } 6545 pos.left = pos.right; 6546 pos.right = pos.right.right; 6547 } 6548 return pos; 6549 }; 6550 var findPosition = (transaction, parent, index, useSearchMarker) => { 6551 const currentAttributes = /* @__PURE__ */ new Map(); 6552 const marker = useSearchMarker ? findMarker(parent, index) : null; 6553 if (marker) { 6554 const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); 6555 return findNextPosition(transaction, pos, index - marker.index); 6556 } else { 6557 const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); 6558 return findNextPosition(transaction, pos, index); 6559 } 6560 }; 6561 var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { 6562 while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( 6563 negatedAttributes.get( 6564 /** @type {ContentFormat} */ 6565 currPos.right.content.key 6566 ), 6567 /** @type {ContentFormat} */ 6568 currPos.right.content.value 6569 ))) { 6570 if (!currPos.right.deleted) { 6571 negatedAttributes.delete( 6572 /** @type {ContentFormat} */ 6573 currPos.right.content.key 6574 ); 6575 } 6576 currPos.forward(); 6577 } 6578 const doc2 = transaction.doc; 6579 const ownClientId = doc2.clientID; 6580 negatedAttributes.forEach((val, key) => { 6581 const left = currPos.left; 6582 const right = currPos.right; 6583 const nextFormat = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 6584 nextFormat.integrate(transaction, 0); 6585 currPos.right = nextFormat; 6586 currPos.forward(); 6587 }); 6588 }; 6589 var updateCurrentAttributes = (currentAttributes, format) => { 6590 const { key, value } = format; 6591 if (value === null) { 6592 currentAttributes.delete(key); 6593 } else { 6594 currentAttributes.set(key, value); 6595 } 6596 }; 6597 var minimizeAttributeChanges = (currPos, attributes) => { 6598 while (true) { 6599 if (currPos.right === null) { 6600 break; 6601 } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( 6602 attributes[ 6603 /** @type {ContentFormat} */ 6604 currPos.right.content.key 6605 ] ?? null, 6606 /** @type {ContentFormat} */ 6607 currPos.right.content.value 6608 )) ; 6609 else { 6610 break; 6611 } 6612 currPos.forward(); 6613 } 6614 }; 6615 var insertAttributes = (transaction, parent, currPos, attributes) => { 6616 const doc2 = transaction.doc; 6617 const ownClientId = doc2.clientID; 6618 const negatedAttributes = /* @__PURE__ */ new Map(); 6619 for (const key in attributes) { 6620 const val = attributes[key]; 6621 const currentVal = currPos.currentAttributes.get(key) ?? null; 6622 if (!equalAttrs(currentVal, val)) { 6623 negatedAttributes.set(key, currentVal); 6624 const { left, right } = currPos; 6625 currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 6626 currPos.right.integrate(transaction, 0); 6627 currPos.forward(); 6628 } 6629 } 6630 return negatedAttributes; 6631 }; 6632 var insertText = (transaction, parent, currPos, text2, attributes) => { 6633 currPos.currentAttributes.forEach((_val, key) => { 6634 if (attributes[key] === void 0) { 6635 attributes[key] = null; 6636 } 6637 }); 6638 const doc2 = transaction.doc; 6639 const ownClientId = doc2.clientID; 6640 minimizeAttributeChanges(currPos, attributes); 6641 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 6642 const content = text2.constructor === String ? new ContentString( 6643 /** @type {string} */ 6644 text2 6645 ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); 6646 let { left, right, index } = currPos; 6647 if (parent._searchMarker) { 6648 updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); 6649 } 6650 right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); 6651 right.integrate(transaction, 0); 6652 currPos.right = right; 6653 currPos.index = index; 6654 currPos.forward(); 6655 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 6656 }; 6657 var formatText = (transaction, parent, currPos, length2, attributes) => { 6658 const doc2 = transaction.doc; 6659 const ownClientId = doc2.clientID; 6660 minimizeAttributeChanges(currPos, attributes); 6661 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 6662 iterationLoop: while (currPos.right !== null && (length2 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { 6663 if (!currPos.right.deleted) { 6664 switch (currPos.right.content.constructor) { 6665 case ContentFormat: { 6666 const { key, value } = ( 6667 /** @type {ContentFormat} */ 6668 currPos.right.content 6669 ); 6670 const attr = attributes[key]; 6671 if (attr !== void 0) { 6672 if (equalAttrs(attr, value)) { 6673 negatedAttributes.delete(key); 6674 } else { 6675 if (length2 === 0) { 6676 break iterationLoop; 6677 } 6678 negatedAttributes.set(key, value); 6679 } 6680 currPos.right.delete(transaction); 6681 } else { 6682 currPos.currentAttributes.set(key, value); 6683 } 6684 break; 6685 } 6686 default: 6687 if (length2 < currPos.right.length) { 6688 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); 6689 } 6690 length2 -= currPos.right.length; 6691 break; 6692 } 6693 } 6694 currPos.forward(); 6695 } 6696 if (length2 > 0) { 6697 let newlines = ""; 6698 for (; length2 > 0; length2--) { 6699 newlines += "\n"; 6700 } 6701 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)); 6702 currPos.right.integrate(transaction, 0); 6703 currPos.forward(); 6704 } 6705 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 6706 }; 6707 var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { 6708 let end = start; 6709 const endFormats = create(); 6710 while (end && (!end.countable || end.deleted)) { 6711 if (!end.deleted && end.content.constructor === ContentFormat) { 6712 const cf = ( 6713 /** @type {ContentFormat} */ 6714 end.content 6715 ); 6716 endFormats.set(cf.key, cf); 6717 } 6718 end = end.right; 6719 } 6720 let cleanups = 0; 6721 let reachedCurr = false; 6722 while (start !== end) { 6723 if (curr === start) { 6724 reachedCurr = true; 6725 } 6726 if (!start.deleted) { 6727 const content = start.content; 6728 switch (content.constructor) { 6729 case ContentFormat: { 6730 const { key, value } = ( 6731 /** @type {ContentFormat} */ 6732 content 6733 ); 6734 const startAttrValue = startAttributes.get(key) ?? null; 6735 if (endFormats.get(key) !== content || startAttrValue === value) { 6736 start.delete(transaction); 6737 cleanups++; 6738 if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { 6739 if (startAttrValue === null) { 6740 currAttributes.delete(key); 6741 } else { 6742 currAttributes.set(key, startAttrValue); 6743 } 6744 } 6745 } 6746 if (!reachedCurr && !start.deleted) { 6747 updateCurrentAttributes( 6748 currAttributes, 6749 /** @type {ContentFormat} */ 6750 content 6751 ); 6752 } 6753 break; 6754 } 6755 } 6756 } 6757 start = /** @type {Item} */ 6758 start.right; 6759 } 6760 return cleanups; 6761 }; 6762 var cleanupContextlessFormattingGap = (transaction, item) => { 6763 while (item && item.right && (item.right.deleted || !item.right.countable)) { 6764 item = item.right; 6765 } 6766 const attrs = /* @__PURE__ */ new Set(); 6767 while (item && (item.deleted || !item.countable)) { 6768 if (!item.deleted && item.content.constructor === ContentFormat) { 6769 const key = ( 6770 /** @type {ContentFormat} */ 6771 item.content.key 6772 ); 6773 if (attrs.has(key)) { 6774 item.delete(transaction); 6775 } else { 6776 attrs.add(key); 6777 } 6778 } 6779 item = item.left; 6780 } 6781 }; 6782 var cleanupYTextFormatting = (type) => { 6783 let res = 0; 6784 transact( 6785 /** @type {Doc} */ 6786 type.doc, 6787 (transaction) => { 6788 let start = ( 6789 /** @type {Item} */ 6790 type._start 6791 ); 6792 let end = type._start; 6793 let startAttributes = create(); 6794 const currentAttributes = copy(startAttributes); 6795 while (end) { 6796 if (end.deleted === false) { 6797 switch (end.content.constructor) { 6798 case ContentFormat: 6799 updateCurrentAttributes( 6800 currentAttributes, 6801 /** @type {ContentFormat} */ 6802 end.content 6803 ); 6804 break; 6805 default: 6806 res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); 6807 startAttributes = copy(currentAttributes); 6808 start = end; 6809 break; 6810 } 6811 } 6812 end = end.right; 6813 } 6814 } 6815 ); 6816 return res; 6817 }; 6818 var cleanupYTextAfterTransaction = (transaction) => { 6819 const needFullCleanup = /* @__PURE__ */ new Set(); 6820 const doc2 = transaction.doc; 6821 for (const [client, afterClock] of transaction.afterState.entries()) { 6822 const clock = transaction.beforeState.get(client) || 0; 6823 if (afterClock === clock) { 6824 continue; 6825 } 6826 iterateStructs( 6827 transaction, 6828 /** @type {Array<Item|GC>} */ 6829 doc2.store.clients.get(client), 6830 clock, 6831 afterClock, 6832 (item) => { 6833 if (!item.deleted && /** @type {Item} */ 6834 item.content.constructor === ContentFormat && item.constructor !== GC) { 6835 needFullCleanup.add( 6836 /** @type {any} */ 6837 item.parent 6838 ); 6839 } 6840 } 6841 ); 6842 } 6843 transact(doc2, (t) => { 6844 iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { 6845 if (item instanceof GC || !/** @type {YText} */ 6846 item.parent._hasFormatting || needFullCleanup.has( 6847 /** @type {YText} */ 6848 item.parent 6849 )) { 6850 return; 6851 } 6852 const parent = ( 6853 /** @type {YText} */ 6854 item.parent 6855 ); 6856 if (item.content.constructor === ContentFormat) { 6857 needFullCleanup.add(parent); 6858 } else { 6859 cleanupContextlessFormattingGap(t, item); 6860 } 6861 }); 6862 for (const yText of needFullCleanup) { 6863 cleanupYTextFormatting(yText); 6864 } 6865 }); 6866 }; 6867 var deleteText = (transaction, currPos, length2) => { 6868 const startLength = length2; 6869 const startAttrs = copy(currPos.currentAttributes); 6870 const start = currPos.right; 6871 while (length2 > 0 && currPos.right !== null) { 6872 if (currPos.right.deleted === false) { 6873 switch (currPos.right.content.constructor) { 6874 case ContentType: 6875 case ContentEmbed: 6876 case ContentString: 6877 if (length2 < currPos.right.length) { 6878 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); 6879 } 6880 length2 -= currPos.right.length; 6881 currPos.right.delete(transaction); 6882 break; 6883 } 6884 } 6885 currPos.forward(); 6886 } 6887 if (start) { 6888 cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); 6889 } 6890 const parent = ( 6891 /** @type {AbstractType<any>} */ 6892 /** @type {Item} */ 6893 (currPos.left || currPos.right).parent 6894 ); 6895 if (parent._searchMarker) { 6896 updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length2); 6897 } 6898 return currPos; 6899 }; 6900 var YTextEvent = class extends YEvent { 6901 /** 6902 * @param {YText} ytext 6903 * @param {Transaction} transaction 6904 * @param {Set<any>} subs The keys that changed 6905 */ 6906 constructor(ytext, transaction, subs) { 6907 super(ytext, transaction); 6908 this.childListChanged = false; 6909 this.keysChanged = /* @__PURE__ */ new Set(); 6910 subs.forEach((sub) => { 6911 if (sub === null) { 6912 this.childListChanged = true; 6913 } else { 6914 this.keysChanged.add(sub); 6915 } 6916 }); 6917 } 6918 /** 6919 * @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}>}} 6920 */ 6921 get changes() { 6922 if (this._changes === null) { 6923 const changes = { 6924 keys: this.keys, 6925 delta: this.delta, 6926 added: /* @__PURE__ */ new Set(), 6927 deleted: /* @__PURE__ */ new Set() 6928 }; 6929 this._changes = changes; 6930 } 6931 return ( 6932 /** @type {any} */ 6933 this._changes 6934 ); 6935 } 6936 /** 6937 * Compute the changes in the delta format. 6938 * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. 6939 * 6940 * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>} 6941 * 6942 * @public 6943 */ 6944 get delta() { 6945 if (this._delta === null) { 6946 const y = ( 6947 /** @type {Doc} */ 6948 this.target.doc 6949 ); 6950 const delta = []; 6951 transact(y, (transaction) => { 6952 const currentAttributes = /* @__PURE__ */ new Map(); 6953 const oldAttributes = /* @__PURE__ */ new Map(); 6954 let item = this.target._start; 6955 let action = null; 6956 const attributes = {}; 6957 let insert = ""; 6958 let retain = 0; 6959 let deleteLen = 0; 6960 const addOp = () => { 6961 if (action !== null) { 6962 let op = null; 6963 switch (action) { 6964 case "delete": 6965 if (deleteLen > 0) { 6966 op = { delete: deleteLen }; 6967 } 6968 deleteLen = 0; 6969 break; 6970 case "insert": 6971 if (typeof insert === "object" || insert.length > 0) { 6972 op = { insert }; 6973 if (currentAttributes.size > 0) { 6974 op.attributes = {}; 6975 currentAttributes.forEach((value, key) => { 6976 if (value !== null) { 6977 op.attributes[key] = value; 6978 } 6979 }); 6980 } 6981 } 6982 insert = ""; 6983 break; 6984 case "retain": 6985 if (retain > 0) { 6986 op = { retain }; 6987 if (!isEmpty(attributes)) { 6988 op.attributes = assign({}, attributes); 6989 } 6990 } 6991 retain = 0; 6992 break; 6993 } 6994 if (op) delta.push(op); 6995 action = null; 6996 } 6997 }; 6998 while (item !== null) { 6999 switch (item.content.constructor) { 7000 case ContentType: 7001 case ContentEmbed: 7002 if (this.adds(item)) { 7003 if (!this.deletes(item)) { 7004 addOp(); 7005 action = "insert"; 7006 insert = item.content.getContent()[0]; 7007 addOp(); 7008 } 7009 } else if (this.deletes(item)) { 7010 if (action !== "delete") { 7011 addOp(); 7012 action = "delete"; 7013 } 7014 deleteLen += 1; 7015 } else if (!item.deleted) { 7016 if (action !== "retain") { 7017 addOp(); 7018 action = "retain"; 7019 } 7020 retain += 1; 7021 } 7022 break; 7023 case ContentString: 7024 if (this.adds(item)) { 7025 if (!this.deletes(item)) { 7026 if (action !== "insert") { 7027 addOp(); 7028 action = "insert"; 7029 } 7030 insert += /** @type {ContentString} */ 7031 item.content.str; 7032 } 7033 } else if (this.deletes(item)) { 7034 if (action !== "delete") { 7035 addOp(); 7036 action = "delete"; 7037 } 7038 deleteLen += item.length; 7039 } else if (!item.deleted) { 7040 if (action !== "retain") { 7041 addOp(); 7042 action = "retain"; 7043 } 7044 retain += item.length; 7045 } 7046 break; 7047 case ContentFormat: { 7048 const { key, value } = ( 7049 /** @type {ContentFormat} */ 7050 item.content 7051 ); 7052 if (this.adds(item)) { 7053 if (!this.deletes(item)) { 7054 const curVal = currentAttributes.get(key) ?? null; 7055 if (!equalAttrs(curVal, value)) { 7056 if (action === "retain") { 7057 addOp(); 7058 } 7059 if (equalAttrs(value, oldAttributes.get(key) ?? null)) { 7060 delete attributes[key]; 7061 } else { 7062 attributes[key] = value; 7063 } 7064 } else if (value !== null) { 7065 item.delete(transaction); 7066 } 7067 } 7068 } else if (this.deletes(item)) { 7069 oldAttributes.set(key, value); 7070 const curVal = currentAttributes.get(key) ?? null; 7071 if (!equalAttrs(curVal, value)) { 7072 if (action === "retain") { 7073 addOp(); 7074 } 7075 attributes[key] = curVal; 7076 } 7077 } else if (!item.deleted) { 7078 oldAttributes.set(key, value); 7079 const attr = attributes[key]; 7080 if (attr !== void 0) { 7081 if (!equalAttrs(attr, value)) { 7082 if (action === "retain") { 7083 addOp(); 7084 } 7085 if (value === null) { 7086 delete attributes[key]; 7087 } else { 7088 attributes[key] = value; 7089 } 7090 } else if (attr !== null) { 7091 item.delete(transaction); 7092 } 7093 } 7094 } 7095 if (!item.deleted) { 7096 if (action === "insert") { 7097 addOp(); 7098 } 7099 updateCurrentAttributes( 7100 currentAttributes, 7101 /** @type {ContentFormat} */ 7102 item.content 7103 ); 7104 } 7105 break; 7106 } 7107 } 7108 item = item.right; 7109 } 7110 addOp(); 7111 while (delta.length > 0) { 7112 const lastOp = delta[delta.length - 1]; 7113 if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { 7114 delta.pop(); 7115 } else { 7116 break; 7117 } 7118 } 7119 }); 7120 this._delta = delta; 7121 } 7122 return ( 7123 /** @type {any} */ 7124 this._delta 7125 ); 7126 } 7127 }; 7128 var YText = class _YText extends AbstractType { 7129 /** 7130 * @param {String} [string] The initial value of the YText. 7131 */ 7132 constructor(string) { 7133 super(); 7134 this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; 7135 this._searchMarker = []; 7136 this._hasFormatting = false; 7137 } 7138 /** 7139 * Number of characters of this text type. 7140 * 7141 * @type {number} 7142 */ 7143 get length() { 7144 this.doc ?? warnPrematureAccess(); 7145 return this._length; 7146 } 7147 /** 7148 * @param {Doc} y 7149 * @param {Item} item 7150 */ 7151 _integrate(y, item) { 7152 super._integrate(y, item); 7153 try { 7154 this._pending.forEach((f) => f()); 7155 } catch (e) { 7156 console.error(e); 7157 } 7158 this._pending = null; 7159 } 7160 _copy() { 7161 return new _YText(); 7162 } 7163 /** 7164 * Makes a copy of this data type that can be included somewhere else. 7165 * 7166 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7167 * 7168 * @return {YText} 7169 */ 7170 clone() { 7171 const text2 = new _YText(); 7172 text2.applyDelta(this.toDelta()); 7173 return text2; 7174 } 7175 /** 7176 * Creates YTextEvent and calls observers. 7177 * 7178 * @param {Transaction} transaction 7179 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7180 */ 7181 _callObserver(transaction, parentSubs) { 7182 super._callObserver(transaction, parentSubs); 7183 const event = new YTextEvent(this, transaction, parentSubs); 7184 callTypeObservers(this, transaction, event); 7185 if (!transaction.local && this._hasFormatting) { 7186 transaction._needFormattingCleanup = true; 7187 } 7188 } 7189 /** 7190 * Returns the unformatted string representation of this YText type. 7191 * 7192 * @public 7193 */ 7194 toString() { 7195 this.doc ?? warnPrematureAccess(); 7196 let str = ""; 7197 let n = this._start; 7198 while (n !== null) { 7199 if (!n.deleted && n.countable && n.content.constructor === ContentString) { 7200 str += /** @type {ContentString} */ 7201 n.content.str; 7202 } 7203 n = n.right; 7204 } 7205 return str; 7206 } 7207 /** 7208 * Returns the unformatted string representation of this YText type. 7209 * 7210 * @return {string} 7211 * @public 7212 */ 7213 toJSON() { 7214 return this.toString(); 7215 } 7216 /** 7217 * Apply a {@link Delta} on this shared YText type. 7218 * 7219 * @param {Array<any>} delta The changes to apply on this element. 7220 * @param {object} opts 7221 * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. 7222 * 7223 * 7224 * @public 7225 */ 7226 applyDelta(delta, { sanitize = true } = {}) { 7227 if (this.doc !== null) { 7228 transact(this.doc, (transaction) => { 7229 const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); 7230 for (let i = 0; i < delta.length; i++) { 7231 const op = delta[i]; 7232 if (op.insert !== void 0) { 7233 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; 7234 if (typeof ins !== "string" || ins.length > 0) { 7235 insertText(transaction, this, currPos, ins, op.attributes || {}); 7236 } 7237 } else if (op.retain !== void 0) { 7238 formatText(transaction, this, currPos, op.retain, op.attributes || {}); 7239 } else if (op.delete !== void 0) { 7240 deleteText(transaction, currPos, op.delete); 7241 } 7242 } 7243 }); 7244 } else { 7245 this._pending.push(() => this.applyDelta(delta)); 7246 } 7247 } 7248 /** 7249 * Returns the Delta representation of this YText type. 7250 * 7251 * @param {Snapshot} [snapshot] 7252 * @param {Snapshot} [prevSnapshot] 7253 * @param {function('removed' | 'added', ID):any} [computeYChange] 7254 * @return {any} The Delta representation of this type. 7255 * 7256 * @public 7257 */ 7258 toDelta(snapshot2, prevSnapshot, computeYChange) { 7259 this.doc ?? warnPrematureAccess(); 7260 const ops = []; 7261 const currentAttributes = /* @__PURE__ */ new Map(); 7262 const doc2 = ( 7263 /** @type {Doc} */ 7264 this.doc 7265 ); 7266 let str = ""; 7267 let n = this._start; 7268 function packStr() { 7269 if (str.length > 0) { 7270 const attributes = {}; 7271 let addAttributes = false; 7272 currentAttributes.forEach((value, key) => { 7273 addAttributes = true; 7274 attributes[key] = value; 7275 }); 7276 const op = { insert: str }; 7277 if (addAttributes) { 7278 op.attributes = attributes; 7279 } 7280 ops.push(op); 7281 str = ""; 7282 } 7283 } 7284 const computeDelta = () => { 7285 while (n !== null) { 7286 if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { 7287 switch (n.content.constructor) { 7288 case ContentString: { 7289 const cur = currentAttributes.get("ychange"); 7290 if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { 7291 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { 7292 packStr(); 7293 currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); 7294 } 7295 } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { 7296 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { 7297 packStr(); 7298 currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); 7299 } 7300 } else if (cur !== void 0) { 7301 packStr(); 7302 currentAttributes.delete("ychange"); 7303 } 7304 str += /** @type {ContentString} */ 7305 n.content.str; 7306 break; 7307 } 7308 case ContentType: 7309 case ContentEmbed: { 7310 packStr(); 7311 const op = { 7312 insert: n.content.getContent()[0] 7313 }; 7314 if (currentAttributes.size > 0) { 7315 const attrs = ( 7316 /** @type {Object<string,any>} */ 7317 {} 7318 ); 7319 op.attributes = attrs; 7320 currentAttributes.forEach((value, key) => { 7321 attrs[key] = value; 7322 }); 7323 } 7324 ops.push(op); 7325 break; 7326 } 7327 case ContentFormat: 7328 if (isVisible(n, snapshot2)) { 7329 packStr(); 7330 updateCurrentAttributes( 7331 currentAttributes, 7332 /** @type {ContentFormat} */ 7333 n.content 7334 ); 7335 } 7336 break; 7337 } 7338 } 7339 n = n.right; 7340 } 7341 packStr(); 7342 }; 7343 if (snapshot2 || prevSnapshot) { 7344 transact(doc2, (transaction) => { 7345 if (snapshot2) { 7346 splitSnapshotAffectedStructs(transaction, snapshot2); 7347 } 7348 if (prevSnapshot) { 7349 splitSnapshotAffectedStructs(transaction, prevSnapshot); 7350 } 7351 computeDelta(); 7352 }, "cleanup"); 7353 } else { 7354 computeDelta(); 7355 } 7356 return ops; 7357 } 7358 /** 7359 * Insert text at a given index. 7360 * 7361 * @param {number} index The index at which to start inserting. 7362 * @param {String} text The text to insert at the specified position. 7363 * @param {TextAttributes} [attributes] Optionally define some formatting 7364 * information to apply on the inserted 7365 * Text. 7366 * @public 7367 */ 7368 insert(index, text2, attributes) { 7369 if (text2.length <= 0) { 7370 return; 7371 } 7372 const y = this.doc; 7373 if (y !== null) { 7374 transact(y, (transaction) => { 7375 const pos = findPosition(transaction, this, index, !attributes); 7376 if (!attributes) { 7377 attributes = {}; 7378 pos.currentAttributes.forEach((v, k) => { 7379 attributes[k] = v; 7380 }); 7381 } 7382 insertText(transaction, this, pos, text2, attributes); 7383 }); 7384 } else { 7385 this._pending.push(() => this.insert(index, text2, attributes)); 7386 } 7387 } 7388 /** 7389 * Inserts an embed at a index. 7390 * 7391 * @param {number} index The index to insert the embed at. 7392 * @param {Object | AbstractType<any>} embed The Object that represents the embed. 7393 * @param {TextAttributes} [attributes] Attribute information to apply on the 7394 * embed 7395 * 7396 * @public 7397 */ 7398 insertEmbed(index, embed, attributes) { 7399 const y = this.doc; 7400 if (y !== null) { 7401 transact(y, (transaction) => { 7402 const pos = findPosition(transaction, this, index, !attributes); 7403 insertText(transaction, this, pos, embed, attributes || {}); 7404 }); 7405 } else { 7406 this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); 7407 } 7408 } 7409 /** 7410 * Deletes text starting from an index. 7411 * 7412 * @param {number} index Index at which to start deleting. 7413 * @param {number} length The number of characters to remove. Defaults to 1. 7414 * 7415 * @public 7416 */ 7417 delete(index, length2) { 7418 if (length2 === 0) { 7419 return; 7420 } 7421 const y = this.doc; 7422 if (y !== null) { 7423 transact(y, (transaction) => { 7424 deleteText(transaction, findPosition(transaction, this, index, true), length2); 7425 }); 7426 } else { 7427 this._pending.push(() => this.delete(index, length2)); 7428 } 7429 } 7430 /** 7431 * Assigns properties to a range of text. 7432 * 7433 * @param {number} index The position where to start formatting. 7434 * @param {number} length The amount of characters to assign properties to. 7435 * @param {TextAttributes} attributes Attribute information to apply on the 7436 * text. 7437 * 7438 * @public 7439 */ 7440 format(index, length2, attributes) { 7441 if (length2 === 0) { 7442 return; 7443 } 7444 const y = this.doc; 7445 if (y !== null) { 7446 transact(y, (transaction) => { 7447 const pos = findPosition(transaction, this, index, false); 7448 if (pos.right === null) { 7449 return; 7450 } 7451 formatText(transaction, this, pos, length2, attributes); 7452 }); 7453 } else { 7454 this._pending.push(() => this.format(index, length2, attributes)); 7455 } 7456 } 7457 /** 7458 * Removes an attribute. 7459 * 7460 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7461 * 7462 * @param {String} attributeName The attribute name that is to be removed. 7463 * 7464 * @public 7465 */ 7466 removeAttribute(attributeName) { 7467 if (this.doc !== null) { 7468 transact(this.doc, (transaction) => { 7469 typeMapDelete(transaction, this, attributeName); 7470 }); 7471 } else { 7472 this._pending.push(() => this.removeAttribute(attributeName)); 7473 } 7474 } 7475 /** 7476 * Sets or updates an attribute. 7477 * 7478 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7479 * 7480 * @param {String} attributeName The attribute name that is to be set. 7481 * @param {any} attributeValue The attribute value that is to be set. 7482 * 7483 * @public 7484 */ 7485 setAttribute(attributeName, attributeValue) { 7486 if (this.doc !== null) { 7487 transact(this.doc, (transaction) => { 7488 typeMapSet(transaction, this, attributeName, attributeValue); 7489 }); 7490 } else { 7491 this._pending.push(() => this.setAttribute(attributeName, attributeValue)); 7492 } 7493 } 7494 /** 7495 * Returns an attribute value that belongs to the attribute name. 7496 * 7497 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7498 * 7499 * @param {String} attributeName The attribute name that identifies the 7500 * queried value. 7501 * @return {any} The queried attribute value. 7502 * 7503 * @public 7504 */ 7505 getAttribute(attributeName) { 7506 return ( 7507 /** @type {any} */ 7508 typeMapGet(this, attributeName) 7509 ); 7510 } 7511 /** 7512 * Returns all attribute name/value pairs in a JSON Object. 7513 * 7514 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7515 * 7516 * @return {Object<string, any>} A JSON Object that describes the attributes. 7517 * 7518 * @public 7519 */ 7520 getAttributes() { 7521 return typeMapGetAll(this); 7522 } 7523 /** 7524 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7525 */ 7526 _write(encoder) { 7527 encoder.writeTypeRef(YTextRefID); 7528 } 7529 }; 7530 var readYText = (_decoder) => new YText(); 7531 var YXmlTreeWalker = class { 7532 /** 7533 * @param {YXmlFragment | YXmlElement} root 7534 * @param {function(AbstractType<any>):boolean} [f] 7535 */ 7536 constructor(root, f = () => true) { 7537 this._filter = f; 7538 this._root = root; 7539 this._currentNode = /** @type {Item} */ 7540 root._start; 7541 this._firstCall = true; 7542 root.doc ?? warnPrematureAccess(); 7543 } 7544 [Symbol.iterator]() { 7545 return this; 7546 } 7547 /** 7548 * Get the next node. 7549 * 7550 * @return {IteratorResult<YXmlElement|YXmlText|YXmlHook>} The next node. 7551 * 7552 * @public 7553 */ 7554 next() { 7555 let n = this._currentNode; 7556 let type = n && n.content && /** @type {any} */ 7557 n.content.type; 7558 if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { 7559 do { 7560 type = /** @type {any} */ 7561 n.content.type; 7562 if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { 7563 n = type._start; 7564 } else { 7565 while (n !== null) { 7566 const nxt = n.next; 7567 if (nxt !== null) { 7568 n = nxt; 7569 break; 7570 } else if (n.parent === this._root) { 7571 n = null; 7572 } else { 7573 n = /** @type {AbstractType<any>} */ 7574 n.parent._item; 7575 } 7576 } 7577 } 7578 } while (n !== null && (n.deleted || !this._filter( 7579 /** @type {ContentType} */ 7580 n.content.type 7581 ))); 7582 } 7583 this._firstCall = false; 7584 if (n === null) { 7585 return { value: void 0, done: true }; 7586 } 7587 this._currentNode = n; 7588 return { value: ( 7589 /** @type {any} */ 7590 n.content.type 7591 ), done: false }; 7592 } 7593 }; 7594 var YXmlFragment = class _YXmlFragment extends AbstractType { 7595 constructor() { 7596 super(); 7597 this._prelimContent = []; 7598 } 7599 /** 7600 * @type {YXmlElement|YXmlText|null} 7601 */ 7602 get firstChild() { 7603 const first = this._first; 7604 return first ? first.content.getContent()[0] : null; 7605 } 7606 /** 7607 * Integrate this type into the Yjs instance. 7608 * 7609 * * Save this struct in the os 7610 * * This type is sent to other client 7611 * * Observer functions are fired 7612 * 7613 * @param {Doc} y The Yjs instance 7614 * @param {Item} item 7615 */ 7616 _integrate(y, item) { 7617 super._integrate(y, item); 7618 this.insert( 7619 0, 7620 /** @type {Array<any>} */ 7621 this._prelimContent 7622 ); 7623 this._prelimContent = null; 7624 } 7625 _copy() { 7626 return new _YXmlFragment(); 7627 } 7628 /** 7629 * Makes a copy of this data type that can be included somewhere else. 7630 * 7631 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7632 * 7633 * @return {YXmlFragment} 7634 */ 7635 clone() { 7636 const el = new _YXmlFragment(); 7637 el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); 7638 return el; 7639 } 7640 get length() { 7641 this.doc ?? warnPrematureAccess(); 7642 return this._prelimContent === null ? this._length : this._prelimContent.length; 7643 } 7644 /** 7645 * Create a subtree of childNodes. 7646 * 7647 * @example 7648 * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') 7649 * for (let node in walker) { 7650 * // `node` is a div node 7651 * nop(node) 7652 * } 7653 * 7654 * @param {function(AbstractType<any>):boolean} filter Function that is called on each child element and 7655 * returns a Boolean indicating whether the child 7656 * is to be included in the subtree. 7657 * @return {YXmlTreeWalker} A subtree and a position within it. 7658 * 7659 * @public 7660 */ 7661 createTreeWalker(filter) { 7662 return new YXmlTreeWalker(this, filter); 7663 } 7664 /** 7665 * Returns the first YXmlElement that matches the query. 7666 * Similar to DOM's {@link querySelector}. 7667 * 7668 * Query support: 7669 * - tagname 7670 * TODO: 7671 * - id 7672 * - attribute 7673 * 7674 * @param {CSS_Selector} query The query on the children. 7675 * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. 7676 * 7677 * @public 7678 */ 7679 querySelector(query) { 7680 query = query.toUpperCase(); 7681 const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); 7682 const next = iterator.next(); 7683 if (next.done) { 7684 return null; 7685 } else { 7686 return next.value; 7687 } 7688 } 7689 /** 7690 * Returns all YXmlElements that match the query. 7691 * Similar to Dom's {@link querySelectorAll}. 7692 * 7693 * @todo Does not yet support all queries. Currently only query by tagName. 7694 * 7695 * @param {CSS_Selector} query The query on the children 7696 * @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query. 7697 * 7698 * @public 7699 */ 7700 querySelectorAll(query) { 7701 query = query.toUpperCase(); 7702 return from(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); 7703 } 7704 /** 7705 * Creates YXmlEvent and calls observers. 7706 * 7707 * @param {Transaction} transaction 7708 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7709 */ 7710 _callObserver(transaction, parentSubs) { 7711 callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); 7712 } 7713 /** 7714 * Get the string representation of all the children of this YXmlFragment. 7715 * 7716 * @return {string} The string representation of all children. 7717 */ 7718 toString() { 7719 return typeListMap(this, (xml) => xml.toString()).join(""); 7720 } 7721 /** 7722 * @return {string} 7723 */ 7724 toJSON() { 7725 return this.toString(); 7726 } 7727 /** 7728 * Creates a Dom Element that mirrors this YXmlElement. 7729 * 7730 * @param {Document} [_document=document] The document object (you must define 7731 * this when calling this method in 7732 * nodejs) 7733 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 7734 * are presented in the DOM 7735 * @param {any} [binding] You should not set this property. This is 7736 * used if DomBinding wants to create a 7737 * association to the created DOM type. 7738 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 7739 * 7740 * @public 7741 */ 7742 toDOM(_document = document, hooks = {}, binding) { 7743 const fragment = _document.createDocumentFragment(); 7744 if (binding !== void 0) { 7745 binding._createAssociation(fragment, this); 7746 } 7747 typeListForEach(this, (xmlType) => { 7748 fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); 7749 }); 7750 return fragment; 7751 } 7752 /** 7753 * Inserts new content at an index. 7754 * 7755 * @example 7756 * // Insert character 'a' at position 0 7757 * xml.insert(0, [new Y.XmlText('text')]) 7758 * 7759 * @param {number} index The index to insert content at 7760 * @param {Array<YXmlElement|YXmlText>} content The array of content 7761 */ 7762 insert(index, content) { 7763 if (this.doc !== null) { 7764 transact(this.doc, (transaction) => { 7765 typeListInsertGenerics(transaction, this, index, content); 7766 }); 7767 } else { 7768 this._prelimContent.splice(index, 0, ...content); 7769 } 7770 } 7771 /** 7772 * Inserts new content at an index. 7773 * 7774 * @example 7775 * // Insert character 'a' at position 0 7776 * xml.insert(0, [new Y.XmlText('text')]) 7777 * 7778 * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at 7779 * @param {Array<YXmlElement|YXmlText>} content The array of content 7780 */ 7781 insertAfter(ref, content) { 7782 if (this.doc !== null) { 7783 transact(this.doc, (transaction) => { 7784 const refItem = ref && ref instanceof AbstractType ? ref._item : ref; 7785 typeListInsertGenericsAfter(transaction, this, refItem, content); 7786 }); 7787 } else { 7788 const pc = ( 7789 /** @type {Array<any>} */ 7790 this._prelimContent 7791 ); 7792 const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; 7793 if (index === 0 && ref !== null) { 7794 throw create3("Reference item not found"); 7795 } 7796 pc.splice(index, 0, ...content); 7797 } 7798 } 7799 /** 7800 * Deletes elements starting from an index. 7801 * 7802 * @param {number} index Index at which to start deleting elements 7803 * @param {number} [length=1] The number of elements to remove. Defaults to 1. 7804 */ 7805 delete(index, length2 = 1) { 7806 if (this.doc !== null) { 7807 transact(this.doc, (transaction) => { 7808 typeListDelete(transaction, this, index, length2); 7809 }); 7810 } else { 7811 this._prelimContent.splice(index, length2); 7812 } 7813 } 7814 /** 7815 * Transforms this YArray to a JavaScript Array. 7816 * 7817 * @return {Array<YXmlElement|YXmlText|YXmlHook>} 7818 */ 7819 toArray() { 7820 return typeListToArray(this); 7821 } 7822 /** 7823 * Appends content to this YArray. 7824 * 7825 * @param {Array<YXmlElement|YXmlText>} content Array of content to append. 7826 */ 7827 push(content) { 7828 this.insert(this.length, content); 7829 } 7830 /** 7831 * Prepends content to this YArray. 7832 * 7833 * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend. 7834 */ 7835 unshift(content) { 7836 this.insert(0, content); 7837 } 7838 /** 7839 * Returns the i-th element from a YArray. 7840 * 7841 * @param {number} index The index of the element to return from the YArray 7842 * @return {YXmlElement|YXmlText} 7843 */ 7844 get(index) { 7845 return typeListGet(this, index); 7846 } 7847 /** 7848 * Returns a portion of this YXmlFragment into a JavaScript Array selected 7849 * from start to end (end not included). 7850 * 7851 * @param {number} [start] 7852 * @param {number} [end] 7853 * @return {Array<YXmlElement|YXmlText>} 7854 */ 7855 slice(start = 0, end = this.length) { 7856 return typeListSlice(this, start, end); 7857 } 7858 /** 7859 * Executes a provided function on once on every child element. 7860 * 7861 * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. 7862 */ 7863 forEach(f) { 7864 typeListForEach(this, f); 7865 } 7866 /** 7867 * Transform the properties of this type to binary and write it to an 7868 * BinaryEncoder. 7869 * 7870 * This is called when this Item is sent to a remote peer. 7871 * 7872 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7873 */ 7874 _write(encoder) { 7875 encoder.writeTypeRef(YXmlFragmentRefID); 7876 } 7877 }; 7878 var readYXmlFragment = (_decoder) => new YXmlFragment(); 7879 var YXmlElement = class _YXmlElement extends YXmlFragment { 7880 constructor(nodeName = "UNDEFINED") { 7881 super(); 7882 this.nodeName = nodeName; 7883 this._prelimAttrs = /* @__PURE__ */ new Map(); 7884 } 7885 /** 7886 * @type {YXmlElement|YXmlText|null} 7887 */ 7888 get nextSibling() { 7889 const n = this._item ? this._item.next : null; 7890 return n ? ( 7891 /** @type {YXmlElement|YXmlText} */ 7892 /** @type {ContentType} */ 7893 n.content.type 7894 ) : null; 7895 } 7896 /** 7897 * @type {YXmlElement|YXmlText|null} 7898 */ 7899 get prevSibling() { 7900 const n = this._item ? this._item.prev : null; 7901 return n ? ( 7902 /** @type {YXmlElement|YXmlText} */ 7903 /** @type {ContentType} */ 7904 n.content.type 7905 ) : null; 7906 } 7907 /** 7908 * Integrate this type into the Yjs instance. 7909 * 7910 * * Save this struct in the os 7911 * * This type is sent to other client 7912 * * Observer functions are fired 7913 * 7914 * @param {Doc} y The Yjs instance 7915 * @param {Item} item 7916 */ 7917 _integrate(y, item) { 7918 super._integrate(y, item); 7919 /** @type {Map<string, any>} */ 7920 this._prelimAttrs.forEach((value, key) => { 7921 this.setAttribute(key, value); 7922 }); 7923 this._prelimAttrs = null; 7924 } 7925 /** 7926 * Creates an Item with the same effect as this Item (without position effect) 7927 * 7928 * @return {YXmlElement} 7929 */ 7930 _copy() { 7931 return new _YXmlElement(this.nodeName); 7932 } 7933 /** 7934 * Makes a copy of this data type that can be included somewhere else. 7935 * 7936 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7937 * 7938 * @return {YXmlElement<KV>} 7939 */ 7940 clone() { 7941 const el = new _YXmlElement(this.nodeName); 7942 const attrs = this.getAttributes(); 7943 forEach(attrs, (value, key) => { 7944 el.setAttribute( 7945 key, 7946 /** @type {any} */ 7947 value 7948 ); 7949 }); 7950 el.insert(0, this.toArray().map((v) => v instanceof AbstractType ? v.clone() : v)); 7951 return el; 7952 } 7953 /** 7954 * Returns the XML serialization of this YXmlElement. 7955 * The attributes are ordered by attribute-name, so you can easily use this 7956 * method to compare YXmlElements 7957 * 7958 * @return {string} The string representation of this type. 7959 * 7960 * @public 7961 */ 7962 toString() { 7963 const attrs = this.getAttributes(); 7964 const stringBuilder = []; 7965 const keys2 = []; 7966 for (const key in attrs) { 7967 keys2.push(key); 7968 } 7969 keys2.sort(); 7970 const keysLen = keys2.length; 7971 for (let i = 0; i < keysLen; i++) { 7972 const key = keys2[i]; 7973 stringBuilder.push(key + '="' + attrs[key] + '"'); 7974 } 7975 const nodeName = this.nodeName.toLocaleLowerCase(); 7976 const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; 7977 return `<$nodeName}$attrsString}>$super.toString()}</$nodeName}>`; 7978 } 7979 /** 7980 * Removes an attribute from this YXmlElement. 7981 * 7982 * @param {string} attributeName The attribute name that is to be removed. 7983 * 7984 * @public 7985 */ 7986 removeAttribute(attributeName) { 7987 if (this.doc !== null) { 7988 transact(this.doc, (transaction) => { 7989 typeMapDelete(transaction, this, attributeName); 7990 }); 7991 } else { 7992 this._prelimAttrs.delete(attributeName); 7993 } 7994 } 7995 /** 7996 * Sets or updates an attribute. 7997 * 7998 * @template {keyof KV & string} KEY 7999 * 8000 * @param {KEY} attributeName The attribute name that is to be set. 8001 * @param {KV[KEY]} attributeValue The attribute value that is to be set. 8002 * 8003 * @public 8004 */ 8005 setAttribute(attributeName, attributeValue) { 8006 if (this.doc !== null) { 8007 transact(this.doc, (transaction) => { 8008 typeMapSet(transaction, this, attributeName, attributeValue); 8009 }); 8010 } else { 8011 this._prelimAttrs.set(attributeName, attributeValue); 8012 } 8013 } 8014 /** 8015 * Returns an attribute value that belongs to the attribute name. 8016 * 8017 * @template {keyof KV & string} KEY 8018 * 8019 * @param {KEY} attributeName The attribute name that identifies the 8020 * queried value. 8021 * @return {KV[KEY]|undefined} The queried attribute value. 8022 * 8023 * @public 8024 */ 8025 getAttribute(attributeName) { 8026 return ( 8027 /** @type {any} */ 8028 typeMapGet(this, attributeName) 8029 ); 8030 } 8031 /** 8032 * Returns whether an attribute exists 8033 * 8034 * @param {string} attributeName The attribute name to check for existence. 8035 * @return {boolean} whether the attribute exists. 8036 * 8037 * @public 8038 */ 8039 hasAttribute(attributeName) { 8040 return ( 8041 /** @type {any} */ 8042 typeMapHas(this, attributeName) 8043 ); 8044 } 8045 /** 8046 * Returns all attribute name/value pairs in a JSON Object. 8047 * 8048 * @param {Snapshot} [snapshot] 8049 * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes. 8050 * 8051 * @public 8052 */ 8053 getAttributes(snapshot2) { 8054 return ( 8055 /** @type {any} */ 8056 snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) 8057 ); 8058 } 8059 /** 8060 * Creates a Dom Element that mirrors this YXmlElement. 8061 * 8062 * @param {Document} [_document=document] The document object (you must define 8063 * this when calling this method in 8064 * nodejs) 8065 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 8066 * are presented in the DOM 8067 * @param {any} [binding] You should not set this property. This is 8068 * used if DomBinding wants to create a 8069 * association to the created DOM type. 8070 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8071 * 8072 * @public 8073 */ 8074 toDOM(_document = document, hooks = {}, binding) { 8075 const dom = _document.createElement(this.nodeName); 8076 const attrs = this.getAttributes(); 8077 for (const key in attrs) { 8078 const value = attrs[key]; 8079 if (typeof value === "string") { 8080 dom.setAttribute(key, value); 8081 } 8082 } 8083 typeListForEach(this, (yxml) => { 8084 dom.appendChild(yxml.toDOM(_document, hooks, binding)); 8085 }); 8086 if (binding !== void 0) { 8087 binding._createAssociation(dom, this); 8088 } 8089 return dom; 8090 } 8091 /** 8092 * Transform the properties of this type to binary and write it to an 8093 * BinaryEncoder. 8094 * 8095 * This is called when this Item is sent to a remote peer. 8096 * 8097 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8098 */ 8099 _write(encoder) { 8100 encoder.writeTypeRef(YXmlElementRefID); 8101 encoder.writeKey(this.nodeName); 8102 } 8103 }; 8104 var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); 8105 var YXmlEvent = class extends YEvent { 8106 /** 8107 * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. 8108 * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the 8109 * child list changed. 8110 * @param {Transaction} transaction The transaction instance with which the 8111 * change was created. 8112 */ 8113 constructor(target, subs, transaction) { 8114 super(target, transaction); 8115 this.childListChanged = false; 8116 this.attributesChanged = /* @__PURE__ */ new Set(); 8117 subs.forEach((sub) => { 8118 if (sub === null) { 8119 this.childListChanged = true; 8120 } else { 8121 this.attributesChanged.add(sub); 8122 } 8123 }); 8124 } 8125 }; 8126 var YXmlHook = class _YXmlHook extends YMap { 8127 /** 8128 * @param {string} hookName nodeName of the Dom Node. 8129 */ 8130 constructor(hookName) { 8131 super(); 8132 this.hookName = hookName; 8133 } 8134 /** 8135 * Creates an Item with the same effect as this Item (without position effect) 8136 */ 8137 _copy() { 8138 return new _YXmlHook(this.hookName); 8139 } 8140 /** 8141 * Makes a copy of this data type that can be included somewhere else. 8142 * 8143 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8144 * 8145 * @return {YXmlHook} 8146 */ 8147 clone() { 8148 const el = new _YXmlHook(this.hookName); 8149 this.forEach((value, key) => { 8150 el.set(key, value); 8151 }); 8152 return el; 8153 } 8154 /** 8155 * Creates a Dom Element that mirrors this YXmlElement. 8156 * 8157 * @param {Document} [_document=document] The document object (you must define 8158 * this when calling this method in 8159 * nodejs) 8160 * @param {Object.<string, any>} [hooks] Optional property to customize how hooks 8161 * are presented in the DOM 8162 * @param {any} [binding] You should not set this property. This is 8163 * used if DomBinding wants to create a 8164 * association to the created DOM type 8165 * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8166 * 8167 * @public 8168 */ 8169 toDOM(_document = document, hooks = {}, binding) { 8170 const hook = hooks[this.hookName]; 8171 let dom; 8172 if (hook !== void 0) { 8173 dom = hook.createDom(this); 8174 } else { 8175 dom = document.createElement(this.hookName); 8176 } 8177 dom.setAttribute("data-yjs-hook", this.hookName); 8178 if (binding !== void 0) { 8179 binding._createAssociation(dom, this); 8180 } 8181 return dom; 8182 } 8183 /** 8184 * Transform the properties of this type to binary and write it to an 8185 * BinaryEncoder. 8186 * 8187 * This is called when this Item is sent to a remote peer. 8188 * 8189 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8190 */ 8191 _write(encoder) { 8192 encoder.writeTypeRef(YXmlHookRefID); 8193 encoder.writeKey(this.hookName); 8194 } 8195 }; 8196 var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); 8197 var YXmlText = class _YXmlText extends YText { 8198 /** 8199 * @type {YXmlElement|YXmlText|null} 8200 */ 8201 get nextSibling() { 8202 const n = this._item ? this._item.next : null; 8203 return n ? ( 8204 /** @type {YXmlElement|YXmlText} */ 8205 /** @type {ContentType} */ 8206 n.content.type 8207 ) : null; 8208 } 8209 /** 8210 * @type {YXmlElement|YXmlText|null} 8211 */ 8212 get prevSibling() { 8213 const n = this._item ? this._item.prev : null; 8214 return n ? ( 8215 /** @type {YXmlElement|YXmlText} */ 8216 /** @type {ContentType} */ 8217 n.content.type 8218 ) : null; 8219 } 8220 _copy() { 8221 return new _YXmlText(); 8222 } 8223 /** 8224 * Makes a copy of this data type that can be included somewhere else. 8225 * 8226 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8227 * 8228 * @return {YXmlText} 8229 */ 8230 clone() { 8231 const text2 = new _YXmlText(); 8232 text2.applyDelta(this.toDelta()); 8233 return text2; 8234 } 8235 /** 8236 * Creates a Dom Element that mirrors this YXmlText. 8237 * 8238 * @param {Document} [_document=document] The document object (you must define 8239 * this when calling this method in 8240 * nodejs) 8241 * @param {Object<string, any>} [hooks] Optional property to customize how hooks 8242 * are presented in the DOM 8243 * @param {any} [binding] You should not set this property. This is 8244 * used if DomBinding wants to create a 8245 * association to the created DOM type. 8246 * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8247 * 8248 * @public 8249 */ 8250 toDOM(_document = document, hooks, binding) { 8251 const dom = _document.createTextNode(this.toString()); 8252 if (binding !== void 0) { 8253 binding._createAssociation(dom, this); 8254 } 8255 return dom; 8256 } 8257 toString() { 8258 return this.toDelta().map((delta) => { 8259 const nestedNodes = []; 8260 for (const nodeName in delta.attributes) { 8261 const attrs = []; 8262 for (const key in delta.attributes[nodeName]) { 8263 attrs.push({ key, value: delta.attributes[nodeName][key] }); 8264 } 8265 attrs.sort((a, b) => a.key < b.key ? -1 : 1); 8266 nestedNodes.push({ nodeName, attrs }); 8267 } 8268 nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1); 8269 let str = ""; 8270 for (let i = 0; i < nestedNodes.length; i++) { 8271 const node = nestedNodes[i]; 8272 str += `<$node.nodeName}`; 8273 for (let j = 0; j < node.attrs.length; j++) { 8274 const attr = node.attrs[j]; 8275 str += ` $attr.key}="$attr.value}"`; 8276 } 8277 str += ">"; 8278 } 8279 str += delta.insert; 8280 for (let i = nestedNodes.length - 1; i >= 0; i--) { 8281 str += `</$nestedNodes[i].nodeName}>`; 8282 } 8283 return str; 8284 }).join(""); 8285 } 8286 /** 8287 * @return {string} 8288 */ 8289 toJSON() { 8290 return this.toString(); 8291 } 8292 /** 8293 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8294 */ 8295 _write(encoder) { 8296 encoder.writeTypeRef(YXmlTextRefID); 8297 } 8298 }; 8299 var readYXmlText = (decoder) => new YXmlText(); 8300 var AbstractStruct = class { 8301 /** 8302 * @param {ID} id 8303 * @param {number} length 8304 */ 8305 constructor(id2, length2) { 8306 this.id = id2; 8307 this.length = length2; 8308 } 8309 /** 8310 * @type {boolean} 8311 */ 8312 get deleted() { 8313 throw methodUnimplemented(); 8314 } 8315 /** 8316 * Merge this struct with the item to the right. 8317 * This method is already assuming that `this.id.clock + this.length === this.id.clock`. 8318 * Also this method does *not* remove right from StructStore! 8319 * @param {AbstractStruct} right 8320 * @return {boolean} whether this merged with right 8321 */ 8322 mergeWith(right) { 8323 return false; 8324 } 8325 /** 8326 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8327 * @param {number} offset 8328 * @param {number} encodingRef 8329 */ 8330 write(encoder, offset, encodingRef) { 8331 throw methodUnimplemented(); 8332 } 8333 /** 8334 * @param {Transaction} transaction 8335 * @param {number} offset 8336 */ 8337 integrate(transaction, offset) { 8338 throw methodUnimplemented(); 8339 } 8340 }; 8341 var structGCRefNumber = 0; 8342 var GC = class extends AbstractStruct { 8343 get deleted() { 8344 return true; 8345 } 8346 delete() { 8347 } 8348 /** 8349 * @param {GC} right 8350 * @return {boolean} 8351 */ 8352 mergeWith(right) { 8353 if (this.constructor !== right.constructor) { 8354 return false; 8355 } 8356 this.length += right.length; 8357 return true; 8358 } 8359 /** 8360 * @param {Transaction} transaction 8361 * @param {number} offset 8362 */ 8363 integrate(transaction, offset) { 8364 if (offset > 0) { 8365 this.id.clock += offset; 8366 this.length -= offset; 8367 } 8368 addStruct(transaction.doc.store, this); 8369 } 8370 /** 8371 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8372 * @param {number} offset 8373 */ 8374 write(encoder, offset) { 8375 encoder.writeInfo(structGCRefNumber); 8376 encoder.writeLen(this.length - offset); 8377 } 8378 /** 8379 * @param {Transaction} transaction 8380 * @param {StructStore} store 8381 * @return {null | number} 8382 */ 8383 getMissing(transaction, store) { 8384 return null; 8385 } 8386 }; 8387 var ContentBinary = class _ContentBinary { 8388 /** 8389 * @param {Uint8Array} content 8390 */ 8391 constructor(content) { 8392 this.content = content; 8393 } 8394 /** 8395 * @return {number} 8396 */ 8397 getLength() { 8398 return 1; 8399 } 8400 /** 8401 * @return {Array<any>} 8402 */ 8403 getContent() { 8404 return [this.content]; 8405 } 8406 /** 8407 * @return {boolean} 8408 */ 8409 isCountable() { 8410 return true; 8411 } 8412 /** 8413 * @return {ContentBinary} 8414 */ 8415 copy() { 8416 return new _ContentBinary(this.content); 8417 } 8418 /** 8419 * @param {number} offset 8420 * @return {ContentBinary} 8421 */ 8422 splice(offset) { 8423 throw methodUnimplemented(); 8424 } 8425 /** 8426 * @param {ContentBinary} right 8427 * @return {boolean} 8428 */ 8429 mergeWith(right) { 8430 return false; 8431 } 8432 /** 8433 * @param {Transaction} transaction 8434 * @param {Item} item 8435 */ 8436 integrate(transaction, item) { 8437 } 8438 /** 8439 * @param {Transaction} transaction 8440 */ 8441 delete(transaction) { 8442 } 8443 /** 8444 * @param {StructStore} store 8445 */ 8446 gc(store) { 8447 } 8448 /** 8449 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8450 * @param {number} offset 8451 */ 8452 write(encoder, offset) { 8453 encoder.writeBuf(this.content); 8454 } 8455 /** 8456 * @return {number} 8457 */ 8458 getRef() { 8459 return 3; 8460 } 8461 }; 8462 var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); 8463 var ContentDeleted = class _ContentDeleted { 8464 /** 8465 * @param {number} len 8466 */ 8467 constructor(len) { 8468 this.len = len; 8469 } 8470 /** 8471 * @return {number} 8472 */ 8473 getLength() { 8474 return this.len; 8475 } 8476 /** 8477 * @return {Array<any>} 8478 */ 8479 getContent() { 8480 return []; 8481 } 8482 /** 8483 * @return {boolean} 8484 */ 8485 isCountable() { 8486 return false; 8487 } 8488 /** 8489 * @return {ContentDeleted} 8490 */ 8491 copy() { 8492 return new _ContentDeleted(this.len); 8493 } 8494 /** 8495 * @param {number} offset 8496 * @return {ContentDeleted} 8497 */ 8498 splice(offset) { 8499 const right = new _ContentDeleted(this.len - offset); 8500 this.len = offset; 8501 return right; 8502 } 8503 /** 8504 * @param {ContentDeleted} right 8505 * @return {boolean} 8506 */ 8507 mergeWith(right) { 8508 this.len += right.len; 8509 return true; 8510 } 8511 /** 8512 * @param {Transaction} transaction 8513 * @param {Item} item 8514 */ 8515 integrate(transaction, item) { 8516 addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); 8517 item.markDeleted(); 8518 } 8519 /** 8520 * @param {Transaction} transaction 8521 */ 8522 delete(transaction) { 8523 } 8524 /** 8525 * @param {StructStore} store 8526 */ 8527 gc(store) { 8528 } 8529 /** 8530 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8531 * @param {number} offset 8532 */ 8533 write(encoder, offset) { 8534 encoder.writeLen(this.len - offset); 8535 } 8536 /** 8537 * @return {number} 8538 */ 8539 getRef() { 8540 return 1; 8541 } 8542 }; 8543 var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); 8544 var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); 8545 var ContentDoc = class _ContentDoc { 8546 /** 8547 * @param {Doc} doc 8548 */ 8549 constructor(doc2) { 8550 if (doc2._item) { 8551 console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); 8552 } 8553 this.doc = doc2; 8554 const opts = {}; 8555 this.opts = opts; 8556 if (!doc2.gc) { 8557 opts.gc = false; 8558 } 8559 if (doc2.autoLoad) { 8560 opts.autoLoad = true; 8561 } 8562 if (doc2.meta !== null) { 8563 opts.meta = doc2.meta; 8564 } 8565 } 8566 /** 8567 * @return {number} 8568 */ 8569 getLength() { 8570 return 1; 8571 } 8572 /** 8573 * @return {Array<any>} 8574 */ 8575 getContent() { 8576 return [this.doc]; 8577 } 8578 /** 8579 * @return {boolean} 8580 */ 8581 isCountable() { 8582 return true; 8583 } 8584 /** 8585 * @return {ContentDoc} 8586 */ 8587 copy() { 8588 return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); 8589 } 8590 /** 8591 * @param {number} offset 8592 * @return {ContentDoc} 8593 */ 8594 splice(offset) { 8595 throw methodUnimplemented(); 8596 } 8597 /** 8598 * @param {ContentDoc} right 8599 * @return {boolean} 8600 */ 8601 mergeWith(right) { 8602 return false; 8603 } 8604 /** 8605 * @param {Transaction} transaction 8606 * @param {Item} item 8607 */ 8608 integrate(transaction, item) { 8609 this.doc._item = item; 8610 transaction.subdocsAdded.add(this.doc); 8611 if (this.doc.shouldLoad) { 8612 transaction.subdocsLoaded.add(this.doc); 8613 } 8614 } 8615 /** 8616 * @param {Transaction} transaction 8617 */ 8618 delete(transaction) { 8619 if (transaction.subdocsAdded.has(this.doc)) { 8620 transaction.subdocsAdded.delete(this.doc); 8621 } else { 8622 transaction.subdocsRemoved.add(this.doc); 8623 } 8624 } 8625 /** 8626 * @param {StructStore} store 8627 */ 8628 gc(store) { 8629 } 8630 /** 8631 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8632 * @param {number} offset 8633 */ 8634 write(encoder, offset) { 8635 encoder.writeString(this.doc.guid); 8636 encoder.writeAny(this.opts); 8637 } 8638 /** 8639 * @return {number} 8640 */ 8641 getRef() { 8642 return 9; 8643 } 8644 }; 8645 var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); 8646 var ContentEmbed = class _ContentEmbed { 8647 /** 8648 * @param {Object} embed 8649 */ 8650 constructor(embed) { 8651 this.embed = embed; 8652 } 8653 /** 8654 * @return {number} 8655 */ 8656 getLength() { 8657 return 1; 8658 } 8659 /** 8660 * @return {Array<any>} 8661 */ 8662 getContent() { 8663 return [this.embed]; 8664 } 8665 /** 8666 * @return {boolean} 8667 */ 8668 isCountable() { 8669 return true; 8670 } 8671 /** 8672 * @return {ContentEmbed} 8673 */ 8674 copy() { 8675 return new _ContentEmbed(this.embed); 8676 } 8677 /** 8678 * @param {number} offset 8679 * @return {ContentEmbed} 8680 */ 8681 splice(offset) { 8682 throw methodUnimplemented(); 8683 } 8684 /** 8685 * @param {ContentEmbed} right 8686 * @return {boolean} 8687 */ 8688 mergeWith(right) { 8689 return false; 8690 } 8691 /** 8692 * @param {Transaction} transaction 8693 * @param {Item} item 8694 */ 8695 integrate(transaction, item) { 8696 } 8697 /** 8698 * @param {Transaction} transaction 8699 */ 8700 delete(transaction) { 8701 } 8702 /** 8703 * @param {StructStore} store 8704 */ 8705 gc(store) { 8706 } 8707 /** 8708 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8709 * @param {number} offset 8710 */ 8711 write(encoder, offset) { 8712 encoder.writeJSON(this.embed); 8713 } 8714 /** 8715 * @return {number} 8716 */ 8717 getRef() { 8718 return 5; 8719 } 8720 }; 8721 var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); 8722 var ContentFormat = class _ContentFormat { 8723 /** 8724 * @param {string} key 8725 * @param {Object} value 8726 */ 8727 constructor(key, value) { 8728 this.key = key; 8729 this.value = value; 8730 } 8731 /** 8732 * @return {number} 8733 */ 8734 getLength() { 8735 return 1; 8736 } 8737 /** 8738 * @return {Array<any>} 8739 */ 8740 getContent() { 8741 return []; 8742 } 8743 /** 8744 * @return {boolean} 8745 */ 8746 isCountable() { 8747 return false; 8748 } 8749 /** 8750 * @return {ContentFormat} 8751 */ 8752 copy() { 8753 return new _ContentFormat(this.key, this.value); 8754 } 8755 /** 8756 * @param {number} _offset 8757 * @return {ContentFormat} 8758 */ 8759 splice(_offset) { 8760 throw methodUnimplemented(); 8761 } 8762 /** 8763 * @param {ContentFormat} _right 8764 * @return {boolean} 8765 */ 8766 mergeWith(_right) { 8767 return false; 8768 } 8769 /** 8770 * @param {Transaction} _transaction 8771 * @param {Item} item 8772 */ 8773 integrate(_transaction, item) { 8774 const p = ( 8775 /** @type {YText} */ 8776 item.parent 8777 ); 8778 p._searchMarker = null; 8779 p._hasFormatting = true; 8780 } 8781 /** 8782 * @param {Transaction} transaction 8783 */ 8784 delete(transaction) { 8785 } 8786 /** 8787 * @param {StructStore} store 8788 */ 8789 gc(store) { 8790 } 8791 /** 8792 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8793 * @param {number} offset 8794 */ 8795 write(encoder, offset) { 8796 encoder.writeKey(this.key); 8797 encoder.writeJSON(this.value); 8798 } 8799 /** 8800 * @return {number} 8801 */ 8802 getRef() { 8803 return 6; 8804 } 8805 }; 8806 var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); 8807 var ContentJSON = class _ContentJSON { 8808 /** 8809 * @param {Array<any>} arr 8810 */ 8811 constructor(arr) { 8812 this.arr = arr; 8813 } 8814 /** 8815 * @return {number} 8816 */ 8817 getLength() { 8818 return this.arr.length; 8819 } 8820 /** 8821 * @return {Array<any>} 8822 */ 8823 getContent() { 8824 return this.arr; 8825 } 8826 /** 8827 * @return {boolean} 8828 */ 8829 isCountable() { 8830 return true; 8831 } 8832 /** 8833 * @return {ContentJSON} 8834 */ 8835 copy() { 8836 return new _ContentJSON(this.arr); 8837 } 8838 /** 8839 * @param {number} offset 8840 * @return {ContentJSON} 8841 */ 8842 splice(offset) { 8843 const right = new _ContentJSON(this.arr.slice(offset)); 8844 this.arr = this.arr.slice(0, offset); 8845 return right; 8846 } 8847 /** 8848 * @param {ContentJSON} right 8849 * @return {boolean} 8850 */ 8851 mergeWith(right) { 8852 this.arr = this.arr.concat(right.arr); 8853 return true; 8854 } 8855 /** 8856 * @param {Transaction} transaction 8857 * @param {Item} item 8858 */ 8859 integrate(transaction, item) { 8860 } 8861 /** 8862 * @param {Transaction} transaction 8863 */ 8864 delete(transaction) { 8865 } 8866 /** 8867 * @param {StructStore} store 8868 */ 8869 gc(store) { 8870 } 8871 /** 8872 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8873 * @param {number} offset 8874 */ 8875 write(encoder, offset) { 8876 const len = this.arr.length; 8877 encoder.writeLen(len - offset); 8878 for (let i = offset; i < len; i++) { 8879 const c = this.arr[i]; 8880 encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); 8881 } 8882 } 8883 /** 8884 * @return {number} 8885 */ 8886 getRef() { 8887 return 2; 8888 } 8889 }; 8890 var readContentJSON = (decoder) => { 8891 const len = decoder.readLen(); 8892 const cs = []; 8893 for (let i = 0; i < len; i++) { 8894 const c = decoder.readString(); 8895 if (c === "undefined") { 8896 cs.push(void 0); 8897 } else { 8898 cs.push(JSON.parse(c)); 8899 } 8900 } 8901 return new ContentJSON(cs); 8902 }; 8903 var isDevMode = getVariable("node_env") === "development"; 8904 var ContentAny = class _ContentAny { 8905 /** 8906 * @param {Array<any>} arr 8907 */ 8908 constructor(arr) { 8909 this.arr = arr; 8910 isDevMode && deepFreeze(arr); 8911 } 8912 /** 8913 * @return {number} 8914 */ 8915 getLength() { 8916 return this.arr.length; 8917 } 8918 /** 8919 * @return {Array<any>} 8920 */ 8921 getContent() { 8922 return this.arr; 8923 } 8924 /** 8925 * @return {boolean} 8926 */ 8927 isCountable() { 8928 return true; 8929 } 8930 /** 8931 * @return {ContentAny} 8932 */ 8933 copy() { 8934 return new _ContentAny(this.arr); 8935 } 8936 /** 8937 * @param {number} offset 8938 * @return {ContentAny} 8939 */ 8940 splice(offset) { 8941 const right = new _ContentAny(this.arr.slice(offset)); 8942 this.arr = this.arr.slice(0, offset); 8943 return right; 8944 } 8945 /** 8946 * @param {ContentAny} right 8947 * @return {boolean} 8948 */ 8949 mergeWith(right) { 8950 this.arr = this.arr.concat(right.arr); 8951 return true; 8952 } 8953 /** 8954 * @param {Transaction} transaction 8955 * @param {Item} item 8956 */ 8957 integrate(transaction, item) { 8958 } 8959 /** 8960 * @param {Transaction} transaction 8961 */ 8962 delete(transaction) { 8963 } 8964 /** 8965 * @param {StructStore} store 8966 */ 8967 gc(store) { 8968 } 8969 /** 8970 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8971 * @param {number} offset 8972 */ 8973 write(encoder, offset) { 8974 const len = this.arr.length; 8975 encoder.writeLen(len - offset); 8976 for (let i = offset; i < len; i++) { 8977 const c = this.arr[i]; 8978 encoder.writeAny(c); 8979 } 8980 } 8981 /** 8982 * @return {number} 8983 */ 8984 getRef() { 8985 return 8; 8986 } 8987 }; 8988 var readContentAny = (decoder) => { 8989 const len = decoder.readLen(); 8990 const cs = []; 8991 for (let i = 0; i < len; i++) { 8992 cs.push(decoder.readAny()); 8993 } 8994 return new ContentAny(cs); 8995 }; 8996 var ContentString = class _ContentString { 8997 /** 8998 * @param {string} str 8999 */ 9000 constructor(str) { 9001 this.str = str; 9002 } 9003 /** 9004 * @return {number} 9005 */ 9006 getLength() { 9007 return this.str.length; 9008 } 9009 /** 9010 * @return {Array<any>} 9011 */ 9012 getContent() { 9013 return this.str.split(""); 9014 } 9015 /** 9016 * @return {boolean} 9017 */ 9018 isCountable() { 9019 return true; 9020 } 9021 /** 9022 * @return {ContentString} 9023 */ 9024 copy() { 9025 return new _ContentString(this.str); 9026 } 9027 /** 9028 * @param {number} offset 9029 * @return {ContentString} 9030 */ 9031 splice(offset) { 9032 const right = new _ContentString(this.str.slice(offset)); 9033 this.str = this.str.slice(0, offset); 9034 const firstCharCode = this.str.charCodeAt(offset - 1); 9035 if (firstCharCode >= 55296 && firstCharCode <= 56319) { 9036 this.str = this.str.slice(0, offset - 1) + "\uFFFD"; 9037 right.str = "\uFFFD" + right.str.slice(1); 9038 } 9039 return right; 9040 } 9041 /** 9042 * @param {ContentString} right 9043 * @return {boolean} 9044 */ 9045 mergeWith(right) { 9046 this.str += right.str; 9047 return true; 9048 } 9049 /** 9050 * @param {Transaction} transaction 9051 * @param {Item} item 9052 */ 9053 integrate(transaction, item) { 9054 } 9055 /** 9056 * @param {Transaction} transaction 9057 */ 9058 delete(transaction) { 9059 } 9060 /** 9061 * @param {StructStore} store 9062 */ 9063 gc(store) { 9064 } 9065 /** 9066 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9067 * @param {number} offset 9068 */ 9069 write(encoder, offset) { 9070 encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); 9071 } 9072 /** 9073 * @return {number} 9074 */ 9075 getRef() { 9076 return 4; 9077 } 9078 }; 9079 var readContentString = (decoder) => new ContentString(decoder.readString()); 9080 var typeRefs = [ 9081 readYArray, 9082 readYMap, 9083 readYText, 9084 readYXmlElement, 9085 readYXmlFragment, 9086 readYXmlHook, 9087 readYXmlText 9088 ]; 9089 var YArrayRefID = 0; 9090 var YMapRefID = 1; 9091 var YTextRefID = 2; 9092 var YXmlElementRefID = 3; 9093 var YXmlFragmentRefID = 4; 9094 var YXmlHookRefID = 5; 9095 var YXmlTextRefID = 6; 9096 var ContentType = class _ContentType { 9097 /** 9098 * @param {AbstractType<any>} type 9099 */ 9100 constructor(type) { 9101 this.type = type; 9102 } 9103 /** 9104 * @return {number} 9105 */ 9106 getLength() { 9107 return 1; 9108 } 9109 /** 9110 * @return {Array<any>} 9111 */ 9112 getContent() { 9113 return [this.type]; 9114 } 9115 /** 9116 * @return {boolean} 9117 */ 9118 isCountable() { 9119 return true; 9120 } 9121 /** 9122 * @return {ContentType} 9123 */ 9124 copy() { 9125 return new _ContentType(this.type._copy()); 9126 } 9127 /** 9128 * @param {number} offset 9129 * @return {ContentType} 9130 */ 9131 splice(offset) { 9132 throw methodUnimplemented(); 9133 } 9134 /** 9135 * @param {ContentType} right 9136 * @return {boolean} 9137 */ 9138 mergeWith(right) { 9139 return false; 9140 } 9141 /** 9142 * @param {Transaction} transaction 9143 * @param {Item} item 9144 */ 9145 integrate(transaction, item) { 9146 this.type._integrate(transaction.doc, item); 9147 } 9148 /** 9149 * @param {Transaction} transaction 9150 */ 9151 delete(transaction) { 9152 let item = this.type._start; 9153 while (item !== null) { 9154 if (!item.deleted) { 9155 item.delete(transaction); 9156 } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { 9157 transaction._mergeStructs.push(item); 9158 } 9159 item = item.right; 9160 } 9161 this.type._map.forEach((item2) => { 9162 if (!item2.deleted) { 9163 item2.delete(transaction); 9164 } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { 9165 transaction._mergeStructs.push(item2); 9166 } 9167 }); 9168 transaction.changed.delete(this.type); 9169 } 9170 /** 9171 * @param {StructStore} store 9172 */ 9173 gc(store) { 9174 let item = this.type._start; 9175 while (item !== null) { 9176 item.gc(store, true); 9177 item = item.right; 9178 } 9179 this.type._start = null; 9180 this.type._map.forEach( 9181 /** @param {Item | null} item */ 9182 (item2) => { 9183 while (item2 !== null) { 9184 item2.gc(store, true); 9185 item2 = item2.left; 9186 } 9187 } 9188 ); 9189 this.type._map = /* @__PURE__ */ new Map(); 9190 } 9191 /** 9192 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9193 * @param {number} offset 9194 */ 9195 write(encoder, offset) { 9196 this.type._write(encoder); 9197 } 9198 /** 9199 * @return {number} 9200 */ 9201 getRef() { 9202 return 7; 9203 } 9204 }; 9205 var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); 9206 var followRedone = (store, id2) => { 9207 let nextID = id2; 9208 let diff = 0; 9209 let item; 9210 do { 9211 if (diff > 0) { 9212 nextID = createID(nextID.client, nextID.clock + diff); 9213 } 9214 item = getItem(store, nextID); 9215 diff = nextID.clock - item.id.clock; 9216 nextID = item.redone; 9217 } while (nextID !== null && item instanceof Item); 9218 return { 9219 item, 9220 diff 9221 }; 9222 }; 9223 var keepItem = (item, keep) => { 9224 while (item !== null && item.keep !== keep) { 9225 item.keep = keep; 9226 item = /** @type {AbstractType<any>} */ 9227 item.parent._item; 9228 } 9229 }; 9230 var splitItem = (transaction, leftItem, diff) => { 9231 const { client, clock } = leftItem.id; 9232 const rightItem = new Item( 9233 createID(client, clock + diff), 9234 leftItem, 9235 createID(client, clock + diff - 1), 9236 leftItem.right, 9237 leftItem.rightOrigin, 9238 leftItem.parent, 9239 leftItem.parentSub, 9240 leftItem.content.splice(diff) 9241 ); 9242 if (leftItem.deleted) { 9243 rightItem.markDeleted(); 9244 } 9245 if (leftItem.keep) { 9246 rightItem.keep = true; 9247 } 9248 if (leftItem.redone !== null) { 9249 rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); 9250 } 9251 leftItem.right = rightItem; 9252 if (rightItem.right !== null) { 9253 rightItem.right.left = rightItem; 9254 } 9255 transaction._mergeStructs.push(rightItem); 9256 if (rightItem.parentSub !== null && rightItem.right === null) { 9257 rightItem.parent._map.set(rightItem.parentSub, rightItem); 9258 } 9259 leftItem.length = diff; 9260 return rightItem; 9261 }; 9262 var isDeletedByUndoStack = (stack, id2) => some( 9263 stack, 9264 /** @param {StackItem} s */ 9265 (s) => isDeleted(s.deletions, id2) 9266 ); 9267 var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { 9268 const doc2 = transaction.doc; 9269 const store = doc2.store; 9270 const ownClientID = doc2.clientID; 9271 const redone = item.redone; 9272 if (redone !== null) { 9273 return getItemCleanStart(transaction, redone); 9274 } 9275 let parentItem = ( 9276 /** @type {AbstractType<any>} */ 9277 item.parent._item 9278 ); 9279 let left = null; 9280 let right; 9281 if (parentItem !== null && parentItem.deleted === true) { 9282 if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { 9283 return null; 9284 } 9285 while (parentItem.redone !== null) { 9286 parentItem = getItemCleanStart(transaction, parentItem.redone); 9287 } 9288 } 9289 const parentType = parentItem === null ? ( 9290 /** @type {AbstractType<any>} */ 9291 item.parent 9292 ) : ( 9293 /** @type {ContentType} */ 9294 parentItem.content.type 9295 ); 9296 if (item.parentSub === null) { 9297 left = item.left; 9298 right = item; 9299 while (left !== null) { 9300 let leftTrace = left; 9301 while (leftTrace !== null && /** @type {AbstractType<any>} */ 9302 leftTrace.parent._item !== parentItem) { 9303 leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); 9304 } 9305 if (leftTrace !== null && /** @type {AbstractType<any>} */ 9306 leftTrace.parent._item === parentItem) { 9307 left = leftTrace; 9308 break; 9309 } 9310 left = left.left; 9311 } 9312 while (right !== null) { 9313 let rightTrace = right; 9314 while (rightTrace !== null && /** @type {AbstractType<any>} */ 9315 rightTrace.parent._item !== parentItem) { 9316 rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); 9317 } 9318 if (rightTrace !== null && /** @type {AbstractType<any>} */ 9319 rightTrace.parent._item === parentItem) { 9320 right = rightTrace; 9321 break; 9322 } 9323 right = right.right; 9324 } 9325 } else { 9326 right = null; 9327 if (item.right && !ignoreRemoteMapChanges) { 9328 left = item; 9329 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))) { 9330 left = left.right; 9331 while (left.redone) left = getItemCleanStart(transaction, left.redone); 9332 } 9333 if (left && left.right !== null) { 9334 return null; 9335 } 9336 } else { 9337 left = parentType._map.get(item.parentSub) || null; 9338 } 9339 } 9340 const nextClock = getState(store, ownClientID); 9341 const nextId = createID(ownClientID, nextClock); 9342 const redoneItem = new Item( 9343 nextId, 9344 left, 9345 left && left.lastId, 9346 right, 9347 right && right.id, 9348 parentType, 9349 item.parentSub, 9350 item.content.copy() 9351 ); 9352 item.redone = nextId; 9353 keepItem(redoneItem, true); 9354 redoneItem.integrate(transaction, 0); 9355 return redoneItem; 9356 }; 9357 var Item = class _Item extends AbstractStruct { 9358 /** 9359 * @param {ID} id 9360 * @param {Item | null} left 9361 * @param {ID | null} origin 9362 * @param {Item | null} right 9363 * @param {ID | null} rightOrigin 9364 * @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. 9365 * @param {string | null} parentSub 9366 * @param {AbstractContent} content 9367 */ 9368 constructor(id2, left, origin2, right, rightOrigin, parent, parentSub, content) { 9369 super(id2, content.getLength()); 9370 this.origin = origin2; 9371 this.left = left; 9372 this.right = right; 9373 this.rightOrigin = rightOrigin; 9374 this.parent = parent; 9375 this.parentSub = parentSub; 9376 this.redone = null; 9377 this.content = content; 9378 this.info = this.content.isCountable() ? BIT2 : 0; 9379 } 9380 /** 9381 * This is used to mark the item as an indexed fast-search marker 9382 * 9383 * @type {boolean} 9384 */ 9385 set marker(isMarked) { 9386 if ((this.info & BIT4) > 0 !== isMarked) { 9387 this.info ^= BIT4; 9388 } 9389 } 9390 get marker() { 9391 return (this.info & BIT4) > 0; 9392 } 9393 /** 9394 * If true, do not garbage collect this Item. 9395 */ 9396 get keep() { 9397 return (this.info & BIT1) > 0; 9398 } 9399 set keep(doKeep) { 9400 if (this.keep !== doKeep) { 9401 this.info ^= BIT1; 9402 } 9403 } 9404 get countable() { 9405 return (this.info & BIT2) > 0; 9406 } 9407 /** 9408 * Whether this item was deleted or not. 9409 * @type {Boolean} 9410 */ 9411 get deleted() { 9412 return (this.info & BIT3) > 0; 9413 } 9414 set deleted(doDelete) { 9415 if (this.deleted !== doDelete) { 9416 this.info ^= BIT3; 9417 } 9418 } 9419 markDeleted() { 9420 this.info |= BIT3; 9421 } 9422 /** 9423 * Return the creator clientID of the missing op or define missing items and return null. 9424 * 9425 * @param {Transaction} transaction 9426 * @param {StructStore} store 9427 * @return {null | number} 9428 */ 9429 getMissing(transaction, store) { 9430 if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store, this.origin.client)) { 9431 return this.origin.client; 9432 } 9433 if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store, this.rightOrigin.client)) { 9434 return this.rightOrigin.client; 9435 } 9436 if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store, this.parent.client)) { 9437 return this.parent.client; 9438 } 9439 if (this.origin) { 9440 this.left = getItemCleanEnd(transaction, store, this.origin); 9441 this.origin = this.left.lastId; 9442 } 9443 if (this.rightOrigin) { 9444 this.right = getItemCleanStart(transaction, this.rightOrigin); 9445 this.rightOrigin = this.right.id; 9446 } 9447 if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { 9448 this.parent = null; 9449 } else if (!this.parent) { 9450 if (this.left && this.left.constructor === _Item) { 9451 this.parent = this.left.parent; 9452 this.parentSub = this.left.parentSub; 9453 } else if (this.right && this.right.constructor === _Item) { 9454 this.parent = this.right.parent; 9455 this.parentSub = this.right.parentSub; 9456 } 9457 } else if (this.parent.constructor === ID) { 9458 const parentItem = getItem(store, this.parent); 9459 if (parentItem.constructor === GC) { 9460 this.parent = null; 9461 } else { 9462 this.parent = /** @type {ContentType} */ 9463 parentItem.content.type; 9464 } 9465 } 9466 return null; 9467 } 9468 /** 9469 * @param {Transaction} transaction 9470 * @param {number} offset 9471 */ 9472 integrate(transaction, offset) { 9473 if (offset > 0) { 9474 this.id.clock += offset; 9475 this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); 9476 this.origin = this.left.lastId; 9477 this.content = this.content.splice(offset); 9478 this.length -= offset; 9479 } 9480 if (this.parent) { 9481 if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { 9482 let left = this.left; 9483 let o; 9484 if (left !== null) { 9485 o = left.right; 9486 } else if (this.parentSub !== null) { 9487 o = /** @type {AbstractType<any>} */ 9488 this.parent._map.get(this.parentSub) || null; 9489 while (o !== null && o.left !== null) { 9490 o = o.left; 9491 } 9492 } else { 9493 o = /** @type {AbstractType<any>} */ 9494 this.parent._start; 9495 } 9496 const conflictingItems = /* @__PURE__ */ new Set(); 9497 const itemsBeforeOrigin = /* @__PURE__ */ new Set(); 9498 while (o !== null && o !== this.right) { 9499 itemsBeforeOrigin.add(o); 9500 conflictingItems.add(o); 9501 if (compareIDs(this.origin, o.origin)) { 9502 if (o.id.client < this.id.client) { 9503 left = o; 9504 conflictingItems.clear(); 9505 } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { 9506 break; 9507 } 9508 } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { 9509 if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { 9510 left = o; 9511 conflictingItems.clear(); 9512 } 9513 } else { 9514 break; 9515 } 9516 o = o.right; 9517 } 9518 this.left = left; 9519 } 9520 if (this.left !== null) { 9521 const right = this.left.right; 9522 this.right = right; 9523 this.left.right = this; 9524 } else { 9525 let r; 9526 if (this.parentSub !== null) { 9527 r = /** @type {AbstractType<any>} */ 9528 this.parent._map.get(this.parentSub) || null; 9529 while (r !== null && r.left !== null) { 9530 r = r.left; 9531 } 9532 } else { 9533 r = /** @type {AbstractType<any>} */ 9534 this.parent._start; 9535 this.parent._start = this; 9536 } 9537 this.right = r; 9538 } 9539 if (this.right !== null) { 9540 this.right.left = this; 9541 } else if (this.parentSub !== null) { 9542 this.parent._map.set(this.parentSub, this); 9543 if (this.left !== null) { 9544 this.left.delete(transaction); 9545 } 9546 } 9547 if (this.parentSub === null && this.countable && !this.deleted) { 9548 this.parent._length += this.length; 9549 } 9550 addStruct(transaction.doc.store, this); 9551 this.content.integrate(transaction, this); 9552 addChangedTypeToTransaction( 9553 transaction, 9554 /** @type {AbstractType<any>} */ 9555 this.parent, 9556 this.parentSub 9557 ); 9558 if ( 9559 /** @type {AbstractType<any>} */ 9560 this.parent._item !== null && /** @type {AbstractType<any>} */ 9561 this.parent._item.deleted || this.parentSub !== null && this.right !== null 9562 ) { 9563 this.delete(transaction); 9564 } 9565 } else { 9566 new GC(this.id, this.length).integrate(transaction, 0); 9567 } 9568 } 9569 /** 9570 * Returns the next non-deleted item 9571 */ 9572 get next() { 9573 let n = this.right; 9574 while (n !== null && n.deleted) { 9575 n = n.right; 9576 } 9577 return n; 9578 } 9579 /** 9580 * Returns the previous non-deleted item 9581 */ 9582 get prev() { 9583 let n = this.left; 9584 while (n !== null && n.deleted) { 9585 n = n.left; 9586 } 9587 return n; 9588 } 9589 /** 9590 * Computes the last content address of this Item. 9591 */ 9592 get lastId() { 9593 return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); 9594 } 9595 /** 9596 * Try to merge two items 9597 * 9598 * @param {Item} right 9599 * @return {boolean} 9600 */ 9601 mergeWith(right) { 9602 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)) { 9603 const searchMarker = ( 9604 /** @type {AbstractType<any>} */ 9605 this.parent._searchMarker 9606 ); 9607 if (searchMarker) { 9608 searchMarker.forEach((marker) => { 9609 if (marker.p === right) { 9610 marker.p = this; 9611 if (!this.deleted && this.countable) { 9612 marker.index -= this.length; 9613 } 9614 } 9615 }); 9616 } 9617 if (right.keep) { 9618 this.keep = true; 9619 } 9620 this.right = right.right; 9621 if (this.right !== null) { 9622 this.right.left = this; 9623 } 9624 this.length += right.length; 9625 return true; 9626 } 9627 return false; 9628 } 9629 /** 9630 * Mark this Item as deleted. 9631 * 9632 * @param {Transaction} transaction 9633 */ 9634 delete(transaction) { 9635 if (!this.deleted) { 9636 const parent = ( 9637 /** @type {AbstractType<any>} */ 9638 this.parent 9639 ); 9640 if (this.countable && this.parentSub === null) { 9641 parent._length -= this.length; 9642 } 9643 this.markDeleted(); 9644 addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); 9645 addChangedTypeToTransaction(transaction, parent, this.parentSub); 9646 this.content.delete(transaction); 9647 } 9648 } 9649 /** 9650 * @param {StructStore} store 9651 * @param {boolean} parentGCd 9652 */ 9653 gc(store, parentGCd) { 9654 if (!this.deleted) { 9655 throw unexpectedCase(); 9656 } 9657 this.content.gc(store); 9658 if (parentGCd) { 9659 replaceStruct(store, this, new GC(this.id, this.length)); 9660 } else { 9661 this.content = new ContentDeleted(this.length); 9662 } 9663 } 9664 /** 9665 * Transform the properties of this type to binary and write it to an 9666 * BinaryEncoder. 9667 * 9668 * This is called when this Item is sent to a remote peer. 9669 * 9670 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 9671 * @param {number} offset 9672 */ 9673 write(encoder, offset) { 9674 const origin2 = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; 9675 const rightOrigin = this.rightOrigin; 9676 const parentSub = this.parentSub; 9677 const info = this.content.getRef() & BITS5 | (origin2 === null ? 0 : BIT8) | // origin is defined 9678 (rightOrigin === null ? 0 : BIT7) | // right origin is defined 9679 (parentSub === null ? 0 : BIT6); 9680 encoder.writeInfo(info); 9681 if (origin2 !== null) { 9682 encoder.writeLeftID(origin2); 9683 } 9684 if (rightOrigin !== null) { 9685 encoder.writeRightID(rightOrigin); 9686 } 9687 if (origin2 === null && rightOrigin === null) { 9688 const parent = ( 9689 /** @type {AbstractType<any>} */ 9690 this.parent 9691 ); 9692 if (parent._item !== void 0) { 9693 const parentItem = parent._item; 9694 if (parentItem === null) { 9695 const ykey = findRootTypeKey(parent); 9696 encoder.writeParentInfo(true); 9697 encoder.writeString(ykey); 9698 } else { 9699 encoder.writeParentInfo(false); 9700 encoder.writeLeftID(parentItem.id); 9701 } 9702 } else if (parent.constructor === String) { 9703 encoder.writeParentInfo(true); 9704 encoder.writeString(parent); 9705 } else if (parent.constructor === ID) { 9706 encoder.writeParentInfo(false); 9707 encoder.writeLeftID(parent); 9708 } else { 9709 unexpectedCase(); 9710 } 9711 if (parentSub !== null) { 9712 encoder.writeString(parentSub); 9713 } 9714 } 9715 this.content.write(encoder, offset); 9716 } 9717 }; 9718 var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); 9719 var contentRefs = [ 9720 () => { 9721 unexpectedCase(); 9722 }, 9723 // GC is not ItemContent 9724 readContentDeleted, 9725 // 1 9726 readContentJSON, 9727 // 2 9728 readContentBinary, 9729 // 3 9730 readContentString, 9731 // 4 9732 readContentEmbed, 9733 // 5 9734 readContentFormat, 9735 // 6 9736 readContentType, 9737 // 7 9738 readContentAny, 9739 // 8 9740 readContentDoc, 9741 // 9 9742 () => { 9743 unexpectedCase(); 9744 } 9745 // 10 - Skip is not ItemContent 9746 ]; 9747 var structSkipRefNumber = 10; 9748 var Skip = class extends AbstractStruct { 9749 get deleted() { 9750 return true; 9751 } 9752 delete() { 9753 } 9754 /** 9755 * @param {Skip} right 9756 * @return {boolean} 9757 */ 9758 mergeWith(right) { 9759 if (this.constructor !== right.constructor) { 9760 return false; 9761 } 9762 this.length += right.length; 9763 return true; 9764 } 9765 /** 9766 * @param {Transaction} transaction 9767 * @param {number} offset 9768 */ 9769 integrate(transaction, offset) { 9770 unexpectedCase(); 9771 } 9772 /** 9773 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9774 * @param {number} offset 9775 */ 9776 write(encoder, offset) { 9777 encoder.writeInfo(structSkipRefNumber); 9778 writeVarUint(encoder.restEncoder, this.length - offset); 9779 } 9780 /** 9781 * @param {Transaction} transaction 9782 * @param {StructStore} store 9783 * @return {null | number} 9784 */ 9785 getMissing(transaction, store) { 9786 return null; 9787 } 9788 }; 9789 var glo = ( 9790 /** @type {any} */ 9791 typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} 9792 ); 9793 var importIdentifier = "__ $YJS$ __"; 9794 if (glo[importIdentifier] === true) { 9795 console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); 9796 } 9797 glo[importIdentifier] = true; 9798 9799 // node_modules/y-protocols/awareness.js 9800 var outdatedTimeout = 3e4; 9801 var Awareness = class extends Observable { 9802 /** 9803 * @param {Y.Doc} doc 9804 */ 9805 constructor(doc2) { 9806 super(); 9807 this.doc = doc2; 9808 this.clientID = doc2.clientID; 9809 this.states = /* @__PURE__ */ new Map(); 9810 this.meta = /* @__PURE__ */ new Map(); 9811 this._checkInterval = /** @type {any} */ 9812 setInterval(() => { 9813 const now = getUnixTime(); 9814 if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ 9815 this.meta.get(this.clientID).lastUpdated) { 9816 this.setLocalState(this.getLocalState()); 9817 } 9818 const remove = []; 9819 this.meta.forEach((meta, clientid) => { 9820 if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { 9821 remove.push(clientid); 9822 } 9823 }); 9824 if (remove.length > 0) { 9825 removeAwarenessStates(this, remove, "timeout"); 9826 } 9827 }, floor(outdatedTimeout / 10)); 9828 doc2.on("destroy", () => { 9829 this.destroy(); 9830 }); 9831 this.setLocalState({}); 9832 } 9833 destroy() { 9834 this.emit("destroy", [this]); 9835 this.setLocalState(null); 9836 super.destroy(); 9837 clearInterval(this._checkInterval); 9838 } 9839 /** 9840 * @return {Object<string,any>|null} 9841 */ 9842 getLocalState() { 9843 return this.states.get(this.clientID) || null; 9844 } 9845 /** 9846 * @param {Object<string,any>|null} state 9847 */ 9848 setLocalState(state) { 9849 const clientID = this.clientID; 9850 const currLocalMeta = this.meta.get(clientID); 9851 const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; 9852 const prevState = this.states.get(clientID); 9853 if (state === null) { 9854 this.states.delete(clientID); 9855 } else { 9856 this.states.set(clientID, state); 9857 } 9858 this.meta.set(clientID, { 9859 clock, 9860 lastUpdated: getUnixTime() 9861 }); 9862 const added = []; 9863 const updated = []; 9864 const filteredUpdated = []; 9865 const removed = []; 9866 if (state === null) { 9867 removed.push(clientID); 9868 } else if (prevState == null) { 9869 if (state != null) { 9870 added.push(clientID); 9871 } 9872 } else { 9873 updated.push(clientID); 9874 if (!equalityDeep(prevState, state)) { 9875 filteredUpdated.push(clientID); 9876 } 9877 } 9878 if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { 9879 this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); 9880 } 9881 this.emit("update", [{ added, updated, removed }, "local"]); 9882 } 9883 /** 9884 * @param {string} field 9885 * @param {any} value 9886 */ 9887 setLocalStateField(field, value) { 9888 const state = this.getLocalState(); 9889 if (state !== null) { 9890 this.setLocalState({ 9891 ...state, 9892 [field]: value 9893 }); 9894 } 9895 } 9896 /** 9897 * @return {Map<number,Object<string,any>>} 9898 */ 9899 getStates() { 9900 return this.states; 9901 } 9902 }; 9903 var removeAwarenessStates = (awareness, clients, origin2) => { 9904 const removed = []; 9905 for (let i = 0; i < clients.length; i++) { 9906 const clientID = clients[i]; 9907 if (awareness.states.has(clientID)) { 9908 awareness.states.delete(clientID); 9909 if (clientID === awareness.clientID) { 9910 const curMeta = ( 9911 /** @type {MetaClientState} */ 9912 awareness.meta.get(clientID) 9913 ); 9914 awareness.meta.set(clientID, { 9915 clock: curMeta.clock + 1, 9916 lastUpdated: getUnixTime() 9917 }); 9918 } 9919 removed.push(clientID); 9920 } 9921 } 9922 if (removed.length > 0) { 9923 awareness.emit("change", [{ added: [], updated: [], removed }, origin2]); 9924 awareness.emit("update", [{ added: [], updated: [], removed }, origin2]); 9925 } 9926 }; 9927 9928 // packages/sync/build-module/config.mjs 9929 var CRDT_DOC_VERSION = 1; 9930 var CRDT_DOC_META_PERSISTENCE_KEY = "fromPersistence"; 9931 var CRDT_RECORD_MAP_KEY = "document"; 9932 var CRDT_STATE_MAP_KEY = "state"; 9933 var CRDT_STATE_MAP_SAVED_AT_KEY = "savedAt"; 9934 var CRDT_STATE_MAP_SAVED_BY_KEY = "savedBy"; 9935 var CRDT_STATE_MAP_VERSION_KEY = "version"; 9936 var LOCAL_EDITOR_ORIGIN = "gutenberg"; 9937 var LOCAL_SYNC_MANAGER_ORIGIN = "syncManager"; 9938 var LOCAL_UNDO_IGNORED_ORIGIN = "gutenberg-undo-ignored"; 9939 9940 // packages/sync/build-module/errors.mjs 9941 var ConnectionErrorCode = /* @__PURE__ */ ((ConnectionErrorCode2) => { 9942 ConnectionErrorCode2["AUTHENTICATION_FAILED"] = "authentication-failed"; 9943 ConnectionErrorCode2["CONNECTION_EXPIRED"] = "connection-expired"; 9944 ConnectionErrorCode2["CONNECTION_LIMIT_EXCEEDED"] = "connection-limit-exceeded"; 9945 ConnectionErrorCode2["DOCUMENT_SIZE_LIMIT_EXCEEDED"] = "document-size-limit-exceeded"; 9946 ConnectionErrorCode2["PROTOCOL_MISMATCH"] = "protocol-mismatch"; 9947 ConnectionErrorCode2["UNKNOWN_ERROR"] = "unknown-error"; 9948 return ConnectionErrorCode2; 9949 })(ConnectionErrorCode || {}); 9950 var ConnectionError = class extends Error { 9951 constructor(code = "unknown-error", message) { 9952 super(message); 9953 this.code = code; 9954 this.name = "ConnectionError"; 9955 } 9956 }; 9957 9958 // packages/sync/build-module/lock-unlock.mjs 9959 var import_private_apis = __toESM(require_private_apis(), 1); 9960 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 9961 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 9962 "@wordpress/sync" 9963 ); 9964 9965 // packages/sync/build-module/performance.mjs 9966 function logPerformanceTiming(fn) { 9967 return function(...args2) { 9968 const start = performance.now(); 9969 const result = fn.apply(this, args2); 9970 const end = performance.now(); 9971 console.log( 9972 `[SyncManager][performance]: $fn.name} took ${(end - start).toFixed(2)} ms` 9973 ); 9974 return result; 9975 }; 9976 } 9977 function passThru(fn) { 9978 return ((...args2) => fn(...args2)); 9979 } 9980 function yieldToEventLoop(fn) { 9981 return function(...args2) { 9982 setTimeout(() => { 9983 fn.apply(this, args2); 9984 }, 0); 9985 }; 9986 } 9987 9988 // packages/sync/build-module/providers/index.mjs 9989 var import_hooks3 = __toESM(require_hooks(), 1); 9990 9991 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 9992 var import_hooks2 = __toESM(require_hooks(), 1); 9993 9994 // node_modules/y-protocols/sync.js 9995 var messageYjsSyncStep1 = 0; 9996 var messageYjsSyncStep2 = 1; 9997 var messageYjsUpdate = 2; 9998 var writeSyncStep1 = (encoder, doc2) => { 9999 writeVarUint(encoder, messageYjsSyncStep1); 10000 const sv = encodeStateVector(doc2); 10001 writeVarUint8Array(encoder, sv); 10002 }; 10003 var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { 10004 writeVarUint(encoder, messageYjsSyncStep2); 10005 writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); 10006 }; 10007 var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); 10008 var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { 10009 try { 10010 applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); 10011 } catch (error) { 10012 if (errorHandler != null) errorHandler( 10013 /** @type {Error} */ 10014 error 10015 ); 10016 console.error("Caught error while handling a Yjs update", error); 10017 } 10018 }; 10019 var readUpdate2 = readSyncStep2; 10020 var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { 10021 const messageType = readVarUint(decoder); 10022 switch (messageType) { 10023 case messageYjsSyncStep1: 10024 readSyncStep1(decoder, encoder, doc2); 10025 break; 10026 case messageYjsSyncStep2: 10027 readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); 10028 break; 10029 case messageYjsUpdate: 10030 readUpdate2(decoder, doc2, transactionOrigin, errorHandler); 10031 break; 10032 default: 10033 throw new Error("Unknown message type"); 10034 } 10035 return messageType; 10036 }; 10037 10038 // packages/sync/build-module/providers/http-polling/config.mjs 10039 var import_hooks = __toESM(require_hooks(), 1); 10040 var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; 10041 var ERROR_RETRY_DELAYS_SOLO_MS = [ 10042 2e3, 10043 4e3, 10044 8e3, 10045 12e3 10046 // Solo: 26s total retry time solo before dialog 10047 ]; 10048 var ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS = [ 10049 1e3, 10050 2e3, 10051 4e3, 10052 8e3 10053 // With collaborators: 15s total retry time before dialog 10054 ]; 10055 var DISCONNECT_DIALOG_RETRY_MS = 3e4; 10056 var MANUAL_RETRY_INTERVAL_MS = 15e3; 10057 var MAX_ENCODED_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; 10058 var MAX_UPDATE_SIZE_IN_BYTES = Math.floor(MAX_ENCODED_UPDATE_SIZE_IN_BYTES / 4) * 3; 10059 var MAX_ROOMS_PER_REQUEST = 50; 10060 var MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES = 15 * 1024 * 1024; 10061 var MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES = 2 * 1024 * 1024; 10062 var DEFAULT_POLLING_INTERVAL_IN_MS = 4e3; 10063 var DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = 1e3; 10064 function getFilteredPollingInterval(hookName, defaultInterval) { 10065 const filteredInterval = (0, import_hooks.applyFilters)(hookName, defaultInterval); 10066 if (typeof filteredInterval !== "number" || !Number.isFinite(filteredInterval) || filteredInterval <= 0) { 10067 return defaultInterval; 10068 } 10069 return Math.min(filteredInterval, defaultInterval); 10070 } 10071 var POLLING_INTERVAL_IN_MS = getFilteredPollingInterval( 10072 "sync.pollingManager.pollingInterval", 10073 DEFAULT_POLLING_INTERVAL_IN_MS 10074 ); 10075 var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = getFilteredPollingInterval( 10076 "sync.pollingManager.pollingIntervalWithCollaborators", 10077 DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS 10078 ); 10079 var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; 10080 10081 // packages/sync/build-module/providers/http-polling/types.mjs 10082 var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { 10083 SyncUpdateType2["COMPACTION"] = "compaction"; 10084 SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; 10085 SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; 10086 SyncUpdateType2["UPDATE"] = "update"; 10087 return SyncUpdateType2; 10088 })(SyncUpdateType || {}); 10089 10090 // packages/sync/build-module/providers/http-polling/utils.mjs 10091 var import_api_fetch = __toESM(require_api_fetch(), 1); 10092 var SYNC_API_PATH = "/wp-sync/v1/updates"; 10093 function uint8ArrayToBase64(data) { 10094 let binary = ""; 10095 const len = data.byteLength; 10096 for (let i = 0; i < len; i++) { 10097 binary += String.fromCharCode(data[i]); 10098 } 10099 return globalThis.btoa(binary); 10100 } 10101 function base64ToUint8Array(base64) { 10102 const binaryString = globalThis.atob(base64); 10103 const len = binaryString.length; 10104 const bytes = new Uint8Array(len); 10105 for (let i = 0; i < len; i++) { 10106 bytes[i] = binaryString.charCodeAt(i); 10107 } 10108 return bytes; 10109 } 10110 function createSyncUpdate(data, type) { 10111 return { 10112 data: uint8ArrayToBase64(data), 10113 type 10114 }; 10115 } 10116 function createUpdateQueue(initial = [], paused = true) { 10117 let isPaused = paused; 10118 const updates = [...initial]; 10119 return { 10120 add(update) { 10121 updates.push(update); 10122 }, 10123 addBulk(bulkUpdates) { 10124 if (0 === bulkUpdates.length) { 10125 return; 10126 } 10127 updates.push(...bulkUpdates); 10128 }, 10129 clear() { 10130 updates.splice(0, updates.length); 10131 }, 10132 get() { 10133 if (isPaused) { 10134 return []; 10135 } 10136 return updates.splice(0, updates.length); 10137 }, 10138 pause() { 10139 isPaused = true; 10140 }, 10141 peek() { 10142 if (isPaused) { 10143 return []; 10144 } 10145 return [...updates]; 10146 }, 10147 restore(restoredUpdates) { 10148 const filtered = restoredUpdates.filter( 10149 (u) => u.type !== SyncUpdateType.COMPACTION 10150 ); 10151 if (0 === filtered.length) { 10152 return; 10153 } 10154 updates.unshift(...filtered); 10155 }, 10156 restoreExact(restoredUpdates) { 10157 if (0 === restoredUpdates.length) { 10158 return; 10159 } 10160 updates.unshift(...restoredUpdates); 10161 }, 10162 resume() { 10163 isPaused = false; 10164 }, 10165 size() { 10166 return updates.length; 10167 }, 10168 take(count) { 10169 if (isPaused || count <= 0) { 10170 return []; 10171 } 10172 return updates.splice(0, count); 10173 } 10174 }; 10175 } 10176 function postSyncUpdate(payload) { 10177 return (0, import_api_fetch.default)({ 10178 method: "POST", 10179 path: SYNC_API_PATH, 10180 data: payload 10181 }); 10182 } 10183 function postSyncUpdateNonBlocking(payload) { 10184 if (payload.rooms.length === 0) { 10185 return; 10186 } 10187 (0, import_api_fetch.default)({ 10188 method: "POST", 10189 path: SYNC_API_PATH, 10190 data: payload, 10191 keepalive: true 10192 }).catch(() => { 10193 }); 10194 } 10195 function intValueOrDefault(value, defaultValue) { 10196 const intValue = parseInt(String(value), 10); 10197 return isNaN(intValue) ? defaultValue : intValue; 10198 } 10199 function rotateWindow(items, offset, size2) { 10200 if (items.length === 0) { 10201 return { window: [], nextOffset: 0 }; 10202 } 10203 const start = (offset % items.length + items.length) % items.length; 10204 const wrapped = [...items.slice(start), ...items.slice(0, start)]; 10205 return { 10206 window: wrapped.slice(0, Math.max(0, size2)), 10207 nextOffset: (start + Math.max(0, size2)) % items.length 10208 }; 10209 } 10210 10211 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 10212 var POLLING_MANAGER_ORIGIN = "polling-manager"; 10213 function isForbiddenError(error) { 10214 return error?.data?.status === 403; 10215 } 10216 function isRequestBodyTooLargeError(error) { 10217 return error?.data?.status === 413 && error?.code === "rest_sync_body_too_large"; 10218 } 10219 function isProtocolMismatchError(error) { 10220 return error?.code === "rest_sync_protocol_mismatch"; 10221 } 10222 function handleForbiddenError(error, requestedRooms) { 10223 const requestedRoomNames = new Set( 10224 requestedRooms.map((room) => room.room) 10225 ); 10226 const forbiddenRooms = Array.isArray(error.data.rooms) ? error.data.rooms.filter((room) => requestedRoomNames.has(room)) : []; 10227 if (forbiddenRooms.length > 0) { 10228 for (const room of forbiddenRooms) { 10229 const state = roomStates.get(room); 10230 if (state) { 10231 state.log( 10232 "Permission denied, unregistering room", 10233 { error }, 10234 "error", 10235 true 10236 // force 10237 ); 10238 unregisterRoom(room, { sendDisconnectSignal: false }); 10239 } 10240 } 10241 for (const room of requestedRooms) { 10242 if (forbiddenRooms.includes(room.room)) { 10243 continue; 10244 } 10245 if (!roomStates.has(room.room)) { 10246 continue; 10247 } 10248 const remainingState = roomStates.get(room.room); 10249 if (room.updates.length > 0) { 10250 remainingState.updateQueue.restore(room.updates); 10251 } 10252 } 10253 } else { 10254 const rooms = [...roomStates.keys()]; 10255 for (const room of rooms) { 10256 const state = roomStates.get(room); 10257 if (state) { 10258 state.log( 10259 "Permission denied, unregistering room", 10260 { error }, 10261 "error", 10262 true 10263 // force 10264 ); 10265 unregisterRoom(room, { sendDisconnectSignal: false }); 10266 } 10267 } 10268 } 10269 } 10270 var roomStates = /* @__PURE__ */ new Map(); 10271 function createDeprecatedCompactionUpdate(updates) { 10272 const mergeable = updates.filter( 10273 (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( 10274 u.type 10275 ) 10276 ).map((u) => base64ToUint8Array(u.data)); 10277 return createSyncUpdate( 10278 mergeUpdatesV2(mergeable), 10279 SyncUpdateType.COMPACTION 10280 ); 10281 } 10282 function createSyncStep1Update(doc2) { 10283 const encoder = createEncoder(); 10284 writeSyncStep1(encoder, doc2); 10285 return createSyncUpdate( 10286 toUint8Array(encoder), 10287 SyncUpdateType.SYNC_STEP_1 10288 ); 10289 } 10290 function createSyncStep2Update(doc2, step1) { 10291 const decoder = createDecoder(step1); 10292 const encoder = createEncoder(); 10293 readSyncMessage( 10294 decoder, 10295 encoder, 10296 doc2, 10297 POLLING_MANAGER_ORIGIN 10298 ); 10299 return createSyncUpdate( 10300 toUint8Array(encoder), 10301 SyncUpdateType.SYNC_STEP_2 10302 ); 10303 } 10304 function processAwarenessUpdate(state, awareness) { 10305 const currentStates = awareness.getStates(); 10306 const added = /* @__PURE__ */ new Set(); 10307 const updated = /* @__PURE__ */ new Set(); 10308 const removed = new Set( 10309 Array.from(currentStates.keys()).filter( 10310 (clientId) => !state[clientId] 10311 ) 10312 ); 10313 Object.entries(state).forEach(([clientIdString, awarenessState]) => { 10314 const clientId = Number(clientIdString); 10315 if (clientId === awareness.clientID) { 10316 return; 10317 } 10318 if (null === awarenessState) { 10319 currentStates.delete(clientId); 10320 removed.add(clientId); 10321 return; 10322 } 10323 if (!currentStates.has(clientId)) { 10324 currentStates.set(clientId, awarenessState); 10325 added.add(clientId); 10326 return; 10327 } 10328 const currentState = currentStates.get(clientId); 10329 if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { 10330 currentStates.set(clientId, awarenessState); 10331 updated.add(clientId); 10332 } 10333 }); 10334 if (added.size + updated.size > 0) { 10335 awareness.emit("change", [ 10336 { 10337 added: Array.from(added), 10338 updated: Array.from(updated), 10339 // Left blank on purpose, as the removal of clients is handled in the if condition below. 10340 removed: [] 10341 } 10342 ]); 10343 } 10344 if (removed.size > 0) { 10345 removeAwarenessStates( 10346 awareness, 10347 Array.from(removed), 10348 POLLING_MANAGER_ORIGIN 10349 ); 10350 } 10351 } 10352 function processDocUpdate(update, doc2, onSync) { 10353 const data = base64ToUint8Array(update.data); 10354 switch (update.type) { 10355 case SyncUpdateType.SYNC_STEP_1: { 10356 return createSyncStep2Update(doc2, data); 10357 } 10358 case SyncUpdateType.SYNC_STEP_2: { 10359 const decoder = createDecoder(data); 10360 const encoder = createEncoder(); 10361 readSyncMessage( 10362 decoder, 10363 encoder, 10364 doc2, 10365 POLLING_MANAGER_ORIGIN 10366 ); 10367 onSync(); 10368 return; 10369 } 10370 case SyncUpdateType.COMPACTION: 10371 case SyncUpdateType.UPDATE: { 10372 applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); 10373 } 10374 } 10375 } 10376 function checkConnectionLimit(awareness, roomState) { 10377 if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { 10378 return false; 10379 } 10380 hasCheckedConnectionLimit = true; 10381 const maxClientsPerRoom = (0, import_hooks2.applyFilters)( 10382 "sync.pollingProvider.maxClientsPerRoom", 10383 DEFAULT_CLIENT_LIMIT_PER_ROOM, 10384 roomState.room 10385 ); 10386 const clientCount = Object.keys(awareness).length; 10387 const validatedLimit = intValueOrDefault( 10388 maxClientsPerRoom, 10389 DEFAULT_CLIENT_LIMIT_PER_ROOM 10390 ); 10391 if (clientCount > validatedLimit) { 10392 roomState.log("Connection limit exceeded", { 10393 clientCount, 10394 maxClientsPerRoom: validatedLimit, 10395 room: roomState.room 10396 }); 10397 return true; 10398 } 10399 return false; 10400 } 10401 var areListenersRegistered = false; 10402 var consecutiveFailures = 0; 10403 var hasCheckedConnectionLimit = false; 10404 var isManualRetry = false; 10405 var hasCollaborators = false; 10406 var isActiveBrowser = "visible" === document.visibilityState; 10407 var isPolling = false; 10408 var isUnloadPending = false; 10409 var pollInterval = POLLING_INTERVAL_IN_MS; 10410 var pollingTimeoutId = null; 10411 var syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10412 var roomOverflowOffset = 0; 10413 function handleBeforeUnload() { 10414 isUnloadPending = true; 10415 } 10416 function handlePageHide() { 10417 const rooms = Array.from(roomStates.entries()).map( 10418 ([room, state]) => ({ 10419 after: 0, 10420 awareness: null, 10421 client_id: state.clientId, 10422 room, 10423 updates: [] 10424 }) 10425 ); 10426 for (let i = 0; i < rooms.length; i += MAX_ROOMS_PER_REQUEST) { 10427 postSyncUpdateNonBlocking({ 10428 rooms: rooms.slice(i, i + MAX_ROOMS_PER_REQUEST) 10429 }); 10430 } 10431 } 10432 function handleVisibilityChange() { 10433 const wasActive = isActiveBrowser; 10434 isActiveBrowser = document.visibilityState === "visible"; 10435 if (isActiveBrowser && !wasActive) { 10436 if (pollingTimeoutId) { 10437 clearTimeout(pollingTimeoutId); 10438 pollingTimeoutId = null; 10439 poll(); 10440 } 10441 } 10442 } 10443 function selectRoomsForRequest() { 10444 const allRooms = Array.from(roomStates.values()); 10445 if (allRooms.length <= MAX_ROOMS_PER_REQUEST) { 10446 return allRooms; 10447 } 10448 const primaryRoom = allRooms.find((state) => state.isPrimaryRoom); 10449 const overflowRooms = allRooms.filter((state) => state !== primaryRoom); 10450 const overflowSlotsPerRequest = MAX_ROOMS_PER_REQUEST - (primaryRoom ? 1 : 0); 10451 const { window: overflowSlice, nextOffset } = rotateWindow( 10452 overflowRooms, 10453 roomOverflowOffset, 10454 overflowSlotsPerRequest 10455 ); 10456 roomOverflowOffset = nextOffset; 10457 if (primaryRoom) { 10458 return [primaryRoom, ...overflowSlice]; 10459 } 10460 return overflowSlice; 10461 } 10462 var textEncoder = new TextEncoder(); 10463 function getJsonByteLength(value) { 10464 return textEncoder.encode(JSON.stringify(value)).byteLength; 10465 } 10466 function createPayloadRoom(state, updates = []) { 10467 return { 10468 after: state.endCursor ?? 0, 10469 awareness: state.localAwarenessState, 10470 client_id: state.clientId, 10471 room: state.room, 10472 updates 10473 }; 10474 } 10475 function getUpdatePayloadSizeDelta(existingUpdateCount, update) { 10476 const commaSize = existingUpdateCount === 0 ? 0 : 1; 10477 return commaSize + getJsonByteLength(update); 10478 } 10479 function buildPayloadForRequest(selectedRoomStates) { 10480 const payload = { rooms: [] }; 10481 const roomsInRequest = []; 10482 for (const state of selectedRoomStates) { 10483 const room = createPayloadRoom(state); 10484 const candidate = { rooms: [...payload.rooms, room] }; 10485 if (payload.rooms.length > 0 && getJsonByteLength(candidate) > syncRequestBodySizeLimit) { 10486 break; 10487 } 10488 payload.rooms.push(room); 10489 roomsInRequest.push(state); 10490 } 10491 const pendingUpdates = roomsInRequest.map( 10492 (state) => state.updateQueue.peek() 10493 ); 10494 const sentUpdateCounts = roomsInRequest.map(() => 0); 10495 let payloadSize = getJsonByteLength(payload); 10496 let addedUpdate = true; 10497 while (addedUpdate) { 10498 addedUpdate = false; 10499 for (let i = 0; i < roomsInRequest.length; i++) { 10500 const update = pendingUpdates[i][sentUpdateCounts[i]]; 10501 if (!update) { 10502 continue; 10503 } 10504 const sizeDelta = getUpdatePayloadSizeDelta( 10505 sentUpdateCounts[i], 10506 update 10507 ); 10508 if (payloadSize + sizeDelta > syncRequestBodySizeLimit) { 10509 continue; 10510 } 10511 sentUpdateCounts[i]++; 10512 payloadSize += sizeDelta; 10513 addedUpdate = true; 10514 } 10515 } 10516 for (let i = 0; i < roomsInRequest.length; i++) { 10517 payload.rooms[i].updates = roomsInRequest[i].updateQueue.take( 10518 sentUpdateCounts[i] 10519 ); 10520 } 10521 return { payload, roomsInRequest }; 10522 } 10523 function restoreExactUpdates(payload) { 10524 for (const room of payload.rooms) { 10525 if (!roomStates.has(room.room) || room.updates.length === 0) { 10526 continue; 10527 } 10528 roomStates.get(room.room).updateQueue.restoreExact(room.updates); 10529 } 10530 } 10531 function poll() { 10532 isPolling = true; 10533 pollingTimeoutId = null; 10534 async function start() { 10535 if (0 === roomStates.size) { 10536 isPolling = false; 10537 return; 10538 } 10539 isUnloadPending = false; 10540 const { payload, roomsInRequest } = buildPayloadForRequest( 10541 selectRoomsForRequest() 10542 ); 10543 roomsInRequest.forEach((state) => { 10544 state.onStatusChange({ status: "connecting" }); 10545 }); 10546 try { 10547 const { rooms } = await postSyncUpdate(payload); 10548 consecutiveFailures = 0; 10549 isManualRetry = false; 10550 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10551 roomsInRequest.forEach((state) => { 10552 if (roomStates.get(state.room) !== state) { 10553 return; 10554 } 10555 state.onStatusChange({ status: "connected" }); 10556 }); 10557 hasCollaborators = false; 10558 rooms.forEach((room) => { 10559 if (!roomStates.has(room.room)) { 10560 return; 10561 } 10562 const roomState = roomStates.get(room.room); 10563 roomState.endCursor = room.end_cursor; 10564 if (checkConnectionLimit(room.awareness, roomState)) { 10565 roomState.onStatusChange({ 10566 status: "disconnected", 10567 error: new ConnectionError( 10568 ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, 10569 "Connection limit exceeded" 10570 ) 10571 }); 10572 unregisterRoom(room.room); 10573 return; 10574 } 10575 roomState.processAwarenessUpdate(room.awareness); 10576 if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { 10577 hasCollaborators = true; 10578 roomStates.forEach((state) => { 10579 state.updateQueue.resume(); 10580 }); 10581 } 10582 const responseUpdates = []; 10583 for (const update of room.updates) { 10584 try { 10585 const response = roomState.processDocUpdate(update); 10586 if (response) { 10587 responseUpdates.push(response); 10588 } 10589 } catch (error) { 10590 roomState.log( 10591 "Failed to apply sync update", 10592 { error, update }, 10593 "error", 10594 true 10595 // force 10596 ); 10597 } 10598 } 10599 roomState.updateQueue.addBulk(responseUpdates); 10600 if (room.should_compact) { 10601 roomState.log("Server requested compaction update"); 10602 roomState.updateQueue.clear(); 10603 roomState.updateQueue.add( 10604 roomState.createCompactionUpdate() 10605 ); 10606 } else if (room.compaction_request) { 10607 roomState.log("Server requested (old) compaction update"); 10608 roomState.updateQueue.add( 10609 createDeprecatedCompactionUpdate( 10610 room.compaction_request 10611 ) 10612 ); 10613 } 10614 }); 10615 if (isActiveBrowser && hasCollaborators) { 10616 pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; 10617 } else if (isActiveBrowser) { 10618 pollInterval = POLLING_INTERVAL_IN_MS; 10619 } else { 10620 pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; 10621 } 10622 } catch (error) { 10623 if (isForbiddenError(error)) { 10624 handleForbiddenError(error, payload.rooms); 10625 if (roomStates.size === 0) { 10626 isPolling = false; 10627 return; 10628 } 10629 } else if (isRequestBodyTooLargeError(error)) { 10630 syncRequestBodySizeLimit = Math.max( 10631 MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES, 10632 Math.floor(syncRequestBodySizeLimit / 2) 10633 ); 10634 pollInterval = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS[0] : ERROR_RETRY_DELAYS_SOLO_MS[0]; 10635 restoreExactUpdates(payload); 10636 for (const room of payload.rooms) { 10637 if (!roomStates.has(room.room)) { 10638 continue; 10639 } 10640 roomStates.get(room.room).log( 10641 "Sync request body too large, retrying with smaller batches", 10642 { 10643 error, 10644 nextPoll: pollInterval, 10645 syncRequestBodySizeLimit 10646 }, 10647 "error", 10648 true 10649 // force 10650 ); 10651 } 10652 } else if (isProtocolMismatchError(error)) { 10653 const affectedRooms = [...roomStates.entries()]; 10654 for (const [, state] of affectedRooms) { 10655 state.onStatusChange({ 10656 status: "disconnected", 10657 error: new ConnectionError( 10658 ConnectionErrorCode.PROTOCOL_MISMATCH, 10659 "Protocol mismatch between client and server" 10660 ) 10661 }); 10662 } 10663 for (const [room] of affectedRooms) { 10664 unregisterRoom(room, { sendDisconnectSignal: false }); 10665 } 10666 isPolling = false; 10667 return; 10668 } else { 10669 consecutiveFailures++; 10670 const retrySchedule = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS : ERROR_RETRY_DELAYS_SOLO_MS; 10671 if (consecutiveFailures <= retrySchedule.length) { 10672 pollInterval = retrySchedule[consecutiveFailures - 1]; 10673 } else { 10674 pollInterval = DISCONNECT_DIALOG_RETRY_MS; 10675 } 10676 if (isManualRetry) { 10677 pollInterval = MANUAL_RETRY_INTERVAL_MS; 10678 isManualRetry = false; 10679 } 10680 for (const room of payload.rooms) { 10681 if (!roomStates.has(room.room)) { 10682 continue; 10683 } 10684 const state = roomStates.get(room.room); 10685 if (room.updates.length > 0 && state.endCursor > 0) { 10686 state.updateQueue.clear(); 10687 state.updateQueue.add(state.createCompactionUpdate()); 10688 } else if (room.updates.length > 0) { 10689 state.updateQueue.restore(room.updates); 10690 } 10691 state.log( 10692 "Error posting sync update, will retry with backoff", 10693 { error, nextPoll: pollInterval }, 10694 "error", 10695 true 10696 // force 10697 ); 10698 } 10699 if (!isUnloadPending) { 10700 const backgroundRetriesFailed = consecutiveFailures > retrySchedule.length; 10701 roomsInRequest.forEach((state) => { 10702 if (roomStates.get(state.room) !== state) { 10703 return; 10704 } 10705 state.onStatusChange({ 10706 status: "disconnected", 10707 canManuallyRetry: true, 10708 consecutiveFailures, 10709 backgroundRetriesFailed, 10710 willAutoRetryInMs: pollInterval 10711 }); 10712 }); 10713 } 10714 } 10715 } 10716 pollingTimeoutId = setTimeout(poll, pollInterval); 10717 } 10718 void start(); 10719 } 10720 function registerRoom({ 10721 room, 10722 doc: doc2, 10723 awareness, 10724 log, 10725 onSync, 10726 onStatusChange 10727 }) { 10728 if (roomStates.has(room)) { 10729 return; 10730 } 10731 const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); 10732 const isPrimaryRoom = 0 === roomStates.size; 10733 function onAwarenessUpdate() { 10734 roomState.localAwarenessState = awareness.getLocalState() ?? {}; 10735 } 10736 function onDocUpdate(update, origin2) { 10737 if (POLLING_MANAGER_ORIGIN === origin2) { 10738 return; 10739 } 10740 if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { 10741 const state = roomStates.get(room); 10742 if (!state) { 10743 return; 10744 } 10745 state.log("Document size limit exceeded", { 10746 maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, 10747 updateSizeInBytes: update.byteLength 10748 }); 10749 state.onStatusChange({ 10750 status: "disconnected", 10751 error: new ConnectionError( 10752 ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, 10753 "Document size limit exceeded" 10754 ) 10755 }); 10756 unregisterRoom(room); 10757 return; 10758 } 10759 updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); 10760 } 10761 function unregister() { 10762 doc2.off("updateV2", onDocUpdate); 10763 awareness.off("change", onAwarenessUpdate); 10764 updateQueue.clear(); 10765 } 10766 const roomState = { 10767 clientId: doc2.clientID, 10768 createCompactionUpdate: () => createSyncUpdate( 10769 encodeStateAsUpdateV2(doc2), 10770 SyncUpdateType.COMPACTION 10771 ), 10772 endCursor: 0, 10773 isPrimaryRoom, 10774 localAwarenessState: awareness.getLocalState() ?? {}, 10775 log, 10776 onStatusChange, 10777 processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), 10778 processDocUpdate: (update) => processDocUpdate(update, doc2, onSync), 10779 room, 10780 unregister, 10781 updateQueue 10782 }; 10783 doc2.on("updateV2", onDocUpdate); 10784 awareness.on("change", onAwarenessUpdate); 10785 roomStates.set(room, roomState); 10786 if (!areListenersRegistered) { 10787 window.addEventListener("beforeunload", handleBeforeUnload); 10788 window.addEventListener("pagehide", handlePageHide); 10789 document.addEventListener("visibilitychange", handleVisibilityChange); 10790 areListenersRegistered = true; 10791 } 10792 if (!isPolling) { 10793 poll(); 10794 } 10795 } 10796 function unregisterRoom(room, { sendDisconnectSignal = true } = {}) { 10797 const state = roomStates.get(room); 10798 if (state) { 10799 if (sendDisconnectSignal) { 10800 const rooms = [ 10801 { 10802 after: 0, 10803 awareness: null, 10804 client_id: state.clientId, 10805 room, 10806 updates: [] 10807 } 10808 ]; 10809 postSyncUpdateNonBlocking({ rooms }); 10810 } 10811 state.unregister(); 10812 roomStates.delete(room); 10813 } 10814 if (0 === roomStates.size && areListenersRegistered) { 10815 window.removeEventListener("beforeunload", handleBeforeUnload); 10816 window.removeEventListener("pagehide", handlePageHide); 10817 document.removeEventListener( 10818 "visibilitychange", 10819 handleVisibilityChange 10820 ); 10821 areListenersRegistered = false; 10822 hasCheckedConnectionLimit = false; 10823 consecutiveFailures = 0; 10824 roomOverflowOffset = 0; 10825 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10826 } 10827 } 10828 function retryNow() { 10829 isManualRetry = true; 10830 if (pollingTimeoutId) { 10831 clearTimeout(pollingTimeoutId); 10832 pollingTimeoutId = null; 10833 poll(); 10834 } 10835 } 10836 var pollingManager = { 10837 registerRoom, 10838 retryNow, 10839 unregisterRoom 10840 }; 10841 10842 // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs 10843 var HttpPollingProvider = class extends ObservableV2 { 10844 constructor(options) { 10845 super(); 10846 this.options = options; 10847 this.log("Initializing", { room: options.room }); 10848 this.awareness = options.awareness ?? new Awareness(options.ydoc); 10849 this.connect(); 10850 } 10851 awareness; 10852 status = "disconnected"; 10853 synced = false; 10854 /** 10855 * Connect to the endpoint and initialize sync. 10856 */ 10857 connect() { 10858 this.log("Connecting"); 10859 pollingManager.registerRoom({ 10860 room: this.options.room, 10861 doc: this.options.ydoc, 10862 awareness: this.awareness, 10863 log: this.log, 10864 onStatusChange: this.emitStatus, 10865 onSync: this.onSync 10866 }); 10867 } 10868 /** 10869 * Destroy the provider and cleanup resources. 10870 */ 10871 destroy() { 10872 this.disconnect(); 10873 super.destroy(); 10874 } 10875 /** 10876 * Disconnect the provider and allow reconnection later. 10877 */ 10878 disconnect() { 10879 this.log("Disconnecting"); 10880 pollingManager.unregisterRoom(this.options.room); 10881 this.emitStatus({ status: "disconnected" }); 10882 } 10883 /** 10884 * Emit connection status, passing the full object through so that 10885 * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. 10886 * 10887 * @param connectionStatus The connection status object 10888 */ 10889 emitStatus = (connectionStatus) => { 10890 const { status } = connectionStatus; 10891 const error = status === "disconnected" ? connectionStatus.error : void 0; 10892 if (this.status === status && !error) { 10893 return; 10894 } 10895 if (status === "connecting" && this.status !== "disconnected") { 10896 return; 10897 } 10898 this.log("Status change", { status, error }); 10899 this.status = status; 10900 this.emit("status", [connectionStatus]); 10901 }; 10902 /** 10903 * Log debug messages if debugging is enabled. 10904 * 10905 * @param message The debug message 10906 * @param debug Additional debug information 10907 * @param errorLevel The console method to use for logging 10908 * @param force Whether to force logging regardless of debug setting 10909 */ 10910 log = (message, debug = {}, errorLevel = "log", force = false) => { 10911 if (!this.options.debug && !force) { 10912 return; 10913 } 10914 const logFn = console[errorLevel] || console.log; 10915 logFn(`[$this.constructor.name}]: $message}`, { 10916 room: this.options.room, 10917 ...debug 10918 }); 10919 }; 10920 /** 10921 * Handle synchronization events from the polling manager. 10922 */ 10923 onSync = () => { 10924 if (!this.synced) { 10925 this.synced = true; 10926 this.log("Synced"); 10927 } 10928 }; 10929 }; 10930 function createHttpPollingProvider() { 10931 return async ({ 10932 awareness, 10933 objectType, 10934 objectId, 10935 ydoc 10936 }) => { 10937 const room = objectId ? `$objectType}:$objectId}` : objectType; 10938 const provider = new HttpPollingProvider({ 10939 awareness, 10940 // debug: true, 10941 room, 10942 ydoc 10943 }); 10944 return { 10945 destroy: () => provider.destroy(), 10946 // Adapter: ObservableV2.on is compatible with ProviderOn 10947 // The callback receives data as the first parameter 10948 on: (event, callback) => { 10949 provider.on(event, callback); 10950 } 10951 }; 10952 }; 10953 } 10954 10955 // packages/sync/build-module/providers/index.mjs 10956 var providerCreators = null; 10957 function getDefaultProviderCreators() { 10958 return [createHttpPollingProvider()]; 10959 } 10960 function isProviderCreator(creator) { 10961 return "function" === typeof creator; 10962 } 10963 function getProviderCreators() { 10964 if (providerCreators) { 10965 return providerCreators; 10966 } 10967 if (!window._wpCollaborationEnabled) { 10968 return []; 10969 } 10970 const filteredProviderCreators = (0, import_hooks3.applyFilters)( 10971 "sync.providers", 10972 getDefaultProviderCreators() 10973 ); 10974 if (!Array.isArray(filteredProviderCreators)) { 10975 providerCreators = []; 10976 return providerCreators; 10977 } 10978 providerCreators = filteredProviderCreators.filter(isProviderCreator); 10979 return providerCreators; 10980 } 10981 10982 // packages/sync/build-module/y-utilities/y-multidoc-undomanager.mjs 10983 var popStackItem2 = (mum, type) => { 10984 const stack = type === "undo" ? mum.undoStack : mum.redoStack; 10985 while (stack.length > 0) { 10986 const um = ( 10987 /** @type {Y.UndoManager} */ 10988 stack.pop() 10989 ); 10990 const prevUmStack = type === "undo" ? um.undoStack : um.redoStack; 10991 const stackItem = ( 10992 /** @type {any} */ 10993 prevUmStack.pop() 10994 ); 10995 let actionPerformed = false; 10996 if (type === "undo") { 10997 um.undoStack = [stackItem]; 10998 actionPerformed = um.undo() !== null; 10999 um.undoStack = prevUmStack; 11000 } else { 11001 um.redoStack = [stackItem]; 11002 actionPerformed = um.redo() !== null; 11003 um.redoStack = prevUmStack; 11004 } 11005 if (actionPerformed) { 11006 return stackItem; 11007 } 11008 } 11009 return null; 11010 }; 11011 var YMultiDocUndoManager = class extends Observable { 11012 /** 11013 * @param {Y.AbstractType<any>|Array<Y.AbstractType<any>>} typeScope Accepts either a single type, or an array of types 11014 * @param {ConstructorParameters<typeof Y.UndoManager>[1]} opts 11015 */ 11016 constructor(typeScope = [], opts = {}) { 11017 super(); 11018 this.docs = /* @__PURE__ */ new Map(); 11019 this.trackedOrigins = opts.trackedOrigins || /* @__PURE__ */ new Set([null]); 11020 opts.trackedOrigins = this.trackedOrigins; 11021 this._defaultOpts = opts; 11022 this.undoStack = []; 11023 this.redoStack = []; 11024 this.addToScope(typeScope); 11025 } 11026 /** 11027 * @param {Array<Y.AbstractType<any>> | Y.AbstractType<any>} ytypes 11028 */ 11029 addToScope(ytypes) { 11030 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 11031 ytypes.forEach((ytype) => { 11032 const ydoc = ( 11033 /** @type {Y.Doc} */ 11034 ytype.doc 11035 ); 11036 const um = setIfUndefined(this.docs, ydoc, () => { 11037 const um2 = new UndoManager([ytype], this._defaultOpts); 11038 um2.on( 11039 "stack-cleared", 11040 /** @param {any} opts */ 11041 ({ 11042 undoStackCleared, 11043 redoStackCleared 11044 }) => { 11045 this.clear(undoStackCleared, redoStackCleared); 11046 } 11047 ); 11048 ydoc.on("destroy", () => { 11049 this.docs.delete(ydoc); 11050 this.undoStack = this.undoStack.filter( 11051 (um3) => um3.doc !== ydoc 11052 ); 11053 this.redoStack = this.redoStack.filter( 11054 (um3) => um3.doc !== ydoc 11055 ); 11056 }); 11057 um2.on( 11058 "stack-item-added", 11059 /** @param {any} change */ 11060 (change) => { 11061 const stack = change.type === "undo" ? this.undoStack : this.redoStack; 11062 stack.push(um2); 11063 this.emit("stack-item-added", [ 11064 { ...change, ydoc }, 11065 this 11066 ]); 11067 } 11068 ); 11069 um2.on( 11070 "stack-item-updated", 11071 /** @param {any} change */ 11072 (change) => { 11073 this.emit("stack-item-updated", [ 11074 { ...change, ydoc }, 11075 this 11076 ]); 11077 } 11078 ); 11079 um2.on( 11080 "stack-item-popped", 11081 /** @param {any} change */ 11082 (change) => { 11083 this.emit("stack-item-popped", [ 11084 { ...change, ydoc }, 11085 this 11086 ]); 11087 } 11088 ); 11089 return um2; 11090 }); 11091 if (um.scope.every((yt) => yt !== ytype)) { 11092 um.scope.push(ytype); 11093 } 11094 }); 11095 } 11096 /** 11097 * @param {any} origin 11098 */ 11099 /* c8 ignore next 3 */ 11100 addTrackedOrigin(origin2) { 11101 this.trackedOrigins.add(origin2); 11102 } 11103 /** 11104 * @param {any} origin 11105 */ 11106 /* c8 ignore next 3 */ 11107 removeTrackedOrigin(origin2) { 11108 this.trackedOrigins.delete(origin2); 11109 } 11110 /** 11111 * Undo last changes on type. 11112 * 11113 * @return {any?} Returns StackItem if a change was applied 11114 */ 11115 undo() { 11116 return popStackItem2(this, "undo"); 11117 } 11118 /** 11119 * Redo last undo operation. 11120 * 11121 * @return {any?} Returns StackItem if a change was applied 11122 */ 11123 redo() { 11124 return popStackItem2(this, "redo"); 11125 } 11126 clear(clearUndoStack = true, clearRedoStack = true) { 11127 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 11128 this.docs.forEach((um) => { 11129 clearUndoStack && (this.undoStack = []); 11130 clearRedoStack && (this.redoStack = []); 11131 um.clear(clearUndoStack, clearRedoStack); 11132 }); 11133 this.emit("stack-cleared", [ 11134 { 11135 undoStackCleared: clearUndoStack, 11136 redoStackCleared: clearRedoStack 11137 } 11138 ]); 11139 } 11140 } 11141 /* c8 ignore next 5 */ 11142 stopCapturing() { 11143 this.docs.forEach((um) => { 11144 um.stopCapturing(); 11145 }); 11146 } 11147 /** 11148 * Are undo steps available? 11149 * 11150 * @return {boolean} `true` if undo is possible 11151 */ 11152 canUndo() { 11153 return this.undoStack.length > 0; 11154 } 11155 /** 11156 * Are redo steps available? 11157 * 11158 * @return {boolean} `true` if redo is possible 11159 */ 11160 canRedo() { 11161 return this.redoStack.length > 0; 11162 } 11163 destroy() { 11164 this.docs.forEach((um) => um.destroy()); 11165 super.destroy(); 11166 } 11167 }; 11168 11169 // packages/sync/build-module/undo-manager.mjs 11170 function createUndoManager() { 11171 const undoMetaHandlers = /* @__PURE__ */ new Map(); 11172 const yUndoManager = new YMultiDocUndoManager([], { 11173 // Throttle undo/redo captures after 500ms of inactivity. 11174 // 500 was selected from subjective local UX testing, shorter timeouts 11175 // may cause mid-word undo stack items. 11176 captureTimeout: 500, 11177 // Ensure that we only scope the undo/redo to the current editor. 11178 // The yjs document's clientID is added once it's available. 11179 trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) 11180 }); 11181 const getUndoStackState = () => ({ 11182 hasRedo: yUndoManager.canRedo(), 11183 hasUndo: yUndoManager.canUndo() 11184 }); 11185 const notifyUndoStackChange = (ydoc) => { 11186 undoMetaHandlers.get(ydoc)?.onUndoStackChange?.(getUndoStackState()); 11187 }; 11188 yUndoManager.on("stack-item-added", (event) => { 11189 const handlers = undoMetaHandlers.get(event.ydoc); 11190 if (!handlers) { 11191 return; 11192 } 11193 handlers.addUndoMeta(event.ydoc, event.stackItem.meta); 11194 notifyUndoStackChange(event.ydoc); 11195 }); 11196 yUndoManager.on("stack-item-updated", (event) => { 11197 notifyUndoStackChange(event.ydoc); 11198 }); 11199 yUndoManager.on("stack-item-popped", (event) => { 11200 const handlers = undoMetaHandlers.get(event.ydoc); 11201 if (!handlers) { 11202 return; 11203 } 11204 handlers.restoreUndoMeta(event.ydoc, event.stackItem.meta); 11205 notifyUndoStackChange(event.ydoc); 11206 }); 11207 yUndoManager.on("stack-cleared", () => { 11208 undoMetaHandlers.forEach((handlers) => { 11209 handlers.onUndoStackChange?.(getUndoStackState()); 11210 }); 11211 }); 11212 return { 11213 /** 11214 * Record changes into the history. 11215 * Since Yjs automatically tracks changes, this method translates the WordPress 11216 * HistoryRecord format into Yjs operations. 11217 * 11218 * @param _record A record of changes to record. 11219 * @param _isStaged Whether to immediately create an undo point or not. 11220 */ 11221 addRecord(_record, _isStaged = false) { 11222 }, 11223 /** 11224 * Add a Yjs map to the scope of the undo manager. 11225 * 11226 * @param {Y.Map< any >} ymap The Yjs map to add to the scope. 11227 * @param handlers Handlers for the scoped document. 11228 * @param handlers.addUndoMeta Handler to add metadata to undo items. 11229 * @param handlers.onUndoStackChange Handler for undo stack changes. 11230 * @param handlers.restoreUndoMeta Handler to restore metadata from undo items. 11231 */ 11232 addToScope(ymap, handlers) { 11233 if (ymap.doc === null) { 11234 return; 11235 } 11236 const ydoc = ymap.doc; 11237 yUndoManager.addToScope(ymap); 11238 if (!undoMetaHandlers.has(ydoc)) { 11239 ydoc.on("destroy", () => undoMetaHandlers.delete(ydoc)); 11240 } 11241 undoMetaHandlers.set(ydoc, handlers); 11242 }, 11243 /** 11244 * Undo the last recorded changes. 11245 * 11246 */ 11247 undo() { 11248 if (!yUndoManager.canUndo()) { 11249 return; 11250 } 11251 yUndoManager.undo(); 11252 return []; 11253 }, 11254 /** 11255 * Redo the last undone changes. 11256 */ 11257 redo() { 11258 if (!yUndoManager.canRedo()) { 11259 return; 11260 } 11261 yUndoManager.redo(); 11262 return []; 11263 }, 11264 /** 11265 * Check if there are changes that can be undone. 11266 * 11267 * @return {boolean} Whether there are changes to undo. 11268 */ 11269 hasUndo() { 11270 return yUndoManager.canUndo(); 11271 }, 11272 /** 11273 * Check if there are changes that can be redone. 11274 * 11275 * @return {boolean} Whether there are changes to redo. 11276 */ 11277 hasRedo() { 11278 return yUndoManager.canRedo(); 11279 }, 11280 /** 11281 * Stop capturing changes into the current undo item. 11282 * The next change will create a new undo item. 11283 */ 11284 stopCapturing() { 11285 yUndoManager.stopCapturing(); 11286 } 11287 }; 11288 } 11289 11290 // packages/sync/build-module/utils.mjs 11291 function createYjsDoc(documentMeta = {}) { 11292 const metaMap = new Map( 11293 Object.entries(documentMeta) 11294 ); 11295 return new Doc({ meta: metaMap }); 11296 } 11297 function initializeYjsDoc(ydoc) { 11298 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11299 stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); 11300 } 11301 function markEntityAsSaved(ydoc) { 11302 const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); 11303 recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); 11304 recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); 11305 } 11306 function pseudoRandomID() { 11307 return Math.floor(Math.random() * 1e9); 11308 } 11309 function serializeCrdtDoc(crdtDoc) { 11310 return JSON.stringify({ 11311 document: toBase64(encodeStateAsUpdateV2(crdtDoc)), 11312 updateId: pseudoRandomID() 11313 // helps with debugging 11314 }); 11315 } 11316 function deserializeCrdtDoc(serializedCrdtDoc) { 11317 try { 11318 const { document: document2 } = JSON.parse(serializedCrdtDoc); 11319 const docMeta = { 11320 [CRDT_DOC_META_PERSISTENCE_KEY]: true 11321 }; 11322 const ydoc = createYjsDoc(docMeta); 11323 const yupdate = fromBase64(document2); 11324 applyUpdateV2(ydoc, yupdate); 11325 ydoc.clientID = pseudoRandomID(); 11326 return ydoc; 11327 } catch { 11328 return null; 11329 } 11330 } 11331 11332 // packages/sync/build-module/manager.mjs 11333 function getEntityId(objectType, objectId) { 11334 return `$objectType}_$objectId}`; 11335 } 11336 function createSyncManager(debug = false) { 11337 const debugWrap = debug ? logPerformanceTiming : passThru; 11338 const collectionStates = /* @__PURE__ */ new Map(); 11339 const entityStates = /* @__PURE__ */ new Map(); 11340 let undoManager; 11341 function log(component, message, entityId, context = {}) { 11342 if (!debug) { 11343 return; 11344 } 11345 console.log(`[SyncManager][$component}]: $message}`, { 11346 ...context, 11347 entityId 11348 }); 11349 } 11350 async function loadEntity(syncConfig, objectType, objectId, record, handlers) { 11351 const providerCreators2 = getProviderCreators(); 11352 const entityId = getEntityId(objectType, objectId); 11353 if (0 === providerCreators2.length) { 11354 log("loadEntity", "no providers, skipping", entityId); 11355 return; 11356 } 11357 if (entityStates.has(entityId)) { 11358 log("loadEntity", "already loaded", entityId); 11359 return; 11360 } 11361 if (false === syncConfig.shouldSync?.(objectType, objectId)) { 11362 log("loadEntity", "shouldSync false, skipping", entityId); 11363 return; 11364 } 11365 log("loadEntity", "loading", entityId); 11366 handlers = { 11367 addUndoMeta: debugWrap(handlers.addUndoMeta), 11368 editRecord: debugWrap(handlers.editRecord), 11369 getEditedRecord: debugWrap(handlers.getEditedRecord), 11370 onStatusChange: debugWrap(handlers.onStatusChange), 11371 persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), 11372 refetchRecord: debugWrap(handlers.refetchRecord), 11373 restoreUndoMeta: debugWrap(handlers.restoreUndoMeta), 11374 onUndoStackChange: handlers.onUndoStackChange ? debugWrap(handlers.onUndoStackChange) : void 0 11375 }; 11376 const ydoc = createYjsDoc({ objectType }); 11377 const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); 11378 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11379 const now = Date.now(); 11380 let hasObserversAttached = false; 11381 let isEntityUnloaded = false; 11382 const unload = () => { 11383 log("loadEntity", "unloading", entityId); 11384 isEntityUnloaded = true; 11385 providerResults?.forEach((result) => result.destroy()); 11386 handlers.onStatusChange(null); 11387 if (hasObserversAttached) { 11388 recordMap.unobserveDeep(onRecordUpdate); 11389 stateMap.unobserve(onStateMapUpdate); 11390 } 11391 ydoc.destroy(); 11392 entityStates.delete(entityId); 11393 }; 11394 const awareness = syncConfig.createAwareness?.(ydoc, objectId); 11395 const onRecordUpdate = (_events, transaction) => { 11396 if (transaction.local && !(transaction.origin instanceof UndoManager)) { 11397 return; 11398 } 11399 void internal.updateEntityRecord(objectType, objectId); 11400 }; 11401 const onStateMapUpdate = (event, transaction) => { 11402 if (transaction.local) { 11403 return; 11404 } 11405 event.keysChanged.forEach((key) => { 11406 switch (key) { 11407 case CRDT_STATE_MAP_SAVED_AT_KEY: 11408 const savedAt = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11409 if ("number" === typeof savedAt && savedAt > now) { 11410 log("loadEntity", "refetching record", entityId); 11411 void handlers.refetchRecord().catch(() => { 11412 }); 11413 } 11414 break; 11415 } 11416 }); 11417 }; 11418 if (!undoManager) { 11419 undoManager = createUndoManager(); 11420 } 11421 const { addUndoMeta, onUndoStackChange, restoreUndoMeta } = handlers; 11422 undoManager.addToScope(recordMap, { 11423 addUndoMeta, 11424 restoreUndoMeta, 11425 onUndoStackChange 11426 }); 11427 let providerResults; 11428 const entityState = { 11429 awareness, 11430 handlers, 11431 objectId, 11432 objectType, 11433 syncConfig, 11434 unload, 11435 ydoc 11436 }; 11437 entityStates.set(entityId, entityState); 11438 log("loadEntity", "connecting", entityId); 11439 providerResults = await Promise.all( 11440 providerCreators2.map(async (create7) => { 11441 const provider = await create7({ 11442 objectType, 11443 objectId, 11444 ydoc, 11445 awareness 11446 }); 11447 provider.on("status", handlers.onStatusChange); 11448 return provider; 11449 }) 11450 ); 11451 if (isEntityUnloaded) { 11452 log("loadEntity", "unloaded during connect, aborting", entityId); 11453 providerResults.forEach((result) => result.destroy()); 11454 return; 11455 } 11456 initializeYjsDoc(ydoc); 11457 internal.applyPersistedCrdtDoc(objectType, objectId, record); 11458 recordMap.observeDeep(onRecordUpdate); 11459 stateMap.observe(onStateMapUpdate); 11460 hasObserversAttached = true; 11461 } 11462 async function loadCollection(syncConfig, objectType, handlers) { 11463 const providerCreators2 = getProviderCreators(); 11464 const entityId = getEntityId(objectType, null); 11465 if (0 === providerCreators2.length) { 11466 log("loadCollection", "no providers, skipping", entityId); 11467 return; 11468 } 11469 if (collectionStates.has(objectType)) { 11470 log("loadCollection", "already loaded", entityId); 11471 return; 11472 } 11473 if (false === syncConfig.shouldSync?.(objectType, null)) { 11474 log("loadCollection", "shouldSync false, skipping", entityId); 11475 return; 11476 } 11477 log("loadCollection", "loading", entityId); 11478 const ydoc = createYjsDoc({ collection: true, objectType }); 11479 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11480 const now = Date.now(); 11481 let hasObserversAttached = false; 11482 let isCollectionUnloaded = false; 11483 const unload = () => { 11484 log("loadCollection", "unloading", entityId); 11485 isCollectionUnloaded = true; 11486 providerResults?.forEach((result) => result.destroy()); 11487 handlers.onStatusChange(null); 11488 if (hasObserversAttached) { 11489 stateMap.unobserve(onStateMapUpdate); 11490 } 11491 ydoc.destroy(); 11492 collectionStates.delete(objectType); 11493 }; 11494 const onStateMapUpdate = (event, transaction) => { 11495 if (transaction.local) { 11496 return; 11497 } 11498 event.keysChanged.forEach((key) => { 11499 switch (key) { 11500 case CRDT_STATE_MAP_SAVED_AT_KEY: 11501 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11502 if ("number" === typeof newValue && newValue > now) { 11503 void handlers.refetchRecords().catch(() => { 11504 }); 11505 } 11506 break; 11507 } 11508 }); 11509 }; 11510 const awareness = syncConfig.createAwareness?.(ydoc); 11511 let providerResults; 11512 const collectionState = { 11513 awareness, 11514 handlers, 11515 syncConfig, 11516 unload, 11517 ydoc 11518 }; 11519 collectionStates.set(objectType, collectionState); 11520 log("loadCollection", "connecting", entityId); 11521 providerResults = await Promise.all( 11522 providerCreators2.map(async (create7) => { 11523 const provider = await create7({ 11524 awareness, 11525 objectType, 11526 objectId: null, 11527 ydoc 11528 }); 11529 provider.on("status", handlers.onStatusChange); 11530 return provider; 11531 }) 11532 ); 11533 if (isCollectionUnloaded) { 11534 log( 11535 "loadCollection", 11536 "unloaded during connect, aborting", 11537 entityId 11538 ); 11539 providerResults.forEach((result) => result.destroy()); 11540 return; 11541 } 11542 stateMap.observe(onStateMapUpdate); 11543 hasObserversAttached = true; 11544 initializeYjsDoc(ydoc); 11545 } 11546 function unloadEntity(objectType, objectId) { 11547 const entityId = getEntityId(objectType, objectId); 11548 log("unloadEntity", "unloading", entityId); 11549 entityStates.get(entityId)?.unload(); 11550 updateCRDTDoc(objectType, null, {}, origin, { 11551 isSave: true 11552 }); 11553 } 11554 function unloadAll() { 11555 log("unloadAll", "unloading all entities", "all"); 11556 for (const [, entityState] of [...entityStates]) { 11557 entityState.unload(); 11558 } 11559 entityStates.clear(); 11560 undoManager = void 0; 11561 for (const [, collectionState] of [...collectionStates]) { 11562 collectionState.unload(); 11563 } 11564 collectionStates.clear(); 11565 } 11566 function getAwareness(objectType, objectId) { 11567 const entityId = getEntityId(objectType, objectId); 11568 const entityState = entityStates.get(entityId); 11569 if (!entityState || !entityState.awareness) { 11570 return void 0; 11571 } 11572 return entityState.awareness; 11573 } 11574 function _applyPersistedCrdtDoc(objectType, objectId, record) { 11575 const entityId = getEntityId(objectType, objectId); 11576 const entityState = entityStates.get(entityId); 11577 if (!entityState) { 11578 log("applyPersistedCrdtDoc", "no entity state", entityId); 11579 return; 11580 } 11581 const { 11582 handlers, 11583 syncConfig: { 11584 applyChangesToCRDTDoc, 11585 getChangesFromCRDTDoc, 11586 getPersistedCRDTDoc 11587 }, 11588 ydoc: targetDoc 11589 } = entityState; 11590 const serialized = getPersistedCRDTDoc?.(record); 11591 const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; 11592 if (!tempDoc) { 11593 log("applyPersistedCrdtDoc", "no persisted doc", entityId); 11594 targetDoc.transact(() => { 11595 applyChangesToCRDTDoc(targetDoc, record); 11596 handlers.persistCRDTDoc(); 11597 }, LOCAL_SYNC_MANAGER_ORIGIN); 11598 return; 11599 } 11600 const update = encodeStateAsUpdateV2(tempDoc); 11601 applyUpdateV2(targetDoc, update); 11602 const invalidations = getChangesFromCRDTDoc(tempDoc, record); 11603 const invalidatedKeys = Object.keys(invalidations); 11604 tempDoc.destroy(); 11605 if (0 === invalidatedKeys.length) { 11606 log("applyPersistedCrdtDoc", "valid persisted doc", entityId); 11607 return; 11608 } 11609 log("applyPersistedCrdtDoc", "invalidated keys", entityId, { 11610 invalidatedKeys 11611 }); 11612 const changes = invalidatedKeys.reduce( 11613 (acc, key) => Object.assign(acc, { 11614 [key]: record[key] 11615 }), 11616 {} 11617 ); 11618 targetDoc.transact(() => { 11619 applyChangesToCRDTDoc(targetDoc, changes); 11620 handlers.persistCRDTDoc(); 11621 }, LOCAL_SYNC_MANAGER_ORIGIN); 11622 } 11623 function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { 11624 const { isSave = false, isNewUndoLevel = false } = options; 11625 const entityId = getEntityId(objectType, objectId); 11626 const entityState = entityStates.get(entityId); 11627 const collectionState = collectionStates.get(objectType); 11628 if (entityState) { 11629 const { syncConfig, ydoc } = entityState; 11630 if (isNewUndoLevel && undoManager) { 11631 undoManager.stopCapturing?.(); 11632 } 11633 ydoc.transact(() => { 11634 log("updateCRDTDoc", "applying changes", entityId, { 11635 changedKeys: Object.keys(changes) 11636 }); 11637 syncConfig.applyChangesToCRDTDoc(ydoc, changes); 11638 if (isSave) { 11639 markEntityAsSaved(ydoc); 11640 } 11641 }, origin2); 11642 } 11643 if (collectionState && isSave) { 11644 collectionState.ydoc.transact(() => { 11645 markEntityAsSaved(collectionState.ydoc); 11646 }, origin2); 11647 } 11648 } 11649 const deferUpdateCRDTDoc = yieldToEventLoop(updateCRDTDoc); 11650 function updateOrDefer(objectType, objectId, changes, origin2, options = {}) { 11651 const hasRemotePeers = (getAwareness(objectType, objectId)?.getStates().size ?? 0) > 1; 11652 const update = hasRemotePeers ? updateCRDTDoc : deferUpdateCRDTDoc; 11653 update(objectType, objectId, changes, origin2, options); 11654 } 11655 async function _updateEntityRecord(objectType, objectId) { 11656 const entityId = getEntityId(objectType, objectId); 11657 const entityState = entityStates.get(entityId); 11658 if (!entityState) { 11659 log("updateEntityRecord", "no entity state", entityId); 11660 return; 11661 } 11662 const { handlers, syncConfig, ydoc } = entityState; 11663 const changes = syncConfig.getChangesFromCRDTDoc( 11664 ydoc, 11665 await handlers.getEditedRecord() 11666 ); 11667 const changedKeys = Object.keys(changes); 11668 if (0 === changedKeys.length) { 11669 return; 11670 } 11671 log("updateEntityRecord", "changes", entityId, { 11672 changedKeys 11673 }); 11674 handlers.editRecord(changes); 11675 } 11676 async function createPersistedCRDTDoc(objectType, objectId) { 11677 const entityId = getEntityId(objectType, objectId); 11678 const entityState = entityStates.get(entityId); 11679 if (!entityState?.ydoc) { 11680 return null; 11681 } 11682 await new Promise((resolve) => setTimeout(resolve, 0)); 11683 return serializeCrdtDoc(entityState.ydoc); 11684 } 11685 const internal = { 11686 applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), 11687 updateEntityRecord: debugWrap(_updateEntityRecord) 11688 }; 11689 return { 11690 createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), 11691 getAwareness, 11692 load: debugWrap(loadEntity), 11693 loadCollection: debugWrap(loadCollection), 11694 // Use getter to ensure we always return the current value of `undoManager`. 11695 get undoManager() { 11696 return undoManager; 11697 }, 11698 unload: debugWrap(unloadEntity), 11699 unloadAll: debugWrap(unloadAll), 11700 update: debugWrap(updateOrDefer) 11701 }; 11702 } 11703 11704 // node_modules/diff/libesm/diff/base.js 11705 var Diff = class { 11706 diff(oldStr, newStr, options = {}) { 11707 let callback; 11708 if (typeof options === "function") { 11709 callback = options; 11710 options = {}; 11711 } else if ("callback" in options) { 11712 callback = options.callback; 11713 } 11714 const oldString = this.castInput(oldStr, options); 11715 const newString = this.castInput(newStr, options); 11716 const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); 11717 const newTokens = this.removeEmpty(this.tokenize(newString, options)); 11718 return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); 11719 } 11720 diffWithOptionsObj(oldTokens, newTokens, options, callback) { 11721 var _a; 11722 const done = (value) => { 11723 value = this.postProcess(value, options); 11724 if (callback) { 11725 setTimeout(function() { 11726 callback(value); 11727 }, 0); 11728 return void 0; 11729 } else { 11730 return value; 11731 } 11732 }; 11733 const newLen = newTokens.length, oldLen = oldTokens.length; 11734 let editLength = 1; 11735 let maxEditLength = newLen + oldLen; 11736 if (options.maxEditLength != null) { 11737 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 11738 } 11739 const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; 11740 const abortAfterTimestamp = Date.now() + maxExecutionTime; 11741 const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; 11742 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); 11743 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11744 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); 11745 } 11746 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; 11747 const execEditLength = () => { 11748 for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 11749 let basePath; 11750 const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; 11751 if (removePath) { 11752 bestPath[diagonalPath - 1] = void 0; 11753 } 11754 let canAdd = false; 11755 if (addPath) { 11756 const addPathNewPos = addPath.oldPos - diagonalPath; 11757 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 11758 } 11759 const canRemove = removePath && removePath.oldPos + 1 < oldLen; 11760 if (!canAdd && !canRemove) { 11761 bestPath[diagonalPath] = void 0; 11762 continue; 11763 } 11764 if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { 11765 basePath = this.addToPath(addPath, true, false, 0, options); 11766 } else { 11767 basePath = this.addToPath(removePath, false, true, 1, options); 11768 } 11769 newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); 11770 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11771 return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; 11772 } else { 11773 bestPath[diagonalPath] = basePath; 11774 if (basePath.oldPos + 1 >= oldLen) { 11775 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 11776 } 11777 if (newPos + 1 >= newLen) { 11778 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 11779 } 11780 } 11781 } 11782 editLength++; 11783 }; 11784 if (callback) { 11785 (function exec() { 11786 setTimeout(function() { 11787 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 11788 return callback(void 0); 11789 } 11790 if (!execEditLength()) { 11791 exec(); 11792 } 11793 }, 0); 11794 })(); 11795 } else { 11796 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 11797 const ret = execEditLength(); 11798 if (ret) { 11799 return ret; 11800 } 11801 } 11802 } 11803 } 11804 addToPath(path, added, removed, oldPosInc, options) { 11805 const last2 = path.lastComponent; 11806 if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { 11807 return { 11808 oldPos: path.oldPos + oldPosInc, 11809 lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } 11810 }; 11811 } else { 11812 return { 11813 oldPos: path.oldPos + oldPosInc, 11814 lastComponent: { count: 1, added, removed, previousComponent: last2 } 11815 }; 11816 } 11817 } 11818 extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { 11819 const newLen = newTokens.length, oldLen = oldTokens.length; 11820 let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; 11821 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { 11822 newPos++; 11823 oldPos++; 11824 commonCount++; 11825 if (options.oneChangePerToken) { 11826 basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; 11827 } 11828 } 11829 if (commonCount && !options.oneChangePerToken) { 11830 basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; 11831 } 11832 basePath.oldPos = oldPos; 11833 return newPos; 11834 } 11835 equals(left, right, options) { 11836 if (options.comparator) { 11837 return options.comparator(left, right); 11838 } else { 11839 return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 11840 } 11841 } 11842 removeEmpty(array) { 11843 const ret = []; 11844 for (let i = 0; i < array.length; i++) { 11845 if (array[i]) { 11846 ret.push(array[i]); 11847 } 11848 } 11849 return ret; 11850 } 11851 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11852 castInput(value, options) { 11853 return value; 11854 } 11855 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11856 tokenize(value, options) { 11857 return Array.from(value); 11858 } 11859 join(chars) { 11860 return chars.join(""); 11861 } 11862 postProcess(changeObjects, options) { 11863 return changeObjects; 11864 } 11865 get useLongestToken() { 11866 return false; 11867 } 11868 buildValues(lastComponent, newTokens, oldTokens) { 11869 const components = []; 11870 let nextComponent; 11871 while (lastComponent) { 11872 components.push(lastComponent); 11873 nextComponent = lastComponent.previousComponent; 11874 delete lastComponent.previousComponent; 11875 lastComponent = nextComponent; 11876 } 11877 components.reverse(); 11878 const componentLen = components.length; 11879 let componentPos = 0, newPos = 0, oldPos = 0; 11880 for (; componentPos < componentLen; componentPos++) { 11881 const component = components[componentPos]; 11882 if (!component.removed) { 11883 if (!component.added && this.useLongestToken) { 11884 let value = newTokens.slice(newPos, newPos + component.count); 11885 value = value.map(function(value2, i) { 11886 const oldValue = oldTokens[oldPos + i]; 11887 return oldValue.length > value2.length ? oldValue : value2; 11888 }); 11889 component.value = this.join(value); 11890 } else { 11891 component.value = this.join(newTokens.slice(newPos, newPos + component.count)); 11892 } 11893 newPos += component.count; 11894 if (!component.added) { 11895 oldPos += component.count; 11896 } 11897 } else { 11898 component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); 11899 oldPos += component.count; 11900 } 11901 } 11902 return components; 11903 } 11904 }; 11905 11906 // node_modules/diff/libesm/diff/character.js 11907 var CharacterDiff = class extends Diff { 11908 }; 11909 var characterDiff = new CharacterDiff(); 11910 function diffChars(oldStr, newStr, options) { 11911 return characterDiff.diff(oldStr, newStr, options); 11912 } 11913 11914 // node_modules/diff/libesm/diff/line.js 11915 var LineDiff = class extends Diff { 11916 constructor() { 11917 super(...arguments); 11918 this.tokenize = tokenize; 11919 } 11920 equals(left, right, options) { 11921 if (options.ignoreWhitespace) { 11922 if (!options.newlineIsToken || !left.includes("\n")) { 11923 left = left.trim(); 11924 } 11925 if (!options.newlineIsToken || !right.includes("\n")) { 11926 right = right.trim(); 11927 } 11928 } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { 11929 if (left.endsWith("\n")) { 11930 left = left.slice(0, -1); 11931 } 11932 if (right.endsWith("\n")) { 11933 right = right.slice(0, -1); 11934 } 11935 } 11936 return super.equals(left, right, options); 11937 } 11938 }; 11939 var lineDiff = new LineDiff(); 11940 function diffLines(oldStr, newStr, options) { 11941 return lineDiff.diff(oldStr, newStr, options); 11942 } 11943 function tokenize(value, options) { 11944 if (options.stripTrailingCr) { 11945 value = value.replace(/\r\n/g, "\n"); 11946 } 11947 const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); 11948 if (!linesAndNewlines[linesAndNewlines.length - 1]) { 11949 linesAndNewlines.pop(); 11950 } 11951 for (let i = 0; i < linesAndNewlines.length; i++) { 11952 const line = linesAndNewlines[i]; 11953 if (i % 2 && !options.newlineIsToken) { 11954 retLines[retLines.length - 1] += line; 11955 } else { 11956 retLines.push(line); 11957 } 11958 } 11959 return retLines; 11960 } 11961 11962 // packages/sync/build-module/quill-delta/Delta.mjs 11963 var import_es62 = __toESM(require_es6(), 1); 11964 11965 // packages/sync/build-module/quill-delta/AttributeMap.mjs 11966 var import_es6 = __toESM(require_es6(), 1); 11967 function cloneDeep(value) { 11968 return JSON.parse(JSON.stringify(value)); 11969 } 11970 var AttributeMap; 11971 ((AttributeMap2) => { 11972 function compose(a = {}, b = {}, keepNull = false) { 11973 if (typeof a !== "object") { 11974 a = {}; 11975 } 11976 if (typeof b !== "object") { 11977 b = {}; 11978 } 11979 let attributes = cloneDeep(b); 11980 if (!keepNull) { 11981 attributes = Object.keys(attributes).reduce( 11982 (copy2, key) => { 11983 if (attributes[key] !== null || attributes[key] !== void 0) { 11984 copy2[key] = attributes[key]; 11985 } 11986 return copy2; 11987 }, 11988 {} 11989 ); 11990 } 11991 for (const key in a) { 11992 if (a[key] !== void 0 && b[key] === void 0) { 11993 attributes[key] = a[key]; 11994 } 11995 } 11996 return Object.keys(attributes).length > 0 ? attributes : void 0; 11997 } 11998 AttributeMap2.compose = compose; 11999 function diff(a = {}, b = {}) { 12000 if (typeof a !== "object") { 12001 a = {}; 12002 } 12003 if (typeof b !== "object") { 12004 b = {}; 12005 } 12006 const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { 12007 if (!(0, import_es6.default)(a[key], b[key])) { 12008 attrs[key] = b[key] === void 0 ? null : b[key]; 12009 } 12010 return attrs; 12011 }, {}); 12012 return Object.keys(attributes).length > 0 ? attributes : void 0; 12013 } 12014 AttributeMap2.diff = diff; 12015 function invert(attr = {}, base = {}) { 12016 attr = attr || {}; 12017 const baseInverted = Object.keys(base).reduce( 12018 (memo, key) => { 12019 if (base[key] !== attr[key] && attr[key] !== void 0) { 12020 memo[key] = base[key]; 12021 } 12022 return memo; 12023 }, 12024 {} 12025 ); 12026 return Object.keys(attr).reduce((memo, key) => { 12027 if (attr[key] !== base[key] && base[key] === void 0) { 12028 memo[key] = null; 12029 } 12030 return memo; 12031 }, baseInverted); 12032 } 12033 AttributeMap2.invert = invert; 12034 function transform(a, b, priority = false) { 12035 if (typeof a !== "object") { 12036 return b; 12037 } 12038 if (typeof b !== "object") { 12039 return void 0; 12040 } 12041 if (!priority) { 12042 return b; 12043 } 12044 const attributes = Object.keys(b).reduce( 12045 (attrs, key) => { 12046 if (a[key] === void 0) { 12047 attrs[key] = b[key]; 12048 } 12049 return attrs; 12050 }, 12051 {} 12052 ); 12053 return Object.keys(attributes).length > 0 ? attributes : void 0; 12054 } 12055 AttributeMap2.transform = transform; 12056 })(AttributeMap || (AttributeMap = {})); 12057 var AttributeMap_default = AttributeMap; 12058 12059 // packages/sync/build-module/quill-delta/Op.mjs 12060 var Op; 12061 ((Op2) => { 12062 function length2(op) { 12063 if (typeof op.delete === "number") { 12064 return op.delete; 12065 } else if (typeof op.retain === "number") { 12066 return op.retain; 12067 } else if (typeof op.retain === "object" && op.retain !== null) { 12068 return 1; 12069 } 12070 return typeof op.insert === "string" ? op.insert.length : 1; 12071 } 12072 Op2.length = length2; 12073 })(Op || (Op = {})); 12074 var Op_default = Op; 12075 12076 // packages/sync/build-module/quill-delta/OpIterator.mjs 12077 var Iterator = class { 12078 ops; 12079 index; 12080 offset; 12081 constructor(ops) { 12082 this.ops = ops; 12083 this.index = 0; 12084 this.offset = 0; 12085 } 12086 hasNext() { 12087 return this.peekLength() < Infinity; 12088 } 12089 next(length2) { 12090 if (!length2) { 12091 length2 = Infinity; 12092 } 12093 const nextOp = this.ops[this.index]; 12094 if (nextOp) { 12095 const offset = this.offset; 12096 const opLength = Op_default.length(nextOp); 12097 if (length2 >= opLength - offset) { 12098 length2 = opLength - offset; 12099 this.index += 1; 12100 this.offset = 0; 12101 } else { 12102 this.offset += length2; 12103 } 12104 if (typeof nextOp.delete === "number") { 12105 return { delete: length2 }; 12106 } 12107 const retOp = {}; 12108 if (nextOp.attributes) { 12109 retOp.attributes = nextOp.attributes; 12110 } 12111 if (typeof nextOp.retain === "number") { 12112 retOp.retain = length2; 12113 } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { 12114 retOp.retain = nextOp.retain; 12115 } else if (typeof nextOp.insert === "string") { 12116 retOp.insert = nextOp.insert.substr(offset, length2); 12117 } else { 12118 retOp.insert = nextOp.insert; 12119 } 12120 return retOp; 12121 } 12122 return { retain: Infinity }; 12123 } 12124 peek() { 12125 return this.ops[this.index]; 12126 } 12127 peekLength() { 12128 if (this.ops[this.index]) { 12129 return Op_default.length(this.ops[this.index]) - this.offset; 12130 } 12131 return Infinity; 12132 } 12133 peekType() { 12134 const op = this.ops[this.index]; 12135 if (op) { 12136 if (typeof op.delete === "number") { 12137 return "delete"; 12138 } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { 12139 return "retain"; 12140 } 12141 return "insert"; 12142 } 12143 return "retain"; 12144 } 12145 rest() { 12146 if (!this.hasNext()) { 12147 return []; 12148 } else if (this.offset === 0) { 12149 return this.ops.slice(this.index); 12150 } 12151 const offset = this.offset; 12152 const index = this.index; 12153 const next = this.next(); 12154 const rest = this.ops.slice(this.index); 12155 this.offset = offset; 12156 this.index = index; 12157 return [next].concat(rest); 12158 } 12159 }; 12160 12161 // packages/sync/build-module/quill-delta/Delta.mjs 12162 function cloneDeep2(value) { 12163 return JSON.parse(JSON.stringify(value)); 12164 } 12165 var NULL_CHARACTER = String.fromCharCode(0); 12166 var STRING_TOO_LARGE_THRESHOLD = 1e4; 12167 function normalizeChangeCounts(changes) { 12168 return changes.map((change) => ({ 12169 ...change, 12170 count: change.value.length 12171 })); 12172 } 12173 var getEmbedTypeAndData = (a, b) => { 12174 if (typeof a !== "object" || a === null) { 12175 throw new Error(`cannot retain a $typeof a}`); 12176 } 12177 if (typeof b !== "object" || b === null) { 12178 throw new Error(`cannot retain a $typeof b}`); 12179 } 12180 const embedType = Object.keys(a)[0]; 12181 if (!embedType || embedType !== Object.keys(b)[0]) { 12182 throw new Error( 12183 `embed types not matched: $embedType} != $Object.keys(b)[0]}` 12184 ); 12185 } 12186 return [embedType, a[embedType], b[embedType]]; 12187 }; 12188 var Delta = class _Delta { 12189 static Op = Op_default; 12190 static OpIterator = Iterator; 12191 static AttributeMap = AttributeMap_default; 12192 static handlers = {}; 12193 static registerEmbed(embedType, handler) { 12194 this.handlers[embedType] = handler; 12195 } 12196 static unregisterEmbed(embedType) { 12197 delete this.handlers[embedType]; 12198 } 12199 static getHandler(embedType) { 12200 const handler = this.handlers[embedType]; 12201 if (!handler) { 12202 throw new Error(`no handlers for embed type "$embedType}"`); 12203 } 12204 return handler; 12205 } 12206 ops; 12207 constructor(ops) { 12208 if (Array.isArray(ops)) { 12209 this.ops = ops; 12210 } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { 12211 this.ops = ops.ops; 12212 } else { 12213 this.ops = []; 12214 } 12215 } 12216 insert(arg, attributes) { 12217 const newOp = {}; 12218 if (typeof arg === "string" && arg.length === 0) { 12219 return this; 12220 } 12221 newOp.insert = arg; 12222 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12223 newOp.attributes = attributes; 12224 } 12225 return this.push(newOp); 12226 } 12227 delete(length2) { 12228 if (length2 <= 0) { 12229 return this; 12230 } 12231 return this.push({ delete: length2 }); 12232 } 12233 retain(length2, attributes) { 12234 if (typeof length2 === "number" && length2 <= 0) { 12235 return this; 12236 } 12237 const newOp = { retain: length2 }; 12238 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12239 newOp.attributes = attributes; 12240 } 12241 return this.push(newOp); 12242 } 12243 push(newOp) { 12244 let index = this.ops.length; 12245 let lastOp = this.ops[index - 1]; 12246 newOp = cloneDeep2(newOp); 12247 if (typeof lastOp === "object") { 12248 if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { 12249 this.ops[index - 1] = { 12250 delete: lastOp.delete + newOp.delete 12251 }; 12252 return this; 12253 } 12254 if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { 12255 index -= 1; 12256 lastOp = this.ops[index - 1]; 12257 if (typeof lastOp !== "object") { 12258 this.ops.unshift(newOp); 12259 return this; 12260 } 12261 } 12262 if ((0, import_es62.default)(newOp.attributes, lastOp.attributes)) { 12263 if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { 12264 this.ops[index - 1] = { 12265 insert: lastOp.insert + newOp.insert 12266 }; 12267 if (typeof newOp.attributes === "object") { 12268 this.ops[index - 1].attributes = newOp.attributes; 12269 } 12270 return this; 12271 } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { 12272 this.ops[index - 1] = { 12273 retain: lastOp.retain + newOp.retain 12274 }; 12275 if (typeof newOp.attributes === "object") { 12276 this.ops[index - 1].attributes = newOp.attributes; 12277 } 12278 return this; 12279 } 12280 } 12281 } 12282 if (index === this.ops.length) { 12283 this.ops.push(newOp); 12284 } else { 12285 this.ops.splice(index, 0, newOp); 12286 } 12287 return this; 12288 } 12289 chop() { 12290 const lastOp = this.ops[this.ops.length - 1]; 12291 if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { 12292 this.ops.pop(); 12293 } 12294 return this; 12295 } 12296 filter(predicate) { 12297 return this.ops.filter(predicate); 12298 } 12299 forEach(predicate) { 12300 this.ops.forEach(predicate); 12301 } 12302 map(predicate) { 12303 return this.ops.map(predicate); 12304 } 12305 partition(predicate) { 12306 const passed = []; 12307 const failed = []; 12308 this.forEach((op) => { 12309 const target = predicate(op) ? passed : failed; 12310 target.push(op); 12311 }); 12312 return [passed, failed]; 12313 } 12314 reduce(predicate, initialValue) { 12315 return this.ops.reduce(predicate, initialValue); 12316 } 12317 changeLength() { 12318 return this.reduce((length2, elem) => { 12319 if (elem.insert) { 12320 return length2 + Op_default.length(elem); 12321 } else if (elem.delete) { 12322 return length2 - elem.delete; 12323 } 12324 return length2; 12325 }, 0); 12326 } 12327 length() { 12328 return this.reduce((length2, elem) => { 12329 return length2 + Op_default.length(elem); 12330 }, 0); 12331 } 12332 slice(start = 0, end = Infinity) { 12333 const ops = []; 12334 const iter = new Iterator(this.ops); 12335 let index = 0; 12336 while (index < end && iter.hasNext()) { 12337 let nextOp; 12338 if (index < start) { 12339 nextOp = iter.next(start - index); 12340 } else { 12341 nextOp = iter.next(end - index); 12342 ops.push(nextOp); 12343 } 12344 index += Op_default.length(nextOp); 12345 } 12346 return new _Delta(ops); 12347 } 12348 compose(other) { 12349 const thisIter = new Iterator(this.ops); 12350 const otherIter = new Iterator(other.ops); 12351 const ops = []; 12352 const firstOther = otherIter.peek(); 12353 if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { 12354 let firstLeft = firstOther.retain; 12355 while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { 12356 firstLeft -= thisIter.peekLength(); 12357 ops.push(thisIter.next()); 12358 } 12359 if (firstOther.retain - firstLeft > 0) { 12360 otherIter.next(firstOther.retain - firstLeft); 12361 } 12362 } 12363 const delta = new _Delta(ops); 12364 while (thisIter.hasNext() || otherIter.hasNext()) { 12365 if (otherIter.peekType() === "insert") { 12366 delta.push(otherIter.next()); 12367 } else if (thisIter.peekType() === "delete") { 12368 delta.push(thisIter.next()); 12369 } else { 12370 const length2 = Math.min( 12371 thisIter.peekLength(), 12372 otherIter.peekLength() 12373 ); 12374 const thisOp = thisIter.next(length2); 12375 const otherOp = otherIter.next(length2); 12376 if (otherOp.retain) { 12377 const newOp = {}; 12378 if (typeof thisOp.retain === "number") { 12379 newOp.retain = typeof otherOp.retain === "number" ? length2 : otherOp.retain; 12380 } else if (typeof otherOp.retain === "number") { 12381 if (thisOp.retain === null || thisOp.retain === void 0) { 12382 newOp.insert = thisOp.insert; 12383 } else { 12384 newOp.retain = thisOp.retain; 12385 } 12386 } else { 12387 const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; 12388 const [embedType, thisData, otherData] = getEmbedTypeAndData( 12389 thisOp[action], 12390 otherOp.retain 12391 ); 12392 const handler = _Delta.getHandler(embedType); 12393 newOp[action] = { 12394 [embedType]: handler.compose( 12395 thisData, 12396 otherData, 12397 action === "retain" 12398 ) 12399 }; 12400 } 12401 const attributes = AttributeMap_default.compose( 12402 thisOp.attributes, 12403 otherOp.attributes, 12404 typeof thisOp.retain === "number" 12405 ); 12406 if (attributes) { 12407 newOp.attributes = attributes; 12408 } 12409 delta.push(newOp); 12410 if (!otherIter.hasNext() && (0, import_es62.default)(delta.ops[delta.ops.length - 1], newOp)) { 12411 const rest = new _Delta(thisIter.rest()); 12412 return delta.concat(rest).chop(); 12413 } 12414 } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { 12415 delta.push(otherOp); 12416 } 12417 } 12418 } 12419 return delta.chop(); 12420 } 12421 concat(other) { 12422 const delta = new _Delta(this.ops.slice()); 12423 if (other.ops.length > 0) { 12424 delta.push(other.ops[0]); 12425 delta.ops = delta.ops.concat(other.ops.slice(1)); 12426 } 12427 return delta; 12428 } 12429 diff(other) { 12430 if (this.ops === other.ops) { 12431 return new _Delta(); 12432 } 12433 const strings = this.deltasToStrings(other); 12434 const diffResult = normalizeChangeCounts( 12435 diffChars(strings[0], strings[1]) 12436 ); 12437 const thisIter = new Iterator(this.ops); 12438 const otherIter = new Iterator(other.ops); 12439 const retDelta = this.convertChangesToDelta( 12440 diffResult, 12441 thisIter, 12442 otherIter 12443 ); 12444 return retDelta.chop(); 12445 } 12446 eachLine(predicate, newline = "\n") { 12447 const iter = new Iterator(this.ops); 12448 let line = new _Delta(); 12449 let i = 0; 12450 while (iter.hasNext()) { 12451 if (iter.peekType() !== "insert") { 12452 return; 12453 } 12454 const thisOp = iter.peek(); 12455 const start = Op_default.length(thisOp) - iter.peekLength(); 12456 const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; 12457 if (index < 0) { 12458 line.push(iter.next()); 12459 } else if (index > 0) { 12460 line.push(iter.next(index)); 12461 } else { 12462 if (predicate(line, iter.next(1).attributes || {}, i) === false) { 12463 return; 12464 } 12465 i += 1; 12466 line = new _Delta(); 12467 } 12468 } 12469 if (line.length() > 0) { 12470 predicate(line, {}, i); 12471 } 12472 } 12473 invert(base) { 12474 const inverted = new _Delta(); 12475 this.reduce((baseIndex, op) => { 12476 if (op.insert) { 12477 inverted.delete(Op_default.length(op)); 12478 } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { 12479 inverted.retain(op.retain); 12480 return baseIndex + op.retain; 12481 } else if (op.delete || typeof op.retain === "number") { 12482 const length2 = op.delete || op.retain; 12483 const slice = base.slice(baseIndex, baseIndex + length2); 12484 slice.forEach((baseOp) => { 12485 if (op.delete) { 12486 inverted.push(baseOp); 12487 } else if (op.retain && op.attributes) { 12488 inverted.retain( 12489 Op_default.length(baseOp), 12490 AttributeMap_default.invert( 12491 op.attributes, 12492 baseOp.attributes 12493 ) 12494 ); 12495 } 12496 }); 12497 return baseIndex + length2; 12498 } else if (typeof op.retain === "object" && op.retain !== null) { 12499 const slice = base.slice(baseIndex, baseIndex + 1); 12500 const baseOp = new Iterator(slice.ops).next(); 12501 const [embedType, opData, baseOpData] = getEmbedTypeAndData( 12502 op.retain, 12503 baseOp.insert 12504 ); 12505 const handler = _Delta.getHandler(embedType); 12506 inverted.retain( 12507 { [embedType]: handler.invert(opData, baseOpData) }, 12508 AttributeMap_default.invert(op.attributes, baseOp.attributes) 12509 ); 12510 return baseIndex + 1; 12511 } 12512 return baseIndex; 12513 }, 0); 12514 return inverted.chop(); 12515 } 12516 transform(arg, priority = false) { 12517 priority = !!priority; 12518 if (typeof arg === "number") { 12519 return this.transformPosition(arg, priority); 12520 } 12521 const other = arg; 12522 const thisIter = new Iterator(this.ops); 12523 const otherIter = new Iterator(other.ops); 12524 const delta = new _Delta(); 12525 while (thisIter.hasNext() || otherIter.hasNext()) { 12526 if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { 12527 delta.retain(Op_default.length(thisIter.next())); 12528 } else if (otherIter.peekType() === "insert") { 12529 delta.push(otherIter.next()); 12530 } else { 12531 const length2 = Math.min( 12532 thisIter.peekLength(), 12533 otherIter.peekLength() 12534 ); 12535 const thisOp = thisIter.next(length2); 12536 const otherOp = otherIter.next(length2); 12537 if (thisOp.delete) { 12538 continue; 12539 } else if (otherOp.delete) { 12540 delta.push(otherOp); 12541 } else { 12542 const thisData = thisOp.retain; 12543 const otherData = otherOp.retain; 12544 let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length2; 12545 if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { 12546 const embedType = Object.keys(thisData)[0]; 12547 if (embedType === Object.keys(otherData)[0]) { 12548 const handler = _Delta.getHandler(embedType); 12549 if (handler) { 12550 transformedData = { 12551 [embedType]: handler.transform( 12552 thisData[embedType], 12553 otherData[embedType], 12554 priority 12555 ) 12556 }; 12557 } 12558 } 12559 } 12560 delta.retain( 12561 transformedData, 12562 AttributeMap_default.transform( 12563 thisOp.attributes, 12564 otherOp.attributes, 12565 priority 12566 ) 12567 ); 12568 } 12569 } 12570 } 12571 return delta.chop(); 12572 } 12573 transformPosition(index, priority = false) { 12574 priority = !!priority; 12575 const thisIter = new Iterator(this.ops); 12576 let offset = 0; 12577 while (thisIter.hasNext() && offset <= index) { 12578 const length2 = thisIter.peekLength(); 12579 const nextType = thisIter.peekType(); 12580 thisIter.next(); 12581 if (nextType === "delete") { 12582 index -= Math.min(length2, index - offset); 12583 continue; 12584 } else if (nextType === "insert" && (offset < index || !priority)) { 12585 index += length2; 12586 } 12587 offset += length2; 12588 } 12589 return index; 12590 } 12591 /** 12592 * Given a Delta and a cursor position, do a diff and attempt to adjust 12593 * the diff to place insertions or deletions at the cursor position. 12594 * 12595 * @todo There are at least a few known cases where this produces a corrupted 12596 * diff. When this is fixed, it should not be necessary to verify that the 12597 * transformed diff applies cleanly. 12598 * 12599 * @see import("@wordpress/core-data/src/utils/crdt-blocks").mergeRichTextUpdate() 12600 * 12601 * @param other - The other Delta to diff against. 12602 * @param cursorAfterChange - The cursor position index after the change. 12603 * @return A Delta that attempts to place insertions or deletions at the cursor position. 12604 */ 12605 diffWithCursor(other, cursorAfterChange) { 12606 if (this.ops === other.ops) { 12607 return new _Delta(); 12608 } 12609 const strings = this.deltasToStrings(other); 12610 const maxStringLength = Math.max( 12611 ...strings.map((str) => str.length) 12612 ); 12613 if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { 12614 const diffResult = normalizeChangeCounts( 12615 diffLines(strings[0], strings[1]) 12616 ); 12617 const thisIterLarge = new Iterator(this.ops); 12618 const otherIterLarge = new Iterator(other.ops); 12619 return this.convertChangesToDelta( 12620 diffResult, 12621 thisIterLarge, 12622 otherIterLarge 12623 ).chop(); 12624 } else if (cursorAfterChange === null) { 12625 return this.diff(other); 12626 } 12627 let diffs = normalizeChangeCounts( 12628 diffChars(strings[0], strings[1]) 12629 ); 12630 let lastDiffPosition = 0; 12631 const adjustedDiffs = []; 12632 for (let i = 0; i < diffs.length; i++) { 12633 const diff = diffs[i]; 12634 const segmentStart = lastDiffPosition; 12635 const segmentEnd = lastDiffPosition + (diff.count ?? 0); 12636 const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; 12637 const isUnchangedSegment = !diff.added && !diff.removed; 12638 const isRemovalSegment = diff.removed && !diff.added; 12639 const nextDiff = diffs[i + 1]; 12640 const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; 12641 if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { 12642 const movedSegments = this.tryMoveInsertionToCursor( 12643 diff, 12644 nextDiff, 12645 cursorAfterChange, 12646 segmentStart 12647 ); 12648 if (movedSegments) { 12649 adjustedDiffs.push(...movedSegments); 12650 i++; 12651 lastDiffPosition = segmentEnd; 12652 continue; 12653 } 12654 } 12655 if (isRemovalSegment) { 12656 const movedSegments = this.tryMoveDeletionToCursor( 12657 diff, 12658 adjustedDiffs, 12659 cursorAfterChange, 12660 lastDiffPosition 12661 ); 12662 if (movedSegments) { 12663 adjustedDiffs.pop(); 12664 adjustedDiffs.push(...movedSegments); 12665 lastDiffPosition += diff.count ?? 0; 12666 continue; 12667 } 12668 } 12669 adjustedDiffs.push(diff); 12670 if (!diff.added) { 12671 lastDiffPosition += diff.count ?? 0; 12672 } 12673 } 12674 diffs = adjustedDiffs; 12675 const thisIter = new Iterator(this.ops); 12676 const otherIter = new Iterator(other.ops); 12677 const retDelta = this.convertChangesToDelta( 12678 diffs, 12679 thisIter, 12680 otherIter 12681 ); 12682 return retDelta.chop(); 12683 } 12684 /** 12685 * Try to move an insertion operation from after an unchanged segment to the cursor position within it. 12686 * This is a "look-ahead" strategy. 12687 * 12688 * @param diff - The current unchanged diff segment. 12689 * @param nextDiff - The next diff segment (expected to be an insertion). 12690 * @param cursorAfterChange - The cursor position after the change. 12691 * @param segmentStart - The start position of the current segment. 12692 * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. 12693 */ 12694 tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { 12695 const nextDiffInsert = nextDiff.value; 12696 const insertLength = nextDiffInsert.length; 12697 const insertOffset = cursorAfterChange - segmentStart - insertLength; 12698 const textAtCursor = diff.value.substring( 12699 insertOffset, 12700 insertOffset + nextDiffInsert.length 12701 ); 12702 const isInsertMoveable = textAtCursor === nextDiffInsert; 12703 if (!isInsertMoveable) { 12704 return null; 12705 } 12706 const beforeCursor = diff.value.substring(0, insertOffset); 12707 const afterCursor = diff.value.substring(insertOffset); 12708 const result = []; 12709 if (beforeCursor.length > 0) { 12710 result.push({ 12711 value: beforeCursor, 12712 count: beforeCursor.length, 12713 added: false, 12714 removed: false 12715 }); 12716 } 12717 result.push(nextDiff); 12718 if (afterCursor.length > 0) { 12719 result.push({ 12720 value: afterCursor, 12721 count: afterCursor.length, 12722 added: false, 12723 removed: false 12724 }); 12725 } 12726 return result; 12727 } 12728 /** 12729 * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. 12730 * This is a "look-back" strategy. 12731 * 12732 * @param diff - The current deletion diff segment. 12733 * @param adjustedDiffs - The array of previously processed diff segments. 12734 * @param cursorAfterChange - The cursor position after the change. 12735 * @param lastDiffPosition - The position in the document up to (but not including) the current diff. 12736 * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. 12737 */ 12738 tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { 12739 const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; 12740 if (!prevDiff || prevDiff.added || prevDiff.removed) { 12741 return null; 12742 } 12743 const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); 12744 const prevSegmentEnd = lastDiffPosition; 12745 if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { 12746 return null; 12747 } 12748 const deletedChars = diff.value; 12749 const deleteOffset = cursorAfterChange - prevSegmentStart; 12750 const textAtCursor = prevDiff.value.substring( 12751 deleteOffset, 12752 deleteOffset + deletedChars.length 12753 ); 12754 const canBePlacedHere = textAtCursor === deletedChars; 12755 if (!canBePlacedHere) { 12756 return null; 12757 } 12758 const beforeCursor = prevDiff.value.substring(0, deleteOffset); 12759 const atAndAfterCursor = prevDiff.value.substring(deleteOffset); 12760 const deletionLength = diff.count ?? 0; 12761 const afterDeletion = atAndAfterCursor.substring(deletionLength); 12762 const result = []; 12763 if (beforeCursor.length > 0) { 12764 result.push({ 12765 value: beforeCursor, 12766 count: beforeCursor.length, 12767 added: false, 12768 removed: false 12769 }); 12770 } 12771 result.push(diff); 12772 if (afterDeletion.length > 0) { 12773 result.push({ 12774 value: afterDeletion, 12775 count: afterDeletion.length, 12776 added: false, 12777 removed: false 12778 }); 12779 } 12780 return result; 12781 } 12782 /** 12783 * Convert two Deltas to string representations for diffing. 12784 * 12785 * @param other - The other Delta to convert. 12786 * @return A tuple of [thisString, otherString]. 12787 */ 12788 deltasToStrings(other) { 12789 return [this, other].map((delta) => { 12790 return delta.map((op) => { 12791 if (op.insert !== null || op.insert !== void 0) { 12792 return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; 12793 } 12794 const prep = delta === other ? "on" : "with"; 12795 throw new Error( 12796 "diff() called " + prep + " non-document" 12797 ); 12798 }).join(""); 12799 }); 12800 } 12801 /** 12802 * Process diff changes and convert them to Delta operations. 12803 * 12804 * @param changes - The array of changes from the diff algorithm. 12805 * @param thisIter - Iterator for this Delta's operations. 12806 * @param otherIter - Iterator for the other Delta's operations. 12807 * @return A Delta containing the processed diff operations. 12808 */ 12809 convertChangesToDelta(changes, thisIter, otherIter) { 12810 const retDelta = new _Delta(); 12811 changes.forEach((component) => { 12812 let length2 = component.count ?? 0; 12813 while (length2 > 0) { 12814 let opLength = 0; 12815 if (component.added) { 12816 opLength = Math.min(otherIter.peekLength(), length2); 12817 retDelta.push(otherIter.next(opLength)); 12818 } else if (component.removed) { 12819 opLength = Math.min(length2, thisIter.peekLength()); 12820 thisIter.next(opLength); 12821 retDelta.delete(opLength); 12822 } else { 12823 opLength = Math.min( 12824 thisIter.peekLength(), 12825 otherIter.peekLength(), 12826 length2 12827 ); 12828 const thisOp = thisIter.next(opLength); 12829 const otherOp = otherIter.next(opLength); 12830 if ((0, import_es62.default)(thisOp.insert, otherOp.insert)) { 12831 retDelta.retain( 12832 opLength, 12833 AttributeMap_default.diff( 12834 thisOp.attributes, 12835 otherOp.attributes 12836 ) 12837 ); 12838 } else { 12839 retDelta.push(otherOp).delete(opLength); 12840 } 12841 } 12842 length2 -= opLength; 12843 } 12844 }); 12845 return retDelta; 12846 } 12847 }; 12848 var Delta_default = Delta; 12849 12850 // packages/sync/build-module/private-apis.mjs 12851 var privateApis = {}; 12852 lock(privateApis, { 12853 ConnectionErrorCode, 12854 createSyncManager, 12855 Delta: Delta_default, 12856 CRDT_DOC_META_PERSISTENCE_KEY, 12857 CRDT_RECORD_MAP_KEY, 12858 LOCAL_EDITOR_ORIGIN, 12859 LOCAL_UNDO_IGNORED_ORIGIN, 12860 retrySyncConnection: () => pollingManager.retryNow() 12861 }); 12862 12863 // packages/sync/build-module/index.mjs 12864 var YJS_VERSION = "13"; 12865 return __toCommonJS(index_exports); 12866 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Fri Jul 24 08:20:19 2026 | Cross-referenced by PHPXref |