| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 "use strict"; 2 var wp; 3 (wp ||= {}).coreData = (() => { 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/data 36 var require_data = __commonJS({ 37 "package-external:@wordpress/data"(exports, module) { 38 module.exports = window.wp.data; 39 } 40 }); 41 42 // node_modules/fast-deep-equal/es6/index.js 43 var require_es6 = __commonJS({ 44 "node_modules/fast-deep-equal/es6/index.js"(exports, module) { 45 "use strict"; 46 module.exports = function equal(a, b) { 47 if (a === b) return true; 48 if (a && b && typeof a == "object" && typeof b == "object") { 49 if (a.constructor !== b.constructor) return false; 50 var length3, i, keys2; 51 if (Array.isArray(a)) { 52 length3 = a.length; 53 if (length3 != b.length) return false; 54 for (i = length3; i-- !== 0; ) 55 if (!equal(a[i], b[i])) return false; 56 return true; 57 } 58 if (a instanceof Map && b instanceof Map) { 59 if (a.size !== b.size) return false; 60 for (i of a.entries()) 61 if (!b.has(i[0])) return false; 62 for (i of a.entries()) 63 if (!equal(i[1], b.get(i[0]))) return false; 64 return true; 65 } 66 if (a instanceof Set && b instanceof Set) { 67 if (a.size !== b.size) return false; 68 for (i of a.entries()) 69 if (!b.has(i[0])) return false; 70 return true; 71 } 72 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 73 length3 = a.length; 74 if (length3 != b.length) return false; 75 for (i = length3; i-- !== 0; ) 76 if (a[i] !== b[i]) return false; 77 return true; 78 } 79 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 80 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 81 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 82 keys2 = Object.keys(a); 83 length3 = keys2.length; 84 if (length3 !== Object.keys(b).length) return false; 85 for (i = length3; i-- !== 0; ) 86 if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false; 87 for (i = length3; i-- !== 0; ) { 88 var key = keys2[i]; 89 if (!equal(a[key], b[key])) return false; 90 } 91 return true; 92 } 93 return a !== a && b !== b; 94 }; 95 } 96 }); 97 98 // package-external:@wordpress/compose 99 var require_compose = __commonJS({ 100 "package-external:@wordpress/compose"(exports, module) { 101 module.exports = window.wp.compose; 102 } 103 }); 104 105 // package-external:@wordpress/undo-manager 106 var require_undo_manager = __commonJS({ 107 "package-external:@wordpress/undo-manager"(exports, module) { 108 module.exports = window.wp.undoManager; 109 } 110 }); 111 112 // node_modules/equivalent-key-map/equivalent-key-map.js 113 var require_equivalent_key_map = __commonJS({ 114 "node_modules/equivalent-key-map/equivalent-key-map.js"(exports, module) { 115 "use strict"; 116 function _typeof(obj) { 117 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 118 _typeof = function(obj2) { 119 return typeof obj2; 120 }; 121 } else { 122 _typeof = function(obj2) { 123 return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; 124 }; 125 } 126 return _typeof(obj); 127 } 128 function _classCallCheck(instance, Constructor) { 129 if (!(instance instanceof Constructor)) { 130 throw new TypeError("Cannot call a class as a function"); 131 } 132 } 133 function _defineProperties(target, props) { 134 for (var i = 0; i < props.length; i++) { 135 var descriptor = props[i]; 136 descriptor.enumerable = descriptor.enumerable || false; 137 descriptor.configurable = true; 138 if ("value" in descriptor) descriptor.writable = true; 139 Object.defineProperty(target, descriptor.key, descriptor); 140 } 141 } 142 function _createClass(Constructor, protoProps, staticProps) { 143 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 144 if (staticProps) _defineProperties(Constructor, staticProps); 145 return Constructor; 146 } 147 function getValuePair(instance, key) { 148 var _map = instance._map, _arrayTreeMap = instance._arrayTreeMap, _objectTreeMap = instance._objectTreeMap; 149 if (_map.has(key)) { 150 return _map.get(key); 151 } 152 var properties = Object.keys(key).sort(); 153 var map2 = Array.isArray(key) ? _arrayTreeMap : _objectTreeMap; 154 for (var i = 0; i < properties.length; i++) { 155 var property = properties[i]; 156 map2 = map2.get(property); 157 if (map2 === void 0) { 158 return; 159 } 160 var propertyValue = key[property]; 161 map2 = map2.get(propertyValue); 162 if (map2 === void 0) { 163 return; 164 } 165 } 166 var valuePair = map2.get("_ekm_value"); 167 if (!valuePair) { 168 return; 169 } 170 _map.delete(valuePair[0]); 171 valuePair[0] = key; 172 map2.set("_ekm_value", valuePair); 173 _map.set(key, valuePair); 174 return valuePair; 175 } 176 var EquivalentKeyMap2 = /* @__PURE__ */ (function() { 177 function EquivalentKeyMap3(iterable) { 178 _classCallCheck(this, EquivalentKeyMap3); 179 this.clear(); 180 if (iterable instanceof EquivalentKeyMap3) { 181 var iterablePairs = []; 182 iterable.forEach(function(value, key) { 183 iterablePairs.push([key, value]); 184 }); 185 iterable = iterablePairs; 186 } 187 if (iterable != null) { 188 for (var i = 0; i < iterable.length; i++) { 189 this.set(iterable[i][0], iterable[i][1]); 190 } 191 } 192 } 193 _createClass(EquivalentKeyMap3, [{ 194 key: "set", 195 /** 196 * Add or update an element with a specified key and value. 197 * 198 * @param {*} key The key of the element to add. 199 * @param {*} value The value of the element to add. 200 * 201 * @return {EquivalentKeyMap} Map instance. 202 */ 203 value: function set(key, value) { 204 if (key === null || _typeof(key) !== "object") { 205 this._map.set(key, value); 206 return this; 207 } 208 var properties = Object.keys(key).sort(); 209 var valuePair = [key, value]; 210 var map2 = Array.isArray(key) ? this._arrayTreeMap : this._objectTreeMap; 211 for (var i = 0; i < properties.length; i++) { 212 var property = properties[i]; 213 if (!map2.has(property)) { 214 map2.set(property, new EquivalentKeyMap3()); 215 } 216 map2 = map2.get(property); 217 var propertyValue = key[property]; 218 if (!map2.has(propertyValue)) { 219 map2.set(propertyValue, new EquivalentKeyMap3()); 220 } 221 map2 = map2.get(propertyValue); 222 } 223 var previousValuePair = map2.get("_ekm_value"); 224 if (previousValuePair) { 225 this._map.delete(previousValuePair[0]); 226 } 227 map2.set("_ekm_value", valuePair); 228 this._map.set(key, valuePair); 229 return this; 230 } 231 /** 232 * Returns a specified element. 233 * 234 * @param {*} key The key of the element to return. 235 * 236 * @return {?*} The element associated with the specified key or undefined 237 * if the key can't be found. 238 */ 239 }, { 240 key: "get", 241 value: function get(key) { 242 if (key === null || _typeof(key) !== "object") { 243 return this._map.get(key); 244 } 245 var valuePair = getValuePair(this, key); 246 if (valuePair) { 247 return valuePair[1]; 248 } 249 } 250 /** 251 * Returns a boolean indicating whether an element with the specified key 252 * exists or not. 253 * 254 * @param {*} key The key of the element to test for presence. 255 * 256 * @return {boolean} Whether an element with the specified key exists. 257 */ 258 }, { 259 key: "has", 260 value: function has(key) { 261 if (key === null || _typeof(key) !== "object") { 262 return this._map.has(key); 263 } 264 return getValuePair(this, key) !== void 0; 265 } 266 /** 267 * Removes the specified element. 268 * 269 * @param {*} key The key of the element to remove. 270 * 271 * @return {boolean} Returns true if an element existed and has been 272 * removed, or false if the element does not exist. 273 */ 274 }, { 275 key: "delete", 276 value: function _delete(key) { 277 if (!this.has(key)) { 278 return false; 279 } 280 this.set(key, void 0); 281 return true; 282 } 283 /** 284 * Executes a provided function once per each key/value pair, in insertion 285 * order. 286 * 287 * @param {Function} callback Function to execute for each element. 288 * @param {*} thisArg Value to use as `this` when executing 289 * `callback`. 290 */ 291 }, { 292 key: "forEach", 293 value: function forEach2(callback) { 294 var _this = this; 295 var thisArg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : this; 296 this._map.forEach(function(value, key) { 297 if (key !== null && _typeof(key) === "object") { 298 value = value[1]; 299 } 300 callback.call(thisArg, value, key, _this); 301 }); 302 } 303 /** 304 * Removes all elements. 305 */ 306 }, { 307 key: "clear", 308 value: function clear() { 309 this._map = /* @__PURE__ */ new Map(); 310 this._arrayTreeMap = /* @__PURE__ */ new Map(); 311 this._objectTreeMap = /* @__PURE__ */ new Map(); 312 } 313 }, { 314 key: "size", 315 get: function get() { 316 return this._map.size; 317 } 318 }]); 319 return EquivalentKeyMap3; 320 })(); 321 module.exports = EquivalentKeyMap2; 322 } 323 }); 324 325 // package-external:@wordpress/url 326 var require_url = __commonJS({ 327 "package-external:@wordpress/url"(exports, module) { 328 module.exports = window.wp.url; 329 } 330 }); 331 332 // package-external:@wordpress/api-fetch 333 var require_api_fetch = __commonJS({ 334 "package-external:@wordpress/api-fetch"(exports, module) { 335 module.exports = window.wp.apiFetch; 336 } 337 }); 338 339 // package-external:@wordpress/blocks 340 var require_blocks = __commonJS({ 341 "package-external:@wordpress/blocks"(exports, module) { 342 module.exports = window.wp.blocks; 343 } 344 }); 345 346 // package-external:@wordpress/i18n 347 var require_i18n = __commonJS({ 348 "package-external:@wordpress/i18n"(exports, module) { 349 module.exports = window.wp.i18n; 350 } 351 }); 352 353 // package-external:@wordpress/private-apis 354 var require_private_apis = __commonJS({ 355 "package-external:@wordpress/private-apis"(exports, module) { 356 module.exports = window.wp.privateApis; 357 } 358 }); 359 360 // package-external:@wordpress/hooks 361 var require_hooks = __commonJS({ 362 "package-external:@wordpress/hooks"(exports, module) { 363 module.exports = window.wp.hooks; 364 } 365 }); 366 367 // package-external:@wordpress/block-editor 368 var require_block_editor = __commonJS({ 369 "package-external:@wordpress/block-editor"(exports, module) { 370 module.exports = window.wp.blockEditor; 371 } 372 }); 373 374 // package-external:@wordpress/rich-text 375 var require_rich_text = __commonJS({ 376 "package-external:@wordpress/rich-text"(exports, module) { 377 module.exports = window.wp.richText; 378 } 379 }); 380 381 // package-external:@wordpress/deprecated 382 var require_deprecated = __commonJS({ 383 "package-external:@wordpress/deprecated"(exports, module) { 384 module.exports = window.wp.deprecated; 385 } 386 }); 387 388 // package-external:@wordpress/html-entities 389 var require_html_entities = __commonJS({ 390 "package-external:@wordpress/html-entities"(exports, module) { 391 module.exports = window.wp.htmlEntities; 392 } 393 }); 394 395 // package-external:@wordpress/element 396 var require_element = __commonJS({ 397 "package-external:@wordpress/element"(exports, module) { 398 module.exports = window.wp.element; 399 } 400 }); 401 402 // vendor-external:react/jsx-runtime 403 var require_jsx_runtime = __commonJS({ 404 "vendor-external:react/jsx-runtime"(exports, module) { 405 module.exports = window.ReactJSXRuntime; 406 } 407 }); 408 409 // package-external:@wordpress/warning 410 var require_warning = __commonJS({ 411 "package-external:@wordpress/warning"(exports, module) { 412 module.exports = window.wp.warning; 413 } 414 }); 415 416 // packages/core-data/build-module/index.mjs 417 var index_exports = {}; 418 __export(index_exports, { 419 EntityProvider: () => EntityProvider, 420 __experimentalFetchLinkSuggestions: () => fetchLinkSuggestions, 421 __experimentalFetchUrlData: () => experimental_fetch_url_data_default, 422 __experimentalUseEntityRecord: () => __experimentalUseEntityRecord, 423 __experimentalUseEntityRecords: () => __experimentalUseEntityRecords, 424 __experimentalUseResourcePermissions: () => __experimentalUseResourcePermissions, 425 fetchBlockPatterns: () => fetchBlockPatterns, 426 privateApis: () => privateApis2, 427 store: () => store, 428 useEntityBlockEditor: () => useEntityBlockEditor, 429 useEntityId: () => useEntityId, 430 useEntityProp: () => useEntityProp, 431 useEntityRecord: () => useEntityRecord, 432 useEntityRecords: () => useEntityRecords, 433 useResourcePermissions: () => use_resource_permissions_default 434 }); 435 var import_data16 = __toESM(require_data(), 1); 436 437 // packages/core-data/build-module/reducer.mjs 438 var import_es66 = __toESM(require_es6(), 1); 439 var import_compose2 = __toESM(require_compose(), 1); 440 var import_data8 = __toESM(require_data(), 1); 441 var import_undo_manager2 = __toESM(require_undo_manager(), 1); 442 443 // packages/core-data/build-module/utils/conservative-map-item.mjs 444 var import_es6 = __toESM(require_es6(), 1); 445 function conservativeMapItem(item, nextItem) { 446 if (!item) { 447 return nextItem; 448 } 449 let hasChanges = false; 450 const result = {}; 451 for (const key in nextItem) { 452 if ((0, import_es6.default)(item[key], nextItem[key])) { 453 result[key] = item[key]; 454 } else { 455 hasChanges = true; 456 result[key] = nextItem[key]; 457 } 458 } 459 if (!hasChanges) { 460 return item; 461 } 462 for (const key in item) { 463 if (!result.hasOwnProperty(key)) { 464 result[key] = item[key]; 465 } 466 } 467 return result; 468 } 469 470 // packages/core-data/build-module/utils/get-normalized-comma-separable.mjs 471 function getNormalizedCommaSeparable(value) { 472 if (typeof value === "string") { 473 return value.split(","); 474 } else if (Array.isArray(value)) { 475 return value; 476 } 477 return null; 478 } 479 var get_normalized_comma_separable_default = getNormalizedCommaSeparable; 480 481 // packages/core-data/build-module/utils/if-matching-action.mjs 482 var ifMatchingAction = (isMatch) => (reducer) => (state, action) => { 483 if (state === void 0 || isMatch(action)) { 484 return reducer(state, action); 485 } 486 return state; 487 }; 488 var if_matching_action_default = ifMatchingAction; 489 490 // packages/core-data/build-module/utils/forward-resolver.mjs 491 var forwardResolver = (resolverName) => (...args2) => async ({ resolveSelect: resolveSelect2 }) => { 492 await resolveSelect2[resolverName](...args2); 493 }; 494 var forward_resolver_default = forwardResolver; 495 496 // packages/core-data/build-module/utils/on-sub-key.mjs 497 var onSubKey = (actionProperty) => (reducer) => (state = {}, action) => { 498 const key = action[actionProperty]; 499 if (key === void 0) { 500 return state; 501 } 502 const nextKeyState = reducer(state[key], action); 503 if (nextKeyState === state[key]) { 504 return state; 505 } 506 return { 507 ...state, 508 [key]: nextKeyState 509 }; 510 }; 511 var on_sub_key_default = onSubKey; 512 513 // packages/core-data/build-module/utils/replace-action.mjs 514 var replaceAction = (replacer) => (reducer) => (state, action) => { 515 return reducer(state, replacer(action)); 516 }; 517 var replace_action_default = replaceAction; 518 519 // packages/core-data/build-module/utils/with-weak-map-cache.mjs 520 function withWeakMapCache(fn) { 521 const cache3 = /* @__PURE__ */ new WeakMap(); 522 return (key) => { 523 let value; 524 if (cache3.has(key)) { 525 value = cache3.get(key); 526 } else { 527 value = fn(key); 528 if (key !== null && typeof key === "object") { 529 cache3.set(key, value); 530 } 531 } 532 return value; 533 }; 534 } 535 var with_weak_map_cache_default = withWeakMapCache; 536 537 // packages/core-data/build-module/utils/is-raw-attribute.mjs 538 function isRawAttribute(entity2, attribute) { 539 return (entity2.rawAttributes || []).includes(attribute); 540 } 541 542 // packages/core-data/build-module/utils/set-nested-value.mjs 543 function setNestedValue(object, path, value) { 544 if (!object || typeof object !== "object") { 545 return object; 546 } 547 const normalizedPath = Array.isArray(path) ? path : path.split("."); 548 normalizedPath.reduce((acc, key, idx) => { 549 if (acc[key] === void 0) { 550 if (Number.isInteger(normalizedPath[idx + 1])) { 551 acc[key] = []; 552 } else { 553 acc[key] = {}; 554 } 555 } 556 if (idx === normalizedPath.length - 1) { 557 acc[key] = value; 558 } 559 return acc[key]; 560 }, object); 561 return object; 562 } 563 564 // packages/core-data/build-module/utils/get-nested-value.mjs 565 function getNestedValue(object, path, defaultValue) { 566 if (!object || typeof object !== "object" || typeof path !== "string" && !Array.isArray(path)) { 567 return object; 568 } 569 const normalizedPath = Array.isArray(path) ? path : path.split("."); 570 let value = object; 571 normalizedPath.forEach((fieldName) => { 572 value = value?.[fieldName]; 573 }); 574 return value !== void 0 ? value : defaultValue; 575 } 576 577 // packages/core-data/build-module/utils/is-numeric-id.mjs 578 function isNumericID(id2) { 579 return /^\s*\d+\s*$/.test(id2); 580 } 581 582 // packages/core-data/build-module/utils/user-permissions.mjs 583 var ALLOWED_RESOURCE_ACTIONS = [ 584 "create", 585 "read", 586 "update", 587 "delete" 588 ]; 589 function getUserPermissionsFromAllowHeader(allowedMethods) { 590 const permissions = {}; 591 if (!allowedMethods) { 592 return permissions; 593 } 594 const methods = { 595 create: "POST", 596 read: "GET", 597 update: "PUT", 598 delete: "DELETE" 599 }; 600 for (const [actionName, methodName] of Object.entries(methods)) { 601 permissions[actionName] = allowedMethods.includes(methodName); 602 } 603 return permissions; 604 } 605 function getUserPermissionCacheKey(action, resource, id2) { 606 const key = (typeof resource === "object" ? [action, resource.kind, resource.name, resource.id] : [action, resource, id2]).filter(Boolean).join("/"); 607 return key; 608 } 609 610 // packages/core-data/build-module/utils/receive-intermediate-results.mjs 611 var RECEIVE_INTERMEDIATE_RESULTS = /* @__PURE__ */ Symbol( 612 "RECEIVE_INTERMEDIATE_RESULTS" 613 ); 614 615 // packages/core-data/build-module/queried-data/actions.mjs 616 function receiveItems(items2, edits, meta) { 617 return { 618 type: "RECEIVE_ITEMS", 619 items: items2, 620 persistedEdits: edits, 621 meta 622 }; 623 } 624 function removeItems(kind, name, records, invalidateCache = false) { 625 return { 626 type: "REMOVE_ITEMS", 627 itemIds: Array.isArray(records) ? records : [records], 628 kind, 629 name, 630 invalidateCache 631 }; 632 } 633 function receiveQueriedItems(items2, query = {}, edits, meta) { 634 return { 635 ...receiveItems(items2, edits, meta), 636 query 637 }; 638 } 639 640 // packages/core-data/build-module/queried-data/selectors.mjs 641 var import_equivalent_key_map = __toESM(require_equivalent_key_map(), 1); 642 var import_data = __toESM(require_data(), 1); 643 644 // packages/core-data/build-module/queried-data/get-query-parts.mjs 645 var import_url = __toESM(require_url(), 1); 646 function getQueryParts(query) { 647 const parts = { 648 stableKey: "", 649 page: 1, 650 perPage: 10, 651 fields: null, 652 include: null, 653 context: "default" 654 }; 655 const keys2 = Object.keys(query).sort(); 656 for (let i = 0; i < keys2.length; i++) { 657 const key = keys2[i]; 658 let value = query[key]; 659 switch (key) { 660 case "page": 661 parts[key] = Number(value); 662 break; 663 case "per_page": 664 parts.perPage = Number(value); 665 break; 666 case "context": 667 parts.context = value; 668 break; 669 default: 670 if (key === "_fields") { 671 parts.fields = get_normalized_comma_separable_default(value) ?? []; 672 value = parts.fields.join(); 673 } 674 if (key === "include") { 675 if (typeof value === "number") { 676 value = value.toString(); 677 } 678 parts.include = (get_normalized_comma_separable_default(value) ?? []).map(Number); 679 value = parts.include.join(); 680 } 681 parts.stableKey += (parts.stableKey ? "&" : "") + (0, import_url.addQueryArgs)("", { [key]: value }).slice(1); 682 } 683 } 684 return parts; 685 } 686 var get_query_parts_default = with_weak_map_cache_default(getQueryParts); 687 688 // packages/core-data/build-module/queried-data/selectors.mjs 689 var queriedItemsCacheByState = /* @__PURE__ */ new WeakMap(); 690 function getQueriedItemsUncached(state, query) { 691 const { stableKey, page, perPage, include, fields, context } = get_query_parts_default(query); 692 let itemIds; 693 if (state.queries?.[context]?.[stableKey]) { 694 itemIds = state.queries[context][stableKey].itemIds; 695 } 696 if (!itemIds) { 697 return null; 698 } 699 const startOffset = perPage === -1 ? 0 : (page - 1) * perPage; 700 const endOffset = perPage === -1 ? itemIds.length : Math.min(startOffset + perPage, itemIds.length); 701 const items2 = []; 702 for (let i = startOffset; i < endOffset; i++) { 703 const itemId = itemIds[i]; 704 if (Array.isArray(include) && !include.includes(itemId)) { 705 continue; 706 } 707 if (itemId === void 0) { 708 continue; 709 } 710 if (!state.items[context]?.hasOwnProperty(itemId)) { 711 return null; 712 } 713 const item = state.items[context][itemId]; 714 let filteredItem; 715 if (Array.isArray(fields)) { 716 filteredItem = {}; 717 for (let f = 0; f < fields.length; f++) { 718 const field = fields[f].split("."); 719 let value = item; 720 field.forEach((fieldName) => { 721 value = value?.[fieldName]; 722 }); 723 setNestedValue(filteredItem, field, value); 724 } 725 } else { 726 if (!state.itemIsComplete[context]?.[itemId]) { 727 return null; 728 } 729 filteredItem = item; 730 } 731 items2.push(filteredItem); 732 } 733 return items2; 734 } 735 var getQueriedItems = (0, import_data.createSelector)((state, query = {}) => { 736 let queriedItemsCache = queriedItemsCacheByState.get(state); 737 if (queriedItemsCache) { 738 const queriedItems = queriedItemsCache.get(query); 739 if (queriedItems !== void 0) { 740 return queriedItems; 741 } 742 } else { 743 queriedItemsCache = new import_equivalent_key_map.default(); 744 queriedItemsCacheByState.set(state, queriedItemsCache); 745 } 746 const items2 = getQueriedItemsUncached(state, query); 747 queriedItemsCache.set(query, items2); 748 return items2; 749 }); 750 function getQueriedTotalItems(state, query = {}) { 751 const { stableKey, context } = get_query_parts_default(query); 752 return state.queries?.[context]?.[stableKey]?.meta?.totalItems ?? null; 753 } 754 function getQueriedTotalPages(state, query = {}) { 755 const { stableKey, context } = get_query_parts_default(query); 756 return state.queries?.[context]?.[stableKey]?.meta?.totalPages ?? null; 757 } 758 759 // packages/core-data/build-module/queried-data/reducer.mjs 760 var import_data7 = __toESM(require_data(), 1); 761 var import_compose = __toESM(require_compose(), 1); 762 763 // node_modules/tslib/tslib.es6.mjs 764 var __assign = function() { 765 __assign = Object.assign || function __assign2(t) { 766 for (var s, i = 1, n = arguments.length; i < n; i++) { 767 s = arguments[i]; 768 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 769 } 770 return t; 771 }; 772 return __assign.apply(this, arguments); 773 }; 774 775 // node_modules/lower-case/dist.es2015/index.js 776 function lowerCase(str) { 777 return str.toLowerCase(); 778 } 779 780 // node_modules/no-case/dist.es2015/index.js 781 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 782 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 783 function noCase(input, options) { 784 if (options === void 0) { 785 options = {}; 786 } 787 var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d; 788 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 789 var start = 0; 790 var end = result.length; 791 while (result.charAt(start) === "\0") 792 start++; 793 while (result.charAt(end - 1) === "\0") 794 end--; 795 return result.slice(start, end).split("\0").map(transform).join(delimiter); 796 } 797 function replace(input, re, value) { 798 if (re instanceof RegExp) 799 return input.replace(re, value); 800 return re.reduce(function(input2, re2) { 801 return input2.replace(re2, value); 802 }, input); 803 } 804 805 // node_modules/pascal-case/dist.es2015/index.js 806 function pascalCaseTransform(input, index) { 807 var firstChar = input.charAt(0); 808 var lowerChars = input.substr(1).toLowerCase(); 809 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 810 return "_" + firstChar + lowerChars; 811 } 812 return "" + firstChar.toUpperCase() + lowerChars; 813 } 814 function pascalCase(input, options) { 815 if (options === void 0) { 816 options = {}; 817 } 818 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 819 } 820 821 // node_modules/camel-case/dist.es2015/index.js 822 function camelCaseTransform(input, index) { 823 if (index === 0) 824 return input.toLowerCase(); 825 return pascalCaseTransform(input, index); 826 } 827 function camelCase(input, options) { 828 if (options === void 0) { 829 options = {}; 830 } 831 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 832 } 833 834 // node_modules/upper-case-first/dist.es2015/index.js 835 function upperCaseFirst(input) { 836 return input.charAt(0).toUpperCase() + input.substr(1); 837 } 838 839 // node_modules/capital-case/dist.es2015/index.js 840 function capitalCaseTransform(input) { 841 return upperCaseFirst(input.toLowerCase()); 842 } 843 function capitalCase(input, options) { 844 if (options === void 0) { 845 options = {}; 846 } 847 return noCase(input, __assign({ delimiter: " ", transform: capitalCaseTransform }, options)); 848 } 849 850 // packages/core-data/build-module/entities.mjs 851 var import_api_fetch2 = __toESM(require_api_fetch(), 1); 852 var import_blocks4 = __toESM(require_blocks(), 1); 853 var import_i18n = __toESM(require_i18n(), 1); 854 855 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 856 var import_data5 = __toESM(require_data(), 1); 857 858 // node_modules/yjs/dist/yjs.mjs 859 var yjs_exports = {}; 860 __export(yjs_exports, { 861 AbsolutePosition: () => AbsolutePosition, 862 AbstractConnector: () => AbstractConnector, 863 AbstractStruct: () => AbstractStruct, 864 AbstractType: () => AbstractType, 865 Array: () => YArray, 866 ContentAny: () => ContentAny, 867 ContentBinary: () => ContentBinary, 868 ContentDeleted: () => ContentDeleted, 869 ContentDoc: () => ContentDoc, 870 ContentEmbed: () => ContentEmbed, 871 ContentFormat: () => ContentFormat, 872 ContentJSON: () => ContentJSON, 873 ContentString: () => ContentString, 874 ContentType: () => ContentType, 875 Doc: () => Doc, 876 GC: () => GC, 877 ID: () => ID, 878 Item: () => Item, 879 Map: () => YMap, 880 PermanentUserData: () => PermanentUserData, 881 RelativePosition: () => RelativePosition, 882 Skip: () => Skip, 883 Snapshot: () => Snapshot, 884 Text: () => YText, 885 Transaction: () => Transaction, 886 UndoManager: () => UndoManager, 887 UpdateDecoderV1: () => UpdateDecoderV1, 888 UpdateDecoderV2: () => UpdateDecoderV2, 889 UpdateEncoderV1: () => UpdateEncoderV1, 890 UpdateEncoderV2: () => UpdateEncoderV2, 891 XmlElement: () => YXmlElement, 892 XmlFragment: () => YXmlFragment, 893 XmlHook: () => YXmlHook, 894 XmlText: () => YXmlText, 895 YArrayEvent: () => YArrayEvent, 896 YEvent: () => YEvent, 897 YMapEvent: () => YMapEvent, 898 YTextEvent: () => YTextEvent, 899 YXmlEvent: () => YXmlEvent, 900 applyUpdate: () => applyUpdate, 901 applyUpdateV2: () => applyUpdateV2, 902 cleanupYTextFormatting: () => cleanupYTextFormatting, 903 compareIDs: () => compareIDs, 904 compareRelativePositions: () => compareRelativePositions, 905 convertUpdateFormatV1ToV2: () => convertUpdateFormatV1ToV2, 906 convertUpdateFormatV2ToV1: () => convertUpdateFormatV2ToV1, 907 createAbsolutePositionFromRelativePosition: () => createAbsolutePositionFromRelativePosition, 908 createDeleteSet: () => createDeleteSet, 909 createDeleteSetFromStructStore: () => createDeleteSetFromStructStore, 910 createDocFromSnapshot: () => createDocFromSnapshot, 911 createID: () => createID, 912 createRelativePositionFromJSON: () => createRelativePositionFromJSON, 913 createRelativePositionFromTypeIndex: () => createRelativePositionFromTypeIndex, 914 createSnapshot: () => createSnapshot, 915 decodeRelativePosition: () => decodeRelativePosition, 916 decodeSnapshot: () => decodeSnapshot, 917 decodeSnapshotV2: () => decodeSnapshotV2, 918 decodeStateVector: () => decodeStateVector, 919 decodeUpdate: () => decodeUpdate, 920 decodeUpdateV2: () => decodeUpdateV2, 921 diffUpdate: () => diffUpdate, 922 diffUpdateV2: () => diffUpdateV2, 923 emptySnapshot: () => emptySnapshot, 924 encodeRelativePosition: () => encodeRelativePosition, 925 encodeSnapshot: () => encodeSnapshot, 926 encodeSnapshotV2: () => encodeSnapshotV2, 927 encodeStateAsUpdate: () => encodeStateAsUpdate, 928 encodeStateAsUpdateV2: () => encodeStateAsUpdateV2, 929 encodeStateVector: () => encodeStateVector, 930 encodeStateVectorFromUpdate: () => encodeStateVectorFromUpdate, 931 encodeStateVectorFromUpdateV2: () => encodeStateVectorFromUpdateV2, 932 equalDeleteSets: () => equalDeleteSets, 933 equalSnapshots: () => equalSnapshots, 934 findIndexSS: () => findIndexSS, 935 findRootTypeKey: () => findRootTypeKey, 936 getItem: () => getItem, 937 getItemCleanEnd: () => getItemCleanEnd, 938 getItemCleanStart: () => getItemCleanStart, 939 getState: () => getState, 940 getTypeChildren: () => getTypeChildren, 941 isDeleted: () => isDeleted, 942 isParentOf: () => isParentOf, 943 iterateDeletedStructs: () => iterateDeletedStructs, 944 logType: () => logType, 945 logUpdate: () => logUpdate, 946 logUpdateV2: () => logUpdateV2, 947 mergeDeleteSets: () => mergeDeleteSets, 948 mergeUpdates: () => mergeUpdates, 949 mergeUpdatesV2: () => mergeUpdatesV2, 950 obfuscateUpdate: () => obfuscateUpdate, 951 obfuscateUpdateV2: () => obfuscateUpdateV2, 952 parseUpdateMeta: () => parseUpdateMeta, 953 parseUpdateMetaV2: () => parseUpdateMetaV2, 954 readUpdate: () => readUpdate, 955 readUpdateV2: () => readUpdateV2, 956 relativePositionToJSON: () => relativePositionToJSON, 957 snapshot: () => snapshot, 958 snapshotContainsUpdate: () => snapshotContainsUpdate, 959 transact: () => transact, 960 tryGc: () => tryGc, 961 typeListToArraySnapshot: () => typeListToArraySnapshot, 962 typeMapGetAllSnapshot: () => typeMapGetAllSnapshot, 963 typeMapGetSnapshot: () => typeMapGetSnapshot 964 }); 965 966 // node_modules/lib0/map.js 967 var create = () => /* @__PURE__ */ new Map(); 968 var copy = (m) => { 969 const r = create(); 970 m.forEach((v, k) => { 971 r.set(k, v); 972 }); 973 return r; 974 }; 975 var setIfUndefined = (map2, key, createT) => { 976 let set = map2.get(key); 977 if (set === void 0) { 978 map2.set(key, set = createT()); 979 } 980 return set; 981 }; 982 var map = (m, f) => { 983 const res = []; 984 for (const [key, value] of m) { 985 res.push(f(value, key)); 986 } 987 return res; 988 }; 989 var any = (m, f) => { 990 for (const [key, value] of m) { 991 if (f(value, key)) { 992 return true; 993 } 994 } 995 return false; 996 }; 997 998 // node_modules/lib0/set.js 999 var create2 = () => /* @__PURE__ */ new Set(); 1000 1001 // node_modules/lib0/array.js 1002 var last = (arr) => arr[arr.length - 1]; 1003 var appendTo = (dest, src) => { 1004 for (let i = 0; i < src.length; i++) { 1005 dest.push(src[i]); 1006 } 1007 }; 1008 var from = Array.from; 1009 var some = (arr, f) => { 1010 for (let i = 0; i < arr.length; i++) { 1011 if (f(arr[i], i, arr)) { 1012 return true; 1013 } 1014 } 1015 return false; 1016 }; 1017 var unfold = (len, f) => { 1018 const array = new Array(len); 1019 for (let i = 0; i < len; i++) { 1020 array[i] = f(i, array); 1021 } 1022 return array; 1023 }; 1024 var isArray = Array.isArray; 1025 1026 // node_modules/lib0/observable.js 1027 var ObservableV2 = class { 1028 constructor() { 1029 this._observers = create(); 1030 } 1031 /** 1032 * @template {keyof EVENTS & string} NAME 1033 * @param {NAME} name 1034 * @param {EVENTS[NAME]} f 1035 */ 1036 on(name, f) { 1037 setIfUndefined( 1038 this._observers, 1039 /** @type {string} */ 1040 name, 1041 create2 1042 ).add(f); 1043 return f; 1044 } 1045 /** 1046 * @template {keyof EVENTS & string} NAME 1047 * @param {NAME} name 1048 * @param {EVENTS[NAME]} f 1049 */ 1050 once(name, f) { 1051 const _f = (...args2) => { 1052 this.off( 1053 name, 1054 /** @type {any} */ 1055 _f 1056 ); 1057 f(...args2); 1058 }; 1059 this.on( 1060 name, 1061 /** @type {any} */ 1062 _f 1063 ); 1064 } 1065 /** 1066 * @template {keyof EVENTS & string} NAME 1067 * @param {NAME} name 1068 * @param {EVENTS[NAME]} f 1069 */ 1070 off(name, f) { 1071 const observers = this._observers.get(name); 1072 if (observers !== void 0) { 1073 observers.delete(f); 1074 if (observers.size === 0) { 1075 this._observers.delete(name); 1076 } 1077 } 1078 } 1079 /** 1080 * Emit a named event. All registered event listeners that listen to the 1081 * specified name will receive the event. 1082 * 1083 * @todo This should catch exceptions 1084 * 1085 * @template {keyof EVENTS & string} NAME 1086 * @param {NAME} name The event name. 1087 * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. 1088 */ 1089 emit(name, args2) { 1090 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 1091 } 1092 destroy() { 1093 this._observers = create(); 1094 } 1095 }; 1096 var Observable = class { 1097 constructor() { 1098 this._observers = create(); 1099 } 1100 /** 1101 * @param {N} name 1102 * @param {function} f 1103 */ 1104 on(name, f) { 1105 setIfUndefined(this._observers, name, create2).add(f); 1106 } 1107 /** 1108 * @param {N} name 1109 * @param {function} f 1110 */ 1111 once(name, f) { 1112 const _f = (...args2) => { 1113 this.off(name, _f); 1114 f(...args2); 1115 }; 1116 this.on(name, _f); 1117 } 1118 /** 1119 * @param {N} name 1120 * @param {function} f 1121 */ 1122 off(name, f) { 1123 const observers = this._observers.get(name); 1124 if (observers !== void 0) { 1125 observers.delete(f); 1126 if (observers.size === 0) { 1127 this._observers.delete(name); 1128 } 1129 } 1130 } 1131 /** 1132 * Emit a named event. All registered event listeners that listen to the 1133 * specified name will receive the event. 1134 * 1135 * @todo This should catch exceptions 1136 * 1137 * @param {N} name The event name. 1138 * @param {Array<any>} args The arguments that are applied to the event listener. 1139 */ 1140 emit(name, args2) { 1141 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 1142 } 1143 destroy() { 1144 this._observers = create(); 1145 } 1146 }; 1147 1148 // node_modules/lib0/math.js 1149 var floor = Math.floor; 1150 var abs = Math.abs; 1151 var min = (a, b) => a < b ? a : b; 1152 var max = (a, b) => a > b ? a : b; 1153 var isNaN2 = Number.isNaN; 1154 var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; 1155 1156 // node_modules/lib0/binary.js 1157 var BIT1 = 1; 1158 var BIT2 = 2; 1159 var BIT3 = 4; 1160 var BIT4 = 8; 1161 var BIT6 = 32; 1162 var BIT7 = 64; 1163 var BIT8 = 128; 1164 var BIT18 = 1 << 17; 1165 var BIT19 = 1 << 18; 1166 var BIT20 = 1 << 19; 1167 var BIT21 = 1 << 20; 1168 var BIT22 = 1 << 21; 1169 var BIT23 = 1 << 22; 1170 var BIT24 = 1 << 23; 1171 var BIT25 = 1 << 24; 1172 var BIT26 = 1 << 25; 1173 var BIT27 = 1 << 26; 1174 var BIT28 = 1 << 27; 1175 var BIT29 = 1 << 28; 1176 var BIT30 = 1 << 29; 1177 var BIT31 = 1 << 30; 1178 var BIT32 = 1 << 31; 1179 var BITS5 = 31; 1180 var BITS6 = 63; 1181 var BITS7 = 127; 1182 var BITS17 = BIT18 - 1; 1183 var BITS18 = BIT19 - 1; 1184 var BITS19 = BIT20 - 1; 1185 var BITS20 = BIT21 - 1; 1186 var BITS21 = BIT22 - 1; 1187 var BITS22 = BIT23 - 1; 1188 var BITS23 = BIT24 - 1; 1189 var BITS24 = BIT25 - 1; 1190 var BITS25 = BIT26 - 1; 1191 var BITS26 = BIT27 - 1; 1192 var BITS27 = BIT28 - 1; 1193 var BITS28 = BIT29 - 1; 1194 var BITS29 = BIT30 - 1; 1195 var BITS30 = BIT31 - 1; 1196 var BITS31 = 2147483647; 1197 1198 // node_modules/lib0/number.js 1199 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; 1200 var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; 1201 var LOWEST_INT32 = 1 << 31; 1202 var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); 1203 var isNaN3 = Number.isNaN; 1204 var parseInt2 = Number.parseInt; 1205 1206 // node_modules/lib0/string.js 1207 var fromCharCode = String.fromCharCode; 1208 var fromCodePoint = String.fromCodePoint; 1209 var MAX_UTF16_CHARACTER = fromCharCode(65535); 1210 var toLowerCase = (s) => s.toLowerCase(); 1211 var trimLeftRegex = /^\s*/g; 1212 var trimLeft = (s) => s.replace(trimLeftRegex, ""); 1213 var fromCamelCaseRegex = /([A-Z])/g; 1214 var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match) => `$separator}$toLowerCase(match)}`)); 1215 var _encodeUtf8Polyfill = (str) => { 1216 const encodedString = unescape(encodeURIComponent(str)); 1217 const len = encodedString.length; 1218 const buf = new Uint8Array(len); 1219 for (let i = 0; i < len; i++) { 1220 buf[i] = /** @type {number} */ 1221 encodedString.codePointAt(i); 1222 } 1223 return buf; 1224 }; 1225 var utf8TextEncoder = ( 1226 /** @type {TextEncoder} */ 1227 typeof TextEncoder !== "undefined" ? new TextEncoder() : null 1228 ); 1229 var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); 1230 var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; 1231 var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); 1232 if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { 1233 utf8TextDecoder = null; 1234 } 1235 var repeat = (source, n) => unfold(n, () => source).join(""); 1236 1237 // node_modules/lib0/encoding.js 1238 var Encoder = class { 1239 constructor() { 1240 this.cpos = 0; 1241 this.cbuf = new Uint8Array(100); 1242 this.bufs = []; 1243 } 1244 }; 1245 var createEncoder = () => new Encoder(); 1246 var length = (encoder) => { 1247 let len = encoder.cpos; 1248 for (let i = 0; i < encoder.bufs.length; i++) { 1249 len += encoder.bufs[i].length; 1250 } 1251 return len; 1252 }; 1253 var toUint8Array = (encoder) => { 1254 const uint8arr = new Uint8Array(length(encoder)); 1255 let curPos = 0; 1256 for (let i = 0; i < encoder.bufs.length; i++) { 1257 const d = encoder.bufs[i]; 1258 uint8arr.set(d, curPos); 1259 curPos += d.length; 1260 } 1261 uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); 1262 return uint8arr; 1263 }; 1264 var verifyLen = (encoder, len) => { 1265 const bufferLen = encoder.cbuf.length; 1266 if (bufferLen - encoder.cpos < len) { 1267 encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); 1268 encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); 1269 encoder.cpos = 0; 1270 } 1271 }; 1272 var write = (encoder, num) => { 1273 const bufferLen = encoder.cbuf.length; 1274 if (encoder.cpos === bufferLen) { 1275 encoder.bufs.push(encoder.cbuf); 1276 encoder.cbuf = new Uint8Array(bufferLen * 2); 1277 encoder.cpos = 0; 1278 } 1279 encoder.cbuf[encoder.cpos++] = num; 1280 }; 1281 var writeUint8 = write; 1282 var writeVarUint = (encoder, num) => { 1283 while (num > BITS7) { 1284 write(encoder, BIT8 | BITS7 & num); 1285 num = floor(num / 128); 1286 } 1287 write(encoder, BITS7 & num); 1288 }; 1289 var writeVarInt = (encoder, num) => { 1290 const isNegative = isNegativeZero(num); 1291 if (isNegative) { 1292 num = -num; 1293 } 1294 write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); 1295 num = floor(num / 64); 1296 while (num > 0) { 1297 write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); 1298 num = floor(num / 128); 1299 } 1300 }; 1301 var _strBuffer = new Uint8Array(3e4); 1302 var _maxStrBSize = _strBuffer.length / 3; 1303 var _writeVarStringNative = (encoder, str) => { 1304 if (str.length < _maxStrBSize) { 1305 const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; 1306 writeVarUint(encoder, written); 1307 for (let i = 0; i < written; i++) { 1308 write(encoder, _strBuffer[i]); 1309 } 1310 } else { 1311 writeVarUint8Array(encoder, encodeUtf8(str)); 1312 } 1313 }; 1314 var _writeVarStringPolyfill = (encoder, str) => { 1315 const encodedString = unescape(encodeURIComponent(str)); 1316 const len = encodedString.length; 1317 writeVarUint(encoder, len); 1318 for (let i = 0; i < len; i++) { 1319 write( 1320 encoder, 1321 /** @type {number} */ 1322 encodedString.codePointAt(i) 1323 ); 1324 } 1325 }; 1326 var writeVarString = utf8TextEncoder && /** @type {any} */ 1327 utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; 1328 var writeBinaryEncoder = (encoder, append2) => writeUint8Array(encoder, toUint8Array(append2)); 1329 var writeUint8Array = (encoder, uint8Array) => { 1330 const bufferLen = encoder.cbuf.length; 1331 const cpos = encoder.cpos; 1332 const leftCopyLen = min(bufferLen - cpos, uint8Array.length); 1333 const rightCopyLen = uint8Array.length - leftCopyLen; 1334 encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); 1335 encoder.cpos += leftCopyLen; 1336 if (rightCopyLen > 0) { 1337 encoder.bufs.push(encoder.cbuf); 1338 encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); 1339 encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); 1340 encoder.cpos = rightCopyLen; 1341 } 1342 }; 1343 var writeVarUint8Array = (encoder, uint8Array) => { 1344 writeVarUint(encoder, uint8Array.byteLength); 1345 writeUint8Array(encoder, uint8Array); 1346 }; 1347 var writeOnDataView = (encoder, len) => { 1348 verifyLen(encoder, len); 1349 const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); 1350 encoder.cpos += len; 1351 return dview; 1352 }; 1353 var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); 1354 var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); 1355 var writeBigInt64 = (encoder, num) => ( 1356 /** @type {any} */ 1357 writeOnDataView(encoder, 8).setBigInt64(0, num, false) 1358 ); 1359 var floatTestBed = new DataView(new ArrayBuffer(4)); 1360 var isFloat32 = (num) => { 1361 floatTestBed.setFloat32(0, num); 1362 return floatTestBed.getFloat32(0) === num; 1363 }; 1364 var writeAny = (encoder, data) => { 1365 switch (typeof data) { 1366 case "string": 1367 write(encoder, 119); 1368 writeVarString(encoder, data); 1369 break; 1370 case "number": 1371 if (isInteger(data) && abs(data) <= BITS31) { 1372 write(encoder, 125); 1373 writeVarInt(encoder, data); 1374 } else if (isFloat32(data)) { 1375 write(encoder, 124); 1376 writeFloat32(encoder, data); 1377 } else { 1378 write(encoder, 123); 1379 writeFloat64(encoder, data); 1380 } 1381 break; 1382 case "bigint": 1383 write(encoder, 122); 1384 writeBigInt64(encoder, data); 1385 break; 1386 case "object": 1387 if (data === null) { 1388 write(encoder, 126); 1389 } else if (isArray(data)) { 1390 write(encoder, 117); 1391 writeVarUint(encoder, data.length); 1392 for (let i = 0; i < data.length; i++) { 1393 writeAny(encoder, data[i]); 1394 } 1395 } else if (data instanceof Uint8Array) { 1396 write(encoder, 116); 1397 writeVarUint8Array(encoder, data); 1398 } else { 1399 write(encoder, 118); 1400 const keys2 = Object.keys(data); 1401 writeVarUint(encoder, keys2.length); 1402 for (let i = 0; i < keys2.length; i++) { 1403 const key = keys2[i]; 1404 writeVarString(encoder, key); 1405 writeAny(encoder, data[key]); 1406 } 1407 } 1408 break; 1409 case "boolean": 1410 write(encoder, data ? 120 : 121); 1411 break; 1412 default: 1413 write(encoder, 127); 1414 } 1415 }; 1416 var RleEncoder = class extends Encoder { 1417 /** 1418 * @param {function(Encoder, T):void} writer 1419 */ 1420 constructor(writer) { 1421 super(); 1422 this.w = writer; 1423 this.s = null; 1424 this.count = 0; 1425 } 1426 /** 1427 * @param {T} v 1428 */ 1429 write(v) { 1430 if (this.s === v) { 1431 this.count++; 1432 } else { 1433 if (this.count > 0) { 1434 writeVarUint(this, this.count - 1); 1435 } 1436 this.count = 1; 1437 this.w(this, v); 1438 this.s = v; 1439 } 1440 } 1441 }; 1442 var flushUintOptRleEncoder = (encoder) => { 1443 if (encoder.count > 0) { 1444 writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); 1445 if (encoder.count > 1) { 1446 writeVarUint(encoder.encoder, encoder.count - 2); 1447 } 1448 } 1449 }; 1450 var UintOptRleEncoder = class { 1451 constructor() { 1452 this.encoder = new Encoder(); 1453 this.s = 0; 1454 this.count = 0; 1455 } 1456 /** 1457 * @param {number} v 1458 */ 1459 write(v) { 1460 if (this.s === v) { 1461 this.count++; 1462 } else { 1463 flushUintOptRleEncoder(this); 1464 this.count = 1; 1465 this.s = v; 1466 } 1467 } 1468 /** 1469 * Flush the encoded state and transform this to a Uint8Array. 1470 * 1471 * Note that this should only be called once. 1472 */ 1473 toUint8Array() { 1474 flushUintOptRleEncoder(this); 1475 return toUint8Array(this.encoder); 1476 } 1477 }; 1478 var flushIntDiffOptRleEncoder = (encoder) => { 1479 if (encoder.count > 0) { 1480 const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); 1481 writeVarInt(encoder.encoder, encodedDiff); 1482 if (encoder.count > 1) { 1483 writeVarUint(encoder.encoder, encoder.count - 2); 1484 } 1485 } 1486 }; 1487 var IntDiffOptRleEncoder = class { 1488 constructor() { 1489 this.encoder = new Encoder(); 1490 this.s = 0; 1491 this.count = 0; 1492 this.diff = 0; 1493 } 1494 /** 1495 * @param {number} v 1496 */ 1497 write(v) { 1498 if (this.diff === v - this.s) { 1499 this.s = v; 1500 this.count++; 1501 } else { 1502 flushIntDiffOptRleEncoder(this); 1503 this.count = 1; 1504 this.diff = v - this.s; 1505 this.s = v; 1506 } 1507 } 1508 /** 1509 * Flush the encoded state and transform this to a Uint8Array. 1510 * 1511 * Note that this should only be called once. 1512 */ 1513 toUint8Array() { 1514 flushIntDiffOptRleEncoder(this); 1515 return toUint8Array(this.encoder); 1516 } 1517 }; 1518 var StringEncoder = class { 1519 constructor() { 1520 this.sarr = []; 1521 this.s = ""; 1522 this.lensE = new UintOptRleEncoder(); 1523 } 1524 /** 1525 * @param {string} string 1526 */ 1527 write(string) { 1528 this.s += string; 1529 if (this.s.length > 19) { 1530 this.sarr.push(this.s); 1531 this.s = ""; 1532 } 1533 this.lensE.write(string.length); 1534 } 1535 toUint8Array() { 1536 const encoder = new Encoder(); 1537 this.sarr.push(this.s); 1538 this.s = ""; 1539 writeVarString(encoder, this.sarr.join("")); 1540 writeUint8Array(encoder, this.lensE.toUint8Array()); 1541 return toUint8Array(encoder); 1542 } 1543 }; 1544 1545 // node_modules/lib0/error.js 1546 var create3 = (s) => new Error(s); 1547 var methodUnimplemented = () => { 1548 throw create3("Method unimplemented"); 1549 }; 1550 var unexpectedCase = () => { 1551 throw create3("Unexpected case"); 1552 }; 1553 1554 // node_modules/lib0/decoding.js 1555 var errorUnexpectedEndOfArray = create3("Unexpected end of array"); 1556 var errorIntegerOutOfRange = create3("Integer out of Range"); 1557 var Decoder = class { 1558 /** 1559 * @param {Uint8Array} uint8Array Binary data to decode 1560 */ 1561 constructor(uint8Array) { 1562 this.arr = uint8Array; 1563 this.pos = 0; 1564 } 1565 }; 1566 var createDecoder = (uint8Array) => new Decoder(uint8Array); 1567 var hasContent = (decoder) => decoder.pos !== decoder.arr.length; 1568 var readUint8Array = (decoder, len) => { 1569 const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); 1570 decoder.pos += len; 1571 return view; 1572 }; 1573 var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); 1574 var readUint8 = (decoder) => decoder.arr[decoder.pos++]; 1575 var readVarUint = (decoder) => { 1576 let num = 0; 1577 let mult = 1; 1578 const len = decoder.arr.length; 1579 while (decoder.pos < len) { 1580 const r = decoder.arr[decoder.pos++]; 1581 num = num + (r & BITS7) * mult; 1582 mult *= 128; 1583 if (r < BIT8) { 1584 return num; 1585 } 1586 if (num > MAX_SAFE_INTEGER) { 1587 throw errorIntegerOutOfRange; 1588 } 1589 } 1590 throw errorUnexpectedEndOfArray; 1591 }; 1592 var readVarInt = (decoder) => { 1593 let r = decoder.arr[decoder.pos++]; 1594 let num = r & BITS6; 1595 let mult = 64; 1596 const sign = (r & BIT7) > 0 ? -1 : 1; 1597 if ((r & BIT8) === 0) { 1598 return sign * num; 1599 } 1600 const len = decoder.arr.length; 1601 while (decoder.pos < len) { 1602 r = decoder.arr[decoder.pos++]; 1603 num = num + (r & BITS7) * mult; 1604 mult *= 128; 1605 if (r < BIT8) { 1606 return sign * num; 1607 } 1608 if (num > MAX_SAFE_INTEGER) { 1609 throw errorIntegerOutOfRange; 1610 } 1611 } 1612 throw errorUnexpectedEndOfArray; 1613 }; 1614 var _readVarStringPolyfill = (decoder) => { 1615 let remainingLen = readVarUint(decoder); 1616 if (remainingLen === 0) { 1617 return ""; 1618 } else { 1619 let encodedString = String.fromCodePoint(readUint8(decoder)); 1620 if (--remainingLen < 100) { 1621 while (remainingLen--) { 1622 encodedString += String.fromCodePoint(readUint8(decoder)); 1623 } 1624 } else { 1625 while (remainingLen > 0) { 1626 const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; 1627 const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); 1628 decoder.pos += nextLen; 1629 encodedString += String.fromCodePoint.apply( 1630 null, 1631 /** @type {any} */ 1632 bytes 1633 ); 1634 remainingLen -= nextLen; 1635 } 1636 } 1637 return decodeURIComponent(escape(encodedString)); 1638 } 1639 }; 1640 var _readVarStringNative = (decoder) => ( 1641 /** @type any */ 1642 utf8TextDecoder.decode(readVarUint8Array(decoder)) 1643 ); 1644 var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; 1645 var readFromDataView = (decoder, len) => { 1646 const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); 1647 decoder.pos += len; 1648 return dv; 1649 }; 1650 var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); 1651 var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); 1652 var readBigInt64 = (decoder) => ( 1653 /** @type {any} */ 1654 readFromDataView(decoder, 8).getBigInt64(0, false) 1655 ); 1656 var readAnyLookupTable = [ 1657 (decoder) => void 0, 1658 // CASE 127: undefined 1659 (decoder) => null, 1660 // CASE 126: null 1661 readVarInt, 1662 // CASE 125: integer 1663 readFloat32, 1664 // CASE 124: float32 1665 readFloat64, 1666 // CASE 123: float64 1667 readBigInt64, 1668 // CASE 122: bigint 1669 (decoder) => false, 1670 // CASE 121: boolean (false) 1671 (decoder) => true, 1672 // CASE 120: boolean (true) 1673 readVarString, 1674 // CASE 119: string 1675 (decoder) => { 1676 const len = readVarUint(decoder); 1677 const obj = {}; 1678 for (let i = 0; i < len; i++) { 1679 const key = readVarString(decoder); 1680 obj[key] = readAny(decoder); 1681 } 1682 return obj; 1683 }, 1684 (decoder) => { 1685 const len = readVarUint(decoder); 1686 const arr = []; 1687 for (let i = 0; i < len; i++) { 1688 arr.push(readAny(decoder)); 1689 } 1690 return arr; 1691 }, 1692 readVarUint8Array 1693 // CASE 116: Uint8Array 1694 ]; 1695 var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); 1696 var RleDecoder = class extends Decoder { 1697 /** 1698 * @param {Uint8Array} uint8Array 1699 * @param {function(Decoder):T} reader 1700 */ 1701 constructor(uint8Array, reader) { 1702 super(uint8Array); 1703 this.reader = reader; 1704 this.s = null; 1705 this.count = 0; 1706 } 1707 read() { 1708 if (this.count === 0) { 1709 this.s = this.reader(this); 1710 if (hasContent(this)) { 1711 this.count = readVarUint(this) + 1; 1712 } else { 1713 this.count = -1; 1714 } 1715 } 1716 this.count--; 1717 return ( 1718 /** @type {T} */ 1719 this.s 1720 ); 1721 } 1722 }; 1723 var UintOptRleDecoder = class extends Decoder { 1724 /** 1725 * @param {Uint8Array} uint8Array 1726 */ 1727 constructor(uint8Array) { 1728 super(uint8Array); 1729 this.s = 0; 1730 this.count = 0; 1731 } 1732 read() { 1733 if (this.count === 0) { 1734 this.s = readVarInt(this); 1735 const isNegative = isNegativeZero(this.s); 1736 this.count = 1; 1737 if (isNegative) { 1738 this.s = -this.s; 1739 this.count = readVarUint(this) + 2; 1740 } 1741 } 1742 this.count--; 1743 return ( 1744 /** @type {number} */ 1745 this.s 1746 ); 1747 } 1748 }; 1749 var IntDiffOptRleDecoder = class extends Decoder { 1750 /** 1751 * @param {Uint8Array} uint8Array 1752 */ 1753 constructor(uint8Array) { 1754 super(uint8Array); 1755 this.s = 0; 1756 this.count = 0; 1757 this.diff = 0; 1758 } 1759 /** 1760 * @return {number} 1761 */ 1762 read() { 1763 if (this.count === 0) { 1764 const diff = readVarInt(this); 1765 const hasCount = diff & 1; 1766 this.diff = floor(diff / 2); 1767 this.count = 1; 1768 if (hasCount) { 1769 this.count = readVarUint(this) + 2; 1770 } 1771 } 1772 this.s += this.diff; 1773 this.count--; 1774 return this.s; 1775 } 1776 }; 1777 var StringDecoder = class { 1778 /** 1779 * @param {Uint8Array} uint8Array 1780 */ 1781 constructor(uint8Array) { 1782 this.decoder = new UintOptRleDecoder(uint8Array); 1783 this.str = readVarString(this.decoder); 1784 this.spos = 0; 1785 } 1786 /** 1787 * @return {string} 1788 */ 1789 read() { 1790 const end = this.spos + this.decoder.read(); 1791 const res = this.str.slice(this.spos, end); 1792 this.spos = end; 1793 return res; 1794 } 1795 }; 1796 1797 // node_modules/lib0/webcrypto.js 1798 var subtle = crypto.subtle; 1799 var getRandomValues = crypto.getRandomValues.bind(crypto); 1800 1801 // node_modules/lib0/random.js 1802 var uint32 = () => getRandomValues(new Uint32Array(1))[0]; 1803 var uuidv4Template = "10000000-1000-4000-8000" + -1e11; 1804 var uuidv4 = () => uuidv4Template.replace( 1805 /[018]/g, 1806 /** @param {number} c */ 1807 (c) => (c ^ uint32() & 15 >> c / 4).toString(16) 1808 ); 1809 1810 // node_modules/lib0/time.js 1811 var getUnixTime = Date.now; 1812 1813 // node_modules/lib0/promise.js 1814 var create4 = (f) => ( 1815 /** @type {Promise<T>} */ 1816 new Promise(f) 1817 ); 1818 var all = Promise.all.bind(Promise); 1819 1820 // node_modules/lib0/conditions.js 1821 var undefinedToNull = (v) => v === void 0 ? null : v; 1822 1823 // node_modules/lib0/storage.js 1824 var VarStoragePolyfill = class { 1825 constructor() { 1826 this.map = /* @__PURE__ */ new Map(); 1827 } 1828 /** 1829 * @param {string} key 1830 * @param {any} newValue 1831 */ 1832 setItem(key, newValue) { 1833 this.map.set(key, newValue); 1834 } 1835 /** 1836 * @param {string} key 1837 */ 1838 getItem(key) { 1839 return this.map.get(key); 1840 } 1841 }; 1842 var _localStorage = new VarStoragePolyfill(); 1843 var usePolyfill = true; 1844 try { 1845 if (typeof localStorage !== "undefined" && localStorage) { 1846 _localStorage = localStorage; 1847 usePolyfill = false; 1848 } 1849 } catch (e) { 1850 } 1851 var varStorage = _localStorage; 1852 1853 // node_modules/lib0/object.js 1854 var assign = Object.assign; 1855 var keys = Object.keys; 1856 var forEach = (obj, f) => { 1857 for (const key in obj) { 1858 f(obj[key], key); 1859 } 1860 }; 1861 var length2 = (obj) => keys(obj).length; 1862 var size = (obj) => keys(obj).length; 1863 var isEmpty = (obj) => { 1864 for (const _k in obj) { 1865 return false; 1866 } 1867 return true; 1868 }; 1869 var every = (obj, f) => { 1870 for (const key in obj) { 1871 if (!f(obj[key], key)) { 1872 return false; 1873 } 1874 } 1875 return true; 1876 }; 1877 var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); 1878 var equalFlat = (a, b) => a === b || size(a) === size(b) && every(a, (val, key) => (val !== void 0 || hasProperty(b, key)) && b[key] === val); 1879 var freeze = Object.freeze; 1880 var deepFreeze = (o) => { 1881 for (const key in o) { 1882 const c = o[key]; 1883 if (typeof c === "object" || typeof c === "function") { 1884 deepFreeze(o[key]); 1885 } 1886 } 1887 return freeze(o); 1888 }; 1889 1890 // node_modules/lib0/function.js 1891 var callAll = (fs, args2, i = 0) => { 1892 try { 1893 for (; i < fs.length; i++) { 1894 fs[i](...args2); 1895 } 1896 } finally { 1897 if (i < fs.length) { 1898 callAll(fs, args2, i + 1); 1899 } 1900 } 1901 }; 1902 var id = (a) => a; 1903 var equalityStrict = (a, b) => a === b; 1904 var equalityDeep = (a, b) => { 1905 if (a == null || b == null) { 1906 return equalityStrict(a, b); 1907 } 1908 if (a.constructor !== b.constructor) { 1909 return false; 1910 } 1911 if (a === b) { 1912 return true; 1913 } 1914 switch (a.constructor) { 1915 case ArrayBuffer: 1916 a = new Uint8Array(a); 1917 b = new Uint8Array(b); 1918 // eslint-disable-next-line no-fallthrough 1919 case Uint8Array: { 1920 if (a.byteLength !== b.byteLength) { 1921 return false; 1922 } 1923 for (let i = 0; i < a.length; i++) { 1924 if (a[i] !== b[i]) { 1925 return false; 1926 } 1927 } 1928 break; 1929 } 1930 case Set: { 1931 if (a.size !== b.size) { 1932 return false; 1933 } 1934 for (const value of a) { 1935 if (!b.has(value)) { 1936 return false; 1937 } 1938 } 1939 break; 1940 } 1941 case Map: { 1942 if (a.size !== b.size) { 1943 return false; 1944 } 1945 for (const key of a.keys()) { 1946 if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) { 1947 return false; 1948 } 1949 } 1950 break; 1951 } 1952 case Object: 1953 if (length2(a) !== length2(b)) { 1954 return false; 1955 } 1956 for (const key in a) { 1957 if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) { 1958 return false; 1959 } 1960 } 1961 break; 1962 case Array: 1963 if (a.length !== b.length) { 1964 return false; 1965 } 1966 for (let i = 0; i < a.length; i++) { 1967 if (!equalityDeep(a[i], b[i])) { 1968 return false; 1969 } 1970 } 1971 break; 1972 default: 1973 return false; 1974 } 1975 return true; 1976 }; 1977 var isOneOf = (value, options) => options.includes(value); 1978 1979 // node_modules/lib0/environment.js 1980 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]"; 1981 var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; 1982 var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; 1983 var params; 1984 var args = []; 1985 var computeParams = () => { 1986 if (params === void 0) { 1987 if (isNode) { 1988 params = create(); 1989 const pargs = process.argv; 1990 let currParamName = null; 1991 for (let i = 0; i < pargs.length; i++) { 1992 const parg = pargs[i]; 1993 if (parg[0] === "-") { 1994 if (currParamName !== null) { 1995 params.set(currParamName, ""); 1996 } 1997 currParamName = parg; 1998 } else { 1999 if (currParamName !== null) { 2000 params.set(currParamName, parg); 2001 currParamName = null; 2002 } else { 2003 args.push(parg); 2004 } 2005 } 2006 } 2007 if (currParamName !== null) { 2008 params.set(currParamName, ""); 2009 } 2010 } else if (typeof location === "object") { 2011 params = create(); 2012 (location.search || "?").slice(1).split("&").forEach((kv) => { 2013 if (kv.length !== 0) { 2014 const [key, value] = kv.split("="); 2015 params.set(`--$fromCamelCase(key, "-")}`, value); 2016 params.set(`-$fromCamelCase(key, "-")}`, value); 2017 } 2018 }); 2019 } else { 2020 params = create(); 2021 } 2022 } 2023 return params; 2024 }; 2025 var hasParam = (name) => computeParams().has(name); 2026 var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); 2027 var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; 2028 var production = hasConf("production"); 2029 var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); 2030 var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors 2031 !hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); 2032 2033 // node_modules/lib0/buffer.js 2034 var createUint8ArrayFromLen = (len) => new Uint8Array(len); 2035 var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length3) => new Uint8Array(buffer, byteOffset, length3); 2036 var toBase64Browser = (bytes) => { 2037 let s = ""; 2038 for (let i = 0; i < bytes.byteLength; i++) { 2039 s += fromCharCode(bytes[i]); 2040 } 2041 return btoa(s); 2042 }; 2043 var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); 2044 var fromBase64Browser = (s) => { 2045 const a = atob(s); 2046 const bytes = createUint8ArrayFromLen(a.length); 2047 for (let i = 0; i < a.length; i++) { 2048 bytes[i] = a.charCodeAt(i); 2049 } 2050 return bytes; 2051 }; 2052 var fromBase64Node = (s) => { 2053 const buf = Buffer.from(s, "base64"); 2054 return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); 2055 }; 2056 var toBase64 = isBrowser ? toBase64Browser : toBase64Node; 2057 var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; 2058 var copyUint8Array = (uint8Array) => { 2059 const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); 2060 newBuf.set(uint8Array); 2061 return newBuf; 2062 }; 2063 2064 // node_modules/lib0/pair.js 2065 var Pair = class { 2066 /** 2067 * @param {L} left 2068 * @param {R} right 2069 */ 2070 constructor(left, right) { 2071 this.left = left; 2072 this.right = right; 2073 } 2074 }; 2075 var create5 = (left, right) => new Pair(left, right); 2076 2077 // node_modules/lib0/dom.js 2078 var doc = ( 2079 /** @type {Document} */ 2080 typeof document !== "undefined" ? document : {} 2081 ); 2082 var domParser = ( 2083 /** @type {DOMParser} */ 2084 typeof DOMParser !== "undefined" ? new DOMParser() : null 2085 ); 2086 var mapToStyleString = (m) => map(m, (value, key) => `$key}:$value};`).join(""); 2087 var ELEMENT_NODE = doc.ELEMENT_NODE; 2088 var TEXT_NODE = doc.TEXT_NODE; 2089 var CDATA_SECTION_NODE = doc.CDATA_SECTION_NODE; 2090 var COMMENT_NODE = doc.COMMENT_NODE; 2091 var DOCUMENT_NODE = doc.DOCUMENT_NODE; 2092 var DOCUMENT_TYPE_NODE = doc.DOCUMENT_TYPE_NODE; 2093 var DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE; 2094 2095 // node_modules/lib0/symbol.js 2096 var create6 = Symbol; 2097 2098 // node_modules/lib0/logging.common.js 2099 var BOLD = create6(); 2100 var UNBOLD = create6(); 2101 var BLUE = create6(); 2102 var GREY = create6(); 2103 var GREEN = create6(); 2104 var RED = create6(); 2105 var PURPLE = create6(); 2106 var ORANGE = create6(); 2107 var UNCOLOR = create6(); 2108 var computeNoColorLoggingArgs = (args2) => { 2109 if (args2.length === 1 && args2[0]?.constructor === Function) { 2110 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2111 /** @type {[function]} */ 2112 args2[0](); 2113 } 2114 const strBuilder = []; 2115 const logArgs = []; 2116 let i = 0; 2117 for (; i < args2.length; i++) { 2118 const arg = args2[i]; 2119 if (arg === void 0) { 2120 break; 2121 } else if (arg.constructor === String || arg.constructor === Number) { 2122 strBuilder.push(arg); 2123 } else if (arg.constructor === Object) { 2124 break; 2125 } 2126 } 2127 if (i > 0) { 2128 logArgs.push(strBuilder.join("")); 2129 } 2130 for (; i < args2.length; i++) { 2131 const arg = args2[i]; 2132 if (!(arg instanceof Symbol)) { 2133 logArgs.push(arg); 2134 } 2135 } 2136 return logArgs; 2137 }; 2138 var lastLoggingTime = getUnixTime(); 2139 2140 // node_modules/lib0/logging.js 2141 var _browserStyleMap = { 2142 [BOLD]: create5("font-weight", "bold"), 2143 [UNBOLD]: create5("font-weight", "normal"), 2144 [BLUE]: create5("color", "blue"), 2145 [GREEN]: create5("color", "green"), 2146 [GREY]: create5("color", "grey"), 2147 [RED]: create5("color", "red"), 2148 [PURPLE]: create5("color", "purple"), 2149 [ORANGE]: create5("color", "orange"), 2150 // not well supported in chrome when debugging node with inspector - TODO: deprecate 2151 [UNCOLOR]: create5("color", "black") 2152 }; 2153 var computeBrowserLoggingArgs = (args2) => { 2154 if (args2.length === 1 && args2[0]?.constructor === Function) { 2155 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2156 /** @type {[function]} */ 2157 args2[0](); 2158 } 2159 const strBuilder = []; 2160 const styles = []; 2161 const currentStyle = create(); 2162 let logArgs = []; 2163 let i = 0; 2164 for (; i < args2.length; i++) { 2165 const arg = args2[i]; 2166 const style = _browserStyleMap[arg]; 2167 if (style !== void 0) { 2168 currentStyle.set(style.left, style.right); 2169 } else { 2170 if (arg === void 0) { 2171 break; 2172 } 2173 if (arg.constructor === String || arg.constructor === Number) { 2174 const style2 = mapToStyleString(currentStyle); 2175 if (i > 0 || style2.length > 0) { 2176 strBuilder.push("%c" + arg); 2177 styles.push(style2); 2178 } else { 2179 strBuilder.push(arg); 2180 } 2181 } else { 2182 break; 2183 } 2184 } 2185 } 2186 if (i > 0) { 2187 logArgs = styles; 2188 logArgs.unshift(strBuilder.join("")); 2189 } 2190 for (; i < args2.length; i++) { 2191 const arg = args2[i]; 2192 if (!(arg instanceof Symbol)) { 2193 logArgs.push(arg); 2194 } 2195 } 2196 return logArgs; 2197 }; 2198 var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; 2199 var print = (...args2) => { 2200 console.log(...computeLoggingArgs(args2)); 2201 vconsoles.forEach((vc) => vc.print(args2)); 2202 }; 2203 var warn = (...args2) => { 2204 console.warn(...computeLoggingArgs(args2)); 2205 args2.unshift(ORANGE); 2206 vconsoles.forEach((vc) => vc.print(args2)); 2207 }; 2208 var vconsoles = create2(); 2209 2210 // node_modules/lib0/iterator.js 2211 var createIterator = (next) => ({ 2212 /** 2213 * @return {IterableIterator<T>} 2214 */ 2215 [Symbol.iterator]() { 2216 return this; 2217 }, 2218 // @ts-ignore 2219 next 2220 }); 2221 var iteratorFilter = (iterator, filter) => createIterator(() => { 2222 let res; 2223 do { 2224 res = iterator.next(); 2225 } while (!res.done && !filter(res.value)); 2226 return res; 2227 }); 2228 var iteratorMap = (iterator, fmap) => createIterator(() => { 2229 const { done, value } = iterator.next(); 2230 return { done, value: done ? void 0 : fmap(value) }; 2231 }); 2232 2233 // node_modules/yjs/dist/yjs.mjs 2234 var AbstractConnector = class extends ObservableV2 { 2235 /** 2236 * @param {Doc} ydoc 2237 * @param {any} awareness 2238 */ 2239 constructor(ydoc, awareness) { 2240 super(); 2241 this.doc = ydoc; 2242 this.awareness = awareness; 2243 } 2244 }; 2245 var DeleteItem = class { 2246 /** 2247 * @param {number} clock 2248 * @param {number} len 2249 */ 2250 constructor(clock, len) { 2251 this.clock = clock; 2252 this.len = len; 2253 } 2254 }; 2255 var DeleteSet = class { 2256 constructor() { 2257 this.clients = /* @__PURE__ */ new Map(); 2258 } 2259 }; 2260 var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { 2261 const structs = ( 2262 /** @type {Array<GC|Item>} */ 2263 transaction.doc.store.clients.get(clientid) 2264 ); 2265 if (structs != null) { 2266 const lastStruct = structs[structs.length - 1]; 2267 const clockState = lastStruct.id.clock + lastStruct.length; 2268 for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) { 2269 iterateStructs(transaction, structs, del.clock, del.len, f); 2270 } 2271 } 2272 }); 2273 var findIndexDS = (dis, clock) => { 2274 let left = 0; 2275 let right = dis.length - 1; 2276 while (left <= right) { 2277 const midindex = floor((left + right) / 2); 2278 const mid = dis[midindex]; 2279 const midclock = mid.clock; 2280 if (midclock <= clock) { 2281 if (clock < midclock + mid.len) { 2282 return midindex; 2283 } 2284 left = midindex + 1; 2285 } else { 2286 right = midindex - 1; 2287 } 2288 } 2289 return null; 2290 }; 2291 var isDeleted = (ds, id2) => { 2292 const dis = ds.clients.get(id2.client); 2293 return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; 2294 }; 2295 var sortAndMergeDeleteSet = (ds) => { 2296 ds.clients.forEach((dels) => { 2297 dels.sort((a, b) => a.clock - b.clock); 2298 let i, j; 2299 for (i = 1, j = 1; i < dels.length; i++) { 2300 const left = dels[j - 1]; 2301 const right = dels[i]; 2302 if (left.clock + left.len >= right.clock) { 2303 left.len = max(left.len, right.clock + right.len - left.clock); 2304 } else { 2305 if (j < i) { 2306 dels[j] = right; 2307 } 2308 j++; 2309 } 2310 } 2311 dels.length = j; 2312 }); 2313 }; 2314 var mergeDeleteSets = (dss) => { 2315 const merged = new DeleteSet(); 2316 for (let dssI = 0; dssI < dss.length; dssI++) { 2317 dss[dssI].clients.forEach((delsLeft, client) => { 2318 if (!merged.clients.has(client)) { 2319 const dels = delsLeft.slice(); 2320 for (let i = dssI + 1; i < dss.length; i++) { 2321 appendTo(dels, dss[i].clients.get(client) || []); 2322 } 2323 merged.clients.set(client, dels); 2324 } 2325 }); 2326 } 2327 sortAndMergeDeleteSet(merged); 2328 return merged; 2329 }; 2330 var addToDeleteSet = (ds, client, clock, length3) => { 2331 setIfUndefined(ds.clients, client, () => ( 2332 /** @type {Array<DeleteItem>} */ 2333 [] 2334 )).push(new DeleteItem(clock, length3)); 2335 }; 2336 var createDeleteSet = () => new DeleteSet(); 2337 var createDeleteSetFromStructStore = (ss) => { 2338 const ds = createDeleteSet(); 2339 ss.clients.forEach((structs, client) => { 2340 const dsitems = []; 2341 for (let i = 0; i < structs.length; i++) { 2342 const struct = structs[i]; 2343 if (struct.deleted) { 2344 const clock = struct.id.clock; 2345 let len = struct.length; 2346 if (i + 1 < structs.length) { 2347 for (let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1]) { 2348 len += next.length; 2349 } 2350 } 2351 dsitems.push(new DeleteItem(clock, len)); 2352 } 2353 } 2354 if (dsitems.length > 0) { 2355 ds.clients.set(client, dsitems); 2356 } 2357 }); 2358 return ds; 2359 }; 2360 var writeDeleteSet = (encoder, ds) => { 2361 writeVarUint(encoder.restEncoder, ds.clients.size); 2362 from(ds.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, dsitems]) => { 2363 encoder.resetDsCurVal(); 2364 writeVarUint(encoder.restEncoder, client); 2365 const len = dsitems.length; 2366 writeVarUint(encoder.restEncoder, len); 2367 for (let i = 0; i < len; i++) { 2368 const item = dsitems[i]; 2369 encoder.writeDsClock(item.clock); 2370 encoder.writeDsLen(item.len); 2371 } 2372 }); 2373 }; 2374 var readDeleteSet = (decoder) => { 2375 const ds = new DeleteSet(); 2376 const numClients = readVarUint(decoder.restDecoder); 2377 for (let i = 0; i < numClients; i++) { 2378 decoder.resetDsCurVal(); 2379 const client = readVarUint(decoder.restDecoder); 2380 const numberOfDeletes = readVarUint(decoder.restDecoder); 2381 if (numberOfDeletes > 0) { 2382 const dsField = setIfUndefined(ds.clients, client, () => ( 2383 /** @type {Array<DeleteItem>} */ 2384 [] 2385 )); 2386 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2387 dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); 2388 } 2389 } 2390 } 2391 return ds; 2392 }; 2393 var readAndApplyDeleteSet = (decoder, transaction, store2) => { 2394 const unappliedDS = new DeleteSet(); 2395 const numClients = readVarUint(decoder.restDecoder); 2396 for (let i = 0; i < numClients; i++) { 2397 decoder.resetDsCurVal(); 2398 const client = readVarUint(decoder.restDecoder); 2399 const numberOfDeletes = readVarUint(decoder.restDecoder); 2400 const structs = store2.clients.get(client) || []; 2401 const state = getState(store2, client); 2402 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2403 const clock = decoder.readDsClock(); 2404 const clockEnd = clock + decoder.readDsLen(); 2405 if (clock < state) { 2406 if (state < clockEnd) { 2407 addToDeleteSet(unappliedDS, client, state, clockEnd - state); 2408 } 2409 let index = findIndexSS(structs, clock); 2410 let struct = structs[index]; 2411 if (!struct.deleted && struct.id.clock < clock) { 2412 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 2413 index++; 2414 } 2415 while (index < structs.length) { 2416 struct = structs[index++]; 2417 if (struct.id.clock < clockEnd) { 2418 if (!struct.deleted) { 2419 if (clockEnd < struct.id.clock + struct.length) { 2420 structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); 2421 } 2422 struct.delete(transaction); 2423 } 2424 } else { 2425 break; 2426 } 2427 } 2428 } else { 2429 addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); 2430 } 2431 } 2432 } 2433 if (unappliedDS.clients.size > 0) { 2434 const ds = new UpdateEncoderV2(); 2435 writeVarUint(ds.restEncoder, 0); 2436 writeDeleteSet(ds, unappliedDS); 2437 return ds.toUint8Array(); 2438 } 2439 return null; 2440 }; 2441 var equalDeleteSets = (ds1, ds2) => { 2442 if (ds1.clients.size !== ds2.clients.size) return false; 2443 for (const [client, deleteItems1] of ds1.clients.entries()) { 2444 const deleteItems2 = ( 2445 /** @type {Array<import('../internals.js').DeleteItem>} */ 2446 ds2.clients.get(client) 2447 ); 2448 if (deleteItems2 === void 0 || deleteItems1.length !== deleteItems2.length) return false; 2449 for (let i = 0; i < deleteItems1.length; i++) { 2450 const di1 = deleteItems1[i]; 2451 const di2 = deleteItems2[i]; 2452 if (di1.clock !== di2.clock || di1.len !== di2.len) { 2453 return false; 2454 } 2455 } 2456 } 2457 return true; 2458 }; 2459 var generateNewClientId = uint32; 2460 var Doc = class _Doc extends ObservableV2 { 2461 /** 2462 * @param {DocOpts} opts configuration 2463 */ 2464 constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { 2465 super(); 2466 this.gc = gc; 2467 this.gcFilter = gcFilter; 2468 this.clientID = generateNewClientId(); 2469 this.guid = guid; 2470 this.collectionid = collectionid; 2471 this.share = /* @__PURE__ */ new Map(); 2472 this.store = new StructStore(); 2473 this._transaction = null; 2474 this._transactionCleanups = []; 2475 this.subdocs = /* @__PURE__ */ new Set(); 2476 this._item = null; 2477 this.shouldLoad = shouldLoad; 2478 this.autoLoad = autoLoad; 2479 this.meta = meta; 2480 this.isLoaded = false; 2481 this.isSynced = false; 2482 this.isDestroyed = false; 2483 this.whenLoaded = create4((resolve) => { 2484 this.on("load", () => { 2485 this.isLoaded = true; 2486 resolve(this); 2487 }); 2488 }); 2489 const provideSyncedPromise = () => create4((resolve) => { 2490 const eventHandler = (isSynced) => { 2491 if (isSynced === void 0 || isSynced === true) { 2492 this.off("sync", eventHandler); 2493 resolve(); 2494 } 2495 }; 2496 this.on("sync", eventHandler); 2497 }); 2498 this.on("sync", (isSynced) => { 2499 if (isSynced === false && this.isSynced) { 2500 this.whenSynced = provideSyncedPromise(); 2501 } 2502 this.isSynced = isSynced === void 0 || isSynced === true; 2503 if (this.isSynced && !this.isLoaded) { 2504 this.emit("load", [this]); 2505 } 2506 }); 2507 this.whenSynced = provideSyncedPromise(); 2508 } 2509 /** 2510 * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). 2511 * 2512 * `load()` might be used in the future to request any provider to load the most current data. 2513 * 2514 * It is safe to call `load()` multiple times. 2515 */ 2516 load() { 2517 const item = this._item; 2518 if (item !== null && !this.shouldLoad) { 2519 transact( 2520 /** @type {any} */ 2521 item.parent.doc, 2522 (transaction) => { 2523 transaction.subdocsLoaded.add(this); 2524 }, 2525 null, 2526 true 2527 ); 2528 } 2529 this.shouldLoad = true; 2530 } 2531 getSubdocs() { 2532 return this.subdocs; 2533 } 2534 getSubdocGuids() { 2535 return new Set(from(this.subdocs).map((doc2) => doc2.guid)); 2536 } 2537 /** 2538 * Changes that happen inside of a transaction are bundled. This means that 2539 * the observer fires _after_ the transaction is finished and that all changes 2540 * that happened inside of the transaction are sent as one message to the 2541 * other peers. 2542 * 2543 * @template T 2544 * @param {function(Transaction):T} f The function that should be executed as a transaction 2545 * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin 2546 * @return T 2547 * 2548 * @public 2549 */ 2550 transact(f, origin2 = null) { 2551 return transact(this, f, origin2); 2552 } 2553 /** 2554 * Define a shared data type. 2555 * 2556 * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result 2557 * and do not overwrite each other. I.e. 2558 * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` 2559 * 2560 * After this method is called, the type is also available on `ydoc.share.get(name)`. 2561 * 2562 * *Best Practices:* 2563 * Define all types right after the Y.Doc instance is created and store them in a separate object. 2564 * Also use the typed methods `getText(name)`, `getArray(name)`, .. 2565 * 2566 * @template {typeof AbstractType<any>} Type 2567 * @example 2568 * const ydoc = new Y.Doc(..) 2569 * const appState = { 2570 * document: ydoc.getText('document') 2571 * comments: ydoc.getArray('comments') 2572 * } 2573 * 2574 * @param {string} name 2575 * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... 2576 * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor 2577 * 2578 * @public 2579 */ 2580 get(name, TypeConstructor = ( 2581 /** @type {any} */ 2582 AbstractType 2583 )) { 2584 const type = setIfUndefined(this.share, name, () => { 2585 const t = new TypeConstructor(); 2586 t._integrate(this, null); 2587 return t; 2588 }); 2589 const Constr = type.constructor; 2590 if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { 2591 if (Constr === AbstractType) { 2592 const t = new TypeConstructor(); 2593 t._map = type._map; 2594 type._map.forEach( 2595 /** @param {Item?} n */ 2596 (n) => { 2597 for (; n !== null; n = n.left) { 2598 n.parent = t; 2599 } 2600 } 2601 ); 2602 t._start = type._start; 2603 for (let n = t._start; n !== null; n = n.right) { 2604 n.parent = t; 2605 } 2606 t._length = type._length; 2607 this.share.set(name, t); 2608 t._integrate(this, null); 2609 return ( 2610 /** @type {InstanceType<Type>} */ 2611 t 2612 ); 2613 } else { 2614 throw new Error(`Type with the name $name} has already been defined with a different constructor`); 2615 } 2616 } 2617 return ( 2618 /** @type {InstanceType<Type>} */ 2619 type 2620 ); 2621 } 2622 /** 2623 * @template T 2624 * @param {string} [name] 2625 * @return {YArray<T>} 2626 * 2627 * @public 2628 */ 2629 getArray(name = "") { 2630 return ( 2631 /** @type {YArray<T>} */ 2632 this.get(name, YArray) 2633 ); 2634 } 2635 /** 2636 * @param {string} [name] 2637 * @return {YText} 2638 * 2639 * @public 2640 */ 2641 getText(name = "") { 2642 return this.get(name, YText); 2643 } 2644 /** 2645 * @template T 2646 * @param {string} [name] 2647 * @return {YMap<T>} 2648 * 2649 * @public 2650 */ 2651 getMap(name = "") { 2652 return ( 2653 /** @type {YMap<T>} */ 2654 this.get(name, YMap) 2655 ); 2656 } 2657 /** 2658 * @param {string} [name] 2659 * @return {YXmlElement} 2660 * 2661 * @public 2662 */ 2663 getXmlElement(name = "") { 2664 return ( 2665 /** @type {YXmlElement<{[key:string]:string}>} */ 2666 this.get(name, YXmlElement) 2667 ); 2668 } 2669 /** 2670 * @param {string} [name] 2671 * @return {YXmlFragment} 2672 * 2673 * @public 2674 */ 2675 getXmlFragment(name = "") { 2676 return this.get(name, YXmlFragment); 2677 } 2678 /** 2679 * Converts the entire document into a js object, recursively traversing each yjs type 2680 * Doesn't log types that have not been defined (using ydoc.getType(..)). 2681 * 2682 * @deprecated Do not use this method and rather call toJSON directly on the shared types. 2683 * 2684 * @return {Object<string, any>} 2685 */ 2686 toJSON() { 2687 const doc2 = {}; 2688 this.share.forEach((value, key) => { 2689 doc2[key] = value.toJSON(); 2690 }); 2691 return doc2; 2692 } 2693 /** 2694 * Emit `destroy` event and unregister all event handlers. 2695 */ 2696 destroy() { 2697 this.isDestroyed = true; 2698 from(this.subdocs).forEach((subdoc) => subdoc.destroy()); 2699 const item = this._item; 2700 if (item !== null) { 2701 this._item = null; 2702 const content = ( 2703 /** @type {ContentDoc} */ 2704 item.content 2705 ); 2706 content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); 2707 content.doc._item = item; 2708 transact( 2709 /** @type {any} */ 2710 item.parent.doc, 2711 (transaction) => { 2712 const doc2 = content.doc; 2713 if (!item.deleted) { 2714 transaction.subdocsAdded.add(doc2); 2715 } 2716 transaction.subdocsRemoved.add(this); 2717 }, 2718 null, 2719 true 2720 ); 2721 } 2722 this.emit("destroyed", [true]); 2723 this.emit("destroy", [this]); 2724 super.destroy(); 2725 } 2726 }; 2727 var DSDecoderV1 = class { 2728 /** 2729 * @param {decoding.Decoder} decoder 2730 */ 2731 constructor(decoder) { 2732 this.restDecoder = decoder; 2733 } 2734 resetDsCurVal() { 2735 } 2736 /** 2737 * @return {number} 2738 */ 2739 readDsClock() { 2740 return readVarUint(this.restDecoder); 2741 } 2742 /** 2743 * @return {number} 2744 */ 2745 readDsLen() { 2746 return readVarUint(this.restDecoder); 2747 } 2748 }; 2749 var UpdateDecoderV1 = class extends DSDecoderV1 { 2750 /** 2751 * @return {ID} 2752 */ 2753 readLeftID() { 2754 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2755 } 2756 /** 2757 * @return {ID} 2758 */ 2759 readRightID() { 2760 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 2761 } 2762 /** 2763 * Read the next client id. 2764 * Use this in favor of readID whenever possible to reduce the number of objects created. 2765 */ 2766 readClient() { 2767 return readVarUint(this.restDecoder); 2768 } 2769 /** 2770 * @return {number} info An unsigned 8-bit integer 2771 */ 2772 readInfo() { 2773 return readUint8(this.restDecoder); 2774 } 2775 /** 2776 * @return {string} 2777 */ 2778 readString() { 2779 return readVarString(this.restDecoder); 2780 } 2781 /** 2782 * @return {boolean} isKey 2783 */ 2784 readParentInfo() { 2785 return readVarUint(this.restDecoder) === 1; 2786 } 2787 /** 2788 * @return {number} info An unsigned 8-bit integer 2789 */ 2790 readTypeRef() { 2791 return readVarUint(this.restDecoder); 2792 } 2793 /** 2794 * Write len of a struct - well suited for Opt RLE encoder. 2795 * 2796 * @return {number} len 2797 */ 2798 readLen() { 2799 return readVarUint(this.restDecoder); 2800 } 2801 /** 2802 * @return {any} 2803 */ 2804 readAny() { 2805 return readAny(this.restDecoder); 2806 } 2807 /** 2808 * @return {Uint8Array} 2809 */ 2810 readBuf() { 2811 return copyUint8Array(readVarUint8Array(this.restDecoder)); 2812 } 2813 /** 2814 * Legacy implementation uses JSON parse. We use any-decoding in v2. 2815 * 2816 * @return {any} 2817 */ 2818 readJSON() { 2819 return JSON.parse(readVarString(this.restDecoder)); 2820 } 2821 /** 2822 * @return {string} 2823 */ 2824 readKey() { 2825 return readVarString(this.restDecoder); 2826 } 2827 }; 2828 var DSDecoderV2 = class { 2829 /** 2830 * @param {decoding.Decoder} decoder 2831 */ 2832 constructor(decoder) { 2833 this.dsCurrVal = 0; 2834 this.restDecoder = decoder; 2835 } 2836 resetDsCurVal() { 2837 this.dsCurrVal = 0; 2838 } 2839 /** 2840 * @return {number} 2841 */ 2842 readDsClock() { 2843 this.dsCurrVal += readVarUint(this.restDecoder); 2844 return this.dsCurrVal; 2845 } 2846 /** 2847 * @return {number} 2848 */ 2849 readDsLen() { 2850 const diff = readVarUint(this.restDecoder) + 1; 2851 this.dsCurrVal += diff; 2852 return diff; 2853 } 2854 }; 2855 var UpdateDecoderV2 = class extends DSDecoderV2 { 2856 /** 2857 * @param {decoding.Decoder} decoder 2858 */ 2859 constructor(decoder) { 2860 super(decoder); 2861 this.keys = []; 2862 readVarUint(decoder); 2863 this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2864 this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2865 this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2866 this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 2867 this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2868 this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); 2869 this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 2870 this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2871 this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 2872 } 2873 /** 2874 * @return {ID} 2875 */ 2876 readLeftID() { 2877 return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); 2878 } 2879 /** 2880 * @return {ID} 2881 */ 2882 readRightID() { 2883 return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); 2884 } 2885 /** 2886 * Read the next client id. 2887 * Use this in favor of readID whenever possible to reduce the number of objects created. 2888 */ 2889 readClient() { 2890 return this.clientDecoder.read(); 2891 } 2892 /** 2893 * @return {number} info An unsigned 8-bit integer 2894 */ 2895 readInfo() { 2896 return ( 2897 /** @type {number} */ 2898 this.infoDecoder.read() 2899 ); 2900 } 2901 /** 2902 * @return {string} 2903 */ 2904 readString() { 2905 return this.stringDecoder.read(); 2906 } 2907 /** 2908 * @return {boolean} 2909 */ 2910 readParentInfo() { 2911 return this.parentInfoDecoder.read() === 1; 2912 } 2913 /** 2914 * @return {number} An unsigned 8-bit integer 2915 */ 2916 readTypeRef() { 2917 return this.typeRefDecoder.read(); 2918 } 2919 /** 2920 * Write len of a struct - well suited for Opt RLE encoder. 2921 * 2922 * @return {number} 2923 */ 2924 readLen() { 2925 return this.lenDecoder.read(); 2926 } 2927 /** 2928 * @return {any} 2929 */ 2930 readAny() { 2931 return readAny(this.restDecoder); 2932 } 2933 /** 2934 * @return {Uint8Array} 2935 */ 2936 readBuf() { 2937 return readVarUint8Array(this.restDecoder); 2938 } 2939 /** 2940 * This is mainly here for legacy purposes. 2941 * 2942 * 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. 2943 * 2944 * @return {any} 2945 */ 2946 readJSON() { 2947 return readAny(this.restDecoder); 2948 } 2949 /** 2950 * @return {string} 2951 */ 2952 readKey() { 2953 const keyClock = this.keyClockDecoder.read(); 2954 if (keyClock < this.keys.length) { 2955 return this.keys[keyClock]; 2956 } else { 2957 const key = this.stringDecoder.read(); 2958 this.keys.push(key); 2959 return key; 2960 } 2961 } 2962 }; 2963 var DSEncoderV1 = class { 2964 constructor() { 2965 this.restEncoder = createEncoder(); 2966 } 2967 toUint8Array() { 2968 return toUint8Array(this.restEncoder); 2969 } 2970 resetDsCurVal() { 2971 } 2972 /** 2973 * @param {number} clock 2974 */ 2975 writeDsClock(clock) { 2976 writeVarUint(this.restEncoder, clock); 2977 } 2978 /** 2979 * @param {number} len 2980 */ 2981 writeDsLen(len) { 2982 writeVarUint(this.restEncoder, len); 2983 } 2984 }; 2985 var UpdateEncoderV1 = class extends DSEncoderV1 { 2986 /** 2987 * @param {ID} id 2988 */ 2989 writeLeftID(id2) { 2990 writeVarUint(this.restEncoder, id2.client); 2991 writeVarUint(this.restEncoder, id2.clock); 2992 } 2993 /** 2994 * @param {ID} id 2995 */ 2996 writeRightID(id2) { 2997 writeVarUint(this.restEncoder, id2.client); 2998 writeVarUint(this.restEncoder, id2.clock); 2999 } 3000 /** 3001 * Use writeClient and writeClock instead of writeID if possible. 3002 * @param {number} client 3003 */ 3004 writeClient(client) { 3005 writeVarUint(this.restEncoder, client); 3006 } 3007 /** 3008 * @param {number} info An unsigned 8-bit integer 3009 */ 3010 writeInfo(info) { 3011 writeUint8(this.restEncoder, info); 3012 } 3013 /** 3014 * @param {string} s 3015 */ 3016 writeString(s) { 3017 writeVarString(this.restEncoder, s); 3018 } 3019 /** 3020 * @param {boolean} isYKey 3021 */ 3022 writeParentInfo(isYKey) { 3023 writeVarUint(this.restEncoder, isYKey ? 1 : 0); 3024 } 3025 /** 3026 * @param {number} info An unsigned 8-bit integer 3027 */ 3028 writeTypeRef(info) { 3029 writeVarUint(this.restEncoder, info); 3030 } 3031 /** 3032 * Write len of a struct - well suited for Opt RLE encoder. 3033 * 3034 * @param {number} len 3035 */ 3036 writeLen(len) { 3037 writeVarUint(this.restEncoder, len); 3038 } 3039 /** 3040 * @param {any} any 3041 */ 3042 writeAny(any2) { 3043 writeAny(this.restEncoder, any2); 3044 } 3045 /** 3046 * @param {Uint8Array} buf 3047 */ 3048 writeBuf(buf) { 3049 writeVarUint8Array(this.restEncoder, buf); 3050 } 3051 /** 3052 * @param {any} embed 3053 */ 3054 writeJSON(embed) { 3055 writeVarString(this.restEncoder, JSON.stringify(embed)); 3056 } 3057 /** 3058 * @param {string} key 3059 */ 3060 writeKey(key) { 3061 writeVarString(this.restEncoder, key); 3062 } 3063 }; 3064 var DSEncoderV2 = class { 3065 constructor() { 3066 this.restEncoder = createEncoder(); 3067 this.dsCurrVal = 0; 3068 } 3069 toUint8Array() { 3070 return toUint8Array(this.restEncoder); 3071 } 3072 resetDsCurVal() { 3073 this.dsCurrVal = 0; 3074 } 3075 /** 3076 * @param {number} clock 3077 */ 3078 writeDsClock(clock) { 3079 const diff = clock - this.dsCurrVal; 3080 this.dsCurrVal = clock; 3081 writeVarUint(this.restEncoder, diff); 3082 } 3083 /** 3084 * @param {number} len 3085 */ 3086 writeDsLen(len) { 3087 if (len === 0) { 3088 unexpectedCase(); 3089 } 3090 writeVarUint(this.restEncoder, len - 1); 3091 this.dsCurrVal += len; 3092 } 3093 }; 3094 var UpdateEncoderV2 = class extends DSEncoderV2 { 3095 constructor() { 3096 super(); 3097 this.keyMap = /* @__PURE__ */ new Map(); 3098 this.keyClock = 0; 3099 this.keyClockEncoder = new IntDiffOptRleEncoder(); 3100 this.clientEncoder = new UintOptRleEncoder(); 3101 this.leftClockEncoder = new IntDiffOptRleEncoder(); 3102 this.rightClockEncoder = new IntDiffOptRleEncoder(); 3103 this.infoEncoder = new RleEncoder(writeUint8); 3104 this.stringEncoder = new StringEncoder(); 3105 this.parentInfoEncoder = new RleEncoder(writeUint8); 3106 this.typeRefEncoder = new UintOptRleEncoder(); 3107 this.lenEncoder = new UintOptRleEncoder(); 3108 } 3109 toUint8Array() { 3110 const encoder = createEncoder(); 3111 writeVarUint(encoder, 0); 3112 writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); 3113 writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); 3114 writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); 3115 writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); 3116 writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); 3117 writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); 3118 writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); 3119 writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); 3120 writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); 3121 writeUint8Array(encoder, toUint8Array(this.restEncoder)); 3122 return toUint8Array(encoder); 3123 } 3124 /** 3125 * @param {ID} id 3126 */ 3127 writeLeftID(id2) { 3128 this.clientEncoder.write(id2.client); 3129 this.leftClockEncoder.write(id2.clock); 3130 } 3131 /** 3132 * @param {ID} id 3133 */ 3134 writeRightID(id2) { 3135 this.clientEncoder.write(id2.client); 3136 this.rightClockEncoder.write(id2.clock); 3137 } 3138 /** 3139 * @param {number} client 3140 */ 3141 writeClient(client) { 3142 this.clientEncoder.write(client); 3143 } 3144 /** 3145 * @param {number} info An unsigned 8-bit integer 3146 */ 3147 writeInfo(info) { 3148 this.infoEncoder.write(info); 3149 } 3150 /** 3151 * @param {string} s 3152 */ 3153 writeString(s) { 3154 this.stringEncoder.write(s); 3155 } 3156 /** 3157 * @param {boolean} isYKey 3158 */ 3159 writeParentInfo(isYKey) { 3160 this.parentInfoEncoder.write(isYKey ? 1 : 0); 3161 } 3162 /** 3163 * @param {number} info An unsigned 8-bit integer 3164 */ 3165 writeTypeRef(info) { 3166 this.typeRefEncoder.write(info); 3167 } 3168 /** 3169 * Write len of a struct - well suited for Opt RLE encoder. 3170 * 3171 * @param {number} len 3172 */ 3173 writeLen(len) { 3174 this.lenEncoder.write(len); 3175 } 3176 /** 3177 * @param {any} any 3178 */ 3179 writeAny(any2) { 3180 writeAny(this.restEncoder, any2); 3181 } 3182 /** 3183 * @param {Uint8Array} buf 3184 */ 3185 writeBuf(buf) { 3186 writeVarUint8Array(this.restEncoder, buf); 3187 } 3188 /** 3189 * This is mainly here for legacy purposes. 3190 * 3191 * 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. 3192 * 3193 * @param {any} embed 3194 */ 3195 writeJSON(embed) { 3196 writeAny(this.restEncoder, embed); 3197 } 3198 /** 3199 * Property keys are often reused. For example, in y-prosemirror the key `bold` might 3200 * occur very often. For a 3d application, the key `position` might occur very often. 3201 * 3202 * We cache these keys in a Map and refer to them via a unique number. 3203 * 3204 * @param {string} key 3205 */ 3206 writeKey(key) { 3207 const clock = this.keyMap.get(key); 3208 if (clock === void 0) { 3209 this.keyClockEncoder.write(this.keyClock++); 3210 this.stringEncoder.write(key); 3211 } else { 3212 this.keyClockEncoder.write(clock); 3213 } 3214 } 3215 }; 3216 var writeStructs = (encoder, structs, client, clock) => { 3217 clock = max(clock, structs[0].id.clock); 3218 const startNewStructs = findIndexSS(structs, clock); 3219 writeVarUint(encoder.restEncoder, structs.length - startNewStructs); 3220 encoder.writeClient(client); 3221 writeVarUint(encoder.restEncoder, clock); 3222 const firstStruct = structs[startNewStructs]; 3223 firstStruct.write(encoder, clock - firstStruct.id.clock); 3224 for (let i = startNewStructs + 1; i < structs.length; i++) { 3225 structs[i].write(encoder, 0); 3226 } 3227 }; 3228 var writeClientsStructs = (encoder, store2, _sm) => { 3229 const sm = /* @__PURE__ */ new Map(); 3230 _sm.forEach((clock, client) => { 3231 if (getState(store2, client) > clock) { 3232 sm.set(client, clock); 3233 } 3234 }); 3235 getStateVector(store2).forEach((_clock, client) => { 3236 if (!_sm.has(client)) { 3237 sm.set(client, 0); 3238 } 3239 }); 3240 writeVarUint(encoder.restEncoder, sm.size); 3241 from(sm.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3242 writeStructs( 3243 encoder, 3244 /** @type {Array<GC|Item>} */ 3245 store2.clients.get(client), 3246 client, 3247 clock 3248 ); 3249 }); 3250 }; 3251 var readClientsStructRefs = (decoder, doc2) => { 3252 const clientRefs = create(); 3253 const numOfStateUpdates = readVarUint(decoder.restDecoder); 3254 for (let i = 0; i < numOfStateUpdates; i++) { 3255 const numberOfStructs = readVarUint(decoder.restDecoder); 3256 const refs = new Array(numberOfStructs); 3257 const client = decoder.readClient(); 3258 let clock = readVarUint(decoder.restDecoder); 3259 clientRefs.set(client, { i: 0, refs }); 3260 for (let i2 = 0; i2 < numberOfStructs; i2++) { 3261 const info = decoder.readInfo(); 3262 switch (BITS5 & info) { 3263 case 0: { 3264 const len = decoder.readLen(); 3265 refs[i2] = new GC(createID(client, clock), len); 3266 clock += len; 3267 break; 3268 } 3269 case 10: { 3270 const len = readVarUint(decoder.restDecoder); 3271 refs[i2] = new Skip(createID(client, clock), len); 3272 clock += len; 3273 break; 3274 } 3275 default: { 3276 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 3277 const struct = new Item( 3278 createID(client, clock), 3279 null, 3280 // left 3281 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 3282 // origin 3283 null, 3284 // right 3285 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 3286 // right origin 3287 cantCopyParentInfo ? decoder.readParentInfo() ? doc2.get(decoder.readString()) : decoder.readLeftID() : null, 3288 // parent 3289 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 3290 // parentSub 3291 readItemContent(decoder, info) 3292 // item content 3293 ); 3294 refs[i2] = struct; 3295 clock += struct.length; 3296 } 3297 } 3298 } 3299 } 3300 return clientRefs; 3301 }; 3302 var integrateStructs = (transaction, store2, clientsStructRefs) => { 3303 const stack = []; 3304 let clientsStructRefsIds = from(clientsStructRefs.keys()).sort((a, b) => a - b); 3305 if (clientsStructRefsIds.length === 0) { 3306 return null; 3307 } 3308 const getNextStructTarget = () => { 3309 if (clientsStructRefsIds.length === 0) { 3310 return null; 3311 } 3312 let nextStructsTarget = ( 3313 /** @type {{i:number,refs:Array<GC|Item>}} */ 3314 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) 3315 ); 3316 while (nextStructsTarget.refs.length === nextStructsTarget.i) { 3317 clientsStructRefsIds.pop(); 3318 if (clientsStructRefsIds.length > 0) { 3319 nextStructsTarget = /** @type {{i:number,refs:Array<GC|Item>}} */ 3320 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); 3321 } else { 3322 return null; 3323 } 3324 } 3325 return nextStructsTarget; 3326 }; 3327 let curStructsTarget = getNextStructTarget(); 3328 if (curStructsTarget === null) { 3329 return null; 3330 } 3331 const restStructs = new StructStore(); 3332 const missingSV = /* @__PURE__ */ new Map(); 3333 const updateMissingSv = (client, clock) => { 3334 const mclock = missingSV.get(client); 3335 if (mclock == null || mclock > clock) { 3336 missingSV.set(client, clock); 3337 } 3338 }; 3339 let stackHead = ( 3340 /** @type {any} */ 3341 curStructsTarget.refs[ 3342 /** @type {any} */ 3343 curStructsTarget.i++ 3344 ] 3345 ); 3346 const state = /* @__PURE__ */ new Map(); 3347 const addStackToRestSS = () => { 3348 for (const item of stack) { 3349 const client = item.id.client; 3350 const inapplicableItems = clientsStructRefs.get(client); 3351 if (inapplicableItems) { 3352 inapplicableItems.i--; 3353 restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); 3354 clientsStructRefs.delete(client); 3355 inapplicableItems.i = 0; 3356 inapplicableItems.refs = []; 3357 } else { 3358 restStructs.clients.set(client, [item]); 3359 } 3360 clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); 3361 } 3362 stack.length = 0; 3363 }; 3364 while (true) { 3365 if (stackHead.constructor !== Skip) { 3366 const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store2, stackHead.id.client)); 3367 const offset = localClock - stackHead.id.clock; 3368 if (offset < 0) { 3369 stack.push(stackHead); 3370 updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); 3371 addStackToRestSS(); 3372 } else { 3373 const missing = stackHead.getMissing(transaction, store2); 3374 if (missing !== null) { 3375 stack.push(stackHead); 3376 const structRefs = clientsStructRefs.get( 3377 /** @type {number} */ 3378 missing 3379 ) || { refs: [], i: 0 }; 3380 if (structRefs.refs.length === structRefs.i) { 3381 updateMissingSv( 3382 /** @type {number} */ 3383 missing, 3384 getState(store2, missing) 3385 ); 3386 addStackToRestSS(); 3387 } else { 3388 stackHead = structRefs.refs[structRefs.i++]; 3389 continue; 3390 } 3391 } else if (offset === 0 || offset < stackHead.length) { 3392 stackHead.integrate(transaction, offset); 3393 state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); 3394 } 3395 } 3396 } 3397 if (stack.length > 0) { 3398 stackHead = /** @type {GC|Item} */ 3399 stack.pop(); 3400 } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { 3401 stackHead = /** @type {GC|Item} */ 3402 curStructsTarget.refs[curStructsTarget.i++]; 3403 } else { 3404 curStructsTarget = getNextStructTarget(); 3405 if (curStructsTarget === null) { 3406 break; 3407 } else { 3408 stackHead = /** @type {GC|Item} */ 3409 curStructsTarget.refs[curStructsTarget.i++]; 3410 } 3411 } 3412 } 3413 if (restStructs.clients.size > 0) { 3414 const encoder = new UpdateEncoderV2(); 3415 writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); 3416 writeVarUint(encoder.restEncoder, 0); 3417 return { missing: missingSV, update: encoder.toUint8Array() }; 3418 } 3419 return null; 3420 }; 3421 var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); 3422 var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { 3423 transaction.local = false; 3424 let retry = false; 3425 const doc2 = transaction.doc; 3426 const store2 = doc2.store; 3427 const ss = readClientsStructRefs(structDecoder, doc2); 3428 const restStructs = integrateStructs(transaction, store2, ss); 3429 const pending = store2.pendingStructs; 3430 if (pending) { 3431 for (const [client, clock] of pending.missing) { 3432 if (clock < getState(store2, client)) { 3433 retry = true; 3434 break; 3435 } 3436 } 3437 if (restStructs) { 3438 for (const [client, clock] of restStructs.missing) { 3439 const mclock = pending.missing.get(client); 3440 if (mclock == null || mclock > clock) { 3441 pending.missing.set(client, clock); 3442 } 3443 } 3444 pending.update = mergeUpdatesV2([pending.update, restStructs.update]); 3445 } 3446 } else { 3447 store2.pendingStructs = restStructs; 3448 } 3449 const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store2); 3450 if (store2.pendingDs) { 3451 const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store2.pendingDs)); 3452 readVarUint(pendingDSUpdate.restDecoder); 3453 const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store2); 3454 if (dsRest && dsRest2) { 3455 store2.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); 3456 } else { 3457 store2.pendingDs = dsRest || dsRest2; 3458 } 3459 } else { 3460 store2.pendingDs = dsRest; 3461 } 3462 if (retry) { 3463 const update = ( 3464 /** @type {{update: Uint8Array}} */ 3465 store2.pendingStructs.update 3466 ); 3467 store2.pendingStructs = null; 3468 applyUpdateV2(transaction.doc, update); 3469 } 3470 }, transactionOrigin, false); 3471 var readUpdate = (decoder, ydoc, transactionOrigin) => readUpdateV2(decoder, ydoc, transactionOrigin, new UpdateDecoderV1(decoder)); 3472 var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { 3473 const decoder = createDecoder(update); 3474 readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); 3475 }; 3476 var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); 3477 var writeStateAsUpdate = (encoder, doc2, targetStateVector = /* @__PURE__ */ new Map()) => { 3478 writeClientsStructs(encoder, doc2.store, targetStateVector); 3479 writeDeleteSet(encoder, createDeleteSetFromStructStore(doc2.store)); 3480 }; 3481 var encodeStateAsUpdateV2 = (doc2, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { 3482 const targetStateVector = decodeStateVector(encodedTargetStateVector); 3483 writeStateAsUpdate(encoder, doc2, targetStateVector); 3484 const updates = [encoder.toUint8Array()]; 3485 if (doc2.store.pendingDs) { 3486 updates.push(doc2.store.pendingDs); 3487 } 3488 if (doc2.store.pendingStructs) { 3489 updates.push(diffUpdateV2(doc2.store.pendingStructs.update, encodedTargetStateVector)); 3490 } 3491 if (updates.length > 1) { 3492 if (encoder.constructor === UpdateEncoderV1) { 3493 return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); 3494 } else if (encoder.constructor === UpdateEncoderV2) { 3495 return mergeUpdatesV2(updates); 3496 } 3497 } 3498 return updates[0]; 3499 }; 3500 var encodeStateAsUpdate = (doc2, encodedTargetStateVector) => encodeStateAsUpdateV2(doc2, encodedTargetStateVector, new UpdateEncoderV1()); 3501 var readStateVector = (decoder) => { 3502 const ss = /* @__PURE__ */ new Map(); 3503 const ssLength = readVarUint(decoder.restDecoder); 3504 for (let i = 0; i < ssLength; i++) { 3505 const client = readVarUint(decoder.restDecoder); 3506 const clock = readVarUint(decoder.restDecoder); 3507 ss.set(client, clock); 3508 } 3509 return ss; 3510 }; 3511 var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); 3512 var writeStateVector = (encoder, sv) => { 3513 writeVarUint(encoder.restEncoder, sv.size); 3514 from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3515 writeVarUint(encoder.restEncoder, client); 3516 writeVarUint(encoder.restEncoder, clock); 3517 }); 3518 return encoder; 3519 }; 3520 var writeDocumentStateVector = (encoder, doc2) => writeStateVector(encoder, getStateVector(doc2.store)); 3521 var encodeStateVectorV2 = (doc2, encoder = new DSEncoderV2()) => { 3522 if (doc2 instanceof Map) { 3523 writeStateVector(encoder, doc2); 3524 } else { 3525 writeDocumentStateVector(encoder, doc2); 3526 } 3527 return encoder.toUint8Array(); 3528 }; 3529 var encodeStateVector = (doc2) => encodeStateVectorV2(doc2, new DSEncoderV1()); 3530 var EventHandler = class { 3531 constructor() { 3532 this.l = []; 3533 } 3534 }; 3535 var createEventHandler = () => new EventHandler(); 3536 var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); 3537 var removeEventHandlerListener = (eventHandler, f) => { 3538 const l = eventHandler.l; 3539 const len = l.length; 3540 eventHandler.l = l.filter((g) => f !== g); 3541 if (len === eventHandler.l.length) { 3542 console.error("[yjs] Tried to remove event handler that doesn't exist."); 3543 } 3544 }; 3545 var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); 3546 var ID = class { 3547 /** 3548 * @param {number} client client id 3549 * @param {number} clock unique per client id, continuous number 3550 */ 3551 constructor(client, clock) { 3552 this.client = client; 3553 this.clock = clock; 3554 } 3555 }; 3556 var compareIDs = (a, b) => a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock; 3557 var createID = (client, clock) => new ID(client, clock); 3558 var writeID = (encoder, id2) => { 3559 writeVarUint(encoder, id2.client); 3560 writeVarUint(encoder, id2.clock); 3561 }; 3562 var readID = (decoder) => createID(readVarUint(decoder), readVarUint(decoder)); 3563 var findRootTypeKey = (type) => { 3564 for (const [key, value] of type.doc.share.entries()) { 3565 if (value === type) { 3566 return key; 3567 } 3568 } 3569 throw unexpectedCase(); 3570 }; 3571 var isParentOf = (parent, child) => { 3572 while (child !== null) { 3573 if (child.parent === parent) { 3574 return true; 3575 } 3576 child = /** @type {AbstractType<any>} */ 3577 child.parent._item; 3578 } 3579 return false; 3580 }; 3581 var logType = (type) => { 3582 const res = []; 3583 let n = type._start; 3584 while (n) { 3585 res.push(n); 3586 n = n.right; 3587 } 3588 console.log("Children: ", res); 3589 console.log("Children content: ", res.filter((m) => !m.deleted).map((m) => m.content)); 3590 }; 3591 var PermanentUserData = class { 3592 /** 3593 * @param {Doc} doc 3594 * @param {YMap<any>} [storeType] 3595 */ 3596 constructor(doc2, storeType = doc2.getMap("users")) { 3597 const dss = /* @__PURE__ */ new Map(); 3598 this.yusers = storeType; 3599 this.doc = doc2; 3600 this.clients = /* @__PURE__ */ new Map(); 3601 this.dss = dss; 3602 const initUser = (user, userDescription) => { 3603 const ds = user.get("ds"); 3604 const ids = user.get("ids"); 3605 const addClientId = ( 3606 /** @param {number} clientid */ 3607 (clientid) => this.clients.set(clientid, userDescription) 3608 ); 3609 ds.observe( 3610 /** @param {YArrayEvent<any>} event */ 3611 (event) => { 3612 event.changes.added.forEach((item) => { 3613 item.content.getContent().forEach((encodedDs) => { 3614 if (encodedDs instanceof Uint8Array) { 3615 this.dss.set(userDescription, mergeDeleteSets([this.dss.get(userDescription) || createDeleteSet(), readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))])); 3616 } 3617 }); 3618 }); 3619 } 3620 ); 3621 this.dss.set(userDescription, mergeDeleteSets(ds.map((encodedDs) => readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))))); 3622 ids.observe( 3623 /** @param {YArrayEvent<any>} event */ 3624 (event) => event.changes.added.forEach((item) => item.content.getContent().forEach(addClientId)) 3625 ); 3626 ids.forEach(addClientId); 3627 }; 3628 storeType.observe((event) => { 3629 event.keysChanged.forEach( 3630 (userDescription) => initUser(storeType.get(userDescription), userDescription) 3631 ); 3632 }); 3633 storeType.forEach(initUser); 3634 } 3635 /** 3636 * @param {Doc} doc 3637 * @param {number} clientid 3638 * @param {string} userDescription 3639 * @param {Object} conf 3640 * @param {function(Transaction, DeleteSet):boolean} [conf.filter] 3641 */ 3642 setUserMapping(doc2, clientid, userDescription, { filter = () => true } = {}) { 3643 const users2 = this.yusers; 3644 let user = users2.get(userDescription); 3645 if (!user) { 3646 user = new YMap(); 3647 user.set("ids", new YArray()); 3648 user.set("ds", new YArray()); 3649 users2.set(userDescription, user); 3650 } 3651 user.get("ids").push([clientid]); 3652 users2.observe((_event) => { 3653 setTimeout(() => { 3654 const userOverwrite = users2.get(userDescription); 3655 if (userOverwrite !== user) { 3656 user = userOverwrite; 3657 this.clients.forEach((_userDescription, clientid2) => { 3658 if (userDescription === _userDescription) { 3659 user.get("ids").push([clientid2]); 3660 } 3661 }); 3662 const encoder = new DSEncoderV1(); 3663 const ds = this.dss.get(userDescription); 3664 if (ds) { 3665 writeDeleteSet(encoder, ds); 3666 user.get("ds").push([encoder.toUint8Array()]); 3667 } 3668 } 3669 }, 0); 3670 }); 3671 doc2.on( 3672 "afterTransaction", 3673 /** @param {Transaction} transaction */ 3674 (transaction) => { 3675 setTimeout(() => { 3676 const yds = user.get("ds"); 3677 const ds = transaction.deleteSet; 3678 if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) { 3679 const encoder = new DSEncoderV1(); 3680 writeDeleteSet(encoder, ds); 3681 yds.push([encoder.toUint8Array()]); 3682 } 3683 }); 3684 } 3685 ); 3686 } 3687 /** 3688 * @param {number} clientid 3689 * @return {any} 3690 */ 3691 getUserByClientId(clientid) { 3692 return this.clients.get(clientid) || null; 3693 } 3694 /** 3695 * @param {ID} id 3696 * @return {string | null} 3697 */ 3698 getUserByDeletedId(id2) { 3699 for (const [userDescription, ds] of this.dss.entries()) { 3700 if (isDeleted(ds, id2)) { 3701 return userDescription; 3702 } 3703 } 3704 return null; 3705 } 3706 }; 3707 var RelativePosition = class { 3708 /** 3709 * @param {ID|null} type 3710 * @param {string|null} tname 3711 * @param {ID|null} item 3712 * @param {number} assoc 3713 */ 3714 constructor(type, tname, item, assoc = 0) { 3715 this.type = type; 3716 this.tname = tname; 3717 this.item = item; 3718 this.assoc = assoc; 3719 } 3720 }; 3721 var relativePositionToJSON = (rpos) => { 3722 const json = {}; 3723 if (rpos.type) { 3724 json.type = rpos.type; 3725 } 3726 if (rpos.tname) { 3727 json.tname = rpos.tname; 3728 } 3729 if (rpos.item) { 3730 json.item = rpos.item; 3731 } 3732 if (rpos.assoc != null) { 3733 json.assoc = rpos.assoc; 3734 } 3735 return json; 3736 }; 3737 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); 3738 var AbsolutePosition = class { 3739 /** 3740 * @param {AbstractType<any>} type 3741 * @param {number} index 3742 * @param {number} [assoc] 3743 */ 3744 constructor(type, index, assoc = 0) { 3745 this.type = type; 3746 this.index = index; 3747 this.assoc = assoc; 3748 } 3749 }; 3750 var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); 3751 var createRelativePosition = (type, item, assoc) => { 3752 let typeid = null; 3753 let tname = null; 3754 if (type._item === null) { 3755 tname = findRootTypeKey(type); 3756 } else { 3757 typeid = createID(type._item.id.client, type._item.id.clock); 3758 } 3759 return new RelativePosition(typeid, tname, item, assoc); 3760 }; 3761 var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { 3762 let t = type._start; 3763 if (assoc < 0) { 3764 if (index === 0) { 3765 return createRelativePosition(type, null, assoc); 3766 } 3767 index--; 3768 } 3769 while (t !== null) { 3770 if (!t.deleted && t.countable) { 3771 if (t.length > index) { 3772 return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); 3773 } 3774 index -= t.length; 3775 } 3776 if (t.right === null && assoc < 0) { 3777 return createRelativePosition(type, t.lastId, assoc); 3778 } 3779 t = t.right; 3780 } 3781 return createRelativePosition(type, null, assoc); 3782 }; 3783 var writeRelativePosition = (encoder, rpos) => { 3784 const { type, tname, item, assoc } = rpos; 3785 if (item !== null) { 3786 writeVarUint(encoder, 0); 3787 writeID(encoder, item); 3788 } else if (tname !== null) { 3789 writeUint8(encoder, 1); 3790 writeVarString(encoder, tname); 3791 } else if (type !== null) { 3792 writeUint8(encoder, 2); 3793 writeID(encoder, type); 3794 } else { 3795 throw unexpectedCase(); 3796 } 3797 writeVarInt(encoder, assoc); 3798 return encoder; 3799 }; 3800 var encodeRelativePosition = (rpos) => { 3801 const encoder = createEncoder(); 3802 writeRelativePosition(encoder, rpos); 3803 return toUint8Array(encoder); 3804 }; 3805 var readRelativePosition = (decoder) => { 3806 let type = null; 3807 let tname = null; 3808 let itemID = null; 3809 switch (readVarUint(decoder)) { 3810 case 0: 3811 itemID = readID(decoder); 3812 break; 3813 case 1: 3814 tname = readVarString(decoder); 3815 break; 3816 case 2: { 3817 type = readID(decoder); 3818 } 3819 } 3820 const assoc = hasContent(decoder) ? readVarInt(decoder) : 0; 3821 return new RelativePosition(type, tname, itemID, assoc); 3822 }; 3823 var decodeRelativePosition = (uint8Array) => readRelativePosition(createDecoder(uint8Array)); 3824 var getItemWithOffset = (store2, id2) => { 3825 const item = getItem(store2, id2); 3826 const diff = id2.clock - item.id.clock; 3827 return { 3828 item, 3829 diff 3830 }; 3831 }; 3832 var createAbsolutePositionFromRelativePosition = (rpos, doc2, followUndoneDeletions = true) => { 3833 const store2 = doc2.store; 3834 const rightID = rpos.item; 3835 const typeID = rpos.type; 3836 const tname = rpos.tname; 3837 const assoc = rpos.assoc; 3838 let type = null; 3839 let index = 0; 3840 if (rightID !== null) { 3841 if (getState(store2, rightID.client) <= rightID.clock) { 3842 return null; 3843 } 3844 const res = followUndoneDeletions ? followRedone(store2, rightID) : getItemWithOffset(store2, rightID); 3845 const right = res.item; 3846 if (!(right instanceof Item)) { 3847 return null; 3848 } 3849 type = /** @type {AbstractType<any>} */ 3850 right.parent; 3851 if (type._item === null || !type._item.deleted) { 3852 index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); 3853 let n = right.left; 3854 while (n !== null) { 3855 if (!n.deleted && n.countable) { 3856 index += n.length; 3857 } 3858 n = n.left; 3859 } 3860 } 3861 } else { 3862 if (tname !== null) { 3863 type = doc2.get(tname); 3864 } else if (typeID !== null) { 3865 if (getState(store2, typeID.client) <= typeID.clock) { 3866 return null; 3867 } 3868 const { item } = followUndoneDeletions ? followRedone(store2, typeID) : { item: getItem(store2, typeID) }; 3869 if (item instanceof Item && item.content instanceof ContentType) { 3870 type = item.content.type; 3871 } else { 3872 return null; 3873 } 3874 } else { 3875 throw unexpectedCase(); 3876 } 3877 if (assoc >= 0) { 3878 index = type._length; 3879 } else { 3880 index = 0; 3881 } 3882 } 3883 return createAbsolutePosition(type, index, rpos.assoc); 3884 }; 3885 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; 3886 var Snapshot = class { 3887 /** 3888 * @param {DeleteSet} ds 3889 * @param {Map<number,number>} sv state map 3890 */ 3891 constructor(ds, sv) { 3892 this.ds = ds; 3893 this.sv = sv; 3894 } 3895 }; 3896 var equalSnapshots = (snap1, snap2) => { 3897 const ds1 = snap1.ds.clients; 3898 const ds2 = snap2.ds.clients; 3899 const sv1 = snap1.sv; 3900 const sv2 = snap2.sv; 3901 if (sv1.size !== sv2.size || ds1.size !== ds2.size) { 3902 return false; 3903 } 3904 for (const [key, value] of sv1.entries()) { 3905 if (sv2.get(key) !== value) { 3906 return false; 3907 } 3908 } 3909 for (const [client, dsitems1] of ds1.entries()) { 3910 const dsitems2 = ds2.get(client) || []; 3911 if (dsitems1.length !== dsitems2.length) { 3912 return false; 3913 } 3914 for (let i = 0; i < dsitems1.length; i++) { 3915 const dsitem1 = dsitems1[i]; 3916 const dsitem2 = dsitems2[i]; 3917 if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) { 3918 return false; 3919 } 3920 } 3921 } 3922 return true; 3923 }; 3924 var encodeSnapshotV2 = (snapshot2, encoder = new DSEncoderV2()) => { 3925 writeDeleteSet(encoder, snapshot2.ds); 3926 writeStateVector(encoder, snapshot2.sv); 3927 return encoder.toUint8Array(); 3928 }; 3929 var encodeSnapshot = (snapshot2) => encodeSnapshotV2(snapshot2, new DSEncoderV1()); 3930 var decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(createDecoder(buf))) => { 3931 return new Snapshot(readDeleteSet(decoder), readStateVector(decoder)); 3932 }; 3933 var decodeSnapshot = (buf) => decodeSnapshotV2(buf, new DSDecoderV1(createDecoder(buf))); 3934 var createSnapshot = (ds, sm) => new Snapshot(ds, sm); 3935 var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); 3936 var snapshot = (doc2) => createSnapshot(createDeleteSetFromStructStore(doc2.store), getStateVector(doc2.store)); 3937 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); 3938 var splitSnapshotAffectedStructs = (transaction, snapshot2) => { 3939 const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); 3940 const store2 = transaction.doc.store; 3941 if (!meta.has(snapshot2)) { 3942 snapshot2.sv.forEach((clock, client) => { 3943 if (clock < getState(store2, client)) { 3944 getItemCleanStart(transaction, createID(client, clock)); 3945 } 3946 }); 3947 iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { 3948 }); 3949 meta.add(snapshot2); 3950 } 3951 }; 3952 var createDocFromSnapshot = (originDoc, snapshot2, newDoc = new Doc()) => { 3953 if (originDoc.gc) { 3954 throw new Error("Garbage-collection must be disabled in `originDoc`!"); 3955 } 3956 const { sv, ds } = snapshot2; 3957 const encoder = new UpdateEncoderV2(); 3958 originDoc.transact((transaction) => { 3959 let size2 = 0; 3960 sv.forEach((clock) => { 3961 if (clock > 0) { 3962 size2++; 3963 } 3964 }); 3965 writeVarUint(encoder.restEncoder, size2); 3966 for (const [client, clock] of sv) { 3967 if (clock === 0) { 3968 continue; 3969 } 3970 if (clock < getState(originDoc.store, client)) { 3971 getItemCleanStart(transaction, createID(client, clock)); 3972 } 3973 const structs = originDoc.store.clients.get(client) || []; 3974 const lastStructIndex = findIndexSS(structs, clock - 1); 3975 writeVarUint(encoder.restEncoder, lastStructIndex + 1); 3976 encoder.writeClient(client); 3977 writeVarUint(encoder.restEncoder, 0); 3978 for (let i = 0; i <= lastStructIndex; i++) { 3979 structs[i].write(encoder, 0); 3980 } 3981 } 3982 writeDeleteSet(encoder, ds); 3983 }); 3984 applyUpdateV2(newDoc, encoder.toUint8Array(), "snapshot"); 3985 return newDoc; 3986 }; 3987 var snapshotContainsUpdateV2 = (snapshot2, update, YDecoder = UpdateDecoderV2) => { 3988 const updateDecoder = new YDecoder(createDecoder(update)); 3989 const lazyDecoder = new LazyStructReader(updateDecoder, false); 3990 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 3991 if ((snapshot2.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) { 3992 return false; 3993 } 3994 } 3995 const mergedDS = mergeDeleteSets([snapshot2.ds, readDeleteSet(updateDecoder)]); 3996 return equalDeleteSets(snapshot2.ds, mergedDS); 3997 }; 3998 var snapshotContainsUpdate = (snapshot2, update) => snapshotContainsUpdateV2(snapshot2, update, UpdateDecoderV1); 3999 var StructStore = class { 4000 constructor() { 4001 this.clients = /* @__PURE__ */ new Map(); 4002 this.pendingStructs = null; 4003 this.pendingDs = null; 4004 } 4005 }; 4006 var getStateVector = (store2) => { 4007 const sm = /* @__PURE__ */ new Map(); 4008 store2.clients.forEach((structs, client) => { 4009 const struct = structs[structs.length - 1]; 4010 sm.set(client, struct.id.clock + struct.length); 4011 }); 4012 return sm; 4013 }; 4014 var getState = (store2, client) => { 4015 const structs = store2.clients.get(client); 4016 if (structs === void 0) { 4017 return 0; 4018 } 4019 const lastStruct = structs[structs.length - 1]; 4020 return lastStruct.id.clock + lastStruct.length; 4021 }; 4022 var addStruct = (store2, struct) => { 4023 let structs = store2.clients.get(struct.id.client); 4024 if (structs === void 0) { 4025 structs = []; 4026 store2.clients.set(struct.id.client, structs); 4027 } else { 4028 const lastStruct = structs[structs.length - 1]; 4029 if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { 4030 throw unexpectedCase(); 4031 } 4032 } 4033 structs.push(struct); 4034 }; 4035 var findIndexSS = (structs, clock) => { 4036 let left = 0; 4037 let right = structs.length - 1; 4038 let mid = structs[right]; 4039 let midclock = mid.id.clock; 4040 if (midclock === clock) { 4041 return right; 4042 } 4043 let midindex = floor(clock / (midclock + mid.length - 1) * right); 4044 while (left <= right) { 4045 mid = structs[midindex]; 4046 midclock = mid.id.clock; 4047 if (midclock <= clock) { 4048 if (clock < midclock + mid.length) { 4049 return midindex; 4050 } 4051 left = midindex + 1; 4052 } else { 4053 right = midindex - 1; 4054 } 4055 midindex = floor((left + right) / 2); 4056 } 4057 throw unexpectedCase(); 4058 }; 4059 var find = (store2, id2) => { 4060 const structs = store2.clients.get(id2.client); 4061 return structs[findIndexSS(structs, id2.clock)]; 4062 }; 4063 var getItem = ( 4064 /** @type {function(StructStore,ID):Item} */ 4065 find 4066 ); 4067 var findIndexCleanStart = (transaction, structs, clock) => { 4068 const index = findIndexSS(structs, clock); 4069 const struct = structs[index]; 4070 if (struct.id.clock < clock && struct instanceof Item) { 4071 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 4072 return index + 1; 4073 } 4074 return index; 4075 }; 4076 var getItemCleanStart = (transaction, id2) => { 4077 const structs = ( 4078 /** @type {Array<Item>} */ 4079 transaction.doc.store.clients.get(id2.client) 4080 ); 4081 return structs[findIndexCleanStart(transaction, structs, id2.clock)]; 4082 }; 4083 var getItemCleanEnd = (transaction, store2, id2) => { 4084 const structs = store2.clients.get(id2.client); 4085 const index = findIndexSS(structs, id2.clock); 4086 const struct = structs[index]; 4087 if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { 4088 structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); 4089 } 4090 return struct; 4091 }; 4092 var replaceStruct = (store2, struct, newStruct) => { 4093 const structs = ( 4094 /** @type {Array<GC|Item>} */ 4095 store2.clients.get(struct.id.client) 4096 ); 4097 structs[findIndexSS(structs, struct.id.clock)] = newStruct; 4098 }; 4099 var iterateStructs = (transaction, structs, clockStart, len, f) => { 4100 if (len === 0) { 4101 return; 4102 } 4103 const clockEnd = clockStart + len; 4104 let index = findIndexCleanStart(transaction, structs, clockStart); 4105 let struct; 4106 do { 4107 struct = structs[index++]; 4108 if (clockEnd < struct.id.clock + struct.length) { 4109 findIndexCleanStart(transaction, structs, clockEnd); 4110 } 4111 f(struct); 4112 } while (index < structs.length && structs[index].id.clock < clockEnd); 4113 }; 4114 var Transaction = class { 4115 /** 4116 * @param {Doc} doc 4117 * @param {any} origin 4118 * @param {boolean} local 4119 */ 4120 constructor(doc2, origin2, local) { 4121 this.doc = doc2; 4122 this.deleteSet = new DeleteSet(); 4123 this.beforeState = getStateVector(doc2.store); 4124 this.afterState = /* @__PURE__ */ new Map(); 4125 this.changed = /* @__PURE__ */ new Map(); 4126 this.changedParentTypes = /* @__PURE__ */ new Map(); 4127 this._mergeStructs = []; 4128 this.origin = origin2; 4129 this.meta = /* @__PURE__ */ new Map(); 4130 this.local = local; 4131 this.subdocsAdded = /* @__PURE__ */ new Set(); 4132 this.subdocsRemoved = /* @__PURE__ */ new Set(); 4133 this.subdocsLoaded = /* @__PURE__ */ new Set(); 4134 this._needFormattingCleanup = false; 4135 } 4136 }; 4137 var writeUpdateMessageFromTransaction = (encoder, transaction) => { 4138 if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { 4139 return false; 4140 } 4141 sortAndMergeDeleteSet(transaction.deleteSet); 4142 writeStructsFromTransaction(encoder, transaction); 4143 writeDeleteSet(encoder, transaction.deleteSet); 4144 return true; 4145 }; 4146 var addChangedTypeToTransaction = (transaction, type, parentSub) => { 4147 const item = type._item; 4148 if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { 4149 setIfUndefined(transaction.changed, type, create2).add(parentSub); 4150 } 4151 }; 4152 var tryToMergeWithLefts = (structs, pos) => { 4153 let right = structs[pos]; 4154 let left = structs[pos - 1]; 4155 let i = pos; 4156 for (; i > 0; right = left, left = structs[--i - 1]) { 4157 if (left.deleted === right.deleted && left.constructor === right.constructor) { 4158 if (left.mergeWith(right)) { 4159 if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ 4160 right.parent._map.get(right.parentSub) === right) { 4161 right.parent._map.set( 4162 right.parentSub, 4163 /** @type {Item} */ 4164 left 4165 ); 4166 } 4167 continue; 4168 } 4169 } 4170 break; 4171 } 4172 const merged = pos - i; 4173 if (merged) { 4174 structs.splice(pos + 1 - merged, merged); 4175 } 4176 return merged; 4177 }; 4178 var tryGcDeleteSet = (ds, store2, gcFilter) => { 4179 for (const [client, deleteItems] of ds.clients.entries()) { 4180 const structs = ( 4181 /** @type {Array<GC|Item>} */ 4182 store2.clients.get(client) 4183 ); 4184 for (let di = deleteItems.length - 1; di >= 0; di--) { 4185 const deleteItem = deleteItems[di]; 4186 const endDeleteItemClock = deleteItem.clock + deleteItem.len; 4187 for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { 4188 const struct2 = structs[si]; 4189 if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { 4190 break; 4191 } 4192 if (struct2 instanceof Item && struct2.deleted && !struct2.keep && gcFilter(struct2)) { 4193 struct2.gc(store2, false); 4194 } 4195 } 4196 } 4197 } 4198 }; 4199 var tryMergeDeleteSet = (ds, store2) => { 4200 ds.clients.forEach((deleteItems, client) => { 4201 const structs = ( 4202 /** @type {Array<GC|Item>} */ 4203 store2.clients.get(client) 4204 ); 4205 for (let di = deleteItems.length - 1; di >= 0; di--) { 4206 const deleteItem = deleteItems[di]; 4207 const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); 4208 for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { 4209 si -= 1 + tryToMergeWithLefts(structs, si); 4210 } 4211 } 4212 }); 4213 }; 4214 var tryGc = (ds, store2, gcFilter) => { 4215 tryGcDeleteSet(ds, store2, gcFilter); 4216 tryMergeDeleteSet(ds, store2); 4217 }; 4218 var cleanupTransactions = (transactionCleanups, i) => { 4219 if (i < transactionCleanups.length) { 4220 const transaction = transactionCleanups[i]; 4221 const doc2 = transaction.doc; 4222 const store2 = doc2.store; 4223 const ds = transaction.deleteSet; 4224 const mergeStructs = transaction._mergeStructs; 4225 try { 4226 sortAndMergeDeleteSet(ds); 4227 transaction.afterState = getStateVector(transaction.doc.store); 4228 doc2.emit("beforeObserverCalls", [transaction, doc2]); 4229 const fs = []; 4230 transaction.changed.forEach( 4231 (subs, itemtype) => fs.push(() => { 4232 if (itemtype._item === null || !itemtype._item.deleted) { 4233 itemtype._callObserver(transaction, subs); 4234 } 4235 }) 4236 ); 4237 fs.push(() => { 4238 transaction.changedParentTypes.forEach((events, type) => { 4239 if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { 4240 events = events.filter( 4241 (event) => event.target._item === null || !event.target._item.deleted 4242 ); 4243 events.forEach((event) => { 4244 event.currentTarget = type; 4245 event._path = null; 4246 }); 4247 events.sort((event1, event2) => event1.path.length - event2.path.length); 4248 fs.push(() => { 4249 callEventHandlerListeners(type._dEH, events, transaction); 4250 }); 4251 } 4252 }); 4253 fs.push(() => doc2.emit("afterTransaction", [transaction, doc2])); 4254 fs.push(() => { 4255 if (transaction._needFormattingCleanup) { 4256 cleanupYTextAfterTransaction(transaction); 4257 } 4258 }); 4259 }); 4260 callAll(fs, []); 4261 } finally { 4262 if (doc2.gc) { 4263 tryGcDeleteSet(ds, store2, doc2.gcFilter); 4264 } 4265 tryMergeDeleteSet(ds, store2); 4266 transaction.afterState.forEach((clock, client) => { 4267 const beforeClock = transaction.beforeState.get(client) || 0; 4268 if (beforeClock !== clock) { 4269 const structs = ( 4270 /** @type {Array<GC|Item>} */ 4271 store2.clients.get(client) 4272 ); 4273 const firstChangePos = max(findIndexSS(structs, beforeClock), 1); 4274 for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { 4275 i2 -= 1 + tryToMergeWithLefts(structs, i2); 4276 } 4277 } 4278 }); 4279 for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { 4280 const { client, clock } = mergeStructs[i2].id; 4281 const structs = ( 4282 /** @type {Array<GC|Item>} */ 4283 store2.clients.get(client) 4284 ); 4285 const replacedStructPos = findIndexSS(structs, clock); 4286 if (replacedStructPos + 1 < structs.length) { 4287 if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { 4288 continue; 4289 } 4290 } 4291 if (replacedStructPos > 0) { 4292 tryToMergeWithLefts(structs, replacedStructPos); 4293 } 4294 } 4295 if (!transaction.local && transaction.afterState.get(doc2.clientID) !== transaction.beforeState.get(doc2.clientID)) { 4296 print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); 4297 doc2.clientID = generateNewClientId(); 4298 } 4299 doc2.emit("afterTransactionCleanup", [transaction, doc2]); 4300 if (doc2._observers.has("update")) { 4301 const encoder = new UpdateEncoderV1(); 4302 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4303 if (hasContent2) { 4304 doc2.emit("update", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4305 } 4306 } 4307 if (doc2._observers.has("updateV2")) { 4308 const encoder = new UpdateEncoderV2(); 4309 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4310 if (hasContent2) { 4311 doc2.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4312 } 4313 } 4314 const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; 4315 if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { 4316 subdocsAdded.forEach((subdoc) => { 4317 subdoc.clientID = doc2.clientID; 4318 if (subdoc.collectionid == null) { 4319 subdoc.collectionid = doc2.collectionid; 4320 } 4321 doc2.subdocs.add(subdoc); 4322 }); 4323 subdocsRemoved.forEach((subdoc) => doc2.subdocs.delete(subdoc)); 4324 doc2.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc2, transaction]); 4325 subdocsRemoved.forEach((subdoc) => subdoc.destroy()); 4326 } 4327 if (transactionCleanups.length <= i + 1) { 4328 doc2._transactionCleanups = []; 4329 doc2.emit("afterAllTransactions", [doc2, transactionCleanups]); 4330 } else { 4331 cleanupTransactions(transactionCleanups, i + 1); 4332 } 4333 } 4334 } 4335 }; 4336 var transact = (doc2, f, origin2 = null, local = true) => { 4337 const transactionCleanups = doc2._transactionCleanups; 4338 let initialCall = false; 4339 let result = null; 4340 if (doc2._transaction === null) { 4341 initialCall = true; 4342 doc2._transaction = new Transaction(doc2, origin2, local); 4343 transactionCleanups.push(doc2._transaction); 4344 if (transactionCleanups.length === 1) { 4345 doc2.emit("beforeAllTransactions", [doc2]); 4346 } 4347 doc2.emit("beforeTransaction", [doc2._transaction, doc2]); 4348 } 4349 try { 4350 result = f(doc2._transaction); 4351 } finally { 4352 if (initialCall) { 4353 const finishCleanup = doc2._transaction === transactionCleanups[0]; 4354 doc2._transaction = null; 4355 if (finishCleanup) { 4356 cleanupTransactions(transactionCleanups, 0); 4357 } 4358 } 4359 } 4360 return result; 4361 }; 4362 var StackItem = class { 4363 /** 4364 * @param {DeleteSet} deletions 4365 * @param {DeleteSet} insertions 4366 */ 4367 constructor(deletions, insertions) { 4368 this.insertions = insertions; 4369 this.deletions = deletions; 4370 this.meta = /* @__PURE__ */ new Map(); 4371 } 4372 }; 4373 var clearUndoManagerStackItem = (tr, um, stackItem) => { 4374 iterateDeletedStructs(tr, stackItem.deletions, (item) => { 4375 if (item instanceof Item && um.scope.some((type) => type === tr.doc || isParentOf( 4376 /** @type {AbstractType<any>} */ 4377 type, 4378 item 4379 ))) { 4380 keepItem(item, false); 4381 } 4382 }); 4383 }; 4384 var popStackItem = (undoManager2, stack, eventType) => { 4385 let _tr = null; 4386 const doc2 = undoManager2.doc; 4387 const scope = undoManager2.scope; 4388 transact(doc2, (transaction) => { 4389 while (stack.length > 0 && undoManager2.currStackItem === null) { 4390 const store2 = doc2.store; 4391 const stackItem = ( 4392 /** @type {StackItem} */ 4393 stack.pop() 4394 ); 4395 const itemsToRedo = /* @__PURE__ */ new Set(); 4396 const itemsToDelete = []; 4397 let performedChange = false; 4398 iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { 4399 if (struct instanceof Item) { 4400 if (struct.redone !== null) { 4401 let { item, diff } = followRedone(store2, struct.id); 4402 if (diff > 0) { 4403 item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); 4404 } 4405 struct = item; 4406 } 4407 if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( 4408 /** @type {AbstractType<any>} */ 4409 type, 4410 /** @type {Item} */ 4411 struct 4412 ))) { 4413 itemsToDelete.push(struct); 4414 } 4415 } 4416 }); 4417 iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { 4418 if (struct instanceof Item && scope.some((type) => type === transaction.doc || isParentOf( 4419 /** @type {AbstractType<any>} */ 4420 type, 4421 struct 4422 )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. 4423 !isDeleted(stackItem.insertions, struct.id)) { 4424 itemsToRedo.add(struct); 4425 } 4426 }); 4427 itemsToRedo.forEach((struct) => { 4428 performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager2.ignoreRemoteMapChanges, undoManager2) !== null || performedChange; 4429 }); 4430 for (let i = itemsToDelete.length - 1; i >= 0; i--) { 4431 const item = itemsToDelete[i]; 4432 if (undoManager2.deleteFilter(item)) { 4433 item.delete(transaction); 4434 performedChange = true; 4435 } 4436 } 4437 undoManager2.currStackItem = performedChange ? stackItem : null; 4438 } 4439 transaction.changed.forEach((subProps, type) => { 4440 if (subProps.has(null) && type._searchMarker) { 4441 type._searchMarker.length = 0; 4442 } 4443 }); 4444 _tr = transaction; 4445 }, undoManager2); 4446 const res = undoManager2.currStackItem; 4447 if (res != null) { 4448 const changedParentTypes = _tr.changedParentTypes; 4449 undoManager2.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager2 }, undoManager2]); 4450 undoManager2.currStackItem = null; 4451 } 4452 return res; 4453 }; 4454 var UndoManager = class extends ObservableV2 { 4455 /** 4456 * @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. 4457 * @param {UndoManagerOptions} options 4458 */ 4459 constructor(typeScope, { 4460 captureTimeout = 500, 4461 captureTransaction = (_tr) => true, 4462 deleteFilter = () => true, 4463 trackedOrigins = /* @__PURE__ */ new Set([null]), 4464 ignoreRemoteMapChanges = false, 4465 doc: doc2 = ( 4466 /** @type {Doc} */ 4467 isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc 4468 ) 4469 } = {}) { 4470 super(); 4471 this.scope = []; 4472 this.doc = doc2; 4473 this.addToScope(typeScope); 4474 this.deleteFilter = deleteFilter; 4475 trackedOrigins.add(this); 4476 this.trackedOrigins = trackedOrigins; 4477 this.captureTransaction = captureTransaction; 4478 this.undoStack = []; 4479 this.redoStack = []; 4480 this.undoing = false; 4481 this.redoing = false; 4482 this.currStackItem = null; 4483 this.lastChange = 0; 4484 this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; 4485 this.captureTimeout = captureTimeout; 4486 this.afterTransactionHandler = (transaction) => { 4487 if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( 4488 /** @type {AbstractType<any>} */ 4489 type 4490 ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { 4491 return; 4492 } 4493 const undoing = this.undoing; 4494 const redoing = this.redoing; 4495 const stack = undoing ? this.redoStack : this.undoStack; 4496 if (undoing) { 4497 this.stopCapturing(); 4498 } else if (!redoing) { 4499 this.clear(false, true); 4500 } 4501 const insertions = new DeleteSet(); 4502 transaction.afterState.forEach((endClock, client) => { 4503 const startClock = transaction.beforeState.get(client) || 0; 4504 const len = endClock - startClock; 4505 if (len > 0) { 4506 addToDeleteSet(insertions, client, startClock, len); 4507 } 4508 }); 4509 const now = getUnixTime(); 4510 let didAdd = false; 4511 if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { 4512 const lastOp = stack[stack.length - 1]; 4513 lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); 4514 lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); 4515 } else { 4516 stack.push(new StackItem(transaction.deleteSet, insertions)); 4517 didAdd = true; 4518 } 4519 if (!undoing && !redoing) { 4520 this.lastChange = now; 4521 } 4522 iterateDeletedStructs( 4523 transaction, 4524 transaction.deleteSet, 4525 /** @param {Item|GC} item */ 4526 (item) => { 4527 if (item instanceof Item && this.scope.some((type) => type === transaction.doc || isParentOf( 4528 /** @type {AbstractType<any>} */ 4529 type, 4530 item 4531 ))) { 4532 keepItem(item, true); 4533 } 4534 } 4535 ); 4536 const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; 4537 if (didAdd) { 4538 this.emit("stack-item-added", changeEvent); 4539 } else { 4540 this.emit("stack-item-updated", changeEvent); 4541 } 4542 }; 4543 this.doc.on("afterTransaction", this.afterTransactionHandler); 4544 this.doc.on("destroy", () => { 4545 this.destroy(); 4546 }); 4547 } 4548 /** 4549 * Extend the scope. 4550 * 4551 * @param {Array<AbstractType<any> | Doc> | AbstractType<any> | Doc} ytypes 4552 */ 4553 addToScope(ytypes) { 4554 const tmpSet = new Set(this.scope); 4555 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 4556 ytypes.forEach((ytype) => { 4557 if (!tmpSet.has(ytype)) { 4558 tmpSet.add(ytype); 4559 if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn("[yjs#509] Not same Y.Doc"); 4560 this.scope.push(ytype); 4561 } 4562 }); 4563 } 4564 /** 4565 * @param {any} origin 4566 */ 4567 addTrackedOrigin(origin2) { 4568 this.trackedOrigins.add(origin2); 4569 } 4570 /** 4571 * @param {any} origin 4572 */ 4573 removeTrackedOrigin(origin2) { 4574 this.trackedOrigins.delete(origin2); 4575 } 4576 clear(clearUndoStack = true, clearRedoStack = true) { 4577 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 4578 this.doc.transact((tr) => { 4579 if (clearUndoStack) { 4580 this.undoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 4581 this.undoStack = []; 4582 } 4583 if (clearRedoStack) { 4584 this.redoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 4585 this.redoStack = []; 4586 } 4587 this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); 4588 }); 4589 } 4590 } 4591 /** 4592 * UndoManager merges Undo-StackItem if they are created within time-gap 4593 * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next 4594 * StackItem won't be merged. 4595 * 4596 * 4597 * @example 4598 * // without stopCapturing 4599 * ytext.insert(0, 'a') 4600 * ytext.insert(1, 'b') 4601 * um.undo() 4602 * ytext.toString() // => '' (note that 'ab' was removed) 4603 * // with stopCapturing 4604 * ytext.insert(0, 'a') 4605 * um.stopCapturing() 4606 * ytext.insert(0, 'b') 4607 * um.undo() 4608 * ytext.toString() // => 'a' (note that only 'b' was removed) 4609 * 4610 */ 4611 stopCapturing() { 4612 this.lastChange = 0; 4613 } 4614 /** 4615 * Undo last changes on type. 4616 * 4617 * @return {StackItem?} Returns StackItem if a change was applied 4618 */ 4619 undo() { 4620 this.undoing = true; 4621 let res; 4622 try { 4623 res = popStackItem(this, this.undoStack, "undo"); 4624 } finally { 4625 this.undoing = false; 4626 } 4627 return res; 4628 } 4629 /** 4630 * Redo last undo operation. 4631 * 4632 * @return {StackItem?} Returns StackItem if a change was applied 4633 */ 4634 redo() { 4635 this.redoing = true; 4636 let res; 4637 try { 4638 res = popStackItem(this, this.redoStack, "redo"); 4639 } finally { 4640 this.redoing = false; 4641 } 4642 return res; 4643 } 4644 /** 4645 * Are undo steps available? 4646 * 4647 * @return {boolean} `true` if undo is possible 4648 */ 4649 canUndo() { 4650 return this.undoStack.length > 0; 4651 } 4652 /** 4653 * Are redo steps available? 4654 * 4655 * @return {boolean} `true` if redo is possible 4656 */ 4657 canRedo() { 4658 return this.redoStack.length > 0; 4659 } 4660 destroy() { 4661 this.trackedOrigins.delete(this); 4662 this.doc.off("afterTransaction", this.afterTransactionHandler); 4663 super.destroy(); 4664 } 4665 }; 4666 function* lazyStructReaderGenerator(decoder) { 4667 const numOfStateUpdates = readVarUint(decoder.restDecoder); 4668 for (let i = 0; i < numOfStateUpdates; i++) { 4669 const numberOfStructs = readVarUint(decoder.restDecoder); 4670 const client = decoder.readClient(); 4671 let clock = readVarUint(decoder.restDecoder); 4672 for (let i2 = 0; i2 < numberOfStructs; i2++) { 4673 const info = decoder.readInfo(); 4674 if (info === 10) { 4675 const len = readVarUint(decoder.restDecoder); 4676 yield new Skip(createID(client, clock), len); 4677 clock += len; 4678 } else if ((BITS5 & info) !== 0) { 4679 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 4680 const struct = new Item( 4681 createID(client, clock), 4682 null, 4683 // left 4684 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 4685 // origin 4686 null, 4687 // right 4688 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 4689 // right origin 4690 // @ts-ignore Force writing a string here. 4691 cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, 4692 // parent 4693 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 4694 // parentSub 4695 readItemContent(decoder, info) 4696 // item content 4697 ); 4698 yield struct; 4699 clock += struct.length; 4700 } else { 4701 const len = decoder.readLen(); 4702 yield new GC(createID(client, clock), len); 4703 clock += len; 4704 } 4705 } 4706 } 4707 } 4708 var LazyStructReader = class { 4709 /** 4710 * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder 4711 * @param {boolean} filterSkips 4712 */ 4713 constructor(decoder, filterSkips) { 4714 this.gen = lazyStructReaderGenerator(decoder); 4715 this.curr = null; 4716 this.done = false; 4717 this.filterSkips = filterSkips; 4718 this.next(); 4719 } 4720 /** 4721 * @return {Item | GC | Skip |null} 4722 */ 4723 next() { 4724 do { 4725 this.curr = this.gen.next().value || null; 4726 } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); 4727 return this.curr; 4728 } 4729 }; 4730 var logUpdate = (update) => logUpdateV2(update, UpdateDecoderV1); 4731 var logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4732 const structs = []; 4733 const updateDecoder = new YDecoder(createDecoder(update)); 4734 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4735 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4736 structs.push(curr); 4737 } 4738 print("Structs: ", structs); 4739 const ds = readDeleteSet(updateDecoder); 4740 print("DeleteSet: ", ds); 4741 }; 4742 var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1); 4743 var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 4744 const structs = []; 4745 const updateDecoder = new YDecoder(createDecoder(update)); 4746 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4747 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4748 structs.push(curr); 4749 } 4750 return { 4751 structs, 4752 ds: readDeleteSet(updateDecoder) 4753 }; 4754 }; 4755 var LazyStructWriter = class { 4756 /** 4757 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 4758 */ 4759 constructor(encoder) { 4760 this.currClient = 0; 4761 this.startClock = 0; 4762 this.written = 0; 4763 this.encoder = encoder; 4764 this.clientStructs = []; 4765 } 4766 }; 4767 var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); 4768 var encodeStateVectorFromUpdateV2 = (update, YEncoder = DSEncoderV2, YDecoder = UpdateDecoderV2) => { 4769 const encoder = new YEncoder(); 4770 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4771 let curr = updateDecoder.curr; 4772 if (curr !== null) { 4773 let size2 = 0; 4774 let currClient = curr.id.client; 4775 let stopCounting = curr.id.clock !== 0; 4776 let currClock = stopCounting ? 0 : curr.id.clock + curr.length; 4777 for (; curr !== null; curr = updateDecoder.next()) { 4778 if (currClient !== curr.id.client) { 4779 if (currClock !== 0) { 4780 size2++; 4781 writeVarUint(encoder.restEncoder, currClient); 4782 writeVarUint(encoder.restEncoder, currClock); 4783 } 4784 currClient = curr.id.client; 4785 currClock = 0; 4786 stopCounting = curr.id.clock !== 0; 4787 } 4788 if (curr.constructor === Skip) { 4789 stopCounting = true; 4790 } 4791 if (!stopCounting) { 4792 currClock = curr.id.clock + curr.length; 4793 } 4794 } 4795 if (currClock !== 0) { 4796 size2++; 4797 writeVarUint(encoder.restEncoder, currClient); 4798 writeVarUint(encoder.restEncoder, currClock); 4799 } 4800 const enc = createEncoder(); 4801 writeVarUint(enc, size2); 4802 writeBinaryEncoder(enc, encoder.restEncoder); 4803 encoder.restEncoder = enc; 4804 return encoder.toUint8Array(); 4805 } else { 4806 writeVarUint(encoder.restEncoder, 0); 4807 return encoder.toUint8Array(); 4808 } 4809 }; 4810 var encodeStateVectorFromUpdate = (update) => encodeStateVectorFromUpdateV2(update, DSEncoderV1, UpdateDecoderV1); 4811 var parseUpdateMetaV2 = (update, YDecoder = UpdateDecoderV2) => { 4812 const from2 = /* @__PURE__ */ new Map(); 4813 const to = /* @__PURE__ */ new Map(); 4814 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 4815 let curr = updateDecoder.curr; 4816 if (curr !== null) { 4817 let currClient = curr.id.client; 4818 let currClock = curr.id.clock; 4819 from2.set(currClient, currClock); 4820 for (; curr !== null; curr = updateDecoder.next()) { 4821 if (currClient !== curr.id.client) { 4822 to.set(currClient, currClock); 4823 from2.set(curr.id.client, curr.id.clock); 4824 currClient = curr.id.client; 4825 } 4826 currClock = curr.id.clock + curr.length; 4827 } 4828 to.set(currClient, currClock); 4829 } 4830 return { from: from2, to }; 4831 }; 4832 var parseUpdateMeta = (update) => parseUpdateMetaV2(update, UpdateDecoderV1); 4833 var sliceStruct = (left, diff) => { 4834 if (left.constructor === GC) { 4835 const { client, clock } = left.id; 4836 return new GC(createID(client, clock + diff), left.length - diff); 4837 } else if (left.constructor === Skip) { 4838 const { client, clock } = left.id; 4839 return new Skip(createID(client, clock + diff), left.length - diff); 4840 } else { 4841 const leftItem = ( 4842 /** @type {Item} */ 4843 left 4844 ); 4845 const { client, clock } = leftItem.id; 4846 return new Item( 4847 createID(client, clock + diff), 4848 null, 4849 createID(client, clock + diff - 1), 4850 null, 4851 leftItem.rightOrigin, 4852 leftItem.parent, 4853 leftItem.parentSub, 4854 leftItem.content.splice(diff) 4855 ); 4856 } 4857 }; 4858 var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4859 if (updates.length === 1) { 4860 return updates[0]; 4861 } 4862 const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); 4863 let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); 4864 let currWrite = null; 4865 const updateEncoder = new YEncoder(); 4866 const lazyStructEncoder = new LazyStructWriter(updateEncoder); 4867 while (true) { 4868 lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); 4869 lazyStructDecoders.sort( 4870 /** @type {function(any,any):number} */ 4871 (dec1, dec2) => { 4872 if (dec1.curr.id.client === dec2.curr.id.client) { 4873 const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; 4874 if (clockDiff === 0) { 4875 return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; 4876 } else { 4877 return clockDiff; 4878 } 4879 } else { 4880 return dec2.curr.id.client - dec1.curr.id.client; 4881 } 4882 } 4883 ); 4884 if (lazyStructDecoders.length === 0) { 4885 break; 4886 } 4887 const currDecoder = lazyStructDecoders[0]; 4888 const firstClient = ( 4889 /** @type {Item | GC} */ 4890 currDecoder.curr.id.client 4891 ); 4892 if (currWrite !== null) { 4893 let curr = ( 4894 /** @type {Item | GC | null} */ 4895 currDecoder.curr 4896 ); 4897 let iterated = false; 4898 while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { 4899 curr = currDecoder.next(); 4900 iterated = true; 4901 } 4902 if (curr === null || // current decoder is empty 4903 curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` 4904 iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { 4905 continue; 4906 } 4907 if (firstClient !== currWrite.struct.id.client) { 4908 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4909 currWrite = { struct: curr, offset: 0 }; 4910 currDecoder.next(); 4911 } else { 4912 if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { 4913 if (currWrite.struct.constructor === Skip) { 4914 currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; 4915 } else { 4916 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4917 const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; 4918 const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); 4919 currWrite = { struct, offset: 0 }; 4920 } 4921 } else { 4922 const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; 4923 if (diff > 0) { 4924 if (currWrite.struct.constructor === Skip) { 4925 currWrite.struct.length -= diff; 4926 } else { 4927 curr = sliceStruct(curr, diff); 4928 } 4929 } 4930 if (!currWrite.struct.mergeWith( 4931 /** @type {any} */ 4932 curr 4933 )) { 4934 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4935 currWrite = { struct: curr, offset: 0 }; 4936 currDecoder.next(); 4937 } 4938 } 4939 } 4940 } else { 4941 currWrite = { struct: ( 4942 /** @type {Item | GC} */ 4943 currDecoder.curr 4944 ), offset: 0 }; 4945 currDecoder.next(); 4946 } 4947 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()) { 4948 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4949 currWrite = { struct: next, offset: 0 }; 4950 } 4951 } 4952 if (currWrite !== null) { 4953 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 4954 currWrite = null; 4955 } 4956 finishLazyStructWriting(lazyStructEncoder); 4957 const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); 4958 const ds = mergeDeleteSets(dss); 4959 writeDeleteSet(updateEncoder, ds); 4960 return updateEncoder.toUint8Array(); 4961 }; 4962 var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 4963 const state = decodeStateVector(sv); 4964 const encoder = new YEncoder(); 4965 const lazyStructWriter = new LazyStructWriter(encoder); 4966 const decoder = new YDecoder(createDecoder(update)); 4967 const reader = new LazyStructReader(decoder, false); 4968 while (reader.curr) { 4969 const curr = reader.curr; 4970 const currClient = curr.id.client; 4971 const svClock = state.get(currClient) || 0; 4972 if (reader.curr.constructor === Skip) { 4973 reader.next(); 4974 continue; 4975 } 4976 if (curr.id.clock + curr.length > svClock) { 4977 writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); 4978 reader.next(); 4979 while (reader.curr && reader.curr.id.client === currClient) { 4980 writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); 4981 reader.next(); 4982 } 4983 } else { 4984 while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { 4985 reader.next(); 4986 } 4987 } 4988 } 4989 finishLazyStructWriting(lazyStructWriter); 4990 const ds = readDeleteSet(decoder); 4991 writeDeleteSet(encoder, ds); 4992 return encoder.toUint8Array(); 4993 }; 4994 var diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1); 4995 var flushLazyStructWriter = (lazyWriter) => { 4996 if (lazyWriter.written > 0) { 4997 lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); 4998 lazyWriter.encoder.restEncoder = createEncoder(); 4999 lazyWriter.written = 0; 5000 } 5001 }; 5002 var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { 5003 if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { 5004 flushLazyStructWriter(lazyWriter); 5005 } 5006 if (lazyWriter.written === 0) { 5007 lazyWriter.currClient = struct.id.client; 5008 lazyWriter.encoder.writeClient(struct.id.client); 5009 writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); 5010 } 5011 struct.write(lazyWriter.encoder, offset); 5012 lazyWriter.written++; 5013 }; 5014 var finishLazyStructWriting = (lazyWriter) => { 5015 flushLazyStructWriter(lazyWriter); 5016 const restEncoder = lazyWriter.encoder.restEncoder; 5017 writeVarUint(restEncoder, lazyWriter.clientStructs.length); 5018 for (let i = 0; i < lazyWriter.clientStructs.length; i++) { 5019 const partStructs = lazyWriter.clientStructs[i]; 5020 writeVarUint(restEncoder, partStructs.written); 5021 writeUint8Array(restEncoder, partStructs.restEncoder); 5022 } 5023 }; 5024 var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { 5025 const updateDecoder = new YDecoder(createDecoder(update)); 5026 const lazyDecoder = new LazyStructReader(updateDecoder, false); 5027 const updateEncoder = new YEncoder(); 5028 const lazyWriter = new LazyStructWriter(updateEncoder); 5029 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 5030 writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); 5031 } 5032 finishLazyStructWriting(lazyWriter); 5033 const ds = readDeleteSet(updateDecoder); 5034 writeDeleteSet(updateEncoder, ds); 5035 return updateEncoder.toUint8Array(); 5036 }; 5037 var createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {}) => { 5038 let i = 0; 5039 const mapKeyCache = create(); 5040 const nodeNameCache = create(); 5041 const formattingKeyCache = create(); 5042 const formattingValueCache = create(); 5043 formattingValueCache.set(null, null); 5044 return (block) => { 5045 switch (block.constructor) { 5046 case GC: 5047 case Skip: 5048 return block; 5049 case Item: { 5050 const item = ( 5051 /** @type {Item} */ 5052 block 5053 ); 5054 const content = item.content; 5055 switch (content.constructor) { 5056 case ContentDeleted: 5057 break; 5058 case ContentType: { 5059 if (yxml) { 5060 const type = ( 5061 /** @type {ContentType} */ 5062 content.type 5063 ); 5064 if (type instanceof YXmlElement) { 5065 type.nodeName = setIfUndefined(nodeNameCache, type.nodeName, () => "node-" + i); 5066 } 5067 if (type instanceof YXmlHook) { 5068 type.hookName = setIfUndefined(nodeNameCache, type.hookName, () => "hook-" + i); 5069 } 5070 } 5071 break; 5072 } 5073 case ContentAny: { 5074 const c = ( 5075 /** @type {ContentAny} */ 5076 content 5077 ); 5078 c.arr = c.arr.map(() => i); 5079 break; 5080 } 5081 case ContentBinary: { 5082 const c = ( 5083 /** @type {ContentBinary} */ 5084 content 5085 ); 5086 c.content = new Uint8Array([i]); 5087 break; 5088 } 5089 case ContentDoc: { 5090 const c = ( 5091 /** @type {ContentDoc} */ 5092 content 5093 ); 5094 if (subdocs) { 5095 c.opts = {}; 5096 c.doc.guid = i + ""; 5097 } 5098 break; 5099 } 5100 case ContentEmbed: { 5101 const c = ( 5102 /** @type {ContentEmbed} */ 5103 content 5104 ); 5105 c.embed = {}; 5106 break; 5107 } 5108 case ContentFormat: { 5109 const c = ( 5110 /** @type {ContentFormat} */ 5111 content 5112 ); 5113 if (formatting) { 5114 c.key = setIfUndefined(formattingKeyCache, c.key, () => i + ""); 5115 c.value = setIfUndefined(formattingValueCache, c.value, () => ({ i })); 5116 } 5117 break; 5118 } 5119 case ContentJSON: { 5120 const c = ( 5121 /** @type {ContentJSON} */ 5122 content 5123 ); 5124 c.arr = c.arr.map(() => i); 5125 break; 5126 } 5127 case ContentString: { 5128 const c = ( 5129 /** @type {ContentString} */ 5130 content 5131 ); 5132 c.str = repeat(i % 10 + "", c.str.length); 5133 break; 5134 } 5135 default: 5136 unexpectedCase(); 5137 } 5138 if (item.parentSub) { 5139 item.parentSub = setIfUndefined(mapKeyCache, item.parentSub, () => i + ""); 5140 } 5141 i++; 5142 return block; 5143 } 5144 default: 5145 unexpectedCase(); 5146 } 5147 }; 5148 }; 5149 var obfuscateUpdate = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV1, UpdateEncoderV1); 5150 var obfuscateUpdateV2 = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV2, UpdateEncoderV2); 5151 var convertUpdateFormatV1ToV2 = (update) => convertUpdateFormat(update, id, UpdateDecoderV1, UpdateEncoderV2); 5152 var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); 5153 var errorComputeChanges = "You must not compute changes after the event-handler fired."; 5154 var YEvent = class { 5155 /** 5156 * @param {T} target The changed type. 5157 * @param {Transaction} transaction 5158 */ 5159 constructor(target, transaction) { 5160 this.target = target; 5161 this.currentTarget = target; 5162 this.transaction = transaction; 5163 this._changes = null; 5164 this._keys = null; 5165 this._delta = null; 5166 this._path = null; 5167 } 5168 /** 5169 * Computes the path from `y` to the changed type. 5170 * 5171 * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. 5172 * 5173 * The following property holds: 5174 * @example 5175 * let type = y 5176 * event.path.forEach(dir => { 5177 * type = type.get(dir) 5178 * }) 5179 * type === event.target // => true 5180 */ 5181 get path() { 5182 return this._path || (this._path = getPathTo(this.currentTarget, this.target)); 5183 } 5184 /** 5185 * Check if a struct is deleted by this event. 5186 * 5187 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5188 * 5189 * @param {AbstractStruct} struct 5190 * @return {boolean} 5191 */ 5192 deletes(struct) { 5193 return isDeleted(this.transaction.deleteSet, struct.id); 5194 } 5195 /** 5196 * @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>} 5197 */ 5198 get keys() { 5199 if (this._keys === null) { 5200 if (this.transaction.doc._transactionCleanups.length === 0) { 5201 throw create3(errorComputeChanges); 5202 } 5203 const keys2 = /* @__PURE__ */ new Map(); 5204 const target = this.target; 5205 const changed = ( 5206 /** @type Set<string|null> */ 5207 this.transaction.changed.get(target) 5208 ); 5209 changed.forEach((key) => { 5210 if (key !== null) { 5211 const item = ( 5212 /** @type {Item} */ 5213 target._map.get(key) 5214 ); 5215 let action; 5216 let oldValue; 5217 if (this.adds(item)) { 5218 let prev = item.left; 5219 while (prev !== null && this.adds(prev)) { 5220 prev = prev.left; 5221 } 5222 if (this.deletes(item)) { 5223 if (prev !== null && this.deletes(prev)) { 5224 action = "delete"; 5225 oldValue = last(prev.content.getContent()); 5226 } else { 5227 return; 5228 } 5229 } else { 5230 if (prev !== null && this.deletes(prev)) { 5231 action = "update"; 5232 oldValue = last(prev.content.getContent()); 5233 } else { 5234 action = "add"; 5235 oldValue = void 0; 5236 } 5237 } 5238 } else { 5239 if (this.deletes(item)) { 5240 action = "delete"; 5241 oldValue = last( 5242 /** @type {Item} */ 5243 item.content.getContent() 5244 ); 5245 } else { 5246 return; 5247 } 5248 } 5249 keys2.set(key, { action, oldValue }); 5250 } 5251 }); 5252 this._keys = keys2; 5253 } 5254 return this._keys; 5255 } 5256 /** 5257 * This is a computed property. Note that this can only be safely computed during the 5258 * event call. Computing this property after other changes happened might result in 5259 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5260 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5261 * 5262 * @type {Array<{insert?: string | Array<any> | object | AbstractType<any>, retain?: number, delete?: number, attributes?: Object<string, any>}>} 5263 */ 5264 get delta() { 5265 return this.changes.delta; 5266 } 5267 /** 5268 * Check if a struct is added by this event. 5269 * 5270 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5271 * 5272 * @param {AbstractStruct} struct 5273 * @return {boolean} 5274 */ 5275 adds(struct) { 5276 return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); 5277 } 5278 /** 5279 * This is a computed property. Note that this can only be safely computed during the 5280 * event call. Computing this property after other changes happened might result in 5281 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5282 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5283 * 5284 * @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}>}} 5285 */ 5286 get changes() { 5287 let changes = this._changes; 5288 if (changes === null) { 5289 if (this.transaction.doc._transactionCleanups.length === 0) { 5290 throw create3(errorComputeChanges); 5291 } 5292 const target = this.target; 5293 const added = create2(); 5294 const deleted = create2(); 5295 const delta = []; 5296 changes = { 5297 added, 5298 deleted, 5299 delta, 5300 keys: this.keys 5301 }; 5302 const changed = ( 5303 /** @type Set<string|null> */ 5304 this.transaction.changed.get(target) 5305 ); 5306 if (changed.has(null)) { 5307 let lastOp = null; 5308 const packOp = () => { 5309 if (lastOp) { 5310 delta.push(lastOp); 5311 } 5312 }; 5313 for (let item = target._start; item !== null; item = item.right) { 5314 if (item.deleted) { 5315 if (this.deletes(item) && !this.adds(item)) { 5316 if (lastOp === null || lastOp.delete === void 0) { 5317 packOp(); 5318 lastOp = { delete: 0 }; 5319 } 5320 lastOp.delete += item.length; 5321 deleted.add(item); 5322 } 5323 } else { 5324 if (this.adds(item)) { 5325 if (lastOp === null || lastOp.insert === void 0) { 5326 packOp(); 5327 lastOp = { insert: [] }; 5328 } 5329 lastOp.insert = lastOp.insert.concat(item.content.getContent()); 5330 added.add(item); 5331 } else { 5332 if (lastOp === null || lastOp.retain === void 0) { 5333 packOp(); 5334 lastOp = { retain: 0 }; 5335 } 5336 lastOp.retain += item.length; 5337 } 5338 } 5339 } 5340 if (lastOp !== null && lastOp.retain === void 0) { 5341 packOp(); 5342 } 5343 } 5344 this._changes = changes; 5345 } 5346 return ( 5347 /** @type {any} */ 5348 changes 5349 ); 5350 } 5351 }; 5352 var getPathTo = (parent, child) => { 5353 const path = []; 5354 while (child._item !== null && child !== parent) { 5355 if (child._item.parentSub !== null) { 5356 path.unshift(child._item.parentSub); 5357 } else { 5358 let i = 0; 5359 let c = ( 5360 /** @type {AbstractType<any>} */ 5361 child._item.parent._start 5362 ); 5363 while (c !== child._item && c !== null) { 5364 if (!c.deleted && c.countable) { 5365 i += c.length; 5366 } 5367 c = c.right; 5368 } 5369 path.unshift(i); 5370 } 5371 child = /** @type {AbstractType<any>} */ 5372 child._item.parent; 5373 } 5374 return path; 5375 }; 5376 var warnPrematureAccess = () => { 5377 warn("Invalid access: Add Yjs type to a document before reading data."); 5378 }; 5379 var maxSearchMarker = 80; 5380 var globalSearchMarkerTimestamp = 0; 5381 var ArraySearchMarker = class { 5382 /** 5383 * @param {Item} p 5384 * @param {number} index 5385 */ 5386 constructor(p, index) { 5387 p.marker = true; 5388 this.p = p; 5389 this.index = index; 5390 this.timestamp = globalSearchMarkerTimestamp++; 5391 } 5392 }; 5393 var refreshMarkerTimestamp = (marker) => { 5394 marker.timestamp = globalSearchMarkerTimestamp++; 5395 }; 5396 var overwriteMarker = (marker, p, index) => { 5397 marker.p.marker = false; 5398 marker.p = p; 5399 p.marker = true; 5400 marker.index = index; 5401 marker.timestamp = globalSearchMarkerTimestamp++; 5402 }; 5403 var markPosition = (searchMarker, p, index) => { 5404 if (searchMarker.length >= maxSearchMarker) { 5405 const marker = searchMarker.reduce((a, b) => a.timestamp < b.timestamp ? a : b); 5406 overwriteMarker(marker, p, index); 5407 return marker; 5408 } else { 5409 const pm = new ArraySearchMarker(p, index); 5410 searchMarker.push(pm); 5411 return pm; 5412 } 5413 }; 5414 var findMarker = (yarray, index) => { 5415 if (yarray._start === null || index === 0 || yarray._searchMarker === null) { 5416 return null; 5417 } 5418 const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b) => abs(index - a.index) < abs(index - b.index) ? a : b); 5419 let p = yarray._start; 5420 let pindex = 0; 5421 if (marker !== null) { 5422 p = marker.p; 5423 pindex = marker.index; 5424 refreshMarkerTimestamp(marker); 5425 } 5426 while (p.right !== null && pindex < index) { 5427 if (!p.deleted && p.countable) { 5428 if (index < pindex + p.length) { 5429 break; 5430 } 5431 pindex += p.length; 5432 } 5433 p = p.right; 5434 } 5435 while (p.left !== null && pindex > index) { 5436 p = p.left; 5437 if (!p.deleted && p.countable) { 5438 pindex -= p.length; 5439 } 5440 } 5441 while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { 5442 p = p.left; 5443 if (!p.deleted && p.countable) { 5444 pindex -= p.length; 5445 } 5446 } 5447 if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray<any>} */ 5448 p.parent.length / maxSearchMarker) { 5449 overwriteMarker(marker, p, pindex); 5450 return marker; 5451 } else { 5452 return markPosition(yarray._searchMarker, p, pindex); 5453 } 5454 }; 5455 var updateMarkerChanges = (searchMarker, index, len) => { 5456 for (let i = searchMarker.length - 1; i >= 0; i--) { 5457 const m = searchMarker[i]; 5458 if (len > 0) { 5459 let p = m.p; 5460 p.marker = false; 5461 while (p && (p.deleted || !p.countable)) { 5462 p = p.left; 5463 if (p && !p.deleted && p.countable) { 5464 m.index -= p.length; 5465 } 5466 } 5467 if (p === null || p.marker === true) { 5468 searchMarker.splice(i, 1); 5469 continue; 5470 } 5471 m.p = p; 5472 p.marker = true; 5473 } 5474 if (index < m.index || len > 0 && index === m.index) { 5475 m.index = max(index, m.index + len); 5476 } 5477 } 5478 }; 5479 var getTypeChildren = (t) => { 5480 t.doc ?? warnPrematureAccess(); 5481 let s = t._start; 5482 const arr = []; 5483 while (s) { 5484 arr.push(s); 5485 s = s.right; 5486 } 5487 return arr; 5488 }; 5489 var callTypeObservers = (type, transaction, event) => { 5490 const changedType = type; 5491 const changedParentTypes = transaction.changedParentTypes; 5492 while (true) { 5493 setIfUndefined(changedParentTypes, type, () => []).push(event); 5494 if (type._item === null) { 5495 break; 5496 } 5497 type = /** @type {AbstractType<any>} */ 5498 type._item.parent; 5499 } 5500 callEventHandlerListeners(changedType._eH, event, transaction); 5501 }; 5502 var AbstractType = class { 5503 constructor() { 5504 this._item = null; 5505 this._map = /* @__PURE__ */ new Map(); 5506 this._start = null; 5507 this.doc = null; 5508 this._length = 0; 5509 this._eH = createEventHandler(); 5510 this._dEH = createEventHandler(); 5511 this._searchMarker = null; 5512 } 5513 /** 5514 * @return {AbstractType<any>|null} 5515 */ 5516 get parent() { 5517 return this._item ? ( 5518 /** @type {AbstractType<any>} */ 5519 this._item.parent 5520 ) : null; 5521 } 5522 /** 5523 * Integrate this type into the Yjs instance. 5524 * 5525 * * Save this struct in the os 5526 * * This type is sent to other client 5527 * * Observer functions are fired 5528 * 5529 * @param {Doc} y The Yjs instance 5530 * @param {Item|null} item 5531 */ 5532 _integrate(y, item) { 5533 this.doc = y; 5534 this._item = item; 5535 } 5536 /** 5537 * @return {AbstractType<EventType>} 5538 */ 5539 _copy() { 5540 throw methodUnimplemented(); 5541 } 5542 /** 5543 * Makes a copy of this data type that can be included somewhere else. 5544 * 5545 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 5546 * 5547 * @return {AbstractType<EventType>} 5548 */ 5549 clone() { 5550 throw methodUnimplemented(); 5551 } 5552 /** 5553 * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder 5554 */ 5555 _write(_encoder) { 5556 } 5557 /** 5558 * The first non-deleted item 5559 */ 5560 get _first() { 5561 let n = this._start; 5562 while (n !== null && n.deleted) { 5563 n = n.right; 5564 } 5565 return n; 5566 } 5567 /** 5568 * Creates YEvent and calls all type observers. 5569 * Must be implemented by each type. 5570 * 5571 * @param {Transaction} transaction 5572 * @param {Set<null|string>} _parentSubs Keys changed on this type. `null` if list was modified. 5573 */ 5574 _callObserver(transaction, _parentSubs) { 5575 if (!transaction.local && this._searchMarker) { 5576 this._searchMarker.length = 0; 5577 } 5578 } 5579 /** 5580 * Observe all events that are created on this type. 5581 * 5582 * @param {function(EventType, Transaction):void} f Observer function 5583 */ 5584 observe(f) { 5585 addEventHandlerListener(this._eH, f); 5586 } 5587 /** 5588 * Observe all events that are created by this type and its children. 5589 * 5590 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 5591 */ 5592 observeDeep(f) { 5593 addEventHandlerListener(this._dEH, f); 5594 } 5595 /** 5596 * Unregister an observer function. 5597 * 5598 * @param {function(EventType,Transaction):void} f Observer function 5599 */ 5600 unobserve(f) { 5601 removeEventHandlerListener(this._eH, f); 5602 } 5603 /** 5604 * Unregister an observer function. 5605 * 5606 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 5607 */ 5608 unobserveDeep(f) { 5609 removeEventHandlerListener(this._dEH, f); 5610 } 5611 /** 5612 * @abstract 5613 * @return {any} 5614 */ 5615 toJSON() { 5616 } 5617 }; 5618 var typeListSlice = (type, start, end) => { 5619 type.doc ?? warnPrematureAccess(); 5620 if (start < 0) { 5621 start = type._length + start; 5622 } 5623 if (end < 0) { 5624 end = type._length + end; 5625 } 5626 let len = end - start; 5627 const cs = []; 5628 let n = type._start; 5629 while (n !== null && len > 0) { 5630 if (n.countable && !n.deleted) { 5631 const c = n.content.getContent(); 5632 if (c.length <= start) { 5633 start -= c.length; 5634 } else { 5635 for (let i = start; i < c.length && len > 0; i++) { 5636 cs.push(c[i]); 5637 len--; 5638 } 5639 start = 0; 5640 } 5641 } 5642 n = n.right; 5643 } 5644 return cs; 5645 }; 5646 var typeListToArray = (type) => { 5647 type.doc ?? warnPrematureAccess(); 5648 const cs = []; 5649 let n = type._start; 5650 while (n !== null) { 5651 if (n.countable && !n.deleted) { 5652 const c = n.content.getContent(); 5653 for (let i = 0; i < c.length; i++) { 5654 cs.push(c[i]); 5655 } 5656 } 5657 n = n.right; 5658 } 5659 return cs; 5660 }; 5661 var typeListToArraySnapshot = (type, snapshot2) => { 5662 const cs = []; 5663 let n = type._start; 5664 while (n !== null) { 5665 if (n.countable && isVisible(n, snapshot2)) { 5666 const c = n.content.getContent(); 5667 for (let i = 0; i < c.length; i++) { 5668 cs.push(c[i]); 5669 } 5670 } 5671 n = n.right; 5672 } 5673 return cs; 5674 }; 5675 var typeListForEach = (type, f) => { 5676 let index = 0; 5677 let n = type._start; 5678 type.doc ?? warnPrematureAccess(); 5679 while (n !== null) { 5680 if (n.countable && !n.deleted) { 5681 const c = n.content.getContent(); 5682 for (let i = 0; i < c.length; i++) { 5683 f(c[i], index++, type); 5684 } 5685 } 5686 n = n.right; 5687 } 5688 }; 5689 var typeListMap = (type, f) => { 5690 const result = []; 5691 typeListForEach(type, (c, i) => { 5692 result.push(f(c, i, type)); 5693 }); 5694 return result; 5695 }; 5696 var typeListCreateIterator = (type) => { 5697 let n = type._start; 5698 let currentContent = null; 5699 let currentContentIndex = 0; 5700 return { 5701 [Symbol.iterator]() { 5702 return this; 5703 }, 5704 next: () => { 5705 if (currentContent === null) { 5706 while (n !== null && n.deleted) { 5707 n = n.right; 5708 } 5709 if (n === null) { 5710 return { 5711 done: true, 5712 value: void 0 5713 }; 5714 } 5715 currentContent = n.content.getContent(); 5716 currentContentIndex = 0; 5717 n = n.right; 5718 } 5719 const value = currentContent[currentContentIndex++]; 5720 if (currentContent.length <= currentContentIndex) { 5721 currentContent = null; 5722 } 5723 return { 5724 done: false, 5725 value 5726 }; 5727 } 5728 }; 5729 }; 5730 var typeListGet = (type, index) => { 5731 type.doc ?? warnPrematureAccess(); 5732 const marker = findMarker(type, index); 5733 let n = type._start; 5734 if (marker !== null) { 5735 n = marker.p; 5736 index -= marker.index; 5737 } 5738 for (; n !== null; n = n.right) { 5739 if (!n.deleted && n.countable) { 5740 if (index < n.length) { 5741 return n.content.getContent()[index]; 5742 } 5743 index -= n.length; 5744 } 5745 } 5746 }; 5747 var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { 5748 let left = referenceItem; 5749 const doc2 = transaction.doc; 5750 const ownClientId = doc2.clientID; 5751 const store2 = doc2.store; 5752 const right = referenceItem === null ? parent._start : referenceItem.right; 5753 let jsonContent = []; 5754 const packJsonContent = () => { 5755 if (jsonContent.length > 0) { 5756 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); 5757 left.integrate(transaction, 0); 5758 jsonContent = []; 5759 } 5760 }; 5761 content.forEach((c) => { 5762 if (c === null) { 5763 jsonContent.push(c); 5764 } else { 5765 switch (c.constructor) { 5766 case Number: 5767 case Object: 5768 case Boolean: 5769 case Array: 5770 case String: 5771 jsonContent.push(c); 5772 break; 5773 default: 5774 packJsonContent(); 5775 switch (c.constructor) { 5776 case Uint8Array: 5777 case ArrayBuffer: 5778 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( 5779 /** @type {Uint8Array} */ 5780 c 5781 ))); 5782 left.integrate(transaction, 0); 5783 break; 5784 case Doc: 5785 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( 5786 /** @type {Doc} */ 5787 c 5788 )); 5789 left.integrate(transaction, 0); 5790 break; 5791 default: 5792 if (c instanceof AbstractType) { 5793 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); 5794 left.integrate(transaction, 0); 5795 } else { 5796 throw new Error("Unexpected content type in insert operation"); 5797 } 5798 } 5799 } 5800 } 5801 }); 5802 packJsonContent(); 5803 }; 5804 var lengthExceeded = () => create3("Length exceeded!"); 5805 var typeListInsertGenerics = (transaction, parent, index, content) => { 5806 if (index > parent._length) { 5807 throw lengthExceeded(); 5808 } 5809 if (index === 0) { 5810 if (parent._searchMarker) { 5811 updateMarkerChanges(parent._searchMarker, index, content.length); 5812 } 5813 return typeListInsertGenericsAfter(transaction, parent, null, content); 5814 } 5815 const startIndex = index; 5816 const marker = findMarker(parent, index); 5817 let n = parent._start; 5818 if (marker !== null) { 5819 n = marker.p; 5820 index -= marker.index; 5821 if (index === 0) { 5822 n = n.prev; 5823 index += n && n.countable && !n.deleted ? n.length : 0; 5824 } 5825 } 5826 for (; n !== null; n = n.right) { 5827 if (!n.deleted && n.countable) { 5828 if (index <= n.length) { 5829 if (index < n.length) { 5830 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5831 } 5832 break; 5833 } 5834 index -= n.length; 5835 } 5836 } 5837 if (parent._searchMarker) { 5838 updateMarkerChanges(parent._searchMarker, startIndex, content.length); 5839 } 5840 return typeListInsertGenericsAfter(transaction, parent, n, content); 5841 }; 5842 var typeListPushGenerics = (transaction, parent, content) => { 5843 const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); 5844 let n = marker.p; 5845 if (n) { 5846 while (n.right) { 5847 n = n.right; 5848 } 5849 } 5850 return typeListInsertGenericsAfter(transaction, parent, n, content); 5851 }; 5852 var typeListDelete = (transaction, parent, index, length3) => { 5853 if (length3 === 0) { 5854 return; 5855 } 5856 const startIndex = index; 5857 const startLength = length3; 5858 const marker = findMarker(parent, index); 5859 let n = parent._start; 5860 if (marker !== null) { 5861 n = marker.p; 5862 index -= marker.index; 5863 } 5864 for (; n !== null && index > 0; n = n.right) { 5865 if (!n.deleted && n.countable) { 5866 if (index < n.length) { 5867 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 5868 } 5869 index -= n.length; 5870 } 5871 } 5872 while (length3 > 0 && n !== null) { 5873 if (!n.deleted) { 5874 if (length3 < n.length) { 5875 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length3)); 5876 } 5877 n.delete(transaction); 5878 length3 -= n.length; 5879 } 5880 n = n.right; 5881 } 5882 if (length3 > 0) { 5883 throw lengthExceeded(); 5884 } 5885 if (parent._searchMarker) { 5886 updateMarkerChanges( 5887 parent._searchMarker, 5888 startIndex, 5889 -startLength + length3 5890 /* in case we remove the above exception */ 5891 ); 5892 } 5893 }; 5894 var typeMapDelete = (transaction, parent, key) => { 5895 const c = parent._map.get(key); 5896 if (c !== void 0) { 5897 c.delete(transaction); 5898 } 5899 }; 5900 var typeMapSet = (transaction, parent, key, value) => { 5901 const left = parent._map.get(key) || null; 5902 const doc2 = transaction.doc; 5903 const ownClientId = doc2.clientID; 5904 let content; 5905 if (value == null) { 5906 content = new ContentAny([value]); 5907 } else { 5908 switch (value.constructor) { 5909 case Number: 5910 case Object: 5911 case Boolean: 5912 case Array: 5913 case String: 5914 case Date: 5915 case BigInt: 5916 content = new ContentAny([value]); 5917 break; 5918 case Uint8Array: 5919 content = new ContentBinary( 5920 /** @type {Uint8Array} */ 5921 value 5922 ); 5923 break; 5924 case Doc: 5925 content = new ContentDoc( 5926 /** @type {Doc} */ 5927 value 5928 ); 5929 break; 5930 default: 5931 if (value instanceof AbstractType) { 5932 content = new ContentType(value); 5933 } else { 5934 throw new Error("Unexpected content type"); 5935 } 5936 } 5937 } 5938 new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); 5939 }; 5940 var typeMapGet = (parent, key) => { 5941 parent.doc ?? warnPrematureAccess(); 5942 const val = parent._map.get(key); 5943 return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; 5944 }; 5945 var typeMapGetAll = (parent) => { 5946 const res = {}; 5947 parent.doc ?? warnPrematureAccess(); 5948 parent._map.forEach((value, key) => { 5949 if (!value.deleted) { 5950 res[key] = value.content.getContent()[value.length - 1]; 5951 } 5952 }); 5953 return res; 5954 }; 5955 var typeMapHas = (parent, key) => { 5956 parent.doc ?? warnPrematureAccess(); 5957 const val = parent._map.get(key); 5958 return val !== void 0 && !val.deleted; 5959 }; 5960 var typeMapGetSnapshot = (parent, key, snapshot2) => { 5961 let v = parent._map.get(key) || null; 5962 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 5963 v = v.left; 5964 } 5965 return v !== null && isVisible(v, snapshot2) ? v.content.getContent()[v.length - 1] : void 0; 5966 }; 5967 var typeMapGetAllSnapshot = (parent, snapshot2) => { 5968 const res = {}; 5969 parent._map.forEach((value, key) => { 5970 let v = value; 5971 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 5972 v = v.left; 5973 } 5974 if (v !== null && isVisible(v, snapshot2)) { 5975 res[key] = v.content.getContent()[v.length - 1]; 5976 } 5977 }); 5978 return res; 5979 }; 5980 var createMapIterator = (type) => { 5981 type.doc ?? warnPrematureAccess(); 5982 return iteratorFilter( 5983 type._map.entries(), 5984 /** @param {any} entry */ 5985 (entry) => !entry[1].deleted 5986 ); 5987 }; 5988 var YArrayEvent = class extends YEvent { 5989 }; 5990 var YArray = class _YArray extends AbstractType { 5991 constructor() { 5992 super(); 5993 this._prelimContent = []; 5994 this._searchMarker = []; 5995 } 5996 /** 5997 * Construct a new YArray containing the specified items. 5998 * @template {Object<string,any>|Array<any>|number|null|string|Uint8Array} T 5999 * @param {Array<T>} items 6000 * @return {YArray<T>} 6001 */ 6002 static from(items2) { 6003 const a = new _YArray(); 6004 a.push(items2); 6005 return a; 6006 } 6007 /** 6008 * Integrate this type into the Yjs instance. 6009 * 6010 * * Save this struct in the os 6011 * * This type is sent to other client 6012 * * Observer functions are fired 6013 * 6014 * @param {Doc} y The Yjs instance 6015 * @param {Item} item 6016 */ 6017 _integrate(y, item) { 6018 super._integrate(y, item); 6019 this.insert( 6020 0, 6021 /** @type {Array<any>} */ 6022 this._prelimContent 6023 ); 6024 this._prelimContent = null; 6025 } 6026 /** 6027 * @return {YArray<T>} 6028 */ 6029 _copy() { 6030 return new _YArray(); 6031 } 6032 /** 6033 * Makes a copy of this data type that can be included somewhere else. 6034 * 6035 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6036 * 6037 * @return {YArray<T>} 6038 */ 6039 clone() { 6040 const arr = new _YArray(); 6041 arr.insert(0, this.toArray().map( 6042 (el) => el instanceof AbstractType ? ( 6043 /** @type {typeof el} */ 6044 el.clone() 6045 ) : el 6046 )); 6047 return arr; 6048 } 6049 get length() { 6050 this.doc ?? warnPrematureAccess(); 6051 return this._length; 6052 } 6053 /** 6054 * Creates YArrayEvent and calls observers. 6055 * 6056 * @param {Transaction} transaction 6057 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6058 */ 6059 _callObserver(transaction, parentSubs) { 6060 super._callObserver(transaction, parentSubs); 6061 callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); 6062 } 6063 /** 6064 * Inserts new content at an index. 6065 * 6066 * Important: This function expects an array of content. Not just a content 6067 * object. The reason for this "weirdness" is that inserting several elements 6068 * is very efficient when it is done as a single operation. 6069 * 6070 * @example 6071 * // Insert character 'a' at position 0 6072 * yarray.insert(0, ['a']) 6073 * // Insert numbers 1, 2 at position 1 6074 * yarray.insert(1, [1, 2]) 6075 * 6076 * @param {number} index The index to insert content at. 6077 * @param {Array<T>} content The array of content 6078 */ 6079 insert(index, content) { 6080 if (this.doc !== null) { 6081 transact(this.doc, (transaction) => { 6082 typeListInsertGenerics( 6083 transaction, 6084 this, 6085 index, 6086 /** @type {any} */ 6087 content 6088 ); 6089 }); 6090 } else { 6091 this._prelimContent.splice(index, 0, ...content); 6092 } 6093 } 6094 /** 6095 * Appends content to this YArray. 6096 * 6097 * @param {Array<T>} content Array of content to append. 6098 * 6099 * @todo Use the following implementation in all types. 6100 */ 6101 push(content) { 6102 if (this.doc !== null) { 6103 transact(this.doc, (transaction) => { 6104 typeListPushGenerics( 6105 transaction, 6106 this, 6107 /** @type {any} */ 6108 content 6109 ); 6110 }); 6111 } else { 6112 this._prelimContent.push(...content); 6113 } 6114 } 6115 /** 6116 * Prepends content to this YArray. 6117 * 6118 * @param {Array<T>} content Array of content to prepend. 6119 */ 6120 unshift(content) { 6121 this.insert(0, content); 6122 } 6123 /** 6124 * Deletes elements starting from an index. 6125 * 6126 * @param {number} index Index at which to start deleting elements 6127 * @param {number} length The number of elements to remove. Defaults to 1. 6128 */ 6129 delete(index, length3 = 1) { 6130 if (this.doc !== null) { 6131 transact(this.doc, (transaction) => { 6132 typeListDelete(transaction, this, index, length3); 6133 }); 6134 } else { 6135 this._prelimContent.splice(index, length3); 6136 } 6137 } 6138 /** 6139 * Returns the i-th element from a YArray. 6140 * 6141 * @param {number} index The index of the element to return from the YArray 6142 * @return {T} 6143 */ 6144 get(index) { 6145 return typeListGet(this, index); 6146 } 6147 /** 6148 * Transforms this YArray to a JavaScript Array. 6149 * 6150 * @return {Array<T>} 6151 */ 6152 toArray() { 6153 return typeListToArray(this); 6154 } 6155 /** 6156 * Returns a portion of this YArray into a JavaScript Array selected 6157 * from start to end (end not included). 6158 * 6159 * @param {number} [start] 6160 * @param {number} [end] 6161 * @return {Array<T>} 6162 */ 6163 slice(start = 0, end = this.length) { 6164 return typeListSlice(this, start, end); 6165 } 6166 /** 6167 * Transforms this Shared Type to a JSON object. 6168 * 6169 * @return {Array<any>} 6170 */ 6171 toJSON() { 6172 return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); 6173 } 6174 /** 6175 * Returns an Array with the result of calling a provided function on every 6176 * element of this YArray. 6177 * 6178 * @template M 6179 * @param {function(T,number,YArray<T>):M} f Function that produces an element of the new Array 6180 * @return {Array<M>} A new array with each element being the result of the 6181 * callback function 6182 */ 6183 map(f) { 6184 return typeListMap( 6185 this, 6186 /** @type {any} */ 6187 f 6188 ); 6189 } 6190 /** 6191 * Executes a provided function once on every element of this YArray. 6192 * 6193 * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray. 6194 */ 6195 forEach(f) { 6196 typeListForEach(this, f); 6197 } 6198 /** 6199 * @return {IterableIterator<T>} 6200 */ 6201 [Symbol.iterator]() { 6202 return typeListCreateIterator(this); 6203 } 6204 /** 6205 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6206 */ 6207 _write(encoder) { 6208 encoder.writeTypeRef(YArrayRefID); 6209 } 6210 }; 6211 var readYArray = (_decoder) => new YArray(); 6212 var YMapEvent = class extends YEvent { 6213 /** 6214 * @param {YMap<T>} ymap The YArray that changed. 6215 * @param {Transaction} transaction 6216 * @param {Set<any>} subs The keys that changed. 6217 */ 6218 constructor(ymap, transaction, subs) { 6219 super(ymap, transaction); 6220 this.keysChanged = subs; 6221 } 6222 }; 6223 var YMap = class _YMap extends AbstractType { 6224 /** 6225 * 6226 * @param {Iterable<readonly [string, any]>=} entries - an optional iterable to initialize the YMap 6227 */ 6228 constructor(entries) { 6229 super(); 6230 this._prelimContent = null; 6231 if (entries === void 0) { 6232 this._prelimContent = /* @__PURE__ */ new Map(); 6233 } else { 6234 this._prelimContent = new Map(entries); 6235 } 6236 } 6237 /** 6238 * Integrate this type into the Yjs instance. 6239 * 6240 * * Save this struct in the os 6241 * * This type is sent to other client 6242 * * Observer functions are fired 6243 * 6244 * @param {Doc} y The Yjs instance 6245 * @param {Item} item 6246 */ 6247 _integrate(y, item) { 6248 super._integrate(y, item); 6249 this._prelimContent.forEach((value, key) => { 6250 this.set(key, value); 6251 }); 6252 this._prelimContent = null; 6253 } 6254 /** 6255 * @return {YMap<MapType>} 6256 */ 6257 _copy() { 6258 return new _YMap(); 6259 } 6260 /** 6261 * Makes a copy of this data type that can be included somewhere else. 6262 * 6263 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6264 * 6265 * @return {YMap<MapType>} 6266 */ 6267 clone() { 6268 const map2 = new _YMap(); 6269 this.forEach((value, key) => { 6270 map2.set(key, value instanceof AbstractType ? ( 6271 /** @type {typeof value} */ 6272 value.clone() 6273 ) : value); 6274 }); 6275 return map2; 6276 } 6277 /** 6278 * Creates YMapEvent and calls observers. 6279 * 6280 * @param {Transaction} transaction 6281 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6282 */ 6283 _callObserver(transaction, parentSubs) { 6284 callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); 6285 } 6286 /** 6287 * Transforms this Shared Type to a JSON object. 6288 * 6289 * @return {Object<string,any>} 6290 */ 6291 toJSON() { 6292 this.doc ?? warnPrematureAccess(); 6293 const map2 = {}; 6294 this._map.forEach((item, key) => { 6295 if (!item.deleted) { 6296 const v = item.content.getContent()[item.length - 1]; 6297 map2[key] = v instanceof AbstractType ? v.toJSON() : v; 6298 } 6299 }); 6300 return map2; 6301 } 6302 /** 6303 * Returns the size of the YMap (count of key/value pairs) 6304 * 6305 * @return {number} 6306 */ 6307 get size() { 6308 return [...createMapIterator(this)].length; 6309 } 6310 /** 6311 * Returns the keys for each element in the YMap Type. 6312 * 6313 * @return {IterableIterator<string>} 6314 */ 6315 keys() { 6316 return iteratorMap( 6317 createMapIterator(this), 6318 /** @param {any} v */ 6319 (v) => v[0] 6320 ); 6321 } 6322 /** 6323 * Returns the values for each element in the YMap Type. 6324 * 6325 * @return {IterableIterator<MapType>} 6326 */ 6327 values() { 6328 return iteratorMap( 6329 createMapIterator(this), 6330 /** @param {any} v */ 6331 (v) => v[1].content.getContent()[v[1].length - 1] 6332 ); 6333 } 6334 /** 6335 * Returns an Iterator of [key, value] pairs 6336 * 6337 * @return {IterableIterator<[string, MapType]>} 6338 */ 6339 entries() { 6340 return iteratorMap( 6341 createMapIterator(this), 6342 /** @param {any} v */ 6343 (v) => ( 6344 /** @type {any} */ 6345 [v[0], v[1].content.getContent()[v[1].length - 1]] 6346 ) 6347 ); 6348 } 6349 /** 6350 * Executes a provided function on once on every key-value pair. 6351 * 6352 * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray. 6353 */ 6354 forEach(f) { 6355 this.doc ?? warnPrematureAccess(); 6356 this._map.forEach((item, key) => { 6357 if (!item.deleted) { 6358 f(item.content.getContent()[item.length - 1], key, this); 6359 } 6360 }); 6361 } 6362 /** 6363 * Returns an Iterator of [key, value] pairs 6364 * 6365 * @return {IterableIterator<[string, MapType]>} 6366 */ 6367 [Symbol.iterator]() { 6368 return this.entries(); 6369 } 6370 /** 6371 * Remove a specified element from this YMap. 6372 * 6373 * @param {string} key The key of the element to remove. 6374 */ 6375 delete(key) { 6376 if (this.doc !== null) { 6377 transact(this.doc, (transaction) => { 6378 typeMapDelete(transaction, this, key); 6379 }); 6380 } else { 6381 this._prelimContent.delete(key); 6382 } 6383 } 6384 /** 6385 * Adds or updates an element with a specified key and value. 6386 * @template {MapType} VAL 6387 * 6388 * @param {string} key The key of the element to add to this YMap 6389 * @param {VAL} value The value of the element to add 6390 * @return {VAL} 6391 */ 6392 set(key, value) { 6393 if (this.doc !== null) { 6394 transact(this.doc, (transaction) => { 6395 typeMapSet( 6396 transaction, 6397 this, 6398 key, 6399 /** @type {any} */ 6400 value 6401 ); 6402 }); 6403 } else { 6404 this._prelimContent.set(key, value); 6405 } 6406 return value; 6407 } 6408 /** 6409 * Returns a specified element from this YMap. 6410 * 6411 * @param {string} key 6412 * @return {MapType|undefined} 6413 */ 6414 get(key) { 6415 return ( 6416 /** @type {any} */ 6417 typeMapGet(this, key) 6418 ); 6419 } 6420 /** 6421 * Returns a boolean indicating whether the specified key exists or not. 6422 * 6423 * @param {string} key The key to test. 6424 * @return {boolean} 6425 */ 6426 has(key) { 6427 return typeMapHas(this, key); 6428 } 6429 /** 6430 * Removes all elements from this YMap. 6431 */ 6432 clear() { 6433 if (this.doc !== null) { 6434 transact(this.doc, (transaction) => { 6435 this.forEach(function(_value, key, map2) { 6436 typeMapDelete(transaction, map2, key); 6437 }); 6438 }); 6439 } else { 6440 this._prelimContent.clear(); 6441 } 6442 } 6443 /** 6444 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6445 */ 6446 _write(encoder) { 6447 encoder.writeTypeRef(YMapRefID); 6448 } 6449 }; 6450 var readYMap = (_decoder) => new YMap(); 6451 var equalAttrs = (a, b) => a === b || typeof a === "object" && typeof b === "object" && a && b && equalFlat(a, b); 6452 var ItemTextListPosition = class { 6453 /** 6454 * @param {Item|null} left 6455 * @param {Item|null} right 6456 * @param {number} index 6457 * @param {Map<string,any>} currentAttributes 6458 */ 6459 constructor(left, right, index, currentAttributes) { 6460 this.left = left; 6461 this.right = right; 6462 this.index = index; 6463 this.currentAttributes = currentAttributes; 6464 } 6465 /** 6466 * Only call this if you know that this.right is defined 6467 */ 6468 forward() { 6469 if (this.right === null) { 6470 unexpectedCase(); 6471 } 6472 switch (this.right.content.constructor) { 6473 case ContentFormat: 6474 if (!this.right.deleted) { 6475 updateCurrentAttributes( 6476 this.currentAttributes, 6477 /** @type {ContentFormat} */ 6478 this.right.content 6479 ); 6480 } 6481 break; 6482 default: 6483 if (!this.right.deleted) { 6484 this.index += this.right.length; 6485 } 6486 break; 6487 } 6488 this.left = this.right; 6489 this.right = this.right.right; 6490 } 6491 }; 6492 var findNextPosition = (transaction, pos, count) => { 6493 while (pos.right !== null && count > 0) { 6494 switch (pos.right.content.constructor) { 6495 case ContentFormat: 6496 if (!pos.right.deleted) { 6497 updateCurrentAttributes( 6498 pos.currentAttributes, 6499 /** @type {ContentFormat} */ 6500 pos.right.content 6501 ); 6502 } 6503 break; 6504 default: 6505 if (!pos.right.deleted) { 6506 if (count < pos.right.length) { 6507 getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); 6508 } 6509 pos.index += pos.right.length; 6510 count -= pos.right.length; 6511 } 6512 break; 6513 } 6514 pos.left = pos.right; 6515 pos.right = pos.right.right; 6516 } 6517 return pos; 6518 }; 6519 var findPosition = (transaction, parent, index, useSearchMarker) => { 6520 const currentAttributes = /* @__PURE__ */ new Map(); 6521 const marker = useSearchMarker ? findMarker(parent, index) : null; 6522 if (marker) { 6523 const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); 6524 return findNextPosition(transaction, pos, index - marker.index); 6525 } else { 6526 const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); 6527 return findNextPosition(transaction, pos, index); 6528 } 6529 }; 6530 var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { 6531 while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( 6532 negatedAttributes.get( 6533 /** @type {ContentFormat} */ 6534 currPos.right.content.key 6535 ), 6536 /** @type {ContentFormat} */ 6537 currPos.right.content.value 6538 ))) { 6539 if (!currPos.right.deleted) { 6540 negatedAttributes.delete( 6541 /** @type {ContentFormat} */ 6542 currPos.right.content.key 6543 ); 6544 } 6545 currPos.forward(); 6546 } 6547 const doc2 = transaction.doc; 6548 const ownClientId = doc2.clientID; 6549 negatedAttributes.forEach((val, key) => { 6550 const left = currPos.left; 6551 const right = currPos.right; 6552 const nextFormat = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 6553 nextFormat.integrate(transaction, 0); 6554 currPos.right = nextFormat; 6555 currPos.forward(); 6556 }); 6557 }; 6558 var updateCurrentAttributes = (currentAttributes, format) => { 6559 const { key, value } = format; 6560 if (value === null) { 6561 currentAttributes.delete(key); 6562 } else { 6563 currentAttributes.set(key, value); 6564 } 6565 }; 6566 var minimizeAttributeChanges = (currPos, attributes) => { 6567 while (true) { 6568 if (currPos.right === null) { 6569 break; 6570 } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( 6571 attributes[ 6572 /** @type {ContentFormat} */ 6573 currPos.right.content.key 6574 ] ?? null, 6575 /** @type {ContentFormat} */ 6576 currPos.right.content.value 6577 )) ; 6578 else { 6579 break; 6580 } 6581 currPos.forward(); 6582 } 6583 }; 6584 var insertAttributes = (transaction, parent, currPos, attributes) => { 6585 const doc2 = transaction.doc; 6586 const ownClientId = doc2.clientID; 6587 const negatedAttributes = /* @__PURE__ */ new Map(); 6588 for (const key in attributes) { 6589 const val = attributes[key]; 6590 const currentVal = currPos.currentAttributes.get(key) ?? null; 6591 if (!equalAttrs(currentVal, val)) { 6592 negatedAttributes.set(key, currentVal); 6593 const { left, right } = currPos; 6594 currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 6595 currPos.right.integrate(transaction, 0); 6596 currPos.forward(); 6597 } 6598 } 6599 return negatedAttributes; 6600 }; 6601 var insertText = (transaction, parent, currPos, text2, attributes) => { 6602 currPos.currentAttributes.forEach((_val, key) => { 6603 if (attributes[key] === void 0) { 6604 attributes[key] = null; 6605 } 6606 }); 6607 const doc2 = transaction.doc; 6608 const ownClientId = doc2.clientID; 6609 minimizeAttributeChanges(currPos, attributes); 6610 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 6611 const content = text2.constructor === String ? new ContentString( 6612 /** @type {string} */ 6613 text2 6614 ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); 6615 let { left, right, index } = currPos; 6616 if (parent._searchMarker) { 6617 updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); 6618 } 6619 right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); 6620 right.integrate(transaction, 0); 6621 currPos.right = right; 6622 currPos.index = index; 6623 currPos.forward(); 6624 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 6625 }; 6626 var formatText = (transaction, parent, currPos, length3, attributes) => { 6627 const doc2 = transaction.doc; 6628 const ownClientId = doc2.clientID; 6629 minimizeAttributeChanges(currPos, attributes); 6630 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 6631 iterationLoop: while (currPos.right !== null && (length3 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { 6632 if (!currPos.right.deleted) { 6633 switch (currPos.right.content.constructor) { 6634 case ContentFormat: { 6635 const { key, value } = ( 6636 /** @type {ContentFormat} */ 6637 currPos.right.content 6638 ); 6639 const attr = attributes[key]; 6640 if (attr !== void 0) { 6641 if (equalAttrs(attr, value)) { 6642 negatedAttributes.delete(key); 6643 } else { 6644 if (length3 === 0) { 6645 break iterationLoop; 6646 } 6647 negatedAttributes.set(key, value); 6648 } 6649 currPos.right.delete(transaction); 6650 } else { 6651 currPos.currentAttributes.set(key, value); 6652 } 6653 break; 6654 } 6655 default: 6656 if (length3 < currPos.right.length) { 6657 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length3)); 6658 } 6659 length3 -= currPos.right.length; 6660 break; 6661 } 6662 } 6663 currPos.forward(); 6664 } 6665 if (length3 > 0) { 6666 let newlines = ""; 6667 for (; length3 > 0; length3--) { 6668 newlines += "\n"; 6669 } 6670 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)); 6671 currPos.right.integrate(transaction, 0); 6672 currPos.forward(); 6673 } 6674 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 6675 }; 6676 var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { 6677 let end = start; 6678 const endFormats = create(); 6679 while (end && (!end.countable || end.deleted)) { 6680 if (!end.deleted && end.content.constructor === ContentFormat) { 6681 const cf = ( 6682 /** @type {ContentFormat} */ 6683 end.content 6684 ); 6685 endFormats.set(cf.key, cf); 6686 } 6687 end = end.right; 6688 } 6689 let cleanups = 0; 6690 let reachedCurr = false; 6691 while (start !== end) { 6692 if (curr === start) { 6693 reachedCurr = true; 6694 } 6695 if (!start.deleted) { 6696 const content = start.content; 6697 switch (content.constructor) { 6698 case ContentFormat: { 6699 const { key, value } = ( 6700 /** @type {ContentFormat} */ 6701 content 6702 ); 6703 const startAttrValue = startAttributes.get(key) ?? null; 6704 if (endFormats.get(key) !== content || startAttrValue === value) { 6705 start.delete(transaction); 6706 cleanups++; 6707 if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { 6708 if (startAttrValue === null) { 6709 currAttributes.delete(key); 6710 } else { 6711 currAttributes.set(key, startAttrValue); 6712 } 6713 } 6714 } 6715 if (!reachedCurr && !start.deleted) { 6716 updateCurrentAttributes( 6717 currAttributes, 6718 /** @type {ContentFormat} */ 6719 content 6720 ); 6721 } 6722 break; 6723 } 6724 } 6725 } 6726 start = /** @type {Item} */ 6727 start.right; 6728 } 6729 return cleanups; 6730 }; 6731 var cleanupContextlessFormattingGap = (transaction, item) => { 6732 while (item && item.right && (item.right.deleted || !item.right.countable)) { 6733 item = item.right; 6734 } 6735 const attrs = /* @__PURE__ */ new Set(); 6736 while (item && (item.deleted || !item.countable)) { 6737 if (!item.deleted && item.content.constructor === ContentFormat) { 6738 const key = ( 6739 /** @type {ContentFormat} */ 6740 item.content.key 6741 ); 6742 if (attrs.has(key)) { 6743 item.delete(transaction); 6744 } else { 6745 attrs.add(key); 6746 } 6747 } 6748 item = item.left; 6749 } 6750 }; 6751 var cleanupYTextFormatting = (type) => { 6752 let res = 0; 6753 transact( 6754 /** @type {Doc} */ 6755 type.doc, 6756 (transaction) => { 6757 let start = ( 6758 /** @type {Item} */ 6759 type._start 6760 ); 6761 let end = type._start; 6762 let startAttributes = create(); 6763 const currentAttributes = copy(startAttributes); 6764 while (end) { 6765 if (end.deleted === false) { 6766 switch (end.content.constructor) { 6767 case ContentFormat: 6768 updateCurrentAttributes( 6769 currentAttributes, 6770 /** @type {ContentFormat} */ 6771 end.content 6772 ); 6773 break; 6774 default: 6775 res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); 6776 startAttributes = copy(currentAttributes); 6777 start = end; 6778 break; 6779 } 6780 } 6781 end = end.right; 6782 } 6783 } 6784 ); 6785 return res; 6786 }; 6787 var cleanupYTextAfterTransaction = (transaction) => { 6788 const needFullCleanup = /* @__PURE__ */ new Set(); 6789 const doc2 = transaction.doc; 6790 for (const [client, afterClock] of transaction.afterState.entries()) { 6791 const clock = transaction.beforeState.get(client) || 0; 6792 if (afterClock === clock) { 6793 continue; 6794 } 6795 iterateStructs( 6796 transaction, 6797 /** @type {Array<Item|GC>} */ 6798 doc2.store.clients.get(client), 6799 clock, 6800 afterClock, 6801 (item) => { 6802 if (!item.deleted && /** @type {Item} */ 6803 item.content.constructor === ContentFormat && item.constructor !== GC) { 6804 needFullCleanup.add( 6805 /** @type {any} */ 6806 item.parent 6807 ); 6808 } 6809 } 6810 ); 6811 } 6812 transact(doc2, (t) => { 6813 iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { 6814 if (item instanceof GC || !/** @type {YText} */ 6815 item.parent._hasFormatting || needFullCleanup.has( 6816 /** @type {YText} */ 6817 item.parent 6818 )) { 6819 return; 6820 } 6821 const parent = ( 6822 /** @type {YText} */ 6823 item.parent 6824 ); 6825 if (item.content.constructor === ContentFormat) { 6826 needFullCleanup.add(parent); 6827 } else { 6828 cleanupContextlessFormattingGap(t, item); 6829 } 6830 }); 6831 for (const yText of needFullCleanup) { 6832 cleanupYTextFormatting(yText); 6833 } 6834 }); 6835 }; 6836 var deleteText = (transaction, currPos, length3) => { 6837 const startLength = length3; 6838 const startAttrs = copy(currPos.currentAttributes); 6839 const start = currPos.right; 6840 while (length3 > 0 && currPos.right !== null) { 6841 if (currPos.right.deleted === false) { 6842 switch (currPos.right.content.constructor) { 6843 case ContentType: 6844 case ContentEmbed: 6845 case ContentString: 6846 if (length3 < currPos.right.length) { 6847 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length3)); 6848 } 6849 length3 -= currPos.right.length; 6850 currPos.right.delete(transaction); 6851 break; 6852 } 6853 } 6854 currPos.forward(); 6855 } 6856 if (start) { 6857 cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); 6858 } 6859 const parent = ( 6860 /** @type {AbstractType<any>} */ 6861 /** @type {Item} */ 6862 (currPos.left || currPos.right).parent 6863 ); 6864 if (parent._searchMarker) { 6865 updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length3); 6866 } 6867 return currPos; 6868 }; 6869 var YTextEvent = class extends YEvent { 6870 /** 6871 * @param {YText} ytext 6872 * @param {Transaction} transaction 6873 * @param {Set<any>} subs The keys that changed 6874 */ 6875 constructor(ytext, transaction, subs) { 6876 super(ytext, transaction); 6877 this.childListChanged = false; 6878 this.keysChanged = /* @__PURE__ */ new Set(); 6879 subs.forEach((sub) => { 6880 if (sub === null) { 6881 this.childListChanged = true; 6882 } else { 6883 this.keysChanged.add(sub); 6884 } 6885 }); 6886 } 6887 /** 6888 * @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}>}} 6889 */ 6890 get changes() { 6891 if (this._changes === null) { 6892 const changes = { 6893 keys: this.keys, 6894 delta: this.delta, 6895 added: /* @__PURE__ */ new Set(), 6896 deleted: /* @__PURE__ */ new Set() 6897 }; 6898 this._changes = changes; 6899 } 6900 return ( 6901 /** @type {any} */ 6902 this._changes 6903 ); 6904 } 6905 /** 6906 * Compute the changes in the delta format. 6907 * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. 6908 * 6909 * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>} 6910 * 6911 * @public 6912 */ 6913 get delta() { 6914 if (this._delta === null) { 6915 const y = ( 6916 /** @type {Doc} */ 6917 this.target.doc 6918 ); 6919 const delta = []; 6920 transact(y, (transaction) => { 6921 const currentAttributes = /* @__PURE__ */ new Map(); 6922 const oldAttributes = /* @__PURE__ */ new Map(); 6923 let item = this.target._start; 6924 let action = null; 6925 const attributes = {}; 6926 let insert2 = ""; 6927 let retain = 0; 6928 let deleteLen = 0; 6929 const addOp = () => { 6930 if (action !== null) { 6931 let op = null; 6932 switch (action) { 6933 case "delete": 6934 if (deleteLen > 0) { 6935 op = { delete: deleteLen }; 6936 } 6937 deleteLen = 0; 6938 break; 6939 case "insert": 6940 if (typeof insert2 === "object" || insert2.length > 0) { 6941 op = { insert: insert2 }; 6942 if (currentAttributes.size > 0) { 6943 op.attributes = {}; 6944 currentAttributes.forEach((value, key) => { 6945 if (value !== null) { 6946 op.attributes[key] = value; 6947 } 6948 }); 6949 } 6950 } 6951 insert2 = ""; 6952 break; 6953 case "retain": 6954 if (retain > 0) { 6955 op = { retain }; 6956 if (!isEmpty(attributes)) { 6957 op.attributes = assign({}, attributes); 6958 } 6959 } 6960 retain = 0; 6961 break; 6962 } 6963 if (op) delta.push(op); 6964 action = null; 6965 } 6966 }; 6967 while (item !== null) { 6968 switch (item.content.constructor) { 6969 case ContentType: 6970 case ContentEmbed: 6971 if (this.adds(item)) { 6972 if (!this.deletes(item)) { 6973 addOp(); 6974 action = "insert"; 6975 insert2 = item.content.getContent()[0]; 6976 addOp(); 6977 } 6978 } else if (this.deletes(item)) { 6979 if (action !== "delete") { 6980 addOp(); 6981 action = "delete"; 6982 } 6983 deleteLen += 1; 6984 } else if (!item.deleted) { 6985 if (action !== "retain") { 6986 addOp(); 6987 action = "retain"; 6988 } 6989 retain += 1; 6990 } 6991 break; 6992 case ContentString: 6993 if (this.adds(item)) { 6994 if (!this.deletes(item)) { 6995 if (action !== "insert") { 6996 addOp(); 6997 action = "insert"; 6998 } 6999 insert2 += /** @type {ContentString} */ 7000 item.content.str; 7001 } 7002 } else if (this.deletes(item)) { 7003 if (action !== "delete") { 7004 addOp(); 7005 action = "delete"; 7006 } 7007 deleteLen += item.length; 7008 } else if (!item.deleted) { 7009 if (action !== "retain") { 7010 addOp(); 7011 action = "retain"; 7012 } 7013 retain += item.length; 7014 } 7015 break; 7016 case ContentFormat: { 7017 const { key, value } = ( 7018 /** @type {ContentFormat} */ 7019 item.content 7020 ); 7021 if (this.adds(item)) { 7022 if (!this.deletes(item)) { 7023 const curVal = currentAttributes.get(key) ?? null; 7024 if (!equalAttrs(curVal, value)) { 7025 if (action === "retain") { 7026 addOp(); 7027 } 7028 if (equalAttrs(value, oldAttributes.get(key) ?? null)) { 7029 delete attributes[key]; 7030 } else { 7031 attributes[key] = value; 7032 } 7033 } else if (value !== null) { 7034 item.delete(transaction); 7035 } 7036 } 7037 } else if (this.deletes(item)) { 7038 oldAttributes.set(key, value); 7039 const curVal = currentAttributes.get(key) ?? null; 7040 if (!equalAttrs(curVal, value)) { 7041 if (action === "retain") { 7042 addOp(); 7043 } 7044 attributes[key] = curVal; 7045 } 7046 } else if (!item.deleted) { 7047 oldAttributes.set(key, value); 7048 const attr = attributes[key]; 7049 if (attr !== void 0) { 7050 if (!equalAttrs(attr, value)) { 7051 if (action === "retain") { 7052 addOp(); 7053 } 7054 if (value === null) { 7055 delete attributes[key]; 7056 } else { 7057 attributes[key] = value; 7058 } 7059 } else if (attr !== null) { 7060 item.delete(transaction); 7061 } 7062 } 7063 } 7064 if (!item.deleted) { 7065 if (action === "insert") { 7066 addOp(); 7067 } 7068 updateCurrentAttributes( 7069 currentAttributes, 7070 /** @type {ContentFormat} */ 7071 item.content 7072 ); 7073 } 7074 break; 7075 } 7076 } 7077 item = item.right; 7078 } 7079 addOp(); 7080 while (delta.length > 0) { 7081 const lastOp = delta[delta.length - 1]; 7082 if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { 7083 delta.pop(); 7084 } else { 7085 break; 7086 } 7087 } 7088 }); 7089 this._delta = delta; 7090 } 7091 return ( 7092 /** @type {any} */ 7093 this._delta 7094 ); 7095 } 7096 }; 7097 var YText = class _YText extends AbstractType { 7098 /** 7099 * @param {String} [string] The initial value of the YText. 7100 */ 7101 constructor(string) { 7102 super(); 7103 this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; 7104 this._searchMarker = []; 7105 this._hasFormatting = false; 7106 } 7107 /** 7108 * Number of characters of this text type. 7109 * 7110 * @type {number} 7111 */ 7112 get length() { 7113 this.doc ?? warnPrematureAccess(); 7114 return this._length; 7115 } 7116 /** 7117 * @param {Doc} y 7118 * @param {Item} item 7119 */ 7120 _integrate(y, item) { 7121 super._integrate(y, item); 7122 try { 7123 this._pending.forEach((f) => f()); 7124 } catch (e) { 7125 console.error(e); 7126 } 7127 this._pending = null; 7128 } 7129 _copy() { 7130 return new _YText(); 7131 } 7132 /** 7133 * Makes a copy of this data type that can be included somewhere else. 7134 * 7135 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7136 * 7137 * @return {YText} 7138 */ 7139 clone() { 7140 const text2 = new _YText(); 7141 text2.applyDelta(this.toDelta()); 7142 return text2; 7143 } 7144 /** 7145 * Creates YTextEvent and calls observers. 7146 * 7147 * @param {Transaction} transaction 7148 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7149 */ 7150 _callObserver(transaction, parentSubs) { 7151 super._callObserver(transaction, parentSubs); 7152 const event = new YTextEvent(this, transaction, parentSubs); 7153 callTypeObservers(this, transaction, event); 7154 if (!transaction.local && this._hasFormatting) { 7155 transaction._needFormattingCleanup = true; 7156 } 7157 } 7158 /** 7159 * Returns the unformatted string representation of this YText type. 7160 * 7161 * @public 7162 */ 7163 toString() { 7164 this.doc ?? warnPrematureAccess(); 7165 let str = ""; 7166 let n = this._start; 7167 while (n !== null) { 7168 if (!n.deleted && n.countable && n.content.constructor === ContentString) { 7169 str += /** @type {ContentString} */ 7170 n.content.str; 7171 } 7172 n = n.right; 7173 } 7174 return str; 7175 } 7176 /** 7177 * Returns the unformatted string representation of this YText type. 7178 * 7179 * @return {string} 7180 * @public 7181 */ 7182 toJSON() { 7183 return this.toString(); 7184 } 7185 /** 7186 * Apply a {@link Delta} on this shared YText type. 7187 * 7188 * @param {Array<any>} delta The changes to apply on this element. 7189 * @param {object} opts 7190 * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. 7191 * 7192 * 7193 * @public 7194 */ 7195 applyDelta(delta, { sanitize = true } = {}) { 7196 if (this.doc !== null) { 7197 transact(this.doc, (transaction) => { 7198 const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); 7199 for (let i = 0; i < delta.length; i++) { 7200 const op = delta[i]; 7201 if (op.insert !== void 0) { 7202 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; 7203 if (typeof ins !== "string" || ins.length > 0) { 7204 insertText(transaction, this, currPos, ins, op.attributes || {}); 7205 } 7206 } else if (op.retain !== void 0) { 7207 formatText(transaction, this, currPos, op.retain, op.attributes || {}); 7208 } else if (op.delete !== void 0) { 7209 deleteText(transaction, currPos, op.delete); 7210 } 7211 } 7212 }); 7213 } else { 7214 this._pending.push(() => this.applyDelta(delta)); 7215 } 7216 } 7217 /** 7218 * Returns the Delta representation of this YText type. 7219 * 7220 * @param {Snapshot} [snapshot] 7221 * @param {Snapshot} [prevSnapshot] 7222 * @param {function('removed' | 'added', ID):any} [computeYChange] 7223 * @return {any} The Delta representation of this type. 7224 * 7225 * @public 7226 */ 7227 toDelta(snapshot2, prevSnapshot, computeYChange) { 7228 this.doc ?? warnPrematureAccess(); 7229 const ops = []; 7230 const currentAttributes = /* @__PURE__ */ new Map(); 7231 const doc2 = ( 7232 /** @type {Doc} */ 7233 this.doc 7234 ); 7235 let str = ""; 7236 let n = this._start; 7237 function packStr() { 7238 if (str.length > 0) { 7239 const attributes = {}; 7240 let addAttributes = false; 7241 currentAttributes.forEach((value, key) => { 7242 addAttributes = true; 7243 attributes[key] = value; 7244 }); 7245 const op = { insert: str }; 7246 if (addAttributes) { 7247 op.attributes = attributes; 7248 } 7249 ops.push(op); 7250 str = ""; 7251 } 7252 } 7253 const computeDelta = () => { 7254 while (n !== null) { 7255 if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { 7256 switch (n.content.constructor) { 7257 case ContentString: { 7258 const cur = currentAttributes.get("ychange"); 7259 if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { 7260 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { 7261 packStr(); 7262 currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); 7263 } 7264 } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { 7265 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { 7266 packStr(); 7267 currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); 7268 } 7269 } else if (cur !== void 0) { 7270 packStr(); 7271 currentAttributes.delete("ychange"); 7272 } 7273 str += /** @type {ContentString} */ 7274 n.content.str; 7275 break; 7276 } 7277 case ContentType: 7278 case ContentEmbed: { 7279 packStr(); 7280 const op = { 7281 insert: n.content.getContent()[0] 7282 }; 7283 if (currentAttributes.size > 0) { 7284 const attrs = ( 7285 /** @type {Object<string,any>} */ 7286 {} 7287 ); 7288 op.attributes = attrs; 7289 currentAttributes.forEach((value, key) => { 7290 attrs[key] = value; 7291 }); 7292 } 7293 ops.push(op); 7294 break; 7295 } 7296 case ContentFormat: 7297 if (isVisible(n, snapshot2)) { 7298 packStr(); 7299 updateCurrentAttributes( 7300 currentAttributes, 7301 /** @type {ContentFormat} */ 7302 n.content 7303 ); 7304 } 7305 break; 7306 } 7307 } 7308 n = n.right; 7309 } 7310 packStr(); 7311 }; 7312 if (snapshot2 || prevSnapshot) { 7313 transact(doc2, (transaction) => { 7314 if (snapshot2) { 7315 splitSnapshotAffectedStructs(transaction, snapshot2); 7316 } 7317 if (prevSnapshot) { 7318 splitSnapshotAffectedStructs(transaction, prevSnapshot); 7319 } 7320 computeDelta(); 7321 }, "cleanup"); 7322 } else { 7323 computeDelta(); 7324 } 7325 return ops; 7326 } 7327 /** 7328 * Insert text at a given index. 7329 * 7330 * @param {number} index The index at which to start inserting. 7331 * @param {String} text The text to insert at the specified position. 7332 * @param {TextAttributes} [attributes] Optionally define some formatting 7333 * information to apply on the inserted 7334 * Text. 7335 * @public 7336 */ 7337 insert(index, text2, attributes) { 7338 if (text2.length <= 0) { 7339 return; 7340 } 7341 const y = this.doc; 7342 if (y !== null) { 7343 transact(y, (transaction) => { 7344 const pos = findPosition(transaction, this, index, !attributes); 7345 if (!attributes) { 7346 attributes = {}; 7347 pos.currentAttributes.forEach((v, k) => { 7348 attributes[k] = v; 7349 }); 7350 } 7351 insertText(transaction, this, pos, text2, attributes); 7352 }); 7353 } else { 7354 this._pending.push(() => this.insert(index, text2, attributes)); 7355 } 7356 } 7357 /** 7358 * Inserts an embed at a index. 7359 * 7360 * @param {number} index The index to insert the embed at. 7361 * @param {Object | AbstractType<any>} embed The Object that represents the embed. 7362 * @param {TextAttributes} [attributes] Attribute information to apply on the 7363 * embed 7364 * 7365 * @public 7366 */ 7367 insertEmbed(index, embed, attributes) { 7368 const y = this.doc; 7369 if (y !== null) { 7370 transact(y, (transaction) => { 7371 const pos = findPosition(transaction, this, index, !attributes); 7372 insertText(transaction, this, pos, embed, attributes || {}); 7373 }); 7374 } else { 7375 this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); 7376 } 7377 } 7378 /** 7379 * Deletes text starting from an index. 7380 * 7381 * @param {number} index Index at which to start deleting. 7382 * @param {number} length The number of characters to remove. Defaults to 1. 7383 * 7384 * @public 7385 */ 7386 delete(index, length3) { 7387 if (length3 === 0) { 7388 return; 7389 } 7390 const y = this.doc; 7391 if (y !== null) { 7392 transact(y, (transaction) => { 7393 deleteText(transaction, findPosition(transaction, this, index, true), length3); 7394 }); 7395 } else { 7396 this._pending.push(() => this.delete(index, length3)); 7397 } 7398 } 7399 /** 7400 * Assigns properties to a range of text. 7401 * 7402 * @param {number} index The position where to start formatting. 7403 * @param {number} length The amount of characters to assign properties to. 7404 * @param {TextAttributes} attributes Attribute information to apply on the 7405 * text. 7406 * 7407 * @public 7408 */ 7409 format(index, length3, attributes) { 7410 if (length3 === 0) { 7411 return; 7412 } 7413 const y = this.doc; 7414 if (y !== null) { 7415 transact(y, (transaction) => { 7416 const pos = findPosition(transaction, this, index, false); 7417 if (pos.right === null) { 7418 return; 7419 } 7420 formatText(transaction, this, pos, length3, attributes); 7421 }); 7422 } else { 7423 this._pending.push(() => this.format(index, length3, attributes)); 7424 } 7425 } 7426 /** 7427 * Removes an attribute. 7428 * 7429 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7430 * 7431 * @param {String} attributeName The attribute name that is to be removed. 7432 * 7433 * @public 7434 */ 7435 removeAttribute(attributeName) { 7436 if (this.doc !== null) { 7437 transact(this.doc, (transaction) => { 7438 typeMapDelete(transaction, this, attributeName); 7439 }); 7440 } else { 7441 this._pending.push(() => this.removeAttribute(attributeName)); 7442 } 7443 } 7444 /** 7445 * Sets or updates an attribute. 7446 * 7447 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7448 * 7449 * @param {String} attributeName The attribute name that is to be set. 7450 * @param {any} attributeValue The attribute value that is to be set. 7451 * 7452 * @public 7453 */ 7454 setAttribute(attributeName, attributeValue) { 7455 if (this.doc !== null) { 7456 transact(this.doc, (transaction) => { 7457 typeMapSet(transaction, this, attributeName, attributeValue); 7458 }); 7459 } else { 7460 this._pending.push(() => this.setAttribute(attributeName, attributeValue)); 7461 } 7462 } 7463 /** 7464 * Returns an attribute value that belongs to the attribute name. 7465 * 7466 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7467 * 7468 * @param {String} attributeName The attribute name that identifies the 7469 * queried value. 7470 * @return {any} The queried attribute value. 7471 * 7472 * @public 7473 */ 7474 getAttribute(attributeName) { 7475 return ( 7476 /** @type {any} */ 7477 typeMapGet(this, attributeName) 7478 ); 7479 } 7480 /** 7481 * Returns all attribute name/value pairs in a JSON Object. 7482 * 7483 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 7484 * 7485 * @return {Object<string, any>} A JSON Object that describes the attributes. 7486 * 7487 * @public 7488 */ 7489 getAttributes() { 7490 return typeMapGetAll(this); 7491 } 7492 /** 7493 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7494 */ 7495 _write(encoder) { 7496 encoder.writeTypeRef(YTextRefID); 7497 } 7498 }; 7499 var readYText = (_decoder) => new YText(); 7500 var YXmlTreeWalker = class { 7501 /** 7502 * @param {YXmlFragment | YXmlElement} root 7503 * @param {function(AbstractType<any>):boolean} [f] 7504 */ 7505 constructor(root, f = () => true) { 7506 this._filter = f; 7507 this._root = root; 7508 this._currentNode = /** @type {Item} */ 7509 root._start; 7510 this._firstCall = true; 7511 root.doc ?? warnPrematureAccess(); 7512 } 7513 [Symbol.iterator]() { 7514 return this; 7515 } 7516 /** 7517 * Get the next node. 7518 * 7519 * @return {IteratorResult<YXmlElement|YXmlText|YXmlHook>} The next node. 7520 * 7521 * @public 7522 */ 7523 next() { 7524 let n = this._currentNode; 7525 let type = n && n.content && /** @type {any} */ 7526 n.content.type; 7527 if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { 7528 do { 7529 type = /** @type {any} */ 7530 n.content.type; 7531 if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { 7532 n = type._start; 7533 } else { 7534 while (n !== null) { 7535 const nxt = n.next; 7536 if (nxt !== null) { 7537 n = nxt; 7538 break; 7539 } else if (n.parent === this._root) { 7540 n = null; 7541 } else { 7542 n = /** @type {AbstractType<any>} */ 7543 n.parent._item; 7544 } 7545 } 7546 } 7547 } while (n !== null && (n.deleted || !this._filter( 7548 /** @type {ContentType} */ 7549 n.content.type 7550 ))); 7551 } 7552 this._firstCall = false; 7553 if (n === null) { 7554 return { value: void 0, done: true }; 7555 } 7556 this._currentNode = n; 7557 return { value: ( 7558 /** @type {any} */ 7559 n.content.type 7560 ), done: false }; 7561 } 7562 }; 7563 var YXmlFragment = class _YXmlFragment extends AbstractType { 7564 constructor() { 7565 super(); 7566 this._prelimContent = []; 7567 } 7568 /** 7569 * @type {YXmlElement|YXmlText|null} 7570 */ 7571 get firstChild() { 7572 const first = this._first; 7573 return first ? first.content.getContent()[0] : null; 7574 } 7575 /** 7576 * Integrate this type into the Yjs instance. 7577 * 7578 * * Save this struct in the os 7579 * * This type is sent to other client 7580 * * Observer functions are fired 7581 * 7582 * @param {Doc} y The Yjs instance 7583 * @param {Item} item 7584 */ 7585 _integrate(y, item) { 7586 super._integrate(y, item); 7587 this.insert( 7588 0, 7589 /** @type {Array<any>} */ 7590 this._prelimContent 7591 ); 7592 this._prelimContent = null; 7593 } 7594 _copy() { 7595 return new _YXmlFragment(); 7596 } 7597 /** 7598 * Makes a copy of this data type that can be included somewhere else. 7599 * 7600 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7601 * 7602 * @return {YXmlFragment} 7603 */ 7604 clone() { 7605 const el = new _YXmlFragment(); 7606 el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); 7607 return el; 7608 } 7609 get length() { 7610 this.doc ?? warnPrematureAccess(); 7611 return this._prelimContent === null ? this._length : this._prelimContent.length; 7612 } 7613 /** 7614 * Create a subtree of childNodes. 7615 * 7616 * @example 7617 * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') 7618 * for (let node in walker) { 7619 * // `node` is a div node 7620 * nop(node) 7621 * } 7622 * 7623 * @param {function(AbstractType<any>):boolean} filter Function that is called on each child element and 7624 * returns a Boolean indicating whether the child 7625 * is to be included in the subtree. 7626 * @return {YXmlTreeWalker} A subtree and a position within it. 7627 * 7628 * @public 7629 */ 7630 createTreeWalker(filter) { 7631 return new YXmlTreeWalker(this, filter); 7632 } 7633 /** 7634 * Returns the first YXmlElement that matches the query. 7635 * Similar to DOM's {@link querySelector}. 7636 * 7637 * Query support: 7638 * - tagname 7639 * TODO: 7640 * - id 7641 * - attribute 7642 * 7643 * @param {CSS_Selector} query The query on the children. 7644 * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. 7645 * 7646 * @public 7647 */ 7648 querySelector(query) { 7649 query = query.toUpperCase(); 7650 const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); 7651 const next = iterator.next(); 7652 if (next.done) { 7653 return null; 7654 } else { 7655 return next.value; 7656 } 7657 } 7658 /** 7659 * Returns all YXmlElements that match the query. 7660 * Similar to Dom's {@link querySelectorAll}. 7661 * 7662 * @todo Does not yet support all queries. Currently only query by tagName. 7663 * 7664 * @param {CSS_Selector} query The query on the children 7665 * @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query. 7666 * 7667 * @public 7668 */ 7669 querySelectorAll(query) { 7670 query = query.toUpperCase(); 7671 return from(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); 7672 } 7673 /** 7674 * Creates YXmlEvent and calls observers. 7675 * 7676 * @param {Transaction} transaction 7677 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7678 */ 7679 _callObserver(transaction, parentSubs) { 7680 callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); 7681 } 7682 /** 7683 * Get the string representation of all the children of this YXmlFragment. 7684 * 7685 * @return {string} The string representation of all children. 7686 */ 7687 toString() { 7688 return typeListMap(this, (xml) => xml.toString()).join(""); 7689 } 7690 /** 7691 * @return {string} 7692 */ 7693 toJSON() { 7694 return this.toString(); 7695 } 7696 /** 7697 * Creates a Dom Element that mirrors this YXmlElement. 7698 * 7699 * @param {Document} [_document=document] The document object (you must define 7700 * this when calling this method in 7701 * nodejs) 7702 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 7703 * are presented in the DOM 7704 * @param {any} [binding] You should not set this property. This is 7705 * used if DomBinding wants to create a 7706 * association to the created DOM type. 7707 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 7708 * 7709 * @public 7710 */ 7711 toDOM(_document = document, hooks = {}, binding) { 7712 const fragment = _document.createDocumentFragment(); 7713 if (binding !== void 0) { 7714 binding._createAssociation(fragment, this); 7715 } 7716 typeListForEach(this, (xmlType) => { 7717 fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); 7718 }); 7719 return fragment; 7720 } 7721 /** 7722 * Inserts new content at an index. 7723 * 7724 * @example 7725 * // Insert character 'a' at position 0 7726 * xml.insert(0, [new Y.XmlText('text')]) 7727 * 7728 * @param {number} index The index to insert content at 7729 * @param {Array<YXmlElement|YXmlText>} content The array of content 7730 */ 7731 insert(index, content) { 7732 if (this.doc !== null) { 7733 transact(this.doc, (transaction) => { 7734 typeListInsertGenerics(transaction, this, index, content); 7735 }); 7736 } else { 7737 this._prelimContent.splice(index, 0, ...content); 7738 } 7739 } 7740 /** 7741 * Inserts new content at an index. 7742 * 7743 * @example 7744 * // Insert character 'a' at position 0 7745 * xml.insert(0, [new Y.XmlText('text')]) 7746 * 7747 * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at 7748 * @param {Array<YXmlElement|YXmlText>} content The array of content 7749 */ 7750 insertAfter(ref, content) { 7751 if (this.doc !== null) { 7752 transact(this.doc, (transaction) => { 7753 const refItem = ref && ref instanceof AbstractType ? ref._item : ref; 7754 typeListInsertGenericsAfter(transaction, this, refItem, content); 7755 }); 7756 } else { 7757 const pc = ( 7758 /** @type {Array<any>} */ 7759 this._prelimContent 7760 ); 7761 const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; 7762 if (index === 0 && ref !== null) { 7763 throw create3("Reference item not found"); 7764 } 7765 pc.splice(index, 0, ...content); 7766 } 7767 } 7768 /** 7769 * Deletes elements starting from an index. 7770 * 7771 * @param {number} index Index at which to start deleting elements 7772 * @param {number} [length=1] The number of elements to remove. Defaults to 1. 7773 */ 7774 delete(index, length3 = 1) { 7775 if (this.doc !== null) { 7776 transact(this.doc, (transaction) => { 7777 typeListDelete(transaction, this, index, length3); 7778 }); 7779 } else { 7780 this._prelimContent.splice(index, length3); 7781 } 7782 } 7783 /** 7784 * Transforms this YArray to a JavaScript Array. 7785 * 7786 * @return {Array<YXmlElement|YXmlText|YXmlHook>} 7787 */ 7788 toArray() { 7789 return typeListToArray(this); 7790 } 7791 /** 7792 * Appends content to this YArray. 7793 * 7794 * @param {Array<YXmlElement|YXmlText>} content Array of content to append. 7795 */ 7796 push(content) { 7797 this.insert(this.length, content); 7798 } 7799 /** 7800 * Prepends content to this YArray. 7801 * 7802 * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend. 7803 */ 7804 unshift(content) { 7805 this.insert(0, content); 7806 } 7807 /** 7808 * Returns the i-th element from a YArray. 7809 * 7810 * @param {number} index The index of the element to return from the YArray 7811 * @return {YXmlElement|YXmlText} 7812 */ 7813 get(index) { 7814 return typeListGet(this, index); 7815 } 7816 /** 7817 * Returns a portion of this YXmlFragment into a JavaScript Array selected 7818 * from start to end (end not included). 7819 * 7820 * @param {number} [start] 7821 * @param {number} [end] 7822 * @return {Array<YXmlElement|YXmlText>} 7823 */ 7824 slice(start = 0, end = this.length) { 7825 return typeListSlice(this, start, end); 7826 } 7827 /** 7828 * Executes a provided function on once on every child element. 7829 * 7830 * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. 7831 */ 7832 forEach(f) { 7833 typeListForEach(this, f); 7834 } 7835 /** 7836 * Transform the properties of this type to binary and write it to an 7837 * BinaryEncoder. 7838 * 7839 * This is called when this Item is sent to a remote peer. 7840 * 7841 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 7842 */ 7843 _write(encoder) { 7844 encoder.writeTypeRef(YXmlFragmentRefID); 7845 } 7846 }; 7847 var readYXmlFragment = (_decoder) => new YXmlFragment(); 7848 var YXmlElement = class _YXmlElement extends YXmlFragment { 7849 constructor(nodeName = "UNDEFINED") { 7850 super(); 7851 this.nodeName = nodeName; 7852 this._prelimAttrs = /* @__PURE__ */ new Map(); 7853 } 7854 /** 7855 * @type {YXmlElement|YXmlText|null} 7856 */ 7857 get nextSibling() { 7858 const n = this._item ? this._item.next : null; 7859 return n ? ( 7860 /** @type {YXmlElement|YXmlText} */ 7861 /** @type {ContentType} */ 7862 n.content.type 7863 ) : null; 7864 } 7865 /** 7866 * @type {YXmlElement|YXmlText|null} 7867 */ 7868 get prevSibling() { 7869 const n = this._item ? this._item.prev : null; 7870 return n ? ( 7871 /** @type {YXmlElement|YXmlText} */ 7872 /** @type {ContentType} */ 7873 n.content.type 7874 ) : null; 7875 } 7876 /** 7877 * Integrate this type into the Yjs instance. 7878 * 7879 * * Save this struct in the os 7880 * * This type is sent to other client 7881 * * Observer functions are fired 7882 * 7883 * @param {Doc} y The Yjs instance 7884 * @param {Item} item 7885 */ 7886 _integrate(y, item) { 7887 super._integrate(y, item); 7888 /** @type {Map<string, any>} */ 7889 this._prelimAttrs.forEach((value, key) => { 7890 this.setAttribute(key, value); 7891 }); 7892 this._prelimAttrs = null; 7893 } 7894 /** 7895 * Creates an Item with the same effect as this Item (without position effect) 7896 * 7897 * @return {YXmlElement} 7898 */ 7899 _copy() { 7900 return new _YXmlElement(this.nodeName); 7901 } 7902 /** 7903 * Makes a copy of this data type that can be included somewhere else. 7904 * 7905 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7906 * 7907 * @return {YXmlElement<KV>} 7908 */ 7909 clone() { 7910 const el = new _YXmlElement(this.nodeName); 7911 const attrs = this.getAttributes(); 7912 forEach(attrs, (value, key) => { 7913 el.setAttribute( 7914 key, 7915 /** @type {any} */ 7916 value 7917 ); 7918 }); 7919 el.insert(0, this.toArray().map((v) => v instanceof AbstractType ? v.clone() : v)); 7920 return el; 7921 } 7922 /** 7923 * Returns the XML serialization of this YXmlElement. 7924 * The attributes are ordered by attribute-name, so you can easily use this 7925 * method to compare YXmlElements 7926 * 7927 * @return {string} The string representation of this type. 7928 * 7929 * @public 7930 */ 7931 toString() { 7932 const attrs = this.getAttributes(); 7933 const stringBuilder = []; 7934 const keys2 = []; 7935 for (const key in attrs) { 7936 keys2.push(key); 7937 } 7938 keys2.sort(); 7939 const keysLen = keys2.length; 7940 for (let i = 0; i < keysLen; i++) { 7941 const key = keys2[i]; 7942 stringBuilder.push(key + '="' + attrs[key] + '"'); 7943 } 7944 const nodeName = this.nodeName.toLocaleLowerCase(); 7945 const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; 7946 return `<$nodeName}$attrsString}>$super.toString()}</$nodeName}>`; 7947 } 7948 /** 7949 * Removes an attribute from this YXmlElement. 7950 * 7951 * @param {string} attributeName The attribute name that is to be removed. 7952 * 7953 * @public 7954 */ 7955 removeAttribute(attributeName) { 7956 if (this.doc !== null) { 7957 transact(this.doc, (transaction) => { 7958 typeMapDelete(transaction, this, attributeName); 7959 }); 7960 } else { 7961 this._prelimAttrs.delete(attributeName); 7962 } 7963 } 7964 /** 7965 * Sets or updates an attribute. 7966 * 7967 * @template {keyof KV & string} KEY 7968 * 7969 * @param {KEY} attributeName The attribute name that is to be set. 7970 * @param {KV[KEY]} attributeValue The attribute value that is to be set. 7971 * 7972 * @public 7973 */ 7974 setAttribute(attributeName, attributeValue) { 7975 if (this.doc !== null) { 7976 transact(this.doc, (transaction) => { 7977 typeMapSet(transaction, this, attributeName, attributeValue); 7978 }); 7979 } else { 7980 this._prelimAttrs.set(attributeName, attributeValue); 7981 } 7982 } 7983 /** 7984 * Returns an attribute value that belongs to the attribute name. 7985 * 7986 * @template {keyof KV & string} KEY 7987 * 7988 * @param {KEY} attributeName The attribute name that identifies the 7989 * queried value. 7990 * @return {KV[KEY]|undefined} The queried attribute value. 7991 * 7992 * @public 7993 */ 7994 getAttribute(attributeName) { 7995 return ( 7996 /** @type {any} */ 7997 typeMapGet(this, attributeName) 7998 ); 7999 } 8000 /** 8001 * Returns whether an attribute exists 8002 * 8003 * @param {string} attributeName The attribute name to check for existence. 8004 * @return {boolean} whether the attribute exists. 8005 * 8006 * @public 8007 */ 8008 hasAttribute(attributeName) { 8009 return ( 8010 /** @type {any} */ 8011 typeMapHas(this, attributeName) 8012 ); 8013 } 8014 /** 8015 * Returns all attribute name/value pairs in a JSON Object. 8016 * 8017 * @param {Snapshot} [snapshot] 8018 * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes. 8019 * 8020 * @public 8021 */ 8022 getAttributes(snapshot2) { 8023 return ( 8024 /** @type {any} */ 8025 snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) 8026 ); 8027 } 8028 /** 8029 * Creates a Dom Element that mirrors this YXmlElement. 8030 * 8031 * @param {Document} [_document=document] The document object (you must define 8032 * this when calling this method in 8033 * nodejs) 8034 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 8035 * are presented in the DOM 8036 * @param {any} [binding] You should not set this property. This is 8037 * used if DomBinding wants to create a 8038 * association to the created DOM type. 8039 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8040 * 8041 * @public 8042 */ 8043 toDOM(_document = document, hooks = {}, binding) { 8044 const dom = _document.createElement(this.nodeName); 8045 const attrs = this.getAttributes(); 8046 for (const key in attrs) { 8047 const value = attrs[key]; 8048 if (typeof value === "string") { 8049 dom.setAttribute(key, value); 8050 } 8051 } 8052 typeListForEach(this, (yxml) => { 8053 dom.appendChild(yxml.toDOM(_document, hooks, binding)); 8054 }); 8055 if (binding !== void 0) { 8056 binding._createAssociation(dom, this); 8057 } 8058 return dom; 8059 } 8060 /** 8061 * Transform the properties of this type to binary and write it to an 8062 * BinaryEncoder. 8063 * 8064 * This is called when this Item is sent to a remote peer. 8065 * 8066 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8067 */ 8068 _write(encoder) { 8069 encoder.writeTypeRef(YXmlElementRefID); 8070 encoder.writeKey(this.nodeName); 8071 } 8072 }; 8073 var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); 8074 var YXmlEvent = class extends YEvent { 8075 /** 8076 * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. 8077 * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the 8078 * child list changed. 8079 * @param {Transaction} transaction The transaction instance with which the 8080 * change was created. 8081 */ 8082 constructor(target, subs, transaction) { 8083 super(target, transaction); 8084 this.childListChanged = false; 8085 this.attributesChanged = /* @__PURE__ */ new Set(); 8086 subs.forEach((sub) => { 8087 if (sub === null) { 8088 this.childListChanged = true; 8089 } else { 8090 this.attributesChanged.add(sub); 8091 } 8092 }); 8093 } 8094 }; 8095 var YXmlHook = class _YXmlHook extends YMap { 8096 /** 8097 * @param {string} hookName nodeName of the Dom Node. 8098 */ 8099 constructor(hookName) { 8100 super(); 8101 this.hookName = hookName; 8102 } 8103 /** 8104 * Creates an Item with the same effect as this Item (without position effect) 8105 */ 8106 _copy() { 8107 return new _YXmlHook(this.hookName); 8108 } 8109 /** 8110 * Makes a copy of this data type that can be included somewhere else. 8111 * 8112 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8113 * 8114 * @return {YXmlHook} 8115 */ 8116 clone() { 8117 const el = new _YXmlHook(this.hookName); 8118 this.forEach((value, key) => { 8119 el.set(key, value); 8120 }); 8121 return el; 8122 } 8123 /** 8124 * Creates a Dom Element that mirrors this YXmlElement. 8125 * 8126 * @param {Document} [_document=document] The document object (you must define 8127 * this when calling this method in 8128 * nodejs) 8129 * @param {Object.<string, any>} [hooks] Optional property to customize how hooks 8130 * are presented in the DOM 8131 * @param {any} [binding] You should not set this property. This is 8132 * used if DomBinding wants to create a 8133 * association to the created DOM type 8134 * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8135 * 8136 * @public 8137 */ 8138 toDOM(_document = document, hooks = {}, binding) { 8139 const hook = hooks[this.hookName]; 8140 let dom; 8141 if (hook !== void 0) { 8142 dom = hook.createDom(this); 8143 } else { 8144 dom = document.createElement(this.hookName); 8145 } 8146 dom.setAttribute("data-yjs-hook", this.hookName); 8147 if (binding !== void 0) { 8148 binding._createAssociation(dom, this); 8149 } 8150 return dom; 8151 } 8152 /** 8153 * Transform the properties of this type to binary and write it to an 8154 * BinaryEncoder. 8155 * 8156 * This is called when this Item is sent to a remote peer. 8157 * 8158 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8159 */ 8160 _write(encoder) { 8161 encoder.writeTypeRef(YXmlHookRefID); 8162 encoder.writeKey(this.hookName); 8163 } 8164 }; 8165 var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); 8166 var YXmlText = class _YXmlText extends YText { 8167 /** 8168 * @type {YXmlElement|YXmlText|null} 8169 */ 8170 get nextSibling() { 8171 const n = this._item ? this._item.next : null; 8172 return n ? ( 8173 /** @type {YXmlElement|YXmlText} */ 8174 /** @type {ContentType} */ 8175 n.content.type 8176 ) : null; 8177 } 8178 /** 8179 * @type {YXmlElement|YXmlText|null} 8180 */ 8181 get prevSibling() { 8182 const n = this._item ? this._item.prev : null; 8183 return n ? ( 8184 /** @type {YXmlElement|YXmlText} */ 8185 /** @type {ContentType} */ 8186 n.content.type 8187 ) : null; 8188 } 8189 _copy() { 8190 return new _YXmlText(); 8191 } 8192 /** 8193 * Makes a copy of this data type that can be included somewhere else. 8194 * 8195 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8196 * 8197 * @return {YXmlText} 8198 */ 8199 clone() { 8200 const text2 = new _YXmlText(); 8201 text2.applyDelta(this.toDelta()); 8202 return text2; 8203 } 8204 /** 8205 * Creates a Dom Element that mirrors this YXmlText. 8206 * 8207 * @param {Document} [_document=document] The document object (you must define 8208 * this when calling this method in 8209 * nodejs) 8210 * @param {Object<string, any>} [hooks] Optional property to customize how hooks 8211 * are presented in the DOM 8212 * @param {any} [binding] You should not set this property. This is 8213 * used if DomBinding wants to create a 8214 * association to the created DOM type. 8215 * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8216 * 8217 * @public 8218 */ 8219 toDOM(_document = document, hooks, binding) { 8220 const dom = _document.createTextNode(this.toString()); 8221 if (binding !== void 0) { 8222 binding._createAssociation(dom, this); 8223 } 8224 return dom; 8225 } 8226 toString() { 8227 return this.toDelta().map((delta) => { 8228 const nestedNodes = []; 8229 for (const nodeName in delta.attributes) { 8230 const attrs = []; 8231 for (const key in delta.attributes[nodeName]) { 8232 attrs.push({ key, value: delta.attributes[nodeName][key] }); 8233 } 8234 attrs.sort((a, b) => a.key < b.key ? -1 : 1); 8235 nestedNodes.push({ nodeName, attrs }); 8236 } 8237 nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1); 8238 let str = ""; 8239 for (let i = 0; i < nestedNodes.length; i++) { 8240 const node = nestedNodes[i]; 8241 str += `<$node.nodeName}`; 8242 for (let j = 0; j < node.attrs.length; j++) { 8243 const attr = node.attrs[j]; 8244 str += ` $attr.key}="$attr.value}"`; 8245 } 8246 str += ">"; 8247 } 8248 str += delta.insert; 8249 for (let i = nestedNodes.length - 1; i >= 0; i--) { 8250 str += `</$nestedNodes[i].nodeName}>`; 8251 } 8252 return str; 8253 }).join(""); 8254 } 8255 /** 8256 * @return {string} 8257 */ 8258 toJSON() { 8259 return this.toString(); 8260 } 8261 /** 8262 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8263 */ 8264 _write(encoder) { 8265 encoder.writeTypeRef(YXmlTextRefID); 8266 } 8267 }; 8268 var readYXmlText = (decoder) => new YXmlText(); 8269 var AbstractStruct = class { 8270 /** 8271 * @param {ID} id 8272 * @param {number} length 8273 */ 8274 constructor(id2, length3) { 8275 this.id = id2; 8276 this.length = length3; 8277 } 8278 /** 8279 * @type {boolean} 8280 */ 8281 get deleted() { 8282 throw methodUnimplemented(); 8283 } 8284 /** 8285 * Merge this struct with the item to the right. 8286 * This method is already assuming that `this.id.clock + this.length === this.id.clock`. 8287 * Also this method does *not* remove right from StructStore! 8288 * @param {AbstractStruct} right 8289 * @return {boolean} whether this merged with right 8290 */ 8291 mergeWith(right) { 8292 return false; 8293 } 8294 /** 8295 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8296 * @param {number} offset 8297 * @param {number} encodingRef 8298 */ 8299 write(encoder, offset, encodingRef) { 8300 throw methodUnimplemented(); 8301 } 8302 /** 8303 * @param {Transaction} transaction 8304 * @param {number} offset 8305 */ 8306 integrate(transaction, offset) { 8307 throw methodUnimplemented(); 8308 } 8309 }; 8310 var structGCRefNumber = 0; 8311 var GC = class extends AbstractStruct { 8312 get deleted() { 8313 return true; 8314 } 8315 delete() { 8316 } 8317 /** 8318 * @param {GC} right 8319 * @return {boolean} 8320 */ 8321 mergeWith(right) { 8322 if (this.constructor !== right.constructor) { 8323 return false; 8324 } 8325 this.length += right.length; 8326 return true; 8327 } 8328 /** 8329 * @param {Transaction} transaction 8330 * @param {number} offset 8331 */ 8332 integrate(transaction, offset) { 8333 if (offset > 0) { 8334 this.id.clock += offset; 8335 this.length -= offset; 8336 } 8337 addStruct(transaction.doc.store, this); 8338 } 8339 /** 8340 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8341 * @param {number} offset 8342 */ 8343 write(encoder, offset) { 8344 encoder.writeInfo(structGCRefNumber); 8345 encoder.writeLen(this.length - offset); 8346 } 8347 /** 8348 * @param {Transaction} transaction 8349 * @param {StructStore} store 8350 * @return {null | number} 8351 */ 8352 getMissing(transaction, store2) { 8353 return null; 8354 } 8355 }; 8356 var ContentBinary = class _ContentBinary { 8357 /** 8358 * @param {Uint8Array} content 8359 */ 8360 constructor(content) { 8361 this.content = content; 8362 } 8363 /** 8364 * @return {number} 8365 */ 8366 getLength() { 8367 return 1; 8368 } 8369 /** 8370 * @return {Array<any>} 8371 */ 8372 getContent() { 8373 return [this.content]; 8374 } 8375 /** 8376 * @return {boolean} 8377 */ 8378 isCountable() { 8379 return true; 8380 } 8381 /** 8382 * @return {ContentBinary} 8383 */ 8384 copy() { 8385 return new _ContentBinary(this.content); 8386 } 8387 /** 8388 * @param {number} offset 8389 * @return {ContentBinary} 8390 */ 8391 splice(offset) { 8392 throw methodUnimplemented(); 8393 } 8394 /** 8395 * @param {ContentBinary} right 8396 * @return {boolean} 8397 */ 8398 mergeWith(right) { 8399 return false; 8400 } 8401 /** 8402 * @param {Transaction} transaction 8403 * @param {Item} item 8404 */ 8405 integrate(transaction, item) { 8406 } 8407 /** 8408 * @param {Transaction} transaction 8409 */ 8410 delete(transaction) { 8411 } 8412 /** 8413 * @param {StructStore} store 8414 */ 8415 gc(store2) { 8416 } 8417 /** 8418 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8419 * @param {number} offset 8420 */ 8421 write(encoder, offset) { 8422 encoder.writeBuf(this.content); 8423 } 8424 /** 8425 * @return {number} 8426 */ 8427 getRef() { 8428 return 3; 8429 } 8430 }; 8431 var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); 8432 var ContentDeleted = class _ContentDeleted { 8433 /** 8434 * @param {number} len 8435 */ 8436 constructor(len) { 8437 this.len = len; 8438 } 8439 /** 8440 * @return {number} 8441 */ 8442 getLength() { 8443 return this.len; 8444 } 8445 /** 8446 * @return {Array<any>} 8447 */ 8448 getContent() { 8449 return []; 8450 } 8451 /** 8452 * @return {boolean} 8453 */ 8454 isCountable() { 8455 return false; 8456 } 8457 /** 8458 * @return {ContentDeleted} 8459 */ 8460 copy() { 8461 return new _ContentDeleted(this.len); 8462 } 8463 /** 8464 * @param {number} offset 8465 * @return {ContentDeleted} 8466 */ 8467 splice(offset) { 8468 const right = new _ContentDeleted(this.len - offset); 8469 this.len = offset; 8470 return right; 8471 } 8472 /** 8473 * @param {ContentDeleted} right 8474 * @return {boolean} 8475 */ 8476 mergeWith(right) { 8477 this.len += right.len; 8478 return true; 8479 } 8480 /** 8481 * @param {Transaction} transaction 8482 * @param {Item} item 8483 */ 8484 integrate(transaction, item) { 8485 addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); 8486 item.markDeleted(); 8487 } 8488 /** 8489 * @param {Transaction} transaction 8490 */ 8491 delete(transaction) { 8492 } 8493 /** 8494 * @param {StructStore} store 8495 */ 8496 gc(store2) { 8497 } 8498 /** 8499 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8500 * @param {number} offset 8501 */ 8502 write(encoder, offset) { 8503 encoder.writeLen(this.len - offset); 8504 } 8505 /** 8506 * @return {number} 8507 */ 8508 getRef() { 8509 return 1; 8510 } 8511 }; 8512 var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); 8513 var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); 8514 var ContentDoc = class _ContentDoc { 8515 /** 8516 * @param {Doc} doc 8517 */ 8518 constructor(doc2) { 8519 if (doc2._item) { 8520 console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); 8521 } 8522 this.doc = doc2; 8523 const opts = {}; 8524 this.opts = opts; 8525 if (!doc2.gc) { 8526 opts.gc = false; 8527 } 8528 if (doc2.autoLoad) { 8529 opts.autoLoad = true; 8530 } 8531 if (doc2.meta !== null) { 8532 opts.meta = doc2.meta; 8533 } 8534 } 8535 /** 8536 * @return {number} 8537 */ 8538 getLength() { 8539 return 1; 8540 } 8541 /** 8542 * @return {Array<any>} 8543 */ 8544 getContent() { 8545 return [this.doc]; 8546 } 8547 /** 8548 * @return {boolean} 8549 */ 8550 isCountable() { 8551 return true; 8552 } 8553 /** 8554 * @return {ContentDoc} 8555 */ 8556 copy() { 8557 return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); 8558 } 8559 /** 8560 * @param {number} offset 8561 * @return {ContentDoc} 8562 */ 8563 splice(offset) { 8564 throw methodUnimplemented(); 8565 } 8566 /** 8567 * @param {ContentDoc} right 8568 * @return {boolean} 8569 */ 8570 mergeWith(right) { 8571 return false; 8572 } 8573 /** 8574 * @param {Transaction} transaction 8575 * @param {Item} item 8576 */ 8577 integrate(transaction, item) { 8578 this.doc._item = item; 8579 transaction.subdocsAdded.add(this.doc); 8580 if (this.doc.shouldLoad) { 8581 transaction.subdocsLoaded.add(this.doc); 8582 } 8583 } 8584 /** 8585 * @param {Transaction} transaction 8586 */ 8587 delete(transaction) { 8588 if (transaction.subdocsAdded.has(this.doc)) { 8589 transaction.subdocsAdded.delete(this.doc); 8590 } else { 8591 transaction.subdocsRemoved.add(this.doc); 8592 } 8593 } 8594 /** 8595 * @param {StructStore} store 8596 */ 8597 gc(store2) { 8598 } 8599 /** 8600 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8601 * @param {number} offset 8602 */ 8603 write(encoder, offset) { 8604 encoder.writeString(this.doc.guid); 8605 encoder.writeAny(this.opts); 8606 } 8607 /** 8608 * @return {number} 8609 */ 8610 getRef() { 8611 return 9; 8612 } 8613 }; 8614 var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); 8615 var ContentEmbed = class _ContentEmbed { 8616 /** 8617 * @param {Object} embed 8618 */ 8619 constructor(embed) { 8620 this.embed = embed; 8621 } 8622 /** 8623 * @return {number} 8624 */ 8625 getLength() { 8626 return 1; 8627 } 8628 /** 8629 * @return {Array<any>} 8630 */ 8631 getContent() { 8632 return [this.embed]; 8633 } 8634 /** 8635 * @return {boolean} 8636 */ 8637 isCountable() { 8638 return true; 8639 } 8640 /** 8641 * @return {ContentEmbed} 8642 */ 8643 copy() { 8644 return new _ContentEmbed(this.embed); 8645 } 8646 /** 8647 * @param {number} offset 8648 * @return {ContentEmbed} 8649 */ 8650 splice(offset) { 8651 throw methodUnimplemented(); 8652 } 8653 /** 8654 * @param {ContentEmbed} right 8655 * @return {boolean} 8656 */ 8657 mergeWith(right) { 8658 return false; 8659 } 8660 /** 8661 * @param {Transaction} transaction 8662 * @param {Item} item 8663 */ 8664 integrate(transaction, item) { 8665 } 8666 /** 8667 * @param {Transaction} transaction 8668 */ 8669 delete(transaction) { 8670 } 8671 /** 8672 * @param {StructStore} store 8673 */ 8674 gc(store2) { 8675 } 8676 /** 8677 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8678 * @param {number} offset 8679 */ 8680 write(encoder, offset) { 8681 encoder.writeJSON(this.embed); 8682 } 8683 /** 8684 * @return {number} 8685 */ 8686 getRef() { 8687 return 5; 8688 } 8689 }; 8690 var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); 8691 var ContentFormat = class _ContentFormat { 8692 /** 8693 * @param {string} key 8694 * @param {Object} value 8695 */ 8696 constructor(key, value) { 8697 this.key = key; 8698 this.value = value; 8699 } 8700 /** 8701 * @return {number} 8702 */ 8703 getLength() { 8704 return 1; 8705 } 8706 /** 8707 * @return {Array<any>} 8708 */ 8709 getContent() { 8710 return []; 8711 } 8712 /** 8713 * @return {boolean} 8714 */ 8715 isCountable() { 8716 return false; 8717 } 8718 /** 8719 * @return {ContentFormat} 8720 */ 8721 copy() { 8722 return new _ContentFormat(this.key, this.value); 8723 } 8724 /** 8725 * @param {number} _offset 8726 * @return {ContentFormat} 8727 */ 8728 splice(_offset) { 8729 throw methodUnimplemented(); 8730 } 8731 /** 8732 * @param {ContentFormat} _right 8733 * @return {boolean} 8734 */ 8735 mergeWith(_right) { 8736 return false; 8737 } 8738 /** 8739 * @param {Transaction} _transaction 8740 * @param {Item} item 8741 */ 8742 integrate(_transaction, item) { 8743 const p = ( 8744 /** @type {YText} */ 8745 item.parent 8746 ); 8747 p._searchMarker = null; 8748 p._hasFormatting = true; 8749 } 8750 /** 8751 * @param {Transaction} transaction 8752 */ 8753 delete(transaction) { 8754 } 8755 /** 8756 * @param {StructStore} store 8757 */ 8758 gc(store2) { 8759 } 8760 /** 8761 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8762 * @param {number} offset 8763 */ 8764 write(encoder, offset) { 8765 encoder.writeKey(this.key); 8766 encoder.writeJSON(this.value); 8767 } 8768 /** 8769 * @return {number} 8770 */ 8771 getRef() { 8772 return 6; 8773 } 8774 }; 8775 var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); 8776 var ContentJSON = class _ContentJSON { 8777 /** 8778 * @param {Array<any>} arr 8779 */ 8780 constructor(arr) { 8781 this.arr = arr; 8782 } 8783 /** 8784 * @return {number} 8785 */ 8786 getLength() { 8787 return this.arr.length; 8788 } 8789 /** 8790 * @return {Array<any>} 8791 */ 8792 getContent() { 8793 return this.arr; 8794 } 8795 /** 8796 * @return {boolean} 8797 */ 8798 isCountable() { 8799 return true; 8800 } 8801 /** 8802 * @return {ContentJSON} 8803 */ 8804 copy() { 8805 return new _ContentJSON(this.arr); 8806 } 8807 /** 8808 * @param {number} offset 8809 * @return {ContentJSON} 8810 */ 8811 splice(offset) { 8812 const right = new _ContentJSON(this.arr.slice(offset)); 8813 this.arr = this.arr.slice(0, offset); 8814 return right; 8815 } 8816 /** 8817 * @param {ContentJSON} right 8818 * @return {boolean} 8819 */ 8820 mergeWith(right) { 8821 this.arr = this.arr.concat(right.arr); 8822 return true; 8823 } 8824 /** 8825 * @param {Transaction} transaction 8826 * @param {Item} item 8827 */ 8828 integrate(transaction, item) { 8829 } 8830 /** 8831 * @param {Transaction} transaction 8832 */ 8833 delete(transaction) { 8834 } 8835 /** 8836 * @param {StructStore} store 8837 */ 8838 gc(store2) { 8839 } 8840 /** 8841 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8842 * @param {number} offset 8843 */ 8844 write(encoder, offset) { 8845 const len = this.arr.length; 8846 encoder.writeLen(len - offset); 8847 for (let i = offset; i < len; i++) { 8848 const c = this.arr[i]; 8849 encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); 8850 } 8851 } 8852 /** 8853 * @return {number} 8854 */ 8855 getRef() { 8856 return 2; 8857 } 8858 }; 8859 var readContentJSON = (decoder) => { 8860 const len = decoder.readLen(); 8861 const cs = []; 8862 for (let i = 0; i < len; i++) { 8863 const c = decoder.readString(); 8864 if (c === "undefined") { 8865 cs.push(void 0); 8866 } else { 8867 cs.push(JSON.parse(c)); 8868 } 8869 } 8870 return new ContentJSON(cs); 8871 }; 8872 var isDevMode = getVariable("node_env") === "development"; 8873 var ContentAny = class _ContentAny { 8874 /** 8875 * @param {Array<any>} arr 8876 */ 8877 constructor(arr) { 8878 this.arr = arr; 8879 isDevMode && deepFreeze(arr); 8880 } 8881 /** 8882 * @return {number} 8883 */ 8884 getLength() { 8885 return this.arr.length; 8886 } 8887 /** 8888 * @return {Array<any>} 8889 */ 8890 getContent() { 8891 return this.arr; 8892 } 8893 /** 8894 * @return {boolean} 8895 */ 8896 isCountable() { 8897 return true; 8898 } 8899 /** 8900 * @return {ContentAny} 8901 */ 8902 copy() { 8903 return new _ContentAny(this.arr); 8904 } 8905 /** 8906 * @param {number} offset 8907 * @return {ContentAny} 8908 */ 8909 splice(offset) { 8910 const right = new _ContentAny(this.arr.slice(offset)); 8911 this.arr = this.arr.slice(0, offset); 8912 return right; 8913 } 8914 /** 8915 * @param {ContentAny} right 8916 * @return {boolean} 8917 */ 8918 mergeWith(right) { 8919 this.arr = this.arr.concat(right.arr); 8920 return true; 8921 } 8922 /** 8923 * @param {Transaction} transaction 8924 * @param {Item} item 8925 */ 8926 integrate(transaction, item) { 8927 } 8928 /** 8929 * @param {Transaction} transaction 8930 */ 8931 delete(transaction) { 8932 } 8933 /** 8934 * @param {StructStore} store 8935 */ 8936 gc(store2) { 8937 } 8938 /** 8939 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8940 * @param {number} offset 8941 */ 8942 write(encoder, offset) { 8943 const len = this.arr.length; 8944 encoder.writeLen(len - offset); 8945 for (let i = offset; i < len; i++) { 8946 const c = this.arr[i]; 8947 encoder.writeAny(c); 8948 } 8949 } 8950 /** 8951 * @return {number} 8952 */ 8953 getRef() { 8954 return 8; 8955 } 8956 }; 8957 var readContentAny = (decoder) => { 8958 const len = decoder.readLen(); 8959 const cs = []; 8960 for (let i = 0; i < len; i++) { 8961 cs.push(decoder.readAny()); 8962 } 8963 return new ContentAny(cs); 8964 }; 8965 var ContentString = class _ContentString { 8966 /** 8967 * @param {string} str 8968 */ 8969 constructor(str) { 8970 this.str = str; 8971 } 8972 /** 8973 * @return {number} 8974 */ 8975 getLength() { 8976 return this.str.length; 8977 } 8978 /** 8979 * @return {Array<any>} 8980 */ 8981 getContent() { 8982 return this.str.split(""); 8983 } 8984 /** 8985 * @return {boolean} 8986 */ 8987 isCountable() { 8988 return true; 8989 } 8990 /** 8991 * @return {ContentString} 8992 */ 8993 copy() { 8994 return new _ContentString(this.str); 8995 } 8996 /** 8997 * @param {number} offset 8998 * @return {ContentString} 8999 */ 9000 splice(offset) { 9001 const right = new _ContentString(this.str.slice(offset)); 9002 this.str = this.str.slice(0, offset); 9003 const firstCharCode = this.str.charCodeAt(offset - 1); 9004 if (firstCharCode >= 55296 && firstCharCode <= 56319) { 9005 this.str = this.str.slice(0, offset - 1) + "\uFFFD"; 9006 right.str = "\uFFFD" + right.str.slice(1); 9007 } 9008 return right; 9009 } 9010 /** 9011 * @param {ContentString} right 9012 * @return {boolean} 9013 */ 9014 mergeWith(right) { 9015 this.str += right.str; 9016 return true; 9017 } 9018 /** 9019 * @param {Transaction} transaction 9020 * @param {Item} item 9021 */ 9022 integrate(transaction, item) { 9023 } 9024 /** 9025 * @param {Transaction} transaction 9026 */ 9027 delete(transaction) { 9028 } 9029 /** 9030 * @param {StructStore} store 9031 */ 9032 gc(store2) { 9033 } 9034 /** 9035 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9036 * @param {number} offset 9037 */ 9038 write(encoder, offset) { 9039 encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); 9040 } 9041 /** 9042 * @return {number} 9043 */ 9044 getRef() { 9045 return 4; 9046 } 9047 }; 9048 var readContentString = (decoder) => new ContentString(decoder.readString()); 9049 var typeRefs = [ 9050 readYArray, 9051 readYMap, 9052 readYText, 9053 readYXmlElement, 9054 readYXmlFragment, 9055 readYXmlHook, 9056 readYXmlText 9057 ]; 9058 var YArrayRefID = 0; 9059 var YMapRefID = 1; 9060 var YTextRefID = 2; 9061 var YXmlElementRefID = 3; 9062 var YXmlFragmentRefID = 4; 9063 var YXmlHookRefID = 5; 9064 var YXmlTextRefID = 6; 9065 var ContentType = class _ContentType { 9066 /** 9067 * @param {AbstractType<any>} type 9068 */ 9069 constructor(type) { 9070 this.type = type; 9071 } 9072 /** 9073 * @return {number} 9074 */ 9075 getLength() { 9076 return 1; 9077 } 9078 /** 9079 * @return {Array<any>} 9080 */ 9081 getContent() { 9082 return [this.type]; 9083 } 9084 /** 9085 * @return {boolean} 9086 */ 9087 isCountable() { 9088 return true; 9089 } 9090 /** 9091 * @return {ContentType} 9092 */ 9093 copy() { 9094 return new _ContentType(this.type._copy()); 9095 } 9096 /** 9097 * @param {number} offset 9098 * @return {ContentType} 9099 */ 9100 splice(offset) { 9101 throw methodUnimplemented(); 9102 } 9103 /** 9104 * @param {ContentType} right 9105 * @return {boolean} 9106 */ 9107 mergeWith(right) { 9108 return false; 9109 } 9110 /** 9111 * @param {Transaction} transaction 9112 * @param {Item} item 9113 */ 9114 integrate(transaction, item) { 9115 this.type._integrate(transaction.doc, item); 9116 } 9117 /** 9118 * @param {Transaction} transaction 9119 */ 9120 delete(transaction) { 9121 let item = this.type._start; 9122 while (item !== null) { 9123 if (!item.deleted) { 9124 item.delete(transaction); 9125 } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { 9126 transaction._mergeStructs.push(item); 9127 } 9128 item = item.right; 9129 } 9130 this.type._map.forEach((item2) => { 9131 if (!item2.deleted) { 9132 item2.delete(transaction); 9133 } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { 9134 transaction._mergeStructs.push(item2); 9135 } 9136 }); 9137 transaction.changed.delete(this.type); 9138 } 9139 /** 9140 * @param {StructStore} store 9141 */ 9142 gc(store2) { 9143 let item = this.type._start; 9144 while (item !== null) { 9145 item.gc(store2, true); 9146 item = item.right; 9147 } 9148 this.type._start = null; 9149 this.type._map.forEach( 9150 /** @param {Item | null} item */ 9151 (item2) => { 9152 while (item2 !== null) { 9153 item2.gc(store2, true); 9154 item2 = item2.left; 9155 } 9156 } 9157 ); 9158 this.type._map = /* @__PURE__ */ new Map(); 9159 } 9160 /** 9161 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9162 * @param {number} offset 9163 */ 9164 write(encoder, offset) { 9165 this.type._write(encoder); 9166 } 9167 /** 9168 * @return {number} 9169 */ 9170 getRef() { 9171 return 7; 9172 } 9173 }; 9174 var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); 9175 var followRedone = (store2, id2) => { 9176 let nextID = id2; 9177 let diff = 0; 9178 let item; 9179 do { 9180 if (diff > 0) { 9181 nextID = createID(nextID.client, nextID.clock + diff); 9182 } 9183 item = getItem(store2, nextID); 9184 diff = nextID.clock - item.id.clock; 9185 nextID = item.redone; 9186 } while (nextID !== null && item instanceof Item); 9187 return { 9188 item, 9189 diff 9190 }; 9191 }; 9192 var keepItem = (item, keep) => { 9193 while (item !== null && item.keep !== keep) { 9194 item.keep = keep; 9195 item = /** @type {AbstractType<any>} */ 9196 item.parent._item; 9197 } 9198 }; 9199 var splitItem = (transaction, leftItem, diff) => { 9200 const { client, clock } = leftItem.id; 9201 const rightItem = new Item( 9202 createID(client, clock + diff), 9203 leftItem, 9204 createID(client, clock + diff - 1), 9205 leftItem.right, 9206 leftItem.rightOrigin, 9207 leftItem.parent, 9208 leftItem.parentSub, 9209 leftItem.content.splice(diff) 9210 ); 9211 if (leftItem.deleted) { 9212 rightItem.markDeleted(); 9213 } 9214 if (leftItem.keep) { 9215 rightItem.keep = true; 9216 } 9217 if (leftItem.redone !== null) { 9218 rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); 9219 } 9220 leftItem.right = rightItem; 9221 if (rightItem.right !== null) { 9222 rightItem.right.left = rightItem; 9223 } 9224 transaction._mergeStructs.push(rightItem); 9225 if (rightItem.parentSub !== null && rightItem.right === null) { 9226 rightItem.parent._map.set(rightItem.parentSub, rightItem); 9227 } 9228 leftItem.length = diff; 9229 return rightItem; 9230 }; 9231 var isDeletedByUndoStack = (stack, id2) => some( 9232 stack, 9233 /** @param {StackItem} s */ 9234 (s) => isDeleted(s.deletions, id2) 9235 ); 9236 var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { 9237 const doc2 = transaction.doc; 9238 const store2 = doc2.store; 9239 const ownClientID = doc2.clientID; 9240 const redone = item.redone; 9241 if (redone !== null) { 9242 return getItemCleanStart(transaction, redone); 9243 } 9244 let parentItem = ( 9245 /** @type {AbstractType<any>} */ 9246 item.parent._item 9247 ); 9248 let left = null; 9249 let right; 9250 if (parentItem !== null && parentItem.deleted === true) { 9251 if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { 9252 return null; 9253 } 9254 while (parentItem.redone !== null) { 9255 parentItem = getItemCleanStart(transaction, parentItem.redone); 9256 } 9257 } 9258 const parentType = parentItem === null ? ( 9259 /** @type {AbstractType<any>} */ 9260 item.parent 9261 ) : ( 9262 /** @type {ContentType} */ 9263 parentItem.content.type 9264 ); 9265 if (item.parentSub === null) { 9266 left = item.left; 9267 right = item; 9268 while (left !== null) { 9269 let leftTrace = left; 9270 while (leftTrace !== null && /** @type {AbstractType<any>} */ 9271 leftTrace.parent._item !== parentItem) { 9272 leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); 9273 } 9274 if (leftTrace !== null && /** @type {AbstractType<any>} */ 9275 leftTrace.parent._item === parentItem) { 9276 left = leftTrace; 9277 break; 9278 } 9279 left = left.left; 9280 } 9281 while (right !== null) { 9282 let rightTrace = right; 9283 while (rightTrace !== null && /** @type {AbstractType<any>} */ 9284 rightTrace.parent._item !== parentItem) { 9285 rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); 9286 } 9287 if (rightTrace !== null && /** @type {AbstractType<any>} */ 9288 rightTrace.parent._item === parentItem) { 9289 right = rightTrace; 9290 break; 9291 } 9292 right = right.right; 9293 } 9294 } else { 9295 right = null; 9296 if (item.right && !ignoreRemoteMapChanges) { 9297 left = item; 9298 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))) { 9299 left = left.right; 9300 while (left.redone) left = getItemCleanStart(transaction, left.redone); 9301 } 9302 if (left && left.right !== null) { 9303 return null; 9304 } 9305 } else { 9306 left = parentType._map.get(item.parentSub) || null; 9307 } 9308 } 9309 const nextClock = getState(store2, ownClientID); 9310 const nextId = createID(ownClientID, nextClock); 9311 const redoneItem = new Item( 9312 nextId, 9313 left, 9314 left && left.lastId, 9315 right, 9316 right && right.id, 9317 parentType, 9318 item.parentSub, 9319 item.content.copy() 9320 ); 9321 item.redone = nextId; 9322 keepItem(redoneItem, true); 9323 redoneItem.integrate(transaction, 0); 9324 return redoneItem; 9325 }; 9326 var Item = class _Item extends AbstractStruct { 9327 /** 9328 * @param {ID} id 9329 * @param {Item | null} left 9330 * @param {ID | null} origin 9331 * @param {Item | null} right 9332 * @param {ID | null} rightOrigin 9333 * @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. 9334 * @param {string | null} parentSub 9335 * @param {AbstractContent} content 9336 */ 9337 constructor(id2, left, origin2, right, rightOrigin, parent, parentSub, content) { 9338 super(id2, content.getLength()); 9339 this.origin = origin2; 9340 this.left = left; 9341 this.right = right; 9342 this.rightOrigin = rightOrigin; 9343 this.parent = parent; 9344 this.parentSub = parentSub; 9345 this.redone = null; 9346 this.content = content; 9347 this.info = this.content.isCountable() ? BIT2 : 0; 9348 } 9349 /** 9350 * This is used to mark the item as an indexed fast-search marker 9351 * 9352 * @type {boolean} 9353 */ 9354 set marker(isMarked) { 9355 if ((this.info & BIT4) > 0 !== isMarked) { 9356 this.info ^= BIT4; 9357 } 9358 } 9359 get marker() { 9360 return (this.info & BIT4) > 0; 9361 } 9362 /** 9363 * If true, do not garbage collect this Item. 9364 */ 9365 get keep() { 9366 return (this.info & BIT1) > 0; 9367 } 9368 set keep(doKeep) { 9369 if (this.keep !== doKeep) { 9370 this.info ^= BIT1; 9371 } 9372 } 9373 get countable() { 9374 return (this.info & BIT2) > 0; 9375 } 9376 /** 9377 * Whether this item was deleted or not. 9378 * @type {Boolean} 9379 */ 9380 get deleted() { 9381 return (this.info & BIT3) > 0; 9382 } 9383 set deleted(doDelete) { 9384 if (this.deleted !== doDelete) { 9385 this.info ^= BIT3; 9386 } 9387 } 9388 markDeleted() { 9389 this.info |= BIT3; 9390 } 9391 /** 9392 * Return the creator clientID of the missing op or define missing items and return null. 9393 * 9394 * @param {Transaction} transaction 9395 * @param {StructStore} store 9396 * @return {null | number} 9397 */ 9398 getMissing(transaction, store2) { 9399 if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store2, this.origin.client)) { 9400 return this.origin.client; 9401 } 9402 if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store2, this.rightOrigin.client)) { 9403 return this.rightOrigin.client; 9404 } 9405 if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store2, this.parent.client)) { 9406 return this.parent.client; 9407 } 9408 if (this.origin) { 9409 this.left = getItemCleanEnd(transaction, store2, this.origin); 9410 this.origin = this.left.lastId; 9411 } 9412 if (this.rightOrigin) { 9413 this.right = getItemCleanStart(transaction, this.rightOrigin); 9414 this.rightOrigin = this.right.id; 9415 } 9416 if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { 9417 this.parent = null; 9418 } else if (!this.parent) { 9419 if (this.left && this.left.constructor === _Item) { 9420 this.parent = this.left.parent; 9421 this.parentSub = this.left.parentSub; 9422 } else if (this.right && this.right.constructor === _Item) { 9423 this.parent = this.right.parent; 9424 this.parentSub = this.right.parentSub; 9425 } 9426 } else if (this.parent.constructor === ID) { 9427 const parentItem = getItem(store2, this.parent); 9428 if (parentItem.constructor === GC) { 9429 this.parent = null; 9430 } else { 9431 this.parent = /** @type {ContentType} */ 9432 parentItem.content.type; 9433 } 9434 } 9435 return null; 9436 } 9437 /** 9438 * @param {Transaction} transaction 9439 * @param {number} offset 9440 */ 9441 integrate(transaction, offset) { 9442 if (offset > 0) { 9443 this.id.clock += offset; 9444 this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); 9445 this.origin = this.left.lastId; 9446 this.content = this.content.splice(offset); 9447 this.length -= offset; 9448 } 9449 if (this.parent) { 9450 if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { 9451 let left = this.left; 9452 let o; 9453 if (left !== null) { 9454 o = left.right; 9455 } else if (this.parentSub !== null) { 9456 o = /** @type {AbstractType<any>} */ 9457 this.parent._map.get(this.parentSub) || null; 9458 while (o !== null && o.left !== null) { 9459 o = o.left; 9460 } 9461 } else { 9462 o = /** @type {AbstractType<any>} */ 9463 this.parent._start; 9464 } 9465 const conflictingItems = /* @__PURE__ */ new Set(); 9466 const itemsBeforeOrigin = /* @__PURE__ */ new Set(); 9467 while (o !== null && o !== this.right) { 9468 itemsBeforeOrigin.add(o); 9469 conflictingItems.add(o); 9470 if (compareIDs(this.origin, o.origin)) { 9471 if (o.id.client < this.id.client) { 9472 left = o; 9473 conflictingItems.clear(); 9474 } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { 9475 break; 9476 } 9477 } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { 9478 if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { 9479 left = o; 9480 conflictingItems.clear(); 9481 } 9482 } else { 9483 break; 9484 } 9485 o = o.right; 9486 } 9487 this.left = left; 9488 } 9489 if (this.left !== null) { 9490 const right = this.left.right; 9491 this.right = right; 9492 this.left.right = this; 9493 } else { 9494 let r; 9495 if (this.parentSub !== null) { 9496 r = /** @type {AbstractType<any>} */ 9497 this.parent._map.get(this.parentSub) || null; 9498 while (r !== null && r.left !== null) { 9499 r = r.left; 9500 } 9501 } else { 9502 r = /** @type {AbstractType<any>} */ 9503 this.parent._start; 9504 this.parent._start = this; 9505 } 9506 this.right = r; 9507 } 9508 if (this.right !== null) { 9509 this.right.left = this; 9510 } else if (this.parentSub !== null) { 9511 this.parent._map.set(this.parentSub, this); 9512 if (this.left !== null) { 9513 this.left.delete(transaction); 9514 } 9515 } 9516 if (this.parentSub === null && this.countable && !this.deleted) { 9517 this.parent._length += this.length; 9518 } 9519 addStruct(transaction.doc.store, this); 9520 this.content.integrate(transaction, this); 9521 addChangedTypeToTransaction( 9522 transaction, 9523 /** @type {AbstractType<any>} */ 9524 this.parent, 9525 this.parentSub 9526 ); 9527 if ( 9528 /** @type {AbstractType<any>} */ 9529 this.parent._item !== null && /** @type {AbstractType<any>} */ 9530 this.parent._item.deleted || this.parentSub !== null && this.right !== null 9531 ) { 9532 this.delete(transaction); 9533 } 9534 } else { 9535 new GC(this.id, this.length).integrate(transaction, 0); 9536 } 9537 } 9538 /** 9539 * Returns the next non-deleted item 9540 */ 9541 get next() { 9542 let n = this.right; 9543 while (n !== null && n.deleted) { 9544 n = n.right; 9545 } 9546 return n; 9547 } 9548 /** 9549 * Returns the previous non-deleted item 9550 */ 9551 get prev() { 9552 let n = this.left; 9553 while (n !== null && n.deleted) { 9554 n = n.left; 9555 } 9556 return n; 9557 } 9558 /** 9559 * Computes the last content address of this Item. 9560 */ 9561 get lastId() { 9562 return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); 9563 } 9564 /** 9565 * Try to merge two items 9566 * 9567 * @param {Item} right 9568 * @return {boolean} 9569 */ 9570 mergeWith(right) { 9571 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)) { 9572 const searchMarker = ( 9573 /** @type {AbstractType<any>} */ 9574 this.parent._searchMarker 9575 ); 9576 if (searchMarker) { 9577 searchMarker.forEach((marker) => { 9578 if (marker.p === right) { 9579 marker.p = this; 9580 if (!this.deleted && this.countable) { 9581 marker.index -= this.length; 9582 } 9583 } 9584 }); 9585 } 9586 if (right.keep) { 9587 this.keep = true; 9588 } 9589 this.right = right.right; 9590 if (this.right !== null) { 9591 this.right.left = this; 9592 } 9593 this.length += right.length; 9594 return true; 9595 } 9596 return false; 9597 } 9598 /** 9599 * Mark this Item as deleted. 9600 * 9601 * @param {Transaction} transaction 9602 */ 9603 delete(transaction) { 9604 if (!this.deleted) { 9605 const parent = ( 9606 /** @type {AbstractType<any>} */ 9607 this.parent 9608 ); 9609 if (this.countable && this.parentSub === null) { 9610 parent._length -= this.length; 9611 } 9612 this.markDeleted(); 9613 addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); 9614 addChangedTypeToTransaction(transaction, parent, this.parentSub); 9615 this.content.delete(transaction); 9616 } 9617 } 9618 /** 9619 * @param {StructStore} store 9620 * @param {boolean} parentGCd 9621 */ 9622 gc(store2, parentGCd) { 9623 if (!this.deleted) { 9624 throw unexpectedCase(); 9625 } 9626 this.content.gc(store2); 9627 if (parentGCd) { 9628 replaceStruct(store2, this, new GC(this.id, this.length)); 9629 } else { 9630 this.content = new ContentDeleted(this.length); 9631 } 9632 } 9633 /** 9634 * Transform the properties of this type to binary and write it to an 9635 * BinaryEncoder. 9636 * 9637 * This is called when this Item is sent to a remote peer. 9638 * 9639 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 9640 * @param {number} offset 9641 */ 9642 write(encoder, offset) { 9643 const origin2 = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; 9644 const rightOrigin = this.rightOrigin; 9645 const parentSub = this.parentSub; 9646 const info = this.content.getRef() & BITS5 | (origin2 === null ? 0 : BIT8) | // origin is defined 9647 (rightOrigin === null ? 0 : BIT7) | // right origin is defined 9648 (parentSub === null ? 0 : BIT6); 9649 encoder.writeInfo(info); 9650 if (origin2 !== null) { 9651 encoder.writeLeftID(origin2); 9652 } 9653 if (rightOrigin !== null) { 9654 encoder.writeRightID(rightOrigin); 9655 } 9656 if (origin2 === null && rightOrigin === null) { 9657 const parent = ( 9658 /** @type {AbstractType<any>} */ 9659 this.parent 9660 ); 9661 if (parent._item !== void 0) { 9662 const parentItem = parent._item; 9663 if (parentItem === null) { 9664 const ykey = findRootTypeKey(parent); 9665 encoder.writeParentInfo(true); 9666 encoder.writeString(ykey); 9667 } else { 9668 encoder.writeParentInfo(false); 9669 encoder.writeLeftID(parentItem.id); 9670 } 9671 } else if (parent.constructor === String) { 9672 encoder.writeParentInfo(true); 9673 encoder.writeString(parent); 9674 } else if (parent.constructor === ID) { 9675 encoder.writeParentInfo(false); 9676 encoder.writeLeftID(parent); 9677 } else { 9678 unexpectedCase(); 9679 } 9680 if (parentSub !== null) { 9681 encoder.writeString(parentSub); 9682 } 9683 } 9684 this.content.write(encoder, offset); 9685 } 9686 }; 9687 var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); 9688 var contentRefs = [ 9689 () => { 9690 unexpectedCase(); 9691 }, 9692 // GC is not ItemContent 9693 readContentDeleted, 9694 // 1 9695 readContentJSON, 9696 // 2 9697 readContentBinary, 9698 // 3 9699 readContentString, 9700 // 4 9701 readContentEmbed, 9702 // 5 9703 readContentFormat, 9704 // 6 9705 readContentType, 9706 // 7 9707 readContentAny, 9708 // 8 9709 readContentDoc, 9710 // 9 9711 () => { 9712 unexpectedCase(); 9713 } 9714 // 10 - Skip is not ItemContent 9715 ]; 9716 var structSkipRefNumber = 10; 9717 var Skip = class extends AbstractStruct { 9718 get deleted() { 9719 return true; 9720 } 9721 delete() { 9722 } 9723 /** 9724 * @param {Skip} right 9725 * @return {boolean} 9726 */ 9727 mergeWith(right) { 9728 if (this.constructor !== right.constructor) { 9729 return false; 9730 } 9731 this.length += right.length; 9732 return true; 9733 } 9734 /** 9735 * @param {Transaction} transaction 9736 * @param {number} offset 9737 */ 9738 integrate(transaction, offset) { 9739 unexpectedCase(); 9740 } 9741 /** 9742 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9743 * @param {number} offset 9744 */ 9745 write(encoder, offset) { 9746 encoder.writeInfo(structSkipRefNumber); 9747 writeVarUint(encoder.restEncoder, this.length - offset); 9748 } 9749 /** 9750 * @param {Transaction} transaction 9751 * @param {StructStore} store 9752 * @return {null | number} 9753 */ 9754 getMissing(transaction, store2) { 9755 return null; 9756 } 9757 }; 9758 var glo = ( 9759 /** @type {any} */ 9760 typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} 9761 ); 9762 var importIdentifier = "__ $YJS$ __"; 9763 if (glo[importIdentifier] === true) { 9764 console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); 9765 } 9766 glo[importIdentifier] = true; 9767 9768 // packages/sync/node_modules/y-protocols/awareness.js 9769 var outdatedTimeout = 3e4; 9770 var Awareness = class extends Observable { 9771 /** 9772 * @param {Y.Doc} doc 9773 */ 9774 constructor(doc2) { 9775 super(); 9776 this.doc = doc2; 9777 this.clientID = doc2.clientID; 9778 this.states = /* @__PURE__ */ new Map(); 9779 this.meta = /* @__PURE__ */ new Map(); 9780 this._checkInterval = /** @type {any} */ 9781 setInterval(() => { 9782 const now = getUnixTime(); 9783 if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ 9784 this.meta.get(this.clientID).lastUpdated) { 9785 this.setLocalState(this.getLocalState()); 9786 } 9787 const remove = []; 9788 this.meta.forEach((meta, clientid) => { 9789 if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { 9790 remove.push(clientid); 9791 } 9792 }); 9793 if (remove.length > 0) { 9794 removeAwarenessStates(this, remove, "timeout"); 9795 } 9796 }, floor(outdatedTimeout / 10)); 9797 doc2.on("destroy", () => { 9798 this.destroy(); 9799 }); 9800 this.setLocalState({}); 9801 } 9802 destroy() { 9803 this.emit("destroy", [this]); 9804 this.setLocalState(null); 9805 super.destroy(); 9806 clearInterval(this._checkInterval); 9807 } 9808 /** 9809 * @return {Object<string,any>|null} 9810 */ 9811 getLocalState() { 9812 return this.states.get(this.clientID) || null; 9813 } 9814 /** 9815 * @param {Object<string,any>|null} state 9816 */ 9817 setLocalState(state) { 9818 const clientID = this.clientID; 9819 const currLocalMeta = this.meta.get(clientID); 9820 const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; 9821 const prevState = this.states.get(clientID); 9822 if (state === null) { 9823 this.states.delete(clientID); 9824 } else { 9825 this.states.set(clientID, state); 9826 } 9827 this.meta.set(clientID, { 9828 clock, 9829 lastUpdated: getUnixTime() 9830 }); 9831 const added = []; 9832 const updated = []; 9833 const filteredUpdated = []; 9834 const removed = []; 9835 if (state === null) { 9836 removed.push(clientID); 9837 } else if (prevState == null) { 9838 if (state != null) { 9839 added.push(clientID); 9840 } 9841 } else { 9842 updated.push(clientID); 9843 if (!equalityDeep(prevState, state)) { 9844 filteredUpdated.push(clientID); 9845 } 9846 } 9847 if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { 9848 this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); 9849 } 9850 this.emit("update", [{ added, updated, removed }, "local"]); 9851 } 9852 /** 9853 * @param {string} field 9854 * @param {any} value 9855 */ 9856 setLocalStateField(field, value) { 9857 const state = this.getLocalState(); 9858 if (state !== null) { 9859 this.setLocalState({ 9860 ...state, 9861 [field]: value 9862 }); 9863 } 9864 } 9865 /** 9866 * @return {Map<number,Object<string,any>>} 9867 */ 9868 getStates() { 9869 return this.states; 9870 } 9871 }; 9872 var removeAwarenessStates = (awareness, clients, origin2) => { 9873 const removed = []; 9874 for (let i = 0; i < clients.length; i++) { 9875 const clientID = clients[i]; 9876 if (awareness.states.has(clientID)) { 9877 awareness.states.delete(clientID); 9878 if (clientID === awareness.clientID) { 9879 const curMeta = ( 9880 /** @type {MetaClientState} */ 9881 awareness.meta.get(clientID) 9882 ); 9883 awareness.meta.set(clientID, { 9884 clock: curMeta.clock + 1, 9885 lastUpdated: getUnixTime() 9886 }); 9887 } 9888 removed.push(clientID); 9889 } 9890 } 9891 if (removed.length > 0) { 9892 awareness.emit("change", [{ added: [], updated: [], removed }, origin2]); 9893 awareness.emit("update", [{ added: [], updated: [], removed }, origin2]); 9894 } 9895 }; 9896 9897 // packages/sync/build-module/config.mjs 9898 var CRDT_DOC_VERSION = 1; 9899 var CRDT_DOC_META_PERSISTENCE_KEY = "fromPersistence"; 9900 var CRDT_RECORD_MAP_KEY = "document"; 9901 var CRDT_STATE_MAP_KEY = "state"; 9902 var CRDT_STATE_MAP_SAVED_AT_KEY = "savedAt"; 9903 var CRDT_STATE_MAP_SAVED_BY_KEY = "savedBy"; 9904 var CRDT_STATE_MAP_VERSION_KEY = "version"; 9905 var LOCAL_EDITOR_ORIGIN = "gutenberg"; 9906 var LOCAL_SYNC_MANAGER_ORIGIN = "syncManager"; 9907 var LOCAL_UNDO_IGNORED_ORIGIN = "gutenberg-undo-ignored"; 9908 9909 // packages/sync/build-module/errors.mjs 9910 var ConnectionErrorCode = /* @__PURE__ */ ((ConnectionErrorCode22) => { 9911 ConnectionErrorCode22["AUTHENTICATION_FAILED"] = "authentication-failed"; 9912 ConnectionErrorCode22["CONNECTION_EXPIRED"] = "connection-expired"; 9913 ConnectionErrorCode22["CONNECTION_LIMIT_EXCEEDED"] = "connection-limit-exceeded"; 9914 ConnectionErrorCode22["DOCUMENT_SIZE_LIMIT_EXCEEDED"] = "document-size-limit-exceeded"; 9915 ConnectionErrorCode22["UNKNOWN_ERROR"] = "unknown-error"; 9916 return ConnectionErrorCode22; 9917 })(ConnectionErrorCode || {}); 9918 var ConnectionError = class extends Error { 9919 constructor(code = "unknown-error", message) { 9920 super(message); 9921 this.code = code; 9922 this.name = "ConnectionError"; 9923 } 9924 }; 9925 9926 // packages/sync/build-module/lock-unlock.mjs 9927 var import_private_apis = __toESM(require_private_apis(), 1); 9928 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 9929 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 9930 "@wordpress/sync" 9931 ); 9932 9933 // packages/sync/build-module/performance.mjs 9934 function logPerformanceTiming(fn) { 9935 return function(...args2) { 9936 const start = performance.now(); 9937 const result = fn.apply(this, args2); 9938 const end = performance.now(); 9939 console.log( 9940 `[SyncManager][performance]: $fn.name} took ${(end - start).toFixed(2)} ms` 9941 ); 9942 return result; 9943 }; 9944 } 9945 function passThru(fn) { 9946 return ((...args2) => fn(...args2)); 9947 } 9948 function yieldToEventLoop(fn) { 9949 return function(...args2) { 9950 setTimeout(() => { 9951 fn.apply(this, args2); 9952 }, 0); 9953 }; 9954 } 9955 9956 // packages/sync/build-module/providers/index.mjs 9957 var import_hooks3 = __toESM(require_hooks(), 1); 9958 9959 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 9960 var import_hooks2 = __toESM(require_hooks(), 1); 9961 9962 // packages/sync/node_modules/y-protocols/sync.js 9963 var messageYjsSyncStep1 = 0; 9964 var messageYjsSyncStep2 = 1; 9965 var messageYjsUpdate = 2; 9966 var writeSyncStep1 = (encoder, doc2) => { 9967 writeVarUint(encoder, messageYjsSyncStep1); 9968 const sv = encodeStateVector(doc2); 9969 writeVarUint8Array(encoder, sv); 9970 }; 9971 var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { 9972 writeVarUint(encoder, messageYjsSyncStep2); 9973 writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); 9974 }; 9975 var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); 9976 var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { 9977 try { 9978 applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); 9979 } catch (error) { 9980 if (errorHandler != null) errorHandler( 9981 /** @type {Error} */ 9982 error 9983 ); 9984 console.error("Caught error while handling a Yjs update", error); 9985 } 9986 }; 9987 var readUpdate2 = readSyncStep2; 9988 var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { 9989 const messageType = readVarUint(decoder); 9990 switch (messageType) { 9991 case messageYjsSyncStep1: 9992 readSyncStep1(decoder, encoder, doc2); 9993 break; 9994 case messageYjsSyncStep2: 9995 readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); 9996 break; 9997 case messageYjsUpdate: 9998 readUpdate2(decoder, doc2, transactionOrigin, errorHandler); 9999 break; 10000 default: 10001 throw new Error("Unknown message type"); 10002 } 10003 return messageType; 10004 }; 10005 10006 // packages/sync/build-module/providers/http-polling/config.mjs 10007 var import_hooks = __toESM(require_hooks(), 1); 10008 var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; 10009 var ERROR_RETRY_DELAYS_SOLO_MS = [ 10010 2e3, 10011 4e3, 10012 8e3, 10013 12e3 10014 // Solo: 26s total retry time solo before dialog 10015 ]; 10016 var ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS = [ 10017 1e3, 10018 2e3, 10019 4e3, 10020 8e3 10021 // With collaborators: 15s total retry time before dialog 10022 ]; 10023 var DISCONNECT_DIALOG_RETRY_MS = 3e4; 10024 var MANUAL_RETRY_INTERVAL_MS = 15e3; 10025 var MAX_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; 10026 var MAX_ROOMS_PER_REQUEST = 50; 10027 var POLLING_INTERVAL_IN_MS = (0, import_hooks.applyFilters)( 10028 "sync.pollingManager.pollingInterval", 10029 4e3 10030 // 4 seconds 10031 ); 10032 var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = (0, import_hooks.applyFilters)( 10033 "sync.pollingManager.pollingIntervalWithCollaborators", 10034 1e3 10035 // 1 second 10036 ); 10037 var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; 10038 10039 // packages/sync/build-module/providers/http-polling/types.mjs 10040 var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { 10041 SyncUpdateType2["COMPACTION"] = "compaction"; 10042 SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; 10043 SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; 10044 SyncUpdateType2["UPDATE"] = "update"; 10045 return SyncUpdateType2; 10046 })(SyncUpdateType || {}); 10047 10048 // packages/sync/build-module/providers/http-polling/utils.mjs 10049 var import_api_fetch = __toESM(require_api_fetch(), 1); 10050 var SYNC_API_PATH = "/wp-sync/v1/updates"; 10051 function uint8ArrayToBase64(data) { 10052 let binary = ""; 10053 const len = data.byteLength; 10054 for (let i = 0; i < len; i++) { 10055 binary += String.fromCharCode(data[i]); 10056 } 10057 return globalThis.btoa(binary); 10058 } 10059 function base64ToUint8Array(base64) { 10060 const binaryString = globalThis.atob(base64); 10061 const len = binaryString.length; 10062 const bytes = new Uint8Array(len); 10063 for (let i = 0; i < len; i++) { 10064 bytes[i] = binaryString.charCodeAt(i); 10065 } 10066 return bytes; 10067 } 10068 function createSyncUpdate(data, type) { 10069 return { 10070 data: uint8ArrayToBase64(data), 10071 type 10072 }; 10073 } 10074 function createUpdateQueue(initial = [], paused = true) { 10075 let isPaused = paused; 10076 const updates = [...initial]; 10077 return { 10078 add(update) { 10079 updates.push(update); 10080 }, 10081 addBulk(bulkUpdates) { 10082 if (0 === bulkUpdates.length) { 10083 return; 10084 } 10085 updates.push(...bulkUpdates); 10086 }, 10087 clear() { 10088 updates.splice(0, updates.length); 10089 }, 10090 get() { 10091 if (isPaused) { 10092 return []; 10093 } 10094 return updates.splice(0, updates.length); 10095 }, 10096 pause() { 10097 isPaused = true; 10098 }, 10099 restore(restoredUpdates) { 10100 const filtered = restoredUpdates.filter( 10101 (u) => u.type !== SyncUpdateType.COMPACTION 10102 ); 10103 if (0 === filtered.length) { 10104 return; 10105 } 10106 updates.unshift(...filtered); 10107 }, 10108 resume() { 10109 isPaused = false; 10110 }, 10111 size() { 10112 return updates.length; 10113 } 10114 }; 10115 } 10116 async function postSyncUpdate(payload) { 10117 const response = await (0, import_api_fetch.default)({ 10118 body: JSON.stringify(payload), 10119 headers: { 10120 "Content-Type": "application/json" 10121 }, 10122 method: "POST", 10123 parse: false, 10124 path: SYNC_API_PATH 10125 }); 10126 if (!response.ok) { 10127 throw new Error( 10128 `Sync update failed with status $response.status}` 10129 ); 10130 } 10131 return await response.json(); 10132 } 10133 function postSyncUpdateNonBlocking(payload) { 10134 if (payload.rooms.length === 0) { 10135 return; 10136 } 10137 (0, import_api_fetch.default)({ 10138 body: JSON.stringify(payload), 10139 headers: { "Content-Type": "application/json" }, 10140 keepalive: true, 10141 method: "POST", 10142 parse: false, 10143 path: SYNC_API_PATH 10144 }).catch(() => { 10145 }); 10146 } 10147 function intValueOrDefault(value, defaultValue) { 10148 const intValue = parseInt(String(value), 10); 10149 return isNaN(intValue) ? defaultValue : intValue; 10150 } 10151 function rotateWindow(items2, offset, size2) { 10152 if (items2.length === 0) { 10153 return { window: [], nextOffset: 0 }; 10154 } 10155 const start = (offset % items2.length + items2.length) % items2.length; 10156 const wrapped = [...items2.slice(start), ...items2.slice(0, start)]; 10157 return { 10158 window: wrapped.slice(0, Math.max(0, size2)), 10159 nextOffset: (start + Math.max(0, size2)) % items2.length 10160 }; 10161 } 10162 10163 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 10164 var POLLING_MANAGER_ORIGIN = "polling-manager"; 10165 function isForbiddenError(error) { 10166 return error?.data?.status === 403; 10167 } 10168 function identifyForbiddenRoom(error, rooms) { 10169 const message = typeof error.message === "string" ? error.message : ""; 10170 const sortedRooms = [...rooms].sort((a, b) => b.length - a.length); 10171 for (const room of sortedRooms) { 10172 if (message.includes(room)) { 10173 return room; 10174 } 10175 } 10176 return null; 10177 } 10178 function handleForbiddenError(error, requestedRooms) { 10179 const forbiddenRoom = identifyForbiddenRoom( 10180 error, 10181 requestedRooms.map((r) => r.room) 10182 ); 10183 if (forbiddenRoom) { 10184 const state = roomStates.get(forbiddenRoom); 10185 if (state) { 10186 state.log( 10187 "Permission denied, unregistering room", 10188 { error }, 10189 "error", 10190 true 10191 // force 10192 ); 10193 unregisterRoom(forbiddenRoom, { sendDisconnectSignal: false }); 10194 } 10195 for (const room of requestedRooms) { 10196 if (room.room === forbiddenRoom || !roomStates.has(room.room)) { 10197 continue; 10198 } 10199 const remainingState = roomStates.get(room.room); 10200 if (room.updates.length > 0) { 10201 remainingState.updateQueue.restore(room.updates); 10202 } 10203 } 10204 } else { 10205 const rooms = [...roomStates.keys()]; 10206 for (const room of rooms) { 10207 const state = roomStates.get(room); 10208 if (state) { 10209 state.log( 10210 "Permission denied, unregistering room", 10211 { error }, 10212 "error", 10213 true 10214 // force 10215 ); 10216 unregisterRoom(room, { sendDisconnectSignal: false }); 10217 } 10218 } 10219 } 10220 } 10221 var roomStates = /* @__PURE__ */ new Map(); 10222 function createDeprecatedCompactionUpdate(updates) { 10223 const mergeable = updates.filter( 10224 (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( 10225 u.type 10226 ) 10227 ).map((u) => base64ToUint8Array(u.data)); 10228 return createSyncUpdate( 10229 mergeUpdatesV2(mergeable), 10230 SyncUpdateType.COMPACTION 10231 ); 10232 } 10233 function createSyncStep1Update(doc2) { 10234 const encoder = createEncoder(); 10235 writeSyncStep1(encoder, doc2); 10236 return createSyncUpdate( 10237 toUint8Array(encoder), 10238 SyncUpdateType.SYNC_STEP_1 10239 ); 10240 } 10241 function createSyncStep2Update(doc2, step1) { 10242 const decoder = createDecoder(step1); 10243 const encoder = createEncoder(); 10244 readSyncMessage( 10245 decoder, 10246 encoder, 10247 doc2, 10248 POLLING_MANAGER_ORIGIN 10249 ); 10250 return createSyncUpdate( 10251 toUint8Array(encoder), 10252 SyncUpdateType.SYNC_STEP_2 10253 ); 10254 } 10255 function processAwarenessUpdate(state, awareness) { 10256 const currentStates = awareness.getStates(); 10257 const added = /* @__PURE__ */ new Set(); 10258 const updated = /* @__PURE__ */ new Set(); 10259 const removed = new Set( 10260 Array.from(currentStates.keys()).filter( 10261 (clientId) => !state[clientId] 10262 ) 10263 ); 10264 Object.entries(state).forEach(([clientIdString, awarenessState]) => { 10265 const clientId = Number(clientIdString); 10266 if (clientId === awareness.clientID) { 10267 return; 10268 } 10269 if (null === awarenessState) { 10270 currentStates.delete(clientId); 10271 removed.add(clientId); 10272 return; 10273 } 10274 if (!currentStates.has(clientId)) { 10275 currentStates.set(clientId, awarenessState); 10276 added.add(clientId); 10277 return; 10278 } 10279 const currentState = currentStates.get(clientId); 10280 if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { 10281 currentStates.set(clientId, awarenessState); 10282 updated.add(clientId); 10283 } 10284 }); 10285 if (added.size + updated.size > 0) { 10286 awareness.emit("change", [ 10287 { 10288 added: Array.from(added), 10289 updated: Array.from(updated), 10290 // Left blank on purpose, as the removal of clients is handled in the if condition below. 10291 removed: [] 10292 } 10293 ]); 10294 } 10295 if (removed.size > 0) { 10296 removeAwarenessStates( 10297 awareness, 10298 Array.from(removed), 10299 POLLING_MANAGER_ORIGIN 10300 ); 10301 } 10302 } 10303 function processDocUpdate(update, doc2, onSync) { 10304 const data = base64ToUint8Array(update.data); 10305 switch (update.type) { 10306 case SyncUpdateType.SYNC_STEP_1: { 10307 return createSyncStep2Update(doc2, data); 10308 } 10309 case SyncUpdateType.SYNC_STEP_2: { 10310 const decoder = createDecoder(data); 10311 const encoder = createEncoder(); 10312 readSyncMessage( 10313 decoder, 10314 encoder, 10315 doc2, 10316 POLLING_MANAGER_ORIGIN 10317 ); 10318 onSync(); 10319 return; 10320 } 10321 case SyncUpdateType.COMPACTION: 10322 case SyncUpdateType.UPDATE: { 10323 applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); 10324 } 10325 } 10326 } 10327 function checkConnectionLimit(awareness, roomState) { 10328 if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { 10329 return false; 10330 } 10331 hasCheckedConnectionLimit = true; 10332 const maxClientsPerRoom = (0, import_hooks2.applyFilters)( 10333 "sync.pollingProvider.maxClientsPerRoom", 10334 DEFAULT_CLIENT_LIMIT_PER_ROOM, 10335 roomState.room 10336 ); 10337 const clientCount = Object.keys(awareness).length; 10338 const validatedLimit = intValueOrDefault( 10339 maxClientsPerRoom, 10340 DEFAULT_CLIENT_LIMIT_PER_ROOM 10341 ); 10342 if (clientCount > validatedLimit) { 10343 roomState.log("Connection limit exceeded", { 10344 clientCount, 10345 maxClientsPerRoom: validatedLimit, 10346 room: roomState.room 10347 }); 10348 return true; 10349 } 10350 return false; 10351 } 10352 var areListenersRegistered = false; 10353 var consecutiveFailures = 0; 10354 var hasCheckedConnectionLimit = false; 10355 var isManualRetry = false; 10356 var hasCollaborators = false; 10357 var isActiveBrowser = "visible" === document.visibilityState; 10358 var isPolling = false; 10359 var isUnloadPending = false; 10360 var pollInterval = POLLING_INTERVAL_IN_MS; 10361 var pollingTimeoutId = null; 10362 var roomOverflowOffset = 0; 10363 function handleBeforeUnload() { 10364 isUnloadPending = true; 10365 } 10366 function handlePageHide() { 10367 const rooms = Array.from(roomStates.entries()).map( 10368 ([room, state]) => ({ 10369 after: 0, 10370 awareness: null, 10371 client_id: state.clientId, 10372 room, 10373 updates: [] 10374 }) 10375 ); 10376 for (let i = 0; i < rooms.length; i += MAX_ROOMS_PER_REQUEST) { 10377 postSyncUpdateNonBlocking({ 10378 rooms: rooms.slice(i, i + MAX_ROOMS_PER_REQUEST) 10379 }); 10380 } 10381 } 10382 function handleVisibilityChange() { 10383 const wasActive = isActiveBrowser; 10384 isActiveBrowser = document.visibilityState === "visible"; 10385 if (isActiveBrowser && !wasActive) { 10386 if (pollingTimeoutId) { 10387 clearTimeout(pollingTimeoutId); 10388 pollingTimeoutId = null; 10389 poll(); 10390 } 10391 } 10392 } 10393 function selectRoomsForRequest() { 10394 const allRooms = Array.from(roomStates.values()); 10395 if (allRooms.length <= MAX_ROOMS_PER_REQUEST) { 10396 return allRooms; 10397 } 10398 const primaryRoom = allRooms.find((state) => state.isPrimaryRoom); 10399 const overflowRooms = allRooms.filter((state) => state !== primaryRoom); 10400 const overflowSlotsPerRequest = MAX_ROOMS_PER_REQUEST - (primaryRoom ? 1 : 0); 10401 const { window: overflowSlice, nextOffset } = rotateWindow( 10402 overflowRooms, 10403 roomOverflowOffset, 10404 overflowSlotsPerRequest 10405 ); 10406 roomOverflowOffset = nextOffset; 10407 if (primaryRoom) { 10408 return [primaryRoom, ...overflowSlice]; 10409 } 10410 return overflowSlice; 10411 } 10412 function poll() { 10413 isPolling = true; 10414 pollingTimeoutId = null; 10415 async function start() { 10416 if (0 === roomStates.size) { 10417 isPolling = false; 10418 return; 10419 } 10420 isUnloadPending = false; 10421 const roomsInRequest = selectRoomsForRequest(); 10422 const payload = { 10423 rooms: roomsInRequest.map((state) => ({ 10424 after: state.endCursor ?? 0, 10425 awareness: state.localAwarenessState, 10426 client_id: state.clientId, 10427 room: state.room, 10428 updates: state.updateQueue.get() 10429 })) 10430 }; 10431 roomsInRequest.forEach((state) => { 10432 state.onStatusChange({ status: "connecting" }); 10433 }); 10434 try { 10435 const { rooms } = await postSyncUpdate(payload); 10436 consecutiveFailures = 0; 10437 isManualRetry = false; 10438 roomsInRequest.forEach((state) => { 10439 if (roomStates.get(state.room) !== state) { 10440 return; 10441 } 10442 state.onStatusChange({ status: "connected" }); 10443 }); 10444 hasCollaborators = false; 10445 rooms.forEach((room) => { 10446 if (!roomStates.has(room.room)) { 10447 return; 10448 } 10449 const roomState = roomStates.get(room.room); 10450 roomState.endCursor = room.end_cursor; 10451 if (checkConnectionLimit(room.awareness, roomState)) { 10452 roomState.onStatusChange({ 10453 status: "disconnected", 10454 error: new ConnectionError( 10455 ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, 10456 "Connection limit exceeded" 10457 ) 10458 }); 10459 unregisterRoom(room.room); 10460 return; 10461 } 10462 roomState.processAwarenessUpdate(room.awareness); 10463 if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { 10464 hasCollaborators = true; 10465 roomStates.forEach((state) => { 10466 state.updateQueue.resume(); 10467 }); 10468 } 10469 const responseUpdates = []; 10470 for (const update of room.updates) { 10471 try { 10472 const response = roomState.processDocUpdate(update); 10473 if (response) { 10474 responseUpdates.push(response); 10475 } 10476 } catch (error) { 10477 roomState.log( 10478 "Failed to apply sync update", 10479 { error, update }, 10480 "error", 10481 true 10482 // force 10483 ); 10484 } 10485 } 10486 roomState.updateQueue.addBulk(responseUpdates); 10487 if (room.should_compact) { 10488 roomState.log("Server requested compaction update"); 10489 roomState.updateQueue.clear(); 10490 roomState.updateQueue.add( 10491 roomState.createCompactionUpdate() 10492 ); 10493 } else if (room.compaction_request) { 10494 roomState.log("Server requested (old) compaction update"); 10495 roomState.updateQueue.add( 10496 createDeprecatedCompactionUpdate( 10497 room.compaction_request 10498 ) 10499 ); 10500 } 10501 }); 10502 if (isActiveBrowser && hasCollaborators) { 10503 pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; 10504 } else if (isActiveBrowser) { 10505 pollInterval = POLLING_INTERVAL_IN_MS; 10506 } else { 10507 pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; 10508 } 10509 } catch (error) { 10510 if (isForbiddenError(error)) { 10511 handleForbiddenError(error, payload.rooms); 10512 if (roomStates.size === 0) { 10513 isPolling = false; 10514 return; 10515 } 10516 } else { 10517 consecutiveFailures++; 10518 const retrySchedule = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS : ERROR_RETRY_DELAYS_SOLO_MS; 10519 if (consecutiveFailures <= retrySchedule.length) { 10520 pollInterval = retrySchedule[consecutiveFailures - 1]; 10521 } else { 10522 pollInterval = DISCONNECT_DIALOG_RETRY_MS; 10523 } 10524 if (isManualRetry) { 10525 pollInterval = MANUAL_RETRY_INTERVAL_MS; 10526 isManualRetry = false; 10527 } 10528 for (const room of payload.rooms) { 10529 if (!roomStates.has(room.room)) { 10530 continue; 10531 } 10532 const state = roomStates.get(room.room); 10533 if (room.updates.length > 0 && state.endCursor > 0) { 10534 state.updateQueue.clear(); 10535 state.updateQueue.add(state.createCompactionUpdate()); 10536 } else if (room.updates.length > 0) { 10537 state.updateQueue.restore(room.updates); 10538 } 10539 state.log( 10540 "Error posting sync update, will retry with backoff", 10541 { error, nextPoll: pollInterval }, 10542 "error", 10543 true 10544 // force 10545 ); 10546 } 10547 if (!isUnloadPending) { 10548 const backgroundRetriesFailed = consecutiveFailures > retrySchedule.length; 10549 roomsInRequest.forEach((state) => { 10550 if (roomStates.get(state.room) !== state) { 10551 return; 10552 } 10553 state.onStatusChange({ 10554 status: "disconnected", 10555 canManuallyRetry: true, 10556 consecutiveFailures, 10557 backgroundRetriesFailed, 10558 willAutoRetryInMs: pollInterval 10559 }); 10560 }); 10561 } 10562 } 10563 } 10564 pollingTimeoutId = setTimeout(poll, pollInterval); 10565 } 10566 void start(); 10567 } 10568 function registerRoom({ 10569 room, 10570 doc: doc2, 10571 awareness, 10572 log, 10573 onSync, 10574 onStatusChange 10575 }) { 10576 if (roomStates.has(room)) { 10577 return; 10578 } 10579 const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); 10580 const isPrimaryRoom = 0 === roomStates.size; 10581 function onAwarenessUpdate() { 10582 roomState.localAwarenessState = awareness.getLocalState() ?? {}; 10583 } 10584 function onDocUpdate(update, origin2) { 10585 if (POLLING_MANAGER_ORIGIN === origin2) { 10586 return; 10587 } 10588 if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { 10589 const state = roomStates.get(room); 10590 if (!state) { 10591 return; 10592 } 10593 state.log("Document size limit exceeded", { 10594 maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, 10595 updateSizeInBytes: update.byteLength 10596 }); 10597 state.onStatusChange({ 10598 status: "disconnected", 10599 error: new ConnectionError( 10600 ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, 10601 "Document size limit exceeded" 10602 ) 10603 }); 10604 unregisterRoom(room); 10605 } 10606 updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); 10607 } 10608 function unregister() { 10609 doc2.off("updateV2", onDocUpdate); 10610 awareness.off("change", onAwarenessUpdate); 10611 updateQueue.clear(); 10612 } 10613 const roomState = { 10614 clientId: doc2.clientID, 10615 createCompactionUpdate: () => createSyncUpdate( 10616 encodeStateAsUpdateV2(doc2), 10617 SyncUpdateType.COMPACTION 10618 ), 10619 endCursor: 0, 10620 isPrimaryRoom, 10621 localAwarenessState: awareness.getLocalState() ?? {}, 10622 log, 10623 onStatusChange, 10624 processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), 10625 processDocUpdate: (update) => processDocUpdate(update, doc2, onSync), 10626 room, 10627 unregister, 10628 updateQueue 10629 }; 10630 doc2.on("updateV2", onDocUpdate); 10631 awareness.on("change", onAwarenessUpdate); 10632 roomStates.set(room, roomState); 10633 if (!areListenersRegistered) { 10634 window.addEventListener("beforeunload", handleBeforeUnload); 10635 window.addEventListener("pagehide", handlePageHide); 10636 document.addEventListener("visibilitychange", handleVisibilityChange); 10637 areListenersRegistered = true; 10638 } 10639 if (!isPolling) { 10640 poll(); 10641 } 10642 } 10643 function unregisterRoom(room, { sendDisconnectSignal = true } = {}) { 10644 const state = roomStates.get(room); 10645 if (state) { 10646 if (sendDisconnectSignal) { 10647 const rooms = [ 10648 { 10649 after: 0, 10650 awareness: null, 10651 client_id: state.clientId, 10652 room, 10653 updates: [] 10654 } 10655 ]; 10656 postSyncUpdateNonBlocking({ rooms }); 10657 } 10658 state.unregister(); 10659 roomStates.delete(room); 10660 } 10661 if (0 === roomStates.size && areListenersRegistered) { 10662 window.removeEventListener("beforeunload", handleBeforeUnload); 10663 window.removeEventListener("pagehide", handlePageHide); 10664 document.removeEventListener( 10665 "visibilitychange", 10666 handleVisibilityChange 10667 ); 10668 areListenersRegistered = false; 10669 hasCheckedConnectionLimit = false; 10670 consecutiveFailures = 0; 10671 roomOverflowOffset = 0; 10672 } 10673 } 10674 function retryNow() { 10675 isManualRetry = true; 10676 if (pollingTimeoutId) { 10677 clearTimeout(pollingTimeoutId); 10678 pollingTimeoutId = null; 10679 poll(); 10680 } 10681 } 10682 var pollingManager = { 10683 registerRoom, 10684 retryNow, 10685 unregisterRoom 10686 }; 10687 10688 // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs 10689 var HttpPollingProvider = class extends ObservableV2 { 10690 constructor(options) { 10691 super(); 10692 this.options = options; 10693 this.log("Initializing", { room: options.room }); 10694 this.awareness = options.awareness ?? new Awareness(options.ydoc); 10695 this.connect(); 10696 } 10697 awareness; 10698 status = "disconnected"; 10699 synced = false; 10700 /** 10701 * Connect to the endpoint and initialize sync. 10702 */ 10703 connect() { 10704 this.log("Connecting"); 10705 pollingManager.registerRoom({ 10706 room: this.options.room, 10707 doc: this.options.ydoc, 10708 awareness: this.awareness, 10709 log: this.log, 10710 onStatusChange: this.emitStatus, 10711 onSync: this.onSync 10712 }); 10713 } 10714 /** 10715 * Destroy the provider and cleanup resources. 10716 */ 10717 destroy() { 10718 this.disconnect(); 10719 super.destroy(); 10720 } 10721 /** 10722 * Disconnect the provider and allow reconnection later. 10723 */ 10724 disconnect() { 10725 this.log("Disconnecting"); 10726 pollingManager.unregisterRoom(this.options.room); 10727 this.emitStatus({ status: "disconnected" }); 10728 } 10729 /** 10730 * Emit connection status, passing the full object through so that 10731 * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. 10732 * 10733 * @param connectionStatus The connection status object 10734 */ 10735 emitStatus = (connectionStatus) => { 10736 const { status } = connectionStatus; 10737 const error = status === "disconnected" ? connectionStatus.error : void 0; 10738 if (this.status === status && !error) { 10739 return; 10740 } 10741 if (status === "connecting" && this.status !== "disconnected") { 10742 return; 10743 } 10744 this.log("Status change", { status, error }); 10745 this.status = status; 10746 this.emit("status", [connectionStatus]); 10747 }; 10748 /** 10749 * Log debug messages if debugging is enabled. 10750 * 10751 * @param message The debug message 10752 * @param debug Additional debug information 10753 * @param errorLevel The console method to use for logging 10754 * @param force Whether to force logging regardless of debug setting 10755 */ 10756 log = (message, debug = {}, errorLevel = "log", force = false) => { 10757 if (!this.options.debug && !force) { 10758 return; 10759 } 10760 const logFn = console[errorLevel] || console.log; 10761 logFn(`[$this.constructor.name}]: $message}`, { 10762 room: this.options.room, 10763 ...debug 10764 }); 10765 }; 10766 /** 10767 * Handle synchronization events from the polling manager. 10768 */ 10769 onSync = () => { 10770 if (!this.synced) { 10771 this.synced = true; 10772 this.log("Synced"); 10773 } 10774 }; 10775 }; 10776 function createHttpPollingProvider() { 10777 return async ({ 10778 awareness, 10779 objectType, 10780 objectId, 10781 ydoc 10782 }) => { 10783 const room = objectId ? `$objectType}:$objectId}` : objectType; 10784 const provider = new HttpPollingProvider({ 10785 awareness, 10786 // debug: true, 10787 room, 10788 ydoc 10789 }); 10790 return { 10791 destroy: () => provider.destroy(), 10792 // Adapter: ObservableV2.on is compatible with ProviderOn 10793 // The callback receives data as the first parameter 10794 on: (event, callback) => { 10795 provider.on(event, callback); 10796 } 10797 }; 10798 }; 10799 } 10800 10801 // packages/sync/build-module/providers/index.mjs 10802 var providerCreators = null; 10803 function getDefaultProviderCreators() { 10804 return [createHttpPollingProvider()]; 10805 } 10806 function isProviderCreator(creator) { 10807 return "function" === typeof creator; 10808 } 10809 function getProviderCreators() { 10810 if (providerCreators) { 10811 return providerCreators; 10812 } 10813 if (!window._wpCollaborationEnabled) { 10814 return []; 10815 } 10816 const filteredProviderCreators = (0, import_hooks3.applyFilters)( 10817 "sync.providers", 10818 getDefaultProviderCreators() 10819 ); 10820 if (!Array.isArray(filteredProviderCreators)) { 10821 providerCreators = []; 10822 return providerCreators; 10823 } 10824 providerCreators = filteredProviderCreators.filter(isProviderCreator); 10825 return providerCreators; 10826 } 10827 10828 // packages/sync/build-module/y-utilities/y-multidoc-undomanager.mjs 10829 var popStackItem2 = (mum, type) => { 10830 const stack = type === "undo" ? mum.undoStack : mum.redoStack; 10831 while (stack.length > 0) { 10832 const um = ( 10833 /** @type {Y.UndoManager} */ 10834 stack.pop() 10835 ); 10836 const prevUmStack = type === "undo" ? um.undoStack : um.redoStack; 10837 const stackItem = ( 10838 /** @type {any} */ 10839 prevUmStack.pop() 10840 ); 10841 let actionPerformed = false; 10842 if (type === "undo") { 10843 um.undoStack = [stackItem]; 10844 actionPerformed = um.undo() !== null; 10845 um.undoStack = prevUmStack; 10846 } else { 10847 um.redoStack = [stackItem]; 10848 actionPerformed = um.redo() !== null; 10849 um.redoStack = prevUmStack; 10850 } 10851 if (actionPerformed) { 10852 return stackItem; 10853 } 10854 } 10855 return null; 10856 }; 10857 var YMultiDocUndoManager = class extends Observable { 10858 /** 10859 * @param {Y.AbstractType<any>|Array<Y.AbstractType<any>>} typeScope Accepts either a single type, or an array of types 10860 * @param {ConstructorParameters<typeof Y.UndoManager>[1]} opts 10861 */ 10862 constructor(typeScope = [], opts = {}) { 10863 super(); 10864 this.docs = /* @__PURE__ */ new Map(); 10865 this.trackedOrigins = opts.trackedOrigins || /* @__PURE__ */ new Set([null]); 10866 opts.trackedOrigins = this.trackedOrigins; 10867 this._defaultOpts = opts; 10868 this.undoStack = []; 10869 this.redoStack = []; 10870 this.addToScope(typeScope); 10871 } 10872 /** 10873 * @param {Array<Y.AbstractType<any>> | Y.AbstractType<any>} ytypes 10874 */ 10875 addToScope(ytypes) { 10876 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 10877 ytypes.forEach((ytype) => { 10878 const ydoc = ( 10879 /** @type {Y.Doc} */ 10880 ytype.doc 10881 ); 10882 const um = setIfUndefined(this.docs, ydoc, () => { 10883 const um2 = new UndoManager([ytype], this._defaultOpts); 10884 um2.on( 10885 "stack-cleared", 10886 /** @param {any} opts */ 10887 ({ 10888 undoStackCleared, 10889 redoStackCleared 10890 }) => { 10891 this.clear(undoStackCleared, redoStackCleared); 10892 } 10893 ); 10894 ydoc.on("destroy", () => { 10895 this.docs.delete(ydoc); 10896 this.undoStack = this.undoStack.filter( 10897 (um3) => um3.doc !== ydoc 10898 ); 10899 this.redoStack = this.redoStack.filter( 10900 (um3) => um3.doc !== ydoc 10901 ); 10902 }); 10903 um2.on( 10904 "stack-item-added", 10905 /** @param {any} change */ 10906 (change) => { 10907 const stack = change.type === "undo" ? this.undoStack : this.redoStack; 10908 stack.push(um2); 10909 this.emit("stack-item-added", [ 10910 { ...change, ydoc }, 10911 this 10912 ]); 10913 } 10914 ); 10915 um2.on( 10916 "stack-item-updated", 10917 /** @param {any} change */ 10918 (change) => { 10919 this.emit("stack-item-updated", [ 10920 { ...change, ydoc }, 10921 this 10922 ]); 10923 } 10924 ); 10925 um2.on( 10926 "stack-item-popped", 10927 /** @param {any} change */ 10928 (change) => { 10929 this.emit("stack-item-popped", [ 10930 { ...change, ydoc }, 10931 this 10932 ]); 10933 } 10934 ); 10935 return um2; 10936 }); 10937 if (um.scope.every((yt) => yt !== ytype)) { 10938 um.scope.push(ytype); 10939 } 10940 }); 10941 } 10942 /** 10943 * @param {any} origin 10944 */ 10945 /* c8 ignore next 3 */ 10946 addTrackedOrigin(origin2) { 10947 this.trackedOrigins.add(origin2); 10948 } 10949 /** 10950 * @param {any} origin 10951 */ 10952 /* c8 ignore next 3 */ 10953 removeTrackedOrigin(origin2) { 10954 this.trackedOrigins.delete(origin2); 10955 } 10956 /** 10957 * Undo last changes on type. 10958 * 10959 * @return {any?} Returns StackItem if a change was applied 10960 */ 10961 undo() { 10962 return popStackItem2(this, "undo"); 10963 } 10964 /** 10965 * Redo last undo operation. 10966 * 10967 * @return {any?} Returns StackItem if a change was applied 10968 */ 10969 redo() { 10970 return popStackItem2(this, "redo"); 10971 } 10972 clear(clearUndoStack = true, clearRedoStack = true) { 10973 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 10974 this.docs.forEach((um) => { 10975 clearUndoStack && (this.undoStack = []); 10976 clearRedoStack && (this.redoStack = []); 10977 um.clear(clearUndoStack, clearRedoStack); 10978 }); 10979 this.emit("stack-cleared", [ 10980 { 10981 undoStackCleared: clearUndoStack, 10982 redoStackCleared: clearRedoStack 10983 } 10984 ]); 10985 } 10986 } 10987 /* c8 ignore next 5 */ 10988 stopCapturing() { 10989 this.docs.forEach((um) => { 10990 um.stopCapturing(); 10991 }); 10992 } 10993 /** 10994 * Are undo steps available? 10995 * 10996 * @return {boolean} `true` if undo is possible 10997 */ 10998 canUndo() { 10999 return this.undoStack.length > 0; 11000 } 11001 /** 11002 * Are redo steps available? 11003 * 11004 * @return {boolean} `true` if redo is possible 11005 */ 11006 canRedo() { 11007 return this.redoStack.length > 0; 11008 } 11009 destroy() { 11010 this.docs.forEach((um) => um.destroy()); 11011 super.destroy(); 11012 } 11013 }; 11014 11015 // packages/sync/build-module/undo-manager.mjs 11016 function createUndoManager() { 11017 const yUndoManager = new YMultiDocUndoManager([], { 11018 // Throttle undo/redo captures after 500ms of inactivity. 11019 // 500 was selected from subjective local UX testing, shorter timeouts 11020 // may cause mid-word undo stack items. 11021 captureTimeout: 500, 11022 // Ensure that we only scope the undo/redo to the current editor. 11023 // The yjs document's clientID is added once it's available. 11024 trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) 11025 }); 11026 return { 11027 /** 11028 * Record changes into the history. 11029 * Since Yjs automatically tracks changes, this method translates the WordPress 11030 * HistoryRecord format into Yjs operations. 11031 * 11032 * @param _record A record of changes to record. 11033 * @param _isStaged Whether to immediately create an undo point or not. 11034 */ 11035 addRecord(_record, _isStaged = false) { 11036 }, 11037 /** 11038 * Add a Yjs map to the scope of the undo manager. 11039 * 11040 * @param {Y.Map< any >} ymap The Yjs map to add to the scope. 11041 * @param handlers 11042 * @param handlers.addUndoMeta 11043 * @param handlers.restoreUndoMeta 11044 */ 11045 addToScope(ymap, handlers) { 11046 if (ymap.doc === null) { 11047 return; 11048 } 11049 const ydoc = ymap.doc; 11050 yUndoManager.addToScope(ymap); 11051 const { addUndoMeta, restoreUndoMeta } = handlers; 11052 yUndoManager.on("stack-item-added", (event) => { 11053 addUndoMeta(ydoc, event.stackItem.meta); 11054 }); 11055 yUndoManager.on("stack-item-popped", (event) => { 11056 restoreUndoMeta(ydoc, event.stackItem.meta); 11057 }); 11058 }, 11059 /** 11060 * Undo the last recorded changes. 11061 * 11062 */ 11063 undo() { 11064 if (!yUndoManager.canUndo()) { 11065 return; 11066 } 11067 yUndoManager.undo(); 11068 return []; 11069 }, 11070 /** 11071 * Redo the last undone changes. 11072 */ 11073 redo() { 11074 if (!yUndoManager.canRedo()) { 11075 return; 11076 } 11077 yUndoManager.redo(); 11078 return []; 11079 }, 11080 /** 11081 * Check if there are changes that can be undone. 11082 * 11083 * @return {boolean} Whether there are changes to undo. 11084 */ 11085 hasUndo() { 11086 return yUndoManager.canUndo(); 11087 }, 11088 /** 11089 * Check if there are changes that can be redone. 11090 * 11091 * @return {boolean} Whether there are changes to redo. 11092 */ 11093 hasRedo() { 11094 return yUndoManager.canRedo(); 11095 }, 11096 /** 11097 * Stop capturing changes into the current undo item. 11098 * The next change will create a new undo item. 11099 */ 11100 stopCapturing() { 11101 yUndoManager.stopCapturing(); 11102 } 11103 }; 11104 } 11105 11106 // packages/sync/build-module/utils.mjs 11107 function createYjsDoc(documentMeta = {}) { 11108 const metaMap = new Map( 11109 Object.entries(documentMeta) 11110 ); 11111 return new Doc({ meta: metaMap }); 11112 } 11113 function initializeYjsDoc(ydoc) { 11114 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11115 stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); 11116 } 11117 function markEntityAsSaved(ydoc) { 11118 const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); 11119 recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); 11120 recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); 11121 } 11122 function pseudoRandomID() { 11123 return Math.floor(Math.random() * 1e9); 11124 } 11125 function serializeCrdtDoc(crdtDoc) { 11126 return JSON.stringify({ 11127 document: toBase64(encodeStateAsUpdateV2(crdtDoc)), 11128 updateId: pseudoRandomID() 11129 // helps with debugging 11130 }); 11131 } 11132 function deserializeCrdtDoc(serializedCrdtDoc) { 11133 try { 11134 const { document: document2 } = JSON.parse(serializedCrdtDoc); 11135 const docMeta = { 11136 [CRDT_DOC_META_PERSISTENCE_KEY]: true 11137 }; 11138 const ydoc = createYjsDoc(docMeta); 11139 const yupdate = fromBase64(document2); 11140 applyUpdateV2(ydoc, yupdate); 11141 ydoc.clientID = pseudoRandomID(); 11142 return ydoc; 11143 } catch (e) { 11144 return null; 11145 } 11146 } 11147 11148 // packages/sync/build-module/manager.mjs 11149 function getEntityId(objectType, objectId) { 11150 return `$objectType}_$objectId}`; 11151 } 11152 function createSyncManager(debug = false) { 11153 const debugWrap = debug ? logPerformanceTiming : passThru; 11154 const collectionStates = /* @__PURE__ */ new Map(); 11155 const entityStates = /* @__PURE__ */ new Map(); 11156 let undoManager2; 11157 function log(component, message, entityId, context = {}) { 11158 if (!debug) { 11159 return; 11160 } 11161 console.log(`[SyncManager][$component}]: $message}`, { 11162 ...context, 11163 entityId 11164 }); 11165 } 11166 async function loadEntity(syncConfig, objectType, objectId, record, handlers) { 11167 const providerCreators2 = getProviderCreators(); 11168 const entityId = getEntityId(objectType, objectId); 11169 if (0 === providerCreators2.length) { 11170 log("loadEntity", "no providers, skipping", entityId); 11171 return; 11172 } 11173 if (entityStates.has(entityId)) { 11174 log("loadEntity", "already loaded", entityId); 11175 return; 11176 } 11177 if (false === syncConfig.shouldSync?.(objectType, objectId)) { 11178 log("loadEntity", "shouldSync false, skipping", entityId); 11179 return; 11180 } 11181 log("loadEntity", "loading", entityId); 11182 handlers = { 11183 addUndoMeta: debugWrap(handlers.addUndoMeta), 11184 editRecord: debugWrap(handlers.editRecord), 11185 getEditedRecord: debugWrap(handlers.getEditedRecord), 11186 onStatusChange: debugWrap(handlers.onStatusChange), 11187 persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), 11188 refetchRecord: debugWrap(handlers.refetchRecord), 11189 restoreUndoMeta: debugWrap(handlers.restoreUndoMeta) 11190 }; 11191 const ydoc = createYjsDoc({ objectType }); 11192 const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); 11193 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11194 const now = Date.now(); 11195 const unload = () => { 11196 log("loadEntity", "unloading", entityId); 11197 providerResults.forEach((result) => result.destroy()); 11198 handlers.onStatusChange(null); 11199 recordMap.unobserveDeep(onRecordUpdate); 11200 stateMap.unobserve(onStateMapUpdate); 11201 ydoc.destroy(); 11202 entityStates.delete(entityId); 11203 }; 11204 const awareness = syncConfig.createAwareness?.(ydoc, objectId); 11205 const onRecordUpdate = (_events, transaction) => { 11206 if (transaction.local && !(transaction.origin instanceof UndoManager)) { 11207 return; 11208 } 11209 void internal.updateEntityRecord(objectType, objectId); 11210 }; 11211 const onStateMapUpdate = (event, transaction) => { 11212 if (transaction.local) { 11213 return; 11214 } 11215 event.keysChanged.forEach((key) => { 11216 switch (key) { 11217 case CRDT_STATE_MAP_SAVED_AT_KEY: 11218 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11219 if ("number" === typeof newValue && newValue > now) { 11220 log("loadEntity", "refetching record", entityId); 11221 void handlers.refetchRecord().catch(() => { 11222 }); 11223 } 11224 break; 11225 } 11226 }); 11227 }; 11228 if (!undoManager2) { 11229 undoManager2 = createUndoManager(); 11230 } 11231 const { addUndoMeta, restoreUndoMeta } = handlers; 11232 undoManager2.addToScope(recordMap, { 11233 addUndoMeta, 11234 restoreUndoMeta 11235 }); 11236 const entityState = { 11237 awareness, 11238 handlers, 11239 objectId, 11240 objectType, 11241 syncConfig, 11242 unload, 11243 ydoc 11244 }; 11245 entityStates.set(entityId, entityState); 11246 log("loadEntity", "connecting", entityId); 11247 const providerResults = await Promise.all( 11248 providerCreators2.map(async (create9) => { 11249 const provider = await create9({ 11250 objectType, 11251 objectId, 11252 ydoc, 11253 awareness 11254 }); 11255 provider.on("status", handlers.onStatusChange); 11256 return provider; 11257 }) 11258 ); 11259 recordMap.observeDeep(onRecordUpdate); 11260 stateMap.observe(onStateMapUpdate); 11261 initializeYjsDoc(ydoc); 11262 internal.applyPersistedCrdtDoc(objectType, objectId, record); 11263 } 11264 async function loadCollection(syncConfig, objectType, handlers) { 11265 const providerCreators2 = getProviderCreators(); 11266 const entityId = getEntityId(objectType, null); 11267 if (0 === providerCreators2.length) { 11268 log("loadCollection", "no providers, skipping", entityId); 11269 return; 11270 } 11271 if (collectionStates.has(objectType)) { 11272 log("loadCollection", "already loaded", entityId); 11273 return; 11274 } 11275 if (false === syncConfig.shouldSync?.(objectType, null)) { 11276 log("loadCollection", "shouldSync false, skipping", entityId); 11277 return; 11278 } 11279 log("loadCollection", "loading", entityId); 11280 const ydoc = createYjsDoc({ collection: true, objectType }); 11281 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11282 const now = Date.now(); 11283 const unload = () => { 11284 log("loadCollection", "unloading", entityId); 11285 providerResults.forEach((result) => result.destroy()); 11286 handlers.onStatusChange(null); 11287 stateMap.unobserve(onStateMapUpdate); 11288 ydoc.destroy(); 11289 collectionStates.delete(objectType); 11290 }; 11291 const onStateMapUpdate = (event, transaction) => { 11292 if (transaction.local) { 11293 return; 11294 } 11295 event.keysChanged.forEach((key) => { 11296 switch (key) { 11297 case CRDT_STATE_MAP_SAVED_AT_KEY: 11298 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11299 if ("number" === typeof newValue && newValue > now) { 11300 void handlers.refetchRecords().catch(() => { 11301 }); 11302 } 11303 break; 11304 } 11305 }); 11306 }; 11307 const awareness = syncConfig.createAwareness?.(ydoc); 11308 const collectionState = { 11309 awareness, 11310 handlers, 11311 syncConfig, 11312 unload, 11313 ydoc 11314 }; 11315 collectionStates.set(objectType, collectionState); 11316 log("loadCollection", "connecting", entityId); 11317 const providerResults = await Promise.all( 11318 providerCreators2.map(async (create9) => { 11319 const provider = await create9({ 11320 awareness, 11321 objectType, 11322 objectId: null, 11323 ydoc 11324 }); 11325 provider.on("status", handlers.onStatusChange); 11326 return provider; 11327 }) 11328 ); 11329 stateMap.observe(onStateMapUpdate); 11330 initializeYjsDoc(ydoc); 11331 } 11332 function unloadEntity(objectType, objectId) { 11333 const entityId = getEntityId(objectType, objectId); 11334 log("unloadEntity", "unloading", entityId); 11335 entityStates.get(entityId)?.unload(); 11336 updateCRDTDoc(objectType, null, {}, origin, { isSave: true }); 11337 } 11338 function getAwareness(objectType, objectId) { 11339 const entityId = getEntityId(objectType, objectId); 11340 const entityState = entityStates.get(entityId); 11341 if (!entityState || !entityState.awareness) { 11342 return void 0; 11343 } 11344 return entityState.awareness; 11345 } 11346 function _applyPersistedCrdtDoc(objectType, objectId, record) { 11347 const entityId = getEntityId(objectType, objectId); 11348 const entityState = entityStates.get(entityId); 11349 if (!entityState) { 11350 log("applyPersistedCrdtDoc", "no entity state", entityId); 11351 return; 11352 } 11353 const { 11354 handlers, 11355 syncConfig: { 11356 applyChangesToCRDTDoc, 11357 getChangesFromCRDTDoc, 11358 getPersistedCRDTDoc 11359 }, 11360 ydoc: targetDoc 11361 } = entityState; 11362 const serialized = getPersistedCRDTDoc?.(record); 11363 const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; 11364 if (!tempDoc) { 11365 log("applyPersistedCrdtDoc", "no persisted doc", entityId); 11366 targetDoc.transact(() => { 11367 applyChangesToCRDTDoc(targetDoc, record); 11368 handlers.persistCRDTDoc(); 11369 }, LOCAL_SYNC_MANAGER_ORIGIN); 11370 return; 11371 } 11372 const update = encodeStateAsUpdateV2(tempDoc); 11373 applyUpdateV2(targetDoc, update); 11374 const invalidations = getChangesFromCRDTDoc(tempDoc, record); 11375 const invalidatedKeys = Object.keys(invalidations); 11376 tempDoc.destroy(); 11377 if (0 === invalidatedKeys.length) { 11378 log("applyPersistedCrdtDoc", "valid persisted doc", entityId); 11379 return; 11380 } 11381 log("applyPersistedCrdtDoc", "invalidated keys", entityId, { 11382 invalidatedKeys 11383 }); 11384 const changes = invalidatedKeys.reduce( 11385 (acc, key) => Object.assign(acc, { 11386 [key]: record[key] 11387 }), 11388 {} 11389 ); 11390 targetDoc.transact(() => { 11391 applyChangesToCRDTDoc(targetDoc, changes); 11392 handlers.persistCRDTDoc(); 11393 }, LOCAL_SYNC_MANAGER_ORIGIN); 11394 } 11395 function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { 11396 const { isSave = false, isNewUndoLevel = false } = options; 11397 const entityId = getEntityId(objectType, objectId); 11398 const entityState = entityStates.get(entityId); 11399 const collectionState = collectionStates.get(objectType); 11400 if (entityState) { 11401 const { syncConfig, ydoc } = entityState; 11402 if (isNewUndoLevel && undoManager2) { 11403 undoManager2.stopCapturing?.(); 11404 } 11405 ydoc.transact(() => { 11406 log("updateCRDTDoc", "applying changes", entityId, { 11407 changedKeys: Object.keys(changes) 11408 }); 11409 syncConfig.applyChangesToCRDTDoc(ydoc, changes); 11410 if (isSave) { 11411 markEntityAsSaved(ydoc); 11412 } 11413 }, origin2); 11414 } 11415 if (collectionState && isSave) { 11416 collectionState.ydoc.transact(() => { 11417 markEntityAsSaved(collectionState.ydoc); 11418 }, origin2); 11419 } 11420 } 11421 async function _updateEntityRecord(objectType, objectId) { 11422 const entityId = getEntityId(objectType, objectId); 11423 const entityState = entityStates.get(entityId); 11424 if (!entityState) { 11425 log("updateEntityRecord", "no entity state", entityId); 11426 return; 11427 } 11428 const { handlers, syncConfig, ydoc } = entityState; 11429 const changes = syncConfig.getChangesFromCRDTDoc( 11430 ydoc, 11431 await handlers.getEditedRecord() 11432 ); 11433 const changedKeys = Object.keys(changes); 11434 if (0 === changedKeys.length) { 11435 return; 11436 } 11437 log("updateEntityRecord", "changes", entityId, { 11438 changedKeys 11439 }); 11440 handlers.editRecord(changes); 11441 } 11442 async function createPersistedCRDTDoc(objectType, objectId) { 11443 const entityId = getEntityId(objectType, objectId); 11444 const entityState = entityStates.get(entityId); 11445 if (!entityState?.ydoc) { 11446 return null; 11447 } 11448 await new Promise((resolve) => setTimeout(resolve, 0)); 11449 return serializeCrdtDoc(entityState.ydoc); 11450 } 11451 const internal = { 11452 applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), 11453 updateEntityRecord: debugWrap(_updateEntityRecord) 11454 }; 11455 return { 11456 createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), 11457 getAwareness, 11458 load: debugWrap(loadEntity), 11459 loadCollection: debugWrap(loadCollection), 11460 // Use getter to ensure we always return the current value of `undoManager`. 11461 get undoManager() { 11462 return undoManager2; 11463 }, 11464 unload: debugWrap(unloadEntity), 11465 update: debugWrap(yieldToEventLoop(updateCRDTDoc)) 11466 }; 11467 } 11468 11469 // packages/sync/node_modules/diff/libesm/diff/base.js 11470 var Diff = class { 11471 diff(oldStr, newStr, options = {}) { 11472 let callback; 11473 if (typeof options === "function") { 11474 callback = options; 11475 options = {}; 11476 } else if ("callback" in options) { 11477 callback = options.callback; 11478 } 11479 const oldString = this.castInput(oldStr, options); 11480 const newString = this.castInput(newStr, options); 11481 const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); 11482 const newTokens = this.removeEmpty(this.tokenize(newString, options)); 11483 return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); 11484 } 11485 diffWithOptionsObj(oldTokens, newTokens, options, callback) { 11486 var _a; 11487 const done = (value) => { 11488 value = this.postProcess(value, options); 11489 if (callback) { 11490 setTimeout(function() { 11491 callback(value); 11492 }, 0); 11493 return void 0; 11494 } else { 11495 return value; 11496 } 11497 }; 11498 const newLen = newTokens.length, oldLen = oldTokens.length; 11499 let editLength = 1; 11500 let maxEditLength = newLen + oldLen; 11501 if (options.maxEditLength != null) { 11502 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 11503 } 11504 const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; 11505 const abortAfterTimestamp = Date.now() + maxExecutionTime; 11506 const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; 11507 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); 11508 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11509 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); 11510 } 11511 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; 11512 const execEditLength = () => { 11513 for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 11514 let basePath; 11515 const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; 11516 if (removePath) { 11517 bestPath[diagonalPath - 1] = void 0; 11518 } 11519 let canAdd = false; 11520 if (addPath) { 11521 const addPathNewPos = addPath.oldPos - diagonalPath; 11522 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 11523 } 11524 const canRemove = removePath && removePath.oldPos + 1 < oldLen; 11525 if (!canAdd && !canRemove) { 11526 bestPath[diagonalPath] = void 0; 11527 continue; 11528 } 11529 if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { 11530 basePath = this.addToPath(addPath, true, false, 0, options); 11531 } else { 11532 basePath = this.addToPath(removePath, false, true, 1, options); 11533 } 11534 newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); 11535 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 11536 return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; 11537 } else { 11538 bestPath[diagonalPath] = basePath; 11539 if (basePath.oldPos + 1 >= oldLen) { 11540 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 11541 } 11542 if (newPos + 1 >= newLen) { 11543 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 11544 } 11545 } 11546 } 11547 editLength++; 11548 }; 11549 if (callback) { 11550 (function exec() { 11551 setTimeout(function() { 11552 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 11553 return callback(void 0); 11554 } 11555 if (!execEditLength()) { 11556 exec(); 11557 } 11558 }, 0); 11559 })(); 11560 } else { 11561 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 11562 const ret = execEditLength(); 11563 if (ret) { 11564 return ret; 11565 } 11566 } 11567 } 11568 } 11569 addToPath(path, added, removed, oldPosInc, options) { 11570 const last2 = path.lastComponent; 11571 if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { 11572 return { 11573 oldPos: path.oldPos + oldPosInc, 11574 lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } 11575 }; 11576 } else { 11577 return { 11578 oldPos: path.oldPos + oldPosInc, 11579 lastComponent: { count: 1, added, removed, previousComponent: last2 } 11580 }; 11581 } 11582 } 11583 extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { 11584 const newLen = newTokens.length, oldLen = oldTokens.length; 11585 let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; 11586 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { 11587 newPos++; 11588 oldPos++; 11589 commonCount++; 11590 if (options.oneChangePerToken) { 11591 basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; 11592 } 11593 } 11594 if (commonCount && !options.oneChangePerToken) { 11595 basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; 11596 } 11597 basePath.oldPos = oldPos; 11598 return newPos; 11599 } 11600 equals(left, right, options) { 11601 if (options.comparator) { 11602 return options.comparator(left, right); 11603 } else { 11604 return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 11605 } 11606 } 11607 removeEmpty(array) { 11608 const ret = []; 11609 for (let i = 0; i < array.length; i++) { 11610 if (array[i]) { 11611 ret.push(array[i]); 11612 } 11613 } 11614 return ret; 11615 } 11616 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11617 castInput(value, options) { 11618 return value; 11619 } 11620 // eslint-disable-next-line @typescript-eslint/no-unused-vars 11621 tokenize(value, options) { 11622 return Array.from(value); 11623 } 11624 join(chars) { 11625 return chars.join(""); 11626 } 11627 postProcess(changeObjects, options) { 11628 return changeObjects; 11629 } 11630 get useLongestToken() { 11631 return false; 11632 } 11633 buildValues(lastComponent, newTokens, oldTokens) { 11634 const components = []; 11635 let nextComponent; 11636 while (lastComponent) { 11637 components.push(lastComponent); 11638 nextComponent = lastComponent.previousComponent; 11639 delete lastComponent.previousComponent; 11640 lastComponent = nextComponent; 11641 } 11642 components.reverse(); 11643 const componentLen = components.length; 11644 let componentPos = 0, newPos = 0, oldPos = 0; 11645 for (; componentPos < componentLen; componentPos++) { 11646 const component = components[componentPos]; 11647 if (!component.removed) { 11648 if (!component.added && this.useLongestToken) { 11649 let value = newTokens.slice(newPos, newPos + component.count); 11650 value = value.map(function(value2, i) { 11651 const oldValue = oldTokens[oldPos + i]; 11652 return oldValue.length > value2.length ? oldValue : value2; 11653 }); 11654 component.value = this.join(value); 11655 } else { 11656 component.value = this.join(newTokens.slice(newPos, newPos + component.count)); 11657 } 11658 newPos += component.count; 11659 if (!component.added) { 11660 oldPos += component.count; 11661 } 11662 } else { 11663 component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); 11664 oldPos += component.count; 11665 } 11666 } 11667 return components; 11668 } 11669 }; 11670 11671 // packages/sync/node_modules/diff/libesm/diff/character.js 11672 var CharacterDiff = class extends Diff { 11673 }; 11674 var characterDiff = new CharacterDiff(); 11675 function diffChars(oldStr, newStr, options) { 11676 return characterDiff.diff(oldStr, newStr, options); 11677 } 11678 11679 // packages/sync/node_modules/diff/libesm/diff/line.js 11680 var LineDiff = class extends Diff { 11681 constructor() { 11682 super(...arguments); 11683 this.tokenize = tokenize; 11684 } 11685 equals(left, right, options) { 11686 if (options.ignoreWhitespace) { 11687 if (!options.newlineIsToken || !left.includes("\n")) { 11688 left = left.trim(); 11689 } 11690 if (!options.newlineIsToken || !right.includes("\n")) { 11691 right = right.trim(); 11692 } 11693 } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { 11694 if (left.endsWith("\n")) { 11695 left = left.slice(0, -1); 11696 } 11697 if (right.endsWith("\n")) { 11698 right = right.slice(0, -1); 11699 } 11700 } 11701 return super.equals(left, right, options); 11702 } 11703 }; 11704 var lineDiff = new LineDiff(); 11705 function diffLines(oldStr, newStr, options) { 11706 return lineDiff.diff(oldStr, newStr, options); 11707 } 11708 function tokenize(value, options) { 11709 if (options.stripTrailingCr) { 11710 value = value.replace(/\r\n/g, "\n"); 11711 } 11712 const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); 11713 if (!linesAndNewlines[linesAndNewlines.length - 1]) { 11714 linesAndNewlines.pop(); 11715 } 11716 for (let i = 0; i < linesAndNewlines.length; i++) { 11717 const line = linesAndNewlines[i]; 11718 if (i % 2 && !options.newlineIsToken) { 11719 retLines[retLines.length - 1] += line; 11720 } else { 11721 retLines.push(line); 11722 } 11723 } 11724 return retLines; 11725 } 11726 11727 // packages/sync/build-module/quill-delta/Delta.mjs 11728 var import_es63 = __toESM(require_es6(), 1); 11729 11730 // packages/sync/build-module/quill-delta/AttributeMap.mjs 11731 var import_es62 = __toESM(require_es6(), 1); 11732 function cloneDeep(value) { 11733 return JSON.parse(JSON.stringify(value)); 11734 } 11735 var AttributeMap; 11736 ((AttributeMap2) => { 11737 function compose3(a = {}, b = {}, keepNull = false) { 11738 if (typeof a !== "object") { 11739 a = {}; 11740 } 11741 if (typeof b !== "object") { 11742 b = {}; 11743 } 11744 let attributes = cloneDeep(b); 11745 if (!keepNull) { 11746 attributes = Object.keys(attributes).reduce( 11747 (copy2, key) => { 11748 if (attributes[key] !== null || attributes[key] !== void 0) { 11749 copy2[key] = attributes[key]; 11750 } 11751 return copy2; 11752 }, 11753 {} 11754 ); 11755 } 11756 for (const key in a) { 11757 if (a[key] !== void 0 && b[key] === void 0) { 11758 attributes[key] = a[key]; 11759 } 11760 } 11761 return Object.keys(attributes).length > 0 ? attributes : void 0; 11762 } 11763 AttributeMap2.compose = compose3; 11764 function diff(a = {}, b = {}) { 11765 if (typeof a !== "object") { 11766 a = {}; 11767 } 11768 if (typeof b !== "object") { 11769 b = {}; 11770 } 11771 const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { 11772 if (!(0, import_es62.default)(a[key], b[key])) { 11773 attrs[key] = b[key] === void 0 ? null : b[key]; 11774 } 11775 return attrs; 11776 }, {}); 11777 return Object.keys(attributes).length > 0 ? attributes : void 0; 11778 } 11779 AttributeMap2.diff = diff; 11780 function invert(attr = {}, base = {}) { 11781 attr = attr || {}; 11782 const baseInverted = Object.keys(base).reduce( 11783 (memo, key) => { 11784 if (base[key] !== attr[key] && attr[key] !== void 0) { 11785 memo[key] = base[key]; 11786 } 11787 return memo; 11788 }, 11789 {} 11790 ); 11791 return Object.keys(attr).reduce((memo, key) => { 11792 if (attr[key] !== base[key] && base[key] === void 0) { 11793 memo[key] = null; 11794 } 11795 return memo; 11796 }, baseInverted); 11797 } 11798 AttributeMap2.invert = invert; 11799 function transform(a, b, priority = false) { 11800 if (typeof a !== "object") { 11801 return b; 11802 } 11803 if (typeof b !== "object") { 11804 return void 0; 11805 } 11806 if (!priority) { 11807 return b; 11808 } 11809 const attributes = Object.keys(b).reduce( 11810 (attrs, key) => { 11811 if (a[key] === void 0) { 11812 attrs[key] = b[key]; 11813 } 11814 return attrs; 11815 }, 11816 {} 11817 ); 11818 return Object.keys(attributes).length > 0 ? attributes : void 0; 11819 } 11820 AttributeMap2.transform = transform; 11821 })(AttributeMap || (AttributeMap = {})); 11822 var AttributeMap_default = AttributeMap; 11823 11824 // packages/sync/build-module/quill-delta/Op.mjs 11825 var Op; 11826 ((Op2) => { 11827 function length3(op) { 11828 if (typeof op.delete === "number") { 11829 return op.delete; 11830 } else if (typeof op.retain === "number") { 11831 return op.retain; 11832 } else if (typeof op.retain === "object" && op.retain !== null) { 11833 return 1; 11834 } 11835 return typeof op.insert === "string" ? op.insert.length : 1; 11836 } 11837 Op2.length = length3; 11838 })(Op || (Op = {})); 11839 var Op_default = Op; 11840 11841 // packages/sync/build-module/quill-delta/OpIterator.mjs 11842 var Iterator2 = class { 11843 ops; 11844 index; 11845 offset; 11846 constructor(ops) { 11847 this.ops = ops; 11848 this.index = 0; 11849 this.offset = 0; 11850 } 11851 hasNext() { 11852 return this.peekLength() < Infinity; 11853 } 11854 next(length3) { 11855 if (!length3) { 11856 length3 = Infinity; 11857 } 11858 const nextOp = this.ops[this.index]; 11859 if (nextOp) { 11860 const offset = this.offset; 11861 const opLength = Op_default.length(nextOp); 11862 if (length3 >= opLength - offset) { 11863 length3 = opLength - offset; 11864 this.index += 1; 11865 this.offset = 0; 11866 } else { 11867 this.offset += length3; 11868 } 11869 if (typeof nextOp.delete === "number") { 11870 return { delete: length3 }; 11871 } 11872 const retOp = {}; 11873 if (nextOp.attributes) { 11874 retOp.attributes = nextOp.attributes; 11875 } 11876 if (typeof nextOp.retain === "number") { 11877 retOp.retain = length3; 11878 } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { 11879 retOp.retain = nextOp.retain; 11880 } else if (typeof nextOp.insert === "string") { 11881 retOp.insert = nextOp.insert.substr(offset, length3); 11882 } else { 11883 retOp.insert = nextOp.insert; 11884 } 11885 return retOp; 11886 } 11887 return { retain: Infinity }; 11888 } 11889 peek() { 11890 return this.ops[this.index]; 11891 } 11892 peekLength() { 11893 if (this.ops[this.index]) { 11894 return Op_default.length(this.ops[this.index]) - this.offset; 11895 } 11896 return Infinity; 11897 } 11898 peekType() { 11899 const op = this.ops[this.index]; 11900 if (op) { 11901 if (typeof op.delete === "number") { 11902 return "delete"; 11903 } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { 11904 return "retain"; 11905 } 11906 return "insert"; 11907 } 11908 return "retain"; 11909 } 11910 rest() { 11911 if (!this.hasNext()) { 11912 return []; 11913 } else if (this.offset === 0) { 11914 return this.ops.slice(this.index); 11915 } 11916 const offset = this.offset; 11917 const index = this.index; 11918 const next = this.next(); 11919 const rest = this.ops.slice(this.index); 11920 this.offset = offset; 11921 this.index = index; 11922 return [next].concat(rest); 11923 } 11924 }; 11925 11926 // packages/sync/build-module/quill-delta/Delta.mjs 11927 function cloneDeep2(value) { 11928 return JSON.parse(JSON.stringify(value)); 11929 } 11930 var NULL_CHARACTER = String.fromCharCode(0); 11931 var STRING_TOO_LARGE_THRESHOLD = 1e4; 11932 function normalizeChangeCounts(changes) { 11933 return changes.map((change) => ({ 11934 ...change, 11935 count: change.value.length 11936 })); 11937 } 11938 var getEmbedTypeAndData = (a, b) => { 11939 if (typeof a !== "object" || a === null) { 11940 throw new Error(`cannot retain a $typeof a}`); 11941 } 11942 if (typeof b !== "object" || b === null) { 11943 throw new Error(`cannot retain a $typeof b}`); 11944 } 11945 const embedType = Object.keys(a)[0]; 11946 if (!embedType || embedType !== Object.keys(b)[0]) { 11947 throw new Error( 11948 `embed types not matched: $embedType} != $Object.keys(b)[0]}` 11949 ); 11950 } 11951 return [embedType, a[embedType], b[embedType]]; 11952 }; 11953 var Delta = class _Delta { 11954 static Op = Op_default; 11955 static OpIterator = Iterator2; 11956 static AttributeMap = AttributeMap_default; 11957 static handlers = {}; 11958 static registerEmbed(embedType, handler) { 11959 this.handlers[embedType] = handler; 11960 } 11961 static unregisterEmbed(embedType) { 11962 delete this.handlers[embedType]; 11963 } 11964 static getHandler(embedType) { 11965 const handler = this.handlers[embedType]; 11966 if (!handler) { 11967 throw new Error(`no handlers for embed type "$embedType}"`); 11968 } 11969 return handler; 11970 } 11971 ops; 11972 constructor(ops) { 11973 if (Array.isArray(ops)) { 11974 this.ops = ops; 11975 } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { 11976 this.ops = ops.ops; 11977 } else { 11978 this.ops = []; 11979 } 11980 } 11981 insert(arg, attributes) { 11982 const newOp = {}; 11983 if (typeof arg === "string" && arg.length === 0) { 11984 return this; 11985 } 11986 newOp.insert = arg; 11987 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 11988 newOp.attributes = attributes; 11989 } 11990 return this.push(newOp); 11991 } 11992 delete(length3) { 11993 if (length3 <= 0) { 11994 return this; 11995 } 11996 return this.push({ delete: length3 }); 11997 } 11998 retain(length3, attributes) { 11999 if (typeof length3 === "number" && length3 <= 0) { 12000 return this; 12001 } 12002 const newOp = { retain: length3 }; 12003 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12004 newOp.attributes = attributes; 12005 } 12006 return this.push(newOp); 12007 } 12008 push(newOp) { 12009 let index = this.ops.length; 12010 let lastOp = this.ops[index - 1]; 12011 newOp = cloneDeep2(newOp); 12012 if (typeof lastOp === "object") { 12013 if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { 12014 this.ops[index - 1] = { 12015 delete: lastOp.delete + newOp.delete 12016 }; 12017 return this; 12018 } 12019 if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { 12020 index -= 1; 12021 lastOp = this.ops[index - 1]; 12022 if (typeof lastOp !== "object") { 12023 this.ops.unshift(newOp); 12024 return this; 12025 } 12026 } 12027 if ((0, import_es63.default)(newOp.attributes, lastOp.attributes)) { 12028 if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { 12029 this.ops[index - 1] = { 12030 insert: lastOp.insert + newOp.insert 12031 }; 12032 if (typeof newOp.attributes === "object") { 12033 this.ops[index - 1].attributes = newOp.attributes; 12034 } 12035 return this; 12036 } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { 12037 this.ops[index - 1] = { 12038 retain: lastOp.retain + newOp.retain 12039 }; 12040 if (typeof newOp.attributes === "object") { 12041 this.ops[index - 1].attributes = newOp.attributes; 12042 } 12043 return this; 12044 } 12045 } 12046 } 12047 if (index === this.ops.length) { 12048 this.ops.push(newOp); 12049 } else { 12050 this.ops.splice(index, 0, newOp); 12051 } 12052 return this; 12053 } 12054 chop() { 12055 const lastOp = this.ops[this.ops.length - 1]; 12056 if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { 12057 this.ops.pop(); 12058 } 12059 return this; 12060 } 12061 filter(predicate) { 12062 return this.ops.filter(predicate); 12063 } 12064 forEach(predicate) { 12065 this.ops.forEach(predicate); 12066 } 12067 map(predicate) { 12068 return this.ops.map(predicate); 12069 } 12070 partition(predicate) { 12071 const passed = []; 12072 const failed = []; 12073 this.forEach((op) => { 12074 const target = predicate(op) ? passed : failed; 12075 target.push(op); 12076 }); 12077 return [passed, failed]; 12078 } 12079 reduce(predicate, initialValue) { 12080 return this.ops.reduce(predicate, initialValue); 12081 } 12082 changeLength() { 12083 return this.reduce((length3, elem) => { 12084 if (elem.insert) { 12085 return length3 + Op_default.length(elem); 12086 } else if (elem.delete) { 12087 return length3 - elem.delete; 12088 } 12089 return length3; 12090 }, 0); 12091 } 12092 length() { 12093 return this.reduce((length3, elem) => { 12094 return length3 + Op_default.length(elem); 12095 }, 0); 12096 } 12097 slice(start = 0, end = Infinity) { 12098 const ops = []; 12099 const iter = new Iterator2(this.ops); 12100 let index = 0; 12101 while (index < end && iter.hasNext()) { 12102 let nextOp; 12103 if (index < start) { 12104 nextOp = iter.next(start - index); 12105 } else { 12106 nextOp = iter.next(end - index); 12107 ops.push(nextOp); 12108 } 12109 index += Op_default.length(nextOp); 12110 } 12111 return new _Delta(ops); 12112 } 12113 compose(other) { 12114 const thisIter = new Iterator2(this.ops); 12115 const otherIter = new Iterator2(other.ops); 12116 const ops = []; 12117 const firstOther = otherIter.peek(); 12118 if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { 12119 let firstLeft = firstOther.retain; 12120 while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { 12121 firstLeft -= thisIter.peekLength(); 12122 ops.push(thisIter.next()); 12123 } 12124 if (firstOther.retain - firstLeft > 0) { 12125 otherIter.next(firstOther.retain - firstLeft); 12126 } 12127 } 12128 const delta = new _Delta(ops); 12129 while (thisIter.hasNext() || otherIter.hasNext()) { 12130 if (otherIter.peekType() === "insert") { 12131 delta.push(otherIter.next()); 12132 } else if (thisIter.peekType() === "delete") { 12133 delta.push(thisIter.next()); 12134 } else { 12135 const length3 = Math.min( 12136 thisIter.peekLength(), 12137 otherIter.peekLength() 12138 ); 12139 const thisOp = thisIter.next(length3); 12140 const otherOp = otherIter.next(length3); 12141 if (otherOp.retain) { 12142 const newOp = {}; 12143 if (typeof thisOp.retain === "number") { 12144 newOp.retain = typeof otherOp.retain === "number" ? length3 : otherOp.retain; 12145 } else if (typeof otherOp.retain === "number") { 12146 if (thisOp.retain === null || thisOp.retain === void 0) { 12147 newOp.insert = thisOp.insert; 12148 } else { 12149 newOp.retain = thisOp.retain; 12150 } 12151 } else { 12152 const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; 12153 const [embedType, thisData, otherData] = getEmbedTypeAndData( 12154 thisOp[action], 12155 otherOp.retain 12156 ); 12157 const handler = _Delta.getHandler(embedType); 12158 newOp[action] = { 12159 [embedType]: handler.compose( 12160 thisData, 12161 otherData, 12162 action === "retain" 12163 ) 12164 }; 12165 } 12166 const attributes = AttributeMap_default.compose( 12167 thisOp.attributes, 12168 otherOp.attributes, 12169 typeof thisOp.retain === "number" 12170 ); 12171 if (attributes) { 12172 newOp.attributes = attributes; 12173 } 12174 delta.push(newOp); 12175 if (!otherIter.hasNext() && (0, import_es63.default)(delta.ops[delta.ops.length - 1], newOp)) { 12176 const rest = new _Delta(thisIter.rest()); 12177 return delta.concat(rest).chop(); 12178 } 12179 } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { 12180 delta.push(otherOp); 12181 } 12182 } 12183 } 12184 return delta.chop(); 12185 } 12186 concat(other) { 12187 const delta = new _Delta(this.ops.slice()); 12188 if (other.ops.length > 0) { 12189 delta.push(other.ops[0]); 12190 delta.ops = delta.ops.concat(other.ops.slice(1)); 12191 } 12192 return delta; 12193 } 12194 diff(other) { 12195 if (this.ops === other.ops) { 12196 return new _Delta(); 12197 } 12198 const strings = this.deltasToStrings(other); 12199 const diffResult = normalizeChangeCounts( 12200 diffChars(strings[0], strings[1]) 12201 ); 12202 const thisIter = new Iterator2(this.ops); 12203 const otherIter = new Iterator2(other.ops); 12204 const retDelta = this.convertChangesToDelta( 12205 diffResult, 12206 thisIter, 12207 otherIter 12208 ); 12209 return retDelta.chop(); 12210 } 12211 eachLine(predicate, newline = "\n") { 12212 const iter = new Iterator2(this.ops); 12213 let line = new _Delta(); 12214 let i = 0; 12215 while (iter.hasNext()) { 12216 if (iter.peekType() !== "insert") { 12217 return; 12218 } 12219 const thisOp = iter.peek(); 12220 const start = Op_default.length(thisOp) - iter.peekLength(); 12221 const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; 12222 if (index < 0) { 12223 line.push(iter.next()); 12224 } else if (index > 0) { 12225 line.push(iter.next(index)); 12226 } else { 12227 if (predicate(line, iter.next(1).attributes || {}, i) === false) { 12228 return; 12229 } 12230 i += 1; 12231 line = new _Delta(); 12232 } 12233 } 12234 if (line.length() > 0) { 12235 predicate(line, {}, i); 12236 } 12237 } 12238 invert(base) { 12239 const inverted = new _Delta(); 12240 this.reduce((baseIndex, op) => { 12241 if (op.insert) { 12242 inverted.delete(Op_default.length(op)); 12243 } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { 12244 inverted.retain(op.retain); 12245 return baseIndex + op.retain; 12246 } else if (op.delete || typeof op.retain === "number") { 12247 const length3 = op.delete || op.retain; 12248 const slice = base.slice(baseIndex, baseIndex + length3); 12249 slice.forEach((baseOp) => { 12250 if (op.delete) { 12251 inverted.push(baseOp); 12252 } else if (op.retain && op.attributes) { 12253 inverted.retain( 12254 Op_default.length(baseOp), 12255 AttributeMap_default.invert( 12256 op.attributes, 12257 baseOp.attributes 12258 ) 12259 ); 12260 } 12261 }); 12262 return baseIndex + length3; 12263 } else if (typeof op.retain === "object" && op.retain !== null) { 12264 const slice = base.slice(baseIndex, baseIndex + 1); 12265 const baseOp = new Iterator2(slice.ops).next(); 12266 const [embedType, opData, baseOpData] = getEmbedTypeAndData( 12267 op.retain, 12268 baseOp.insert 12269 ); 12270 const handler = _Delta.getHandler(embedType); 12271 inverted.retain( 12272 { [embedType]: handler.invert(opData, baseOpData) }, 12273 AttributeMap_default.invert(op.attributes, baseOp.attributes) 12274 ); 12275 return baseIndex + 1; 12276 } 12277 return baseIndex; 12278 }, 0); 12279 return inverted.chop(); 12280 } 12281 transform(arg, priority = false) { 12282 priority = !!priority; 12283 if (typeof arg === "number") { 12284 return this.transformPosition(arg, priority); 12285 } 12286 const other = arg; 12287 const thisIter = new Iterator2(this.ops); 12288 const otherIter = new Iterator2(other.ops); 12289 const delta = new _Delta(); 12290 while (thisIter.hasNext() || otherIter.hasNext()) { 12291 if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { 12292 delta.retain(Op_default.length(thisIter.next())); 12293 } else if (otherIter.peekType() === "insert") { 12294 delta.push(otherIter.next()); 12295 } else { 12296 const length3 = Math.min( 12297 thisIter.peekLength(), 12298 otherIter.peekLength() 12299 ); 12300 const thisOp = thisIter.next(length3); 12301 const otherOp = otherIter.next(length3); 12302 if (thisOp.delete) { 12303 continue; 12304 } else if (otherOp.delete) { 12305 delta.push(otherOp); 12306 } else { 12307 const thisData = thisOp.retain; 12308 const otherData = otherOp.retain; 12309 let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length3; 12310 if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { 12311 const embedType = Object.keys(thisData)[0]; 12312 if (embedType === Object.keys(otherData)[0]) { 12313 const handler = _Delta.getHandler(embedType); 12314 if (handler) { 12315 transformedData = { 12316 [embedType]: handler.transform( 12317 thisData[embedType], 12318 otherData[embedType], 12319 priority 12320 ) 12321 }; 12322 } 12323 } 12324 } 12325 delta.retain( 12326 transformedData, 12327 AttributeMap_default.transform( 12328 thisOp.attributes, 12329 otherOp.attributes, 12330 priority 12331 ) 12332 ); 12333 } 12334 } 12335 } 12336 return delta.chop(); 12337 } 12338 transformPosition(index, priority = false) { 12339 priority = !!priority; 12340 const thisIter = new Iterator2(this.ops); 12341 let offset = 0; 12342 while (thisIter.hasNext() && offset <= index) { 12343 const length3 = thisIter.peekLength(); 12344 const nextType = thisIter.peekType(); 12345 thisIter.next(); 12346 if (nextType === "delete") { 12347 index -= Math.min(length3, index - offset); 12348 continue; 12349 } else if (nextType === "insert" && (offset < index || !priority)) { 12350 index += length3; 12351 } 12352 offset += length3; 12353 } 12354 return index; 12355 } 12356 /** 12357 * Given a Delta and a cursor position, do a diff and attempt to adjust 12358 * the diff to place insertions or deletions at the cursor position. 12359 * 12360 * @param other - The other Delta to diff against. 12361 * @param cursorAfterChange - The cursor position index after the change. 12362 * @return A Delta that attempts to place insertions or deletions at the cursor position. 12363 */ 12364 diffWithCursor(other, cursorAfterChange) { 12365 if (this.ops === other.ops) { 12366 return new _Delta(); 12367 } 12368 const strings = this.deltasToStrings(other); 12369 const maxStringLength = Math.max( 12370 ...strings.map((str) => str.length) 12371 ); 12372 if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { 12373 const diffResult = normalizeChangeCounts( 12374 diffLines(strings[0], strings[1]) 12375 ); 12376 const thisIterLarge = new Iterator2(this.ops); 12377 const otherIterLarge = new Iterator2(other.ops); 12378 return this.convertChangesToDelta( 12379 diffResult, 12380 thisIterLarge, 12381 otherIterLarge 12382 ).chop(); 12383 } else if (cursorAfterChange === null) { 12384 return this.diff(other); 12385 } 12386 let diffs = normalizeChangeCounts( 12387 diffChars(strings[0], strings[1]) 12388 ); 12389 let lastDiffPosition = 0; 12390 const adjustedDiffs = []; 12391 for (let i = 0; i < diffs.length; i++) { 12392 const diff = diffs[i]; 12393 const segmentStart = lastDiffPosition; 12394 const segmentEnd = lastDiffPosition + (diff.count ?? 0); 12395 const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; 12396 const isUnchangedSegment = !diff.added && !diff.removed; 12397 const isRemovalSegment = diff.removed && !diff.added; 12398 const nextDiff = diffs[i + 1]; 12399 const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; 12400 if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { 12401 const movedSegments = this.tryMoveInsertionToCursor( 12402 diff, 12403 nextDiff, 12404 cursorAfterChange, 12405 segmentStart 12406 ); 12407 if (movedSegments) { 12408 adjustedDiffs.push(...movedSegments); 12409 i++; 12410 lastDiffPosition = segmentEnd; 12411 continue; 12412 } 12413 } 12414 if (isRemovalSegment) { 12415 const movedSegments = this.tryMoveDeletionToCursor( 12416 diff, 12417 adjustedDiffs, 12418 cursorAfterChange, 12419 lastDiffPosition 12420 ); 12421 if (movedSegments) { 12422 adjustedDiffs.pop(); 12423 adjustedDiffs.push(...movedSegments); 12424 lastDiffPosition += diff.count ?? 0; 12425 continue; 12426 } 12427 } 12428 adjustedDiffs.push(diff); 12429 if (!diff.added) { 12430 lastDiffPosition += diff.count ?? 0; 12431 } 12432 } 12433 diffs = adjustedDiffs; 12434 const thisIter = new Iterator2(this.ops); 12435 const otherIter = new Iterator2(other.ops); 12436 const retDelta = this.convertChangesToDelta( 12437 diffs, 12438 thisIter, 12439 otherIter 12440 ); 12441 return retDelta.chop(); 12442 } 12443 /** 12444 * Try to move an insertion operation from after an unchanged segment to the cursor position within it. 12445 * This is a "look-ahead" strategy. 12446 * 12447 * @param diff - The current unchanged diff segment. 12448 * @param nextDiff - The next diff segment (expected to be an insertion). 12449 * @param cursorAfterChange - The cursor position after the change. 12450 * @param segmentStart - The start position of the current segment. 12451 * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. 12452 */ 12453 tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { 12454 const nextDiffInsert = nextDiff.value; 12455 const insertLength = nextDiffInsert.length; 12456 const insertOffset = cursorAfterChange - segmentStart - insertLength; 12457 const textAtCursor = diff.value.substring( 12458 insertOffset, 12459 insertOffset + nextDiffInsert.length 12460 ); 12461 const isInsertMoveable = textAtCursor === nextDiffInsert; 12462 if (!isInsertMoveable) { 12463 return null; 12464 } 12465 const beforeCursor = diff.value.substring(0, insertOffset); 12466 const afterCursor = diff.value.substring(insertOffset); 12467 const result = []; 12468 if (beforeCursor.length > 0) { 12469 result.push({ 12470 value: beforeCursor, 12471 count: beforeCursor.length, 12472 added: false, 12473 removed: false 12474 }); 12475 } 12476 result.push(nextDiff); 12477 if (afterCursor.length > 0) { 12478 result.push({ 12479 value: afterCursor, 12480 count: afterCursor.length, 12481 added: false, 12482 removed: false 12483 }); 12484 } 12485 return result; 12486 } 12487 /** 12488 * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. 12489 * This is a "look-back" strategy. 12490 * 12491 * @param diff - The current deletion diff segment. 12492 * @param adjustedDiffs - The array of previously processed diff segments. 12493 * @param cursorAfterChange - The cursor position after the change. 12494 * @param lastDiffPosition - The position in the document up to (but not including) the current diff. 12495 * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. 12496 */ 12497 tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { 12498 const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; 12499 if (!prevDiff || prevDiff.added || prevDiff.removed) { 12500 return null; 12501 } 12502 const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); 12503 const prevSegmentEnd = lastDiffPosition; 12504 if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { 12505 return null; 12506 } 12507 const deletedChars = diff.value; 12508 const deleteOffset = cursorAfterChange - prevSegmentStart; 12509 const textAtCursor = prevDiff.value.substring( 12510 deleteOffset, 12511 deleteOffset + deletedChars.length 12512 ); 12513 const canBePlacedHere = textAtCursor === deletedChars; 12514 if (!canBePlacedHere) { 12515 return null; 12516 } 12517 const beforeCursor = prevDiff.value.substring(0, deleteOffset); 12518 const atAndAfterCursor = prevDiff.value.substring(deleteOffset); 12519 const deletionLength = diff.count ?? 0; 12520 const afterDeletion = atAndAfterCursor.substring(deletionLength); 12521 const result = []; 12522 if (beforeCursor.length > 0) { 12523 result.push({ 12524 value: beforeCursor, 12525 count: beforeCursor.length, 12526 added: false, 12527 removed: false 12528 }); 12529 } 12530 result.push(diff); 12531 if (afterDeletion.length > 0) { 12532 result.push({ 12533 value: afterDeletion, 12534 count: afterDeletion.length, 12535 added: false, 12536 removed: false 12537 }); 12538 } 12539 return result; 12540 } 12541 /** 12542 * Convert two Deltas to string representations for diffing. 12543 * 12544 * @param other - The other Delta to convert. 12545 * @return A tuple of [thisString, otherString]. 12546 */ 12547 deltasToStrings(other) { 12548 return [this, other].map((delta) => { 12549 return delta.map((op) => { 12550 if (op.insert !== null || op.insert !== void 0) { 12551 return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; 12552 } 12553 const prep = delta === other ? "on" : "with"; 12554 throw new Error( 12555 "diff() called " + prep + " non-document" 12556 ); 12557 }).join(""); 12558 }); 12559 } 12560 /** 12561 * Process diff changes and convert them to Delta operations. 12562 * 12563 * @param changes - The array of changes from the diff algorithm. 12564 * @param thisIter - Iterator for this Delta's operations. 12565 * @param otherIter - Iterator for the other Delta's operations. 12566 * @return A Delta containing the processed diff operations. 12567 */ 12568 convertChangesToDelta(changes, thisIter, otherIter) { 12569 const retDelta = new _Delta(); 12570 changes.forEach((component) => { 12571 let length3 = component.count ?? 0; 12572 while (length3 > 0) { 12573 let opLength = 0; 12574 if (component.added) { 12575 opLength = Math.min(otherIter.peekLength(), length3); 12576 retDelta.push(otherIter.next(opLength)); 12577 } else if (component.removed) { 12578 opLength = Math.min(length3, thisIter.peekLength()); 12579 thisIter.next(opLength); 12580 retDelta.delete(opLength); 12581 } else { 12582 opLength = Math.min( 12583 thisIter.peekLength(), 12584 otherIter.peekLength(), 12585 length3 12586 ); 12587 const thisOp = thisIter.next(opLength); 12588 const otherOp = otherIter.next(opLength); 12589 if ((0, import_es63.default)(thisOp.insert, otherOp.insert)) { 12590 retDelta.retain( 12591 opLength, 12592 AttributeMap_default.diff( 12593 thisOp.attributes, 12594 otherOp.attributes 12595 ) 12596 ); 12597 } else { 12598 retDelta.push(otherOp).delete(opLength); 12599 } 12600 } 12601 length3 -= opLength; 12602 } 12603 }); 12604 return retDelta; 12605 } 12606 }; 12607 var Delta_default = Delta; 12608 12609 // packages/sync/build-module/private-apis.mjs 12610 var privateApis = {}; 12611 lock(privateApis, { 12612 ConnectionErrorCode, 12613 createSyncManager, 12614 Delta: Delta_default, 12615 CRDT_DOC_META_PERSISTENCE_KEY, 12616 CRDT_RECORD_MAP_KEY, 12617 LOCAL_EDITOR_ORIGIN, 12618 LOCAL_UNDO_IGNORED_ORIGIN, 12619 retrySyncConnection: () => pollingManager.retryNow() 12620 }); 12621 12622 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 12623 var import_block_editor3 = __toESM(require_block_editor(), 1); 12624 12625 // packages/core-data/build-module/awareness/base-awareness.mjs 12626 var import_data2 = __toESM(require_data(), 1); 12627 12628 // packages/core-data/build-module/awareness/config.mjs 12629 var AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS = 100; 12630 var LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS = 5; 12631 var REMOVAL_DELAY_IN_MS = 5e3; 12632 12633 // packages/core-data/build-module/awareness/utils.mjs 12634 function getBrowserName() { 12635 const userAgent = window.navigator.userAgent; 12636 let browserName = "Unknown"; 12637 if (userAgent.includes("Firefox")) { 12638 browserName = "Firefox"; 12639 } else if (userAgent.includes("Edg")) { 12640 browserName = "Microsoft Edge"; 12641 } else if (userAgent.includes("Chrome") && !userAgent.includes("Edg")) { 12642 browserName = "Chrome"; 12643 } else if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) { 12644 browserName = "Safari"; 12645 } else if (userAgent.includes("MSIE") || userAgent.includes("Trident")) { 12646 browserName = "Internet Explorer"; 12647 } else if (userAgent.includes("Opera") || userAgent.includes("OPR")) { 12648 browserName = "Opera"; 12649 } 12650 return browserName; 12651 } 12652 function areMapsEqual(map1, map2, comparatorFn) { 12653 if (map1.size !== map2.size) { 12654 return false; 12655 } 12656 for (const [key, value1] of map1.entries()) { 12657 if (!map2.has(key)) { 12658 return false; 12659 } 12660 if (!comparatorFn(value1, map2.get(key))) { 12661 return false; 12662 } 12663 } 12664 return true; 12665 } 12666 function areCollaboratorInfosEqual(collaboratorInfo1, collaboratorInfo2) { 12667 if (!collaboratorInfo1 || !collaboratorInfo2) { 12668 return collaboratorInfo1 === collaboratorInfo2; 12669 } 12670 if (Object.keys(collaboratorInfo1).length !== Object.keys(collaboratorInfo2).length) { 12671 return false; 12672 } 12673 return Object.entries(collaboratorInfo1).every(([key, value]) => { 12674 return value === collaboratorInfo2[key]; 12675 }); 12676 } 12677 function generateCollaboratorInfo(currentCollaborator) { 12678 const { avatar_urls, id: id2, name, slug } = currentCollaborator; 12679 return { 12680 avatar_urls, 12681 // eslint-disable-line camelcase 12682 browserType: getBrowserName(), 12683 enteredAt: Date.now(), 12684 id: id2, 12685 name, 12686 slug 12687 }; 12688 } 12689 function getRecordValue(obj, key) { 12690 if ("object" === typeof obj && null !== obj && key in obj) { 12691 return obj[key]; 12692 } 12693 return null; 12694 } 12695 function getTypedKeys(obj) { 12696 return Object.keys(obj); 12697 } 12698 12699 // packages/core-data/build-module/awareness/typed-awareness.mjs 12700 var TypedAwareness = class extends Awareness { 12701 /** 12702 * Get the states from an awareness document. 12703 */ 12704 getStates() { 12705 return super.getStates(); 12706 } 12707 /** 12708 * Get a local state field from an awareness document. 12709 * @param field 12710 */ 12711 getLocalStateField(field) { 12712 const state = this.getLocalState(); 12713 return getRecordValue(state, field); 12714 } 12715 /** 12716 * Set a local state field on an awareness document. 12717 * @param field 12718 * @param value 12719 */ 12720 setLocalStateField(field, value) { 12721 super.setLocalStateField(field, value); 12722 } 12723 }; 12724 12725 // packages/core-data/build-module/awareness/awareness-state.mjs 12726 var AwarenessWithEqualityChecks = class extends TypedAwareness { 12727 /** OVERRIDDEN METHODS */ 12728 /** 12729 * Set a local state field on an awareness document. Calling this method may 12730 * trigger rerenders of any subscribed components. 12731 * 12732 * Equality checks are provided by the abstract `equalityFieldChecks` property. 12733 * @param field - The field to set. 12734 * @param value - The value to set. 12735 */ 12736 setLocalStateField(field, value) { 12737 if (this.isFieldEqual( 12738 field, 12739 value, 12740 this.getLocalStateField(field) ?? void 0 12741 )) { 12742 return; 12743 } 12744 super.setLocalStateField(field, value); 12745 } 12746 /** CUSTOM METHODS */ 12747 /** 12748 * Determine if a field value has changed using the provided equality checks. 12749 * @param field - The field to check. 12750 * @param value1 - The first value to compare. 12751 * @param value2 - The second value to compare. 12752 */ 12753 isFieldEqual(field, value1, value2) { 12754 if (["clientId", "isConnected", "isMe"].includes(field)) { 12755 return value1 === value2; 12756 } 12757 if (field in this.equalityFieldChecks) { 12758 const fn = this.equalityFieldChecks[field]; 12759 return fn(value1, value2); 12760 } 12761 throw new Error( 12762 `No equality check implemented for awareness state field "$field.toString()}".` 12763 ); 12764 } 12765 /** 12766 * Determine if two states are equal by comparing each field using the 12767 * provided equality checks. 12768 * @param state1 - The first state to compare. 12769 * @param state2 - The second state to compare. 12770 */ 12771 isStateEqual(state1, state2) { 12772 return [ 12773 .../* @__PURE__ */ new Set([ 12774 ...getTypedKeys(state1), 12775 ...getTypedKeys(state2) 12776 ]) 12777 ].every((field) => { 12778 const value1 = state1[field]; 12779 const value2 = state2[field]; 12780 return this.isFieldEqual(field, value1, value2); 12781 }); 12782 } 12783 }; 12784 var AwarenessState = class extends AwarenessWithEqualityChecks { 12785 /** CUSTOM PROPERTIES */ 12786 /** 12787 * Whether the setUp method has been called, to avoid running it multiple 12788 * times. 12789 */ 12790 hasSetupRun = false; 12791 /** 12792 * We keep track of all seen states during the current session for two reasons: 12793 * 12794 * 1. So that we can represent recently disconnected collaborators in our UI, even 12795 * after they have been removed from the awareness document. 12796 * 2. So that we can provide debug information about all collaborators seen during 12797 * the session. 12798 */ 12799 disconnectedCollaborators = /* @__PURE__ */ new Set(); 12800 seenStates = /* @__PURE__ */ new Map(); 12801 /** 12802 * Hold a snapshot of the previous awareness state allows us to compare the 12803 * state values and avoid unnecessary updates to subscribers. 12804 */ 12805 previousSnapshot = /* @__PURE__ */ new Map(); 12806 stateSubscriptions = []; 12807 /** 12808 * In some cases, we may want to throttle setting local state fields to avoid 12809 * overwhelming the awareness document with rapid updates. At the same time, we 12810 * want to ensure that when we read our own state locally, we get the latest 12811 * value -- even if it hasn't yet been set on the awareness instance. 12812 */ 12813 myThrottledState = {}; 12814 throttleTimeouts = /* @__PURE__ */ new Map(); 12815 /** CUSTOM METHODS */ 12816 /** 12817 * Set up the awareness state. This method is idempotent and will only run 12818 * once. Subclasses should override `onSetUp()` instead of this method to 12819 * add their own setup logic. 12820 * 12821 * This is defined as a readonly arrow function property to prevent 12822 * subclasses from overriding it. 12823 */ 12824 setUp = () => { 12825 if (this.hasSetupRun) { 12826 return; 12827 } 12828 this.hasSetupRun = true; 12829 this.onSetUp(); 12830 this.on( 12831 "change", 12832 ({ added, removed, updated }) => { 12833 [...added, ...updated].forEach((id2) => { 12834 this.disconnectedCollaborators.delete(id2); 12835 }); 12836 removed.forEach((id2) => { 12837 this.disconnectedCollaborators.add(id2); 12838 setTimeout(() => { 12839 this.disconnectedCollaborators.delete(id2); 12840 this.updateSubscribers( 12841 true 12842 /* force update */ 12843 ); 12844 }, REMOVAL_DELAY_IN_MS); 12845 }); 12846 this.updateSubscribers(); 12847 } 12848 ); 12849 }; 12850 /** 12851 * Get the most recent state from the last processed change event. 12852 * 12853 * @return An array of EnhancedState< State >. 12854 */ 12855 getCurrentState() { 12856 return Array.from(this.previousSnapshot.values()); 12857 } 12858 /** 12859 * Get all seen states in this session to enable debug reporting. 12860 */ 12861 getSeenStates() { 12862 return this.seenStates; 12863 } 12864 /** 12865 * Allow external code to subscribe to awareness state changes. 12866 * @param callback - The callback to subscribe to. 12867 */ 12868 onStateChange(callback) { 12869 this.stateSubscriptions.push(callback); 12870 return () => { 12871 this.stateSubscriptions = this.stateSubscriptions.filter( 12872 (cb) => cb !== callback 12873 ); 12874 }; 12875 } 12876 /** 12877 * Set a local state field on an awareness document with throttle. See caveats 12878 * of this.setLocalStateField. 12879 * @param field - The field to set. 12880 * @param value - The value to set. 12881 * @param wait - The wait time in milliseconds. 12882 */ 12883 setThrottledLocalStateField(field, value, wait) { 12884 this.setLocalStateField(field, value); 12885 this.throttleTimeouts.set( 12886 field, 12887 setTimeout(() => { 12888 this.throttleTimeouts.delete(field); 12889 if (this.myThrottledState[field]) { 12890 this.setLocalStateField( 12891 field, 12892 this.myThrottledState[field] 12893 ); 12894 delete this.myThrottledState[field]; 12895 } 12896 }, wait) 12897 ); 12898 } 12899 /** 12900 * Set the current collaborator's connection status as awareness state. 12901 * @param isConnected - The connection status. 12902 */ 12903 setConnectionStatus(isConnected) { 12904 if (isConnected) { 12905 this.disconnectedCollaborators.delete(this.clientID); 12906 } else { 12907 this.disconnectedCollaborators.add(this.clientID); 12908 } 12909 this.updateSubscribers( 12910 true 12911 /* force update */ 12912 ); 12913 } 12914 /** 12915 * Update all subscribed listeners with the latest awareness state. 12916 * @param forceUpdate - Whether to force an update. 12917 */ 12918 updateSubscribers(forceUpdate = false) { 12919 if (!this.stateSubscriptions.length) { 12920 return; 12921 } 12922 const states = this.getStates(); 12923 this.seenStates = new Map([ 12924 ...this.seenStates.entries(), 12925 ...states.entries() 12926 ]); 12927 const updatedStates = new Map( 12928 [...this.disconnectedCollaborators, ...states.keys()].filter((clientId) => { 12929 return Object.keys(this.seenStates.get(clientId) ?? {}).length > 0; 12930 }).map((clientId) => { 12931 const rawState = this.seenStates.get(clientId); 12932 const isConnected = !this.disconnectedCollaborators.has(clientId); 12933 const isMe = clientId === this.clientID; 12934 const myState = isMe ? this.myThrottledState : {}; 12935 const state = { 12936 ...rawState, 12937 ...myState, 12938 clientId, 12939 isConnected, 12940 isMe 12941 }; 12942 return [clientId, state]; 12943 }) 12944 ); 12945 if (!forceUpdate) { 12946 if (areMapsEqual( 12947 this.previousSnapshot, 12948 updatedStates, 12949 this.isStateEqual.bind(this) 12950 )) { 12951 return; 12952 } 12953 } 12954 this.previousSnapshot = updatedStates; 12955 this.stateSubscriptions.forEach((callback) => { 12956 callback(Array.from(updatedStates.values())); 12957 }); 12958 } 12959 }; 12960 12961 // packages/core-data/build-module/name.mjs 12962 var STORE_NAME = "core"; 12963 12964 // packages/core-data/build-module/awareness/base-awareness.mjs 12965 var BaseAwarenessState = class extends AwarenessState { 12966 onSetUp() { 12967 void this.setCurrentCollaboratorInfo(); 12968 } 12969 /** 12970 * Set the current collaborator info in the local state. 12971 */ 12972 async setCurrentCollaboratorInfo() { 12973 const currentUser2 = await (0, import_data2.resolveSelect)(STORE_NAME).getCurrentUser(); 12974 const collaboratorInfo = generateCollaboratorInfo(currentUser2); 12975 this.setLocalStateField("collaboratorInfo", collaboratorInfo); 12976 } 12977 }; 12978 var baseEqualityFieldChecks = { 12979 collaboratorInfo: areCollaboratorInfosEqual 12980 }; 12981 var BaseAwareness = class extends BaseAwarenessState { 12982 equalityFieldChecks = baseEqualityFieldChecks; 12983 }; 12984 12985 // packages/core-data/build-module/awareness/block-lookup.mjs 12986 var import_data3 = __toESM(require_data(), 1); 12987 var import_block_editor = __toESM(require_block_editor(), 1); 12988 function getBlockPathInYdoc(yType) { 12989 const path = []; 12990 let current = yType; 12991 while (current) { 12992 const parentArray = current.parent; 12993 if (!parentArray || !(parentArray instanceof yjs_exports.Array)) { 12994 return null; 12995 } 12996 let index = -1; 12997 for (let i = 0; i < parentArray.length; i++) { 12998 if (parentArray.get(i) === current) { 12999 index = i; 13000 break; 13001 } 13002 } 13003 if (index === -1) { 13004 return null; 13005 } 13006 path.unshift(index); 13007 const grandparent = parentArray.parent; 13008 if (grandparent instanceof yjs_exports.Map && grandparent.get("clientId") !== void 0) { 13009 current = grandparent; 13010 } else { 13011 break; 13012 } 13013 } 13014 return path; 13015 } 13016 function resolveBlockClientIdByPath(path) { 13017 if (path.length === 0) { 13018 return null; 13019 } 13020 const { getBlocks } = (0, import_data3.select)(import_block_editor.store); 13021 const postContentBlocks = getPostContentBlocks(getBlocks(), getBlocks); 13022 let blocks = postContentBlocks; 13023 for (let i = 0; i < path.length; i++) { 13024 const block = blocks[path[i]]; 13025 if (!block) { 13026 return null; 13027 } 13028 if (i === path.length - 1) { 13029 return block.clientId; 13030 } 13031 blocks = block.innerBlocks; 13032 } 13033 return null; 13034 } 13035 function getPostContentBlocks(rootBlocks, getBlocks) { 13036 const postContentBlock = findBlockByName(rootBlocks, "core/post-content"); 13037 if (postContentBlock) { 13038 return getBlocks(postContentBlock.clientId); 13039 } 13040 return rootBlocks; 13041 } 13042 function findBlockByName(blocks, name) { 13043 for (const block of blocks) { 13044 if (block.name === name) { 13045 return block; 13046 } 13047 if (block.innerBlocks?.length) { 13048 const found = findBlockByName(block.innerBlocks, name); 13049 if (found) { 13050 return found; 13051 } 13052 } 13053 } 13054 return null; 13055 } 13056 13057 // packages/core-data/build-module/utils/crdt-utils.mjs 13058 var import_rich_text = __toESM(require_rich_text(), 1); 13059 13060 // packages/core-data/build-module/lock-unlock.mjs 13061 var import_private_apis3 = __toESM(require_private_apis(), 1); 13062 var { lock: lock2, unlock: unlock2 } = (0, import_private_apis3.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 13063 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 13064 "@wordpress/core-data" 13065 ); 13066 13067 // packages/core-data/build-module/sync.mjs 13068 var { 13069 ConnectionErrorCode: ConnectionErrorCode2, 13070 createSyncManager: createSyncManager2, 13071 Delta: Delta2, 13072 CRDT_DOC_META_PERSISTENCE_KEY: CRDT_DOC_META_PERSISTENCE_KEY2, 13073 CRDT_RECORD_MAP_KEY: CRDT_RECORD_MAP_KEY2, 13074 LOCAL_EDITOR_ORIGIN: LOCAL_EDITOR_ORIGIN2, 13075 LOCAL_UNDO_IGNORED_ORIGIN: LOCAL_UNDO_IGNORED_ORIGIN2, 13076 retrySyncConnection 13077 } = unlock2(privateApis); 13078 var syncManager; 13079 function getSyncManager() { 13080 if (syncManager) { 13081 return syncManager; 13082 } 13083 syncManager = createSyncManager2(); 13084 return syncManager; 13085 } 13086 13087 // packages/core-data/build-module/utils/crdt-utils.mjs 13088 function getRootMap(doc2, key) { 13089 return doc2.getMap(key); 13090 } 13091 function createYMap(partial = {}) { 13092 return new yjs_exports.Map(Object.entries(partial)); 13093 } 13094 function isYMap(value) { 13095 return value instanceof yjs_exports.Map; 13096 } 13097 function findBlockByClientIdInDoc(blockId, ydoc) { 13098 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY2); 13099 const blocks = ymap.get("blocks"); 13100 if (!(blocks instanceof yjs_exports.Array)) { 13101 return null; 13102 } 13103 return findBlockByClientIdInBlocks(blockId, blocks); 13104 } 13105 var MARKER_START = 57344; 13106 function pickMarker(text2) { 13107 const tryCount = 16; 13108 for (let code = MARKER_START; code < MARKER_START + tryCount; code++) { 13109 const candidate = String.fromCharCode(code); 13110 if (!text2.includes(candidate)) { 13111 return candidate; 13112 } 13113 } 13114 return null; 13115 } 13116 function htmlIndexToRichTextOffset(html, htmlIndex) { 13117 if (!html.includes("<") && !html.includes("&")) { 13118 return htmlIndex; 13119 } 13120 const marker = pickMarker(html); 13121 if (!marker) { 13122 return htmlIndex; 13123 } 13124 const withMarker = html.slice(0, htmlIndex) + marker + html.slice(htmlIndex); 13125 const value = (0, import_rich_text.create)({ html: withMarker }); 13126 const markerPos = value.text.indexOf(marker); 13127 return markerPos === -1 ? htmlIndex : markerPos; 13128 } 13129 function richTextOffsetToHtmlIndex(html, richTextOffset) { 13130 if (!html.includes("<") && !html.includes("&")) { 13131 return richTextOffset; 13132 } 13133 const marker = pickMarker(html); 13134 if (!marker) { 13135 return richTextOffset; 13136 } 13137 const value = (0, import_rich_text.create)({ html }); 13138 const markerValue = (0, import_rich_text.create)({ text: marker }); 13139 if (value.formats[richTextOffset]) { 13140 markerValue.formats[0] = value.formats[richTextOffset]; 13141 } 13142 const withMarker = (0, import_rich_text.insert)( 13143 value, 13144 markerValue, 13145 richTextOffset, 13146 richTextOffset 13147 ); 13148 const htmlWithMarker = (0, import_rich_text.toHTMLString)({ value: withMarker }); 13149 const markerIndex = htmlWithMarker.indexOf(marker); 13150 return markerIndex === -1 ? richTextOffset : markerIndex; 13151 } 13152 function findBlockByClientIdInBlocks(blockId, blocks) { 13153 for (const block of blocks) { 13154 if (block.get("clientId") === blockId) { 13155 return block; 13156 } 13157 const innerBlocks = block.get("innerBlocks"); 13158 if (innerBlocks && innerBlocks.length > 0) { 13159 const innerBlock = findBlockByClientIdInBlocks( 13160 blockId, 13161 innerBlocks 13162 ); 13163 if (innerBlock) { 13164 return innerBlock; 13165 } 13166 } 13167 } 13168 return null; 13169 } 13170 13171 // packages/core-data/build-module/utils/crdt-user-selections.mjs 13172 var import_data4 = __toESM(require_data(), 1); 13173 var import_block_editor2 = __toESM(require_block_editor(), 1); 13174 var SelectionType = /* @__PURE__ */ ((SelectionType2) => { 13175 SelectionType2["None"] = "none"; 13176 SelectionType2["Cursor"] = "cursor"; 13177 SelectionType2["SelectionInOneBlock"] = "selection-in-one-block"; 13178 SelectionType2["SelectionInMultipleBlocks"] = "selection-in-multiple-blocks"; 13179 SelectionType2["WholeBlock"] = "whole-block"; 13180 return SelectionType2; 13181 })(SelectionType || {}); 13182 var SelectionDirection = /* @__PURE__ */ ((SelectionDirection2) => { 13183 SelectionDirection2["Forward"] = "f"; 13184 SelectionDirection2["Backward"] = "b"; 13185 return SelectionDirection2; 13186 })(SelectionDirection || {}); 13187 function getSelectionState(selectionStart, selectionEnd, yDoc, options) { 13188 const { selectionDirection } = options ?? {}; 13189 const ymap = getRootMap(yDoc, CRDT_RECORD_MAP_KEY2); 13190 const yBlocks = ymap.get("blocks"); 13191 const isSelectionEmpty = Object.keys(selectionStart).length === 0; 13192 const noSelection = { 13193 type: "none" 13194 /* None */ 13195 }; 13196 if (isSelectionEmpty || !yBlocks) { 13197 return noSelection; 13198 } 13199 const isSelectionInOneBlock = selectionStart.clientId === selectionEnd.clientId; 13200 const isCursorOnly = isSelectionInOneBlock && selectionStart.offset === selectionEnd.offset; 13201 const isSelectionAWholeBlock = isSelectionInOneBlock && selectionStart.offset === void 0 && selectionEnd.offset === void 0; 13202 if (isSelectionAWholeBlock) { 13203 const path = getBlockPathForLocalClientId(selectionStart.clientId); 13204 const blockPosition = path ? createRelativePositionForBlockPath(path, yBlocks) : null; 13205 if (!blockPosition) { 13206 return noSelection; 13207 } 13208 return { 13209 type: "whole-block", 13210 blockPosition 13211 }; 13212 } else if (isCursorOnly) { 13213 const cursorPosition = getCursorPosition(selectionStart, yBlocks); 13214 if (!cursorPosition) { 13215 return noSelection; 13216 } 13217 return { 13218 type: "cursor", 13219 cursorPosition 13220 }; 13221 } else if (isSelectionInOneBlock) { 13222 const cursorStartPosition2 = getCursorPosition( 13223 selectionStart, 13224 yBlocks 13225 ); 13226 const cursorEndPosition2 = getCursorPosition(selectionEnd, yBlocks); 13227 if (!cursorStartPosition2 || !cursorEndPosition2) { 13228 return noSelection; 13229 } 13230 return { 13231 type: "selection-in-one-block", 13232 cursorStartPosition: cursorStartPosition2, 13233 cursorEndPosition: cursorEndPosition2, 13234 selectionDirection 13235 }; 13236 } 13237 const cursorStartPosition = getCursorPosition(selectionStart, yBlocks); 13238 const cursorEndPosition = getCursorPosition(selectionEnd, yBlocks); 13239 if (!cursorStartPosition || !cursorEndPosition) { 13240 return noSelection; 13241 } 13242 return { 13243 type: "selection-in-multiple-blocks", 13244 cursorStartPosition, 13245 cursorEndPosition, 13246 selectionDirection 13247 }; 13248 } 13249 function getCursorPosition(selection, blocks) { 13250 const path = getBlockPathForLocalClientId(selection.clientId); 13251 const block = path ? findBlockByPath(path, blocks) : null; 13252 if (!block || !selection.attributeKey || void 0 === selection.offset) { 13253 return null; 13254 } 13255 const attributes = block.get("attributes"); 13256 const currentYText = attributes?.get(selection.attributeKey); 13257 if (!(currentYText instanceof yjs_exports.Text)) { 13258 return null; 13259 } 13260 const relativePosition = yjs_exports.createRelativePositionFromTypeIndex( 13261 currentYText, 13262 richTextOffsetToHtmlIndex(currentYText.toString(), selection.offset) 13263 ); 13264 return { 13265 relativePosition, 13266 absoluteOffset: selection.offset 13267 }; 13268 } 13269 function getBlockPathForLocalClientId(clientId) { 13270 const { getBlockIndex, getBlockRootClientId, getBlockName } = (0, import_data4.select)(import_block_editor2.store); 13271 const path = []; 13272 let current = clientId; 13273 while (current) { 13274 const index = getBlockIndex(current); 13275 if (index === -1) { 13276 return null; 13277 } 13278 path.unshift(index); 13279 const parent = getBlockRootClientId(current); 13280 if (!parent) { 13281 break; 13282 } 13283 const parentName = getBlockName(parent); 13284 if (parentName === "core/post-content") { 13285 break; 13286 } 13287 current = parent; 13288 } 13289 return path.length > 0 ? path : null; 13290 } 13291 function findBlockByPath(path, blocks) { 13292 let currentBlocks = blocks; 13293 for (let i = 0; i < path.length; i++) { 13294 if (path[i] >= currentBlocks.length) { 13295 return null; 13296 } 13297 const block = currentBlocks.get(path[i]); 13298 if (!block) { 13299 return null; 13300 } 13301 if (i === path.length - 1) { 13302 return block; 13303 } 13304 currentBlocks = block.get("innerBlocks") ?? new yjs_exports.Array(); 13305 } 13306 return null; 13307 } 13308 function createRelativePositionForBlockPath(path, blocks) { 13309 let currentBlocks = blocks; 13310 for (let i = 0; i < path.length; i++) { 13311 if (path[i] >= currentBlocks.length) { 13312 return null; 13313 } 13314 if (i === path.length - 1) { 13315 return yjs_exports.createRelativePositionFromTypeIndex( 13316 currentBlocks, 13317 path[i] 13318 ); 13319 } 13320 const block = currentBlocks.get(path[i]); 13321 currentBlocks = block?.get("innerBlocks") ?? new yjs_exports.Array(); 13322 } 13323 return null; 13324 } 13325 function areSelectionsStatesEqual(selection1, selection2) { 13326 if (selection1.type !== selection2.type) { 13327 return false; 13328 } 13329 switch (selection1.type) { 13330 case "none": 13331 return true; 13332 case "cursor": 13333 return areCursorPositionsEqual( 13334 selection1.cursorPosition, 13335 selection2.cursorPosition 13336 ); 13337 case "selection-in-one-block": 13338 return areCursorPositionsEqual( 13339 selection1.cursorStartPosition, 13340 selection2.cursorStartPosition 13341 ) && areCursorPositionsEqual( 13342 selection1.cursorEndPosition, 13343 selection2.cursorEndPosition 13344 ) && selection1.selectionDirection === selection2.selectionDirection; 13345 case "selection-in-multiple-blocks": 13346 return areCursorPositionsEqual( 13347 selection1.cursorStartPosition, 13348 selection2.cursorStartPosition 13349 ) && areCursorPositionsEqual( 13350 selection1.cursorEndPosition, 13351 selection2.cursorEndPosition 13352 ) && selection1.selectionDirection === selection2.selectionDirection; 13353 case "whole-block": 13354 return yjs_exports.compareRelativePositions( 13355 selection1.blockPosition, 13356 selection2.blockPosition 13357 ); 13358 default: 13359 return false; 13360 } 13361 } 13362 function areCursorPositionsEqual(cursorPosition1, cursorPosition2) { 13363 const isRelativePositionEqual = yjs_exports.compareRelativePositions( 13364 cursorPosition1.relativePosition, 13365 cursorPosition2.relativePosition 13366 ); 13367 const isAbsoluteOffsetEqual = cursorPosition1.absoluteOffset === cursorPosition2.absoluteOffset; 13368 return isRelativePositionEqual && isAbsoluteOffsetEqual; 13369 } 13370 13371 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 13372 var PostEditorAwareness = class extends BaseAwarenessState { 13373 constructor(doc2, kind, name, postId) { 13374 super(doc2); 13375 this.kind = kind; 13376 this.name = name; 13377 this.postId = postId; 13378 } 13379 equalityFieldChecks = { 13380 ...baseEqualityFieldChecks, 13381 editorState: this.areEditorStatesEqual 13382 }; 13383 onSetUp() { 13384 super.onSetUp(); 13385 this.subscribeToCollaboratorSelectionChanges(); 13386 } 13387 /** 13388 * Subscribe to collaborator selection changes and update the selection state. 13389 */ 13390 subscribeToCollaboratorSelectionChanges() { 13391 const { 13392 getSelectionStart, 13393 getSelectionEnd, 13394 getSelectedBlocksInitialCaretPosition 13395 } = (0, import_data5.select)(import_block_editor3.store); 13396 let selectionStart = getSelectionStart(); 13397 let selectionEnd = getSelectionEnd(); 13398 let localCursorTimeout = null; 13399 let selectionBeforeDebounce = null; 13400 (0, import_data5.subscribe)(() => { 13401 const newSelectionStart = getSelectionStart(); 13402 const newSelectionEnd = getSelectionEnd(); 13403 if (newSelectionStart === selectionStart && newSelectionEnd === selectionEnd) { 13404 return; 13405 } 13406 if (!selectionBeforeDebounce) { 13407 selectionBeforeDebounce = { 13408 start: selectionStart, 13409 end: selectionEnd 13410 }; 13411 } 13412 selectionStart = newSelectionStart; 13413 selectionEnd = newSelectionEnd; 13414 const initialPosition = getSelectedBlocksInitialCaretPosition(); 13415 void this.updateSelectionInEntityRecord( 13416 selectionStart, 13417 selectionEnd, 13418 initialPosition 13419 ); 13420 if (localCursorTimeout) { 13421 clearTimeout(localCursorTimeout); 13422 } 13423 localCursorTimeout = setTimeout(() => { 13424 const selectionStateOptions = {}; 13425 if (selectionBeforeDebounce) { 13426 selectionStateOptions.selectionDirection = detectSelectionDirection( 13427 selectionBeforeDebounce.start, 13428 selectionBeforeDebounce.end, 13429 selectionStart, 13430 selectionEnd 13431 ); 13432 selectionBeforeDebounce = null; 13433 } 13434 const selectionState = getSelectionState( 13435 selectionStart, 13436 selectionEnd, 13437 this.doc, 13438 selectionStateOptions 13439 ); 13440 this.setThrottledLocalStateField( 13441 "editorState", 13442 { selection: selectionState }, 13443 AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS 13444 ); 13445 }, LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS); 13446 }); 13447 } 13448 /** 13449 * Update the entity record with the current collaborator's selection. 13450 * 13451 * @param selectionStart - The start position of the selection. 13452 * @param selectionEnd - The end position of the selection. 13453 * @param initialPosition - The initial position of the selection. 13454 */ 13455 async updateSelectionInEntityRecord(selectionStart, selectionEnd, initialPosition) { 13456 const edits = { 13457 selection: { selectionStart, selectionEnd, initialPosition } 13458 }; 13459 const options = { 13460 undoIgnore: true 13461 }; 13462 (0, import_data5.dispatch)(STORE_NAME).editEntityRecord( 13463 this.kind, 13464 this.name, 13465 this.postId, 13466 edits, 13467 options 13468 ); 13469 } 13470 /** 13471 * Check if two editor states are equal. 13472 * 13473 * @param state1 - The first editor state. 13474 * @param state2 - The second editor state. 13475 * @return True if the editor states are equal, false otherwise. 13476 */ 13477 areEditorStatesEqual(state1, state2) { 13478 if (!state1 || !state2) { 13479 return state1 === state2; 13480 } 13481 if (!state1.selection || !state2.selection) { 13482 return state1.selection === state2.selection; 13483 } 13484 return areSelectionsStatesEqual(state1.selection, state2.selection); 13485 } 13486 /** 13487 * Resolve a selection state to a text index and block client ID. 13488 * 13489 * For text-based selections, navigates up from the resolved Y.Text via 13490 * AbstractType.parent to find the containing block, then resolves the 13491 * local clientId via the block's tree path. 13492 * For WholeBlock selections, resolves the block's relative position and 13493 * then finds the local clientId via tree path. 13494 * 13495 * Tree-path resolution is used instead of reading the clientId directly 13496 * from the Yjs block because the local block-editor store may use different 13497 * clientIds (e.g. in "Show Template" mode where blocks are cloned). 13498 * 13499 * @param selection - The selection state. 13500 * @return The rich-text offset and block client ID, or nulls if not resolvable. 13501 */ 13502 convertSelectionStateToAbsolute(selection) { 13503 if (selection.type === SelectionType.None) { 13504 return { richTextOffset: null, localClientId: null }; 13505 } 13506 if (selection.type === SelectionType.WholeBlock) { 13507 const absolutePos = yjs_exports.createAbsolutePositionFromRelativePosition( 13508 selection.blockPosition, 13509 this.doc 13510 ); 13511 let localClientId2 = null; 13512 if (absolutePos && absolutePos.type instanceof yjs_exports.Array) { 13513 const parentArray = absolutePos.type; 13514 const block = parentArray.get(absolutePos.index); 13515 if (block instanceof yjs_exports.Map) { 13516 const path2 = getBlockPathInYdoc(block); 13517 localClientId2 = path2 ? resolveBlockClientIdByPath(path2) : null; 13518 } 13519 } 13520 return { richTextOffset: null, localClientId: localClientId2 }; 13521 } 13522 const cursorPos = "cursorPosition" in selection ? selection.cursorPosition : selection.cursorStartPosition; 13523 const absolutePosition = yjs_exports.createAbsolutePositionFromRelativePosition( 13524 cursorPos.relativePosition, 13525 this.doc 13526 ); 13527 if (!absolutePosition) { 13528 return { richTextOffset: null, localClientId: null }; 13529 } 13530 const yType = absolutePosition.type.parent?.parent; 13531 const path = yType instanceof yjs_exports.Map ? getBlockPathInYdoc(yType) : null; 13532 const localClientId = path ? resolveBlockClientIdByPath(path) : null; 13533 return { 13534 richTextOffset: htmlIndexToRichTextOffset( 13535 absolutePosition.type.toString(), 13536 absolutePosition.index 13537 ), 13538 localClientId 13539 }; 13540 } 13541 /** 13542 * Type guard to check if a struct is a Y.Item (not Y.GC) 13543 * @param struct - The struct to check. 13544 * @return True if the struct is a Y.Item, false otherwise. 13545 */ 13546 isYItem(struct) { 13547 return "content" in struct; 13548 } 13549 /** 13550 * Get data for debugging, using the awareness state. 13551 * 13552 * @return {YDocDebugData} The debug data. 13553 */ 13554 getDebugData() { 13555 const ydoc = this.doc; 13556 const docData = Object.fromEntries( 13557 Array.from(ydoc.share, ([key, value]) => [ 13558 key, 13559 value.toJSON() 13560 ]) 13561 ); 13562 const collaboratorMapData = new Map( 13563 Array.from(this.getSeenStates().entries()).map( 13564 ([clientId, collaboratorState]) => [ 13565 String(clientId), 13566 { 13567 name: collaboratorState.collaboratorInfo.name, 13568 wpUserId: collaboratorState.collaboratorInfo.id 13569 } 13570 ] 13571 ) 13572 ); 13573 const serializableClientItems = {}; 13574 ydoc.store.clients.forEach((structs, clientId) => { 13575 const items2 = structs.filter(this.isYItem); 13576 serializableClientItems[clientId] = items2.map((item) => { 13577 const { left, right, ...rest } = item; 13578 return { 13579 ...rest, 13580 left: left ? { 13581 id: left.id, 13582 length: left.length, 13583 origin: left.origin, 13584 content: left.content 13585 } : null, 13586 right: right ? { 13587 id: right.id, 13588 length: right.length, 13589 origin: right.origin, 13590 content: right.content 13591 } : null 13592 }; 13593 }); 13594 }); 13595 return { 13596 doc: docData, 13597 clients: serializableClientItems, 13598 collaboratorMap: Object.fromEntries(collaboratorMapData) 13599 }; 13600 } 13601 }; 13602 function detectSelectionDirection(prevStart, prevEnd, newStart, newEnd) { 13603 const startMoved = !areBlockSelectionsEqual(prevStart, newStart); 13604 const endMoved = !areBlockSelectionsEqual(prevEnd, newEnd); 13605 if (startMoved && !endMoved) { 13606 return SelectionDirection.Backward; 13607 } 13608 return SelectionDirection.Forward; 13609 } 13610 function areBlockSelectionsEqual(a, b) { 13611 return a.clientId === b.clientId && a.attributeKey === b.attributeKey && a.offset === b.offset; 13612 } 13613 13614 // packages/core-data/build-module/utils/crdt.mjs 13615 var import_es65 = __toESM(require_es6(), 1); 13616 var import_blocks3 = __toESM(require_blocks(), 1); 13617 13618 // node_modules/uuid/dist/esm-browser/rng.js 13619 var getRandomValues2; 13620 var rnds8 = new Uint8Array(16); 13621 function rng() { 13622 if (!getRandomValues2) { 13623 getRandomValues2 = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); 13624 if (!getRandomValues2) { 13625 throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported"); 13626 } 13627 } 13628 return getRandomValues2(rnds8); 13629 } 13630 13631 // node_modules/uuid/dist/esm-browser/stringify.js 13632 var byteToHex = []; 13633 for (let i = 0; i < 256; ++i) { 13634 byteToHex.push((i + 256).toString(16).slice(1)); 13635 } 13636 function unsafeStringify(arr, offset = 0) { 13637 return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]; 13638 } 13639 13640 // node_modules/uuid/dist/esm-browser/native.js 13641 var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto); 13642 var native_default = { 13643 randomUUID 13644 }; 13645 13646 // node_modules/uuid/dist/esm-browser/v4.js 13647 function v4(options, buf, offset) { 13648 if (native_default.randomUUID && !buf && !options) { 13649 return native_default.randomUUID(); 13650 } 13651 options = options || {}; 13652 const rnds = options.random || (options.rng || rng)(); 13653 rnds[6] = rnds[6] & 15 | 64; 13654 rnds[8] = rnds[8] & 63 | 128; 13655 if (buf) { 13656 offset = offset || 0; 13657 for (let i = 0; i < 16; ++i) { 13658 buf[offset + i] = rnds[i]; 13659 } 13660 return buf; 13661 } 13662 return unsafeStringify(rnds); 13663 } 13664 var v4_default = v4; 13665 13666 // packages/core-data/build-module/utils/crdt-blocks.mjs 13667 var import_es64 = __toESM(require_es6(), 1); 13668 var import_blocks = __toESM(require_blocks(), 1); 13669 var import_rich_text3 = __toESM(require_rich_text(), 1); 13670 13671 // packages/core-data/build-module/utils/crdt-text.mjs 13672 var import_rich_text2 = __toESM(require_rich_text(), 1); 13673 var RICH_TEXT_CACHE_MAX_SIZE = 500; 13674 function createRichTextDataCache(maxSize) { 13675 const cache3 = /* @__PURE__ */ new Map(); 13676 return function(value) { 13677 const cached = cache3.get(value); 13678 if (cached) { 13679 return cached; 13680 } 13681 const result = import_rich_text2.RichTextData.fromHTMLString(value); 13682 if (cache3.size >= maxSize) { 13683 cache3.delete(cache3.keys().next().value); 13684 } 13685 cache3.set(value, result); 13686 return result; 13687 }; 13688 } 13689 var getCachedRichTextData = createRichTextDataCache( 13690 RICH_TEXT_CACHE_MAX_SIZE 13691 ); 13692 13693 // packages/core-data/build-module/utils/crdt-blocks.mjs 13694 var serializableBlocksCache = /* @__PURE__ */ new WeakMap(); 13695 function serializeAttributeValue(value) { 13696 if (value instanceof import_rich_text3.RichTextData) { 13697 return value.valueOf(); 13698 } 13699 if (Array.isArray(value)) { 13700 return value.map(serializeAttributeValue); 13701 } 13702 if (value && typeof value === "object") { 13703 const result = {}; 13704 for (const [k, v] of Object.entries(value)) { 13705 result[k] = serializeAttributeValue(v); 13706 } 13707 return result; 13708 } 13709 return value; 13710 } 13711 function makeBlockAttributesSerializable(blockName, attributes) { 13712 const newAttributes = { ...attributes }; 13713 for (const [key, value] of Object.entries(attributes)) { 13714 if (isLocalAttribute(blockName, key)) { 13715 delete newAttributes[key]; 13716 continue; 13717 } 13718 newAttributes[key] = serializeAttributeValue(value); 13719 } 13720 return newAttributes; 13721 } 13722 function makeBlocksSerializable(blocks) { 13723 return blocks.map((block) => { 13724 const { name, innerBlocks, attributes, ...rest } = block; 13725 delete rest.validationIssues; 13726 return { 13727 ...rest, 13728 name, 13729 attributes: makeBlockAttributesSerializable(name, attributes), 13730 innerBlocks: makeBlocksSerializable(innerBlocks) 13731 }; 13732 }); 13733 } 13734 function deserializeAttributeValue(schema, value) { 13735 if (schema?.type === "rich-text" && typeof value === "string") { 13736 return getCachedRichTextData(value); 13737 } 13738 if (Array.isArray(value)) { 13739 return value.map( 13740 (item) => deserializeAttributeValue(schema, item) 13741 ); 13742 } 13743 if (value && typeof value === "object") { 13744 const result = {}; 13745 for (const [key, innerValue] of Object.entries( 13746 value 13747 )) { 13748 result[key] = deserializeAttributeValue( 13749 schema?.query?.[key], 13750 innerValue 13751 ); 13752 } 13753 return result; 13754 } 13755 return value; 13756 } 13757 function deserializeBlockAttributes(blocks) { 13758 return blocks.map((block) => { 13759 const { name, innerBlocks, attributes, ...rest } = block; 13760 const newAttributes = { ...attributes }; 13761 for (const [key, value] of Object.entries(attributes)) { 13762 const schema = getBlockAttributeType(name, key); 13763 if (schema) { 13764 newAttributes[key] = deserializeAttributeValue( 13765 schema, 13766 value 13767 ); 13768 } 13769 } 13770 return { 13771 ...rest, 13772 name, 13773 attributes: newAttributes, 13774 innerBlocks: deserializeBlockAttributes(innerBlocks ?? []) 13775 }; 13776 }); 13777 } 13778 function areBlocksEqual(gblock, yblock) { 13779 const yblockAsJson = yblock.toJSON(); 13780 const overwrites = { 13781 innerBlocks: null, 13782 clientId: null 13783 }; 13784 const res = (0, import_es64.default)( 13785 Object.assign({}, gblock, overwrites), 13786 Object.assign({}, yblockAsJson, overwrites) 13787 ); 13788 const inners = gblock.innerBlocks || []; 13789 const yinners = yblock.get("innerBlocks"); 13790 return res && inners.length === yinners?.length && inners.every( 13791 (block, i) => areBlocksEqual(block, yinners.get(i)) 13792 ); 13793 } 13794 function createNewYAttributeMap(blockName, attributes) { 13795 return new yjs_exports.Map( 13796 Object.entries(attributes).map( 13797 ([attributeName, attributeValue]) => { 13798 return [ 13799 attributeName, 13800 createNewYAttributeValue( 13801 blockName, 13802 attributeName, 13803 attributeValue 13804 ) 13805 ]; 13806 } 13807 ) 13808 ); 13809 } 13810 function createNewYAttributeValue(blockName, attributeName, attributeValue) { 13811 const isRichText = isRichTextAttribute(blockName, attributeName); 13812 if (isRichText) { 13813 return new yjs_exports.Text(attributeValue?.toString() ?? ""); 13814 } 13815 return attributeValue; 13816 } 13817 function createNewYBlock(block) { 13818 return createYMap( 13819 Object.fromEntries( 13820 Object.entries(block).map(([key, value]) => { 13821 switch (key) { 13822 case "attributes": { 13823 return [ 13824 key, 13825 createNewYAttributeMap(block.name, value) 13826 ]; 13827 } 13828 case "innerBlocks": { 13829 const innerBlocks = new yjs_exports.Array(); 13830 if (!Array.isArray(value)) { 13831 return [key, innerBlocks]; 13832 } 13833 innerBlocks.insert( 13834 0, 13835 value.map( 13836 (innerBlock) => createNewYBlock(innerBlock) 13837 ) 13838 ); 13839 return [key, innerBlocks]; 13840 } 13841 default: 13842 return [key, value]; 13843 } 13844 }) 13845 ) 13846 ); 13847 } 13848 function mergeCrdtBlocks(yblocks, incomingBlocks, cursorPosition) { 13849 if (!serializableBlocksCache.has(incomingBlocks)) { 13850 serializableBlocksCache.set( 13851 incomingBlocks, 13852 makeBlocksSerializable(incomingBlocks) 13853 ); 13854 } 13855 const blocksToSync = serializableBlocksCache.get(incomingBlocks) ?? []; 13856 const numOfCommonEntries = Math.min( 13857 blocksToSync.length ?? 0, 13858 yblocks.length 13859 ); 13860 let left = 0; 13861 let right = 0; 13862 for (; left < numOfCommonEntries && areBlocksEqual(blocksToSync[left], yblocks.get(left)); left++) { 13863 } 13864 for (; right < numOfCommonEntries - left && areBlocksEqual( 13865 blocksToSync[blocksToSync.length - right - 1], 13866 yblocks.get(yblocks.length - right - 1) 13867 ); right++) { 13868 } 13869 const numOfUpdatesNeeded = numOfCommonEntries - left - right; 13870 const numOfInsertionsNeeded = Math.max( 13871 0, 13872 blocksToSync.length - yblocks.length 13873 ); 13874 const numOfDeletionsNeeded = Math.max( 13875 0, 13876 yblocks.length - blocksToSync.length 13877 ); 13878 for (let i = 0; i < numOfUpdatesNeeded; i++, left++) { 13879 const block = blocksToSync[left]; 13880 const yblock = yblocks.get(left); 13881 Object.entries(block).forEach(([key, value]) => { 13882 switch (key) { 13883 case "attributes": { 13884 const currentAttributes = yblock.get(key); 13885 if (!currentAttributes) { 13886 yblock.set( 13887 key, 13888 createNewYAttributeMap(block.name, value) 13889 ); 13890 break; 13891 } 13892 Object.entries(value).forEach( 13893 ([attributeName, attributeValue]) => { 13894 const currentAttribute = currentAttributes?.get(attributeName); 13895 const isExpectedType = isExpectedAttributeType( 13896 block.name, 13897 attributeName, 13898 currentAttribute 13899 ); 13900 const isAttributeChanged = !isExpectedType || !(0, import_es64.default)( 13901 currentAttribute, 13902 attributeValue 13903 ); 13904 if (isAttributeChanged) { 13905 updateYBlockAttribute( 13906 block.name, 13907 attributeName, 13908 attributeValue, 13909 currentAttributes, 13910 cursorPosition 13911 ); 13912 } 13913 } 13914 ); 13915 currentAttributes.forEach( 13916 (_attrValue, attrName) => { 13917 if (!value.hasOwnProperty(attrName)) { 13918 currentAttributes.delete(attrName); 13919 } 13920 } 13921 ); 13922 break; 13923 } 13924 case "innerBlocks": { 13925 let yInnerBlocks = yblock.get(key); 13926 if (!(yInnerBlocks instanceof yjs_exports.Array)) { 13927 yInnerBlocks = new yjs_exports.Array(); 13928 yblock.set(key, yInnerBlocks); 13929 } 13930 mergeCrdtBlocks( 13931 yInnerBlocks, 13932 value ?? [], 13933 cursorPosition 13934 ); 13935 break; 13936 } 13937 default: 13938 if (!(0, import_es64.default)(block[key], yblock.get(key))) { 13939 yblock.set(key, value); 13940 } 13941 } 13942 }); 13943 yblock.forEach((_v, k) => { 13944 if (!block.hasOwnProperty(k)) { 13945 yblock.delete(k); 13946 } 13947 }); 13948 } 13949 yblocks.delete(left, numOfDeletionsNeeded); 13950 for (let i = 0; i < numOfInsertionsNeeded; i++, left++) { 13951 const newBlock = [createNewYBlock(blocksToSync[left])]; 13952 yblocks.insert(left, newBlock); 13953 } 13954 const knownClientIds = /* @__PURE__ */ new Set(); 13955 for (let j = 0; j < yblocks.length; j++) { 13956 const yblock = yblocks.get(j); 13957 let clientId = yblock.get("clientId"); 13958 if (!clientId) { 13959 continue; 13960 } 13961 if (knownClientIds.has(clientId)) { 13962 clientId = v4_default(); 13963 yblock.set("clientId", clientId); 13964 } 13965 knownClientIds.add(clientId); 13966 } 13967 } 13968 function updateYBlockAttribute(blockName, attributeName, attributeValue, currentAttributes, cursorPosition) { 13969 const isRichText = isRichTextAttribute(blockName, attributeName); 13970 const currentAttribute = currentAttributes.get(attributeName); 13971 if (isRichText && "string" === typeof attributeValue && currentAttributes.has(attributeName) && currentAttribute instanceof yjs_exports.Text) { 13972 mergeRichTextUpdate(currentAttribute, attributeValue, cursorPosition); 13973 } else { 13974 currentAttributes.set( 13975 attributeName, 13976 createNewYAttributeValue(blockName, attributeName, attributeValue) 13977 ); 13978 } 13979 } 13980 var cachedBlockAttributeTypes; 13981 function getBlockAttributeType(blockName, attributeName) { 13982 if (!cachedBlockAttributeTypes) { 13983 cachedBlockAttributeTypes = /* @__PURE__ */ new Map(); 13984 for (const blockType of (0, import_blocks.getBlockTypes)()) { 13985 cachedBlockAttributeTypes.set( 13986 blockType.name, 13987 new Map( 13988 Object.entries(blockType.attributes ?? {}).map( 13989 ([name, definition]) => { 13990 const { role, type, query } = definition; 13991 return [name, { role, type, query }]; 13992 } 13993 ) 13994 ) 13995 ); 13996 } 13997 } 13998 return cachedBlockAttributeTypes.get(blockName)?.get(attributeName); 13999 } 14000 function isExpectedAttributeType(blockName, attributeName, attributeValue) { 14001 const expectedAttributeType = getBlockAttributeType( 14002 blockName, 14003 attributeName 14004 )?.type; 14005 if (expectedAttributeType === "rich-text") { 14006 return attributeValue instanceof yjs_exports.Text; 14007 } 14008 if (expectedAttributeType === "string") { 14009 return typeof attributeValue === "string"; 14010 } 14011 return true; 14012 } 14013 function isLocalAttribute(blockName, attributeName) { 14014 return "local" === getBlockAttributeType(blockName, attributeName)?.role; 14015 } 14016 function isRichTextAttribute(blockName, attributeName) { 14017 return "rich-text" === getBlockAttributeType(blockName, attributeName)?.type; 14018 } 14019 var localDoc; 14020 function mergeRichTextUpdate(blockYText, updatedValue, cursorPosition = null) { 14021 if (!localDoc) { 14022 localDoc = new yjs_exports.Doc(); 14023 } 14024 const localYText = localDoc.getText("temporary-text"); 14025 localYText.delete(0, localYText.length); 14026 localYText.insert(0, updatedValue); 14027 const currentValueAsDelta = new Delta2(blockYText.toDelta()); 14028 const updatedValueAsDelta = new Delta2(localYText.toDelta()); 14029 const deltaDiff = currentValueAsDelta.diffWithCursor( 14030 updatedValueAsDelta, 14031 cursorPosition 14032 ); 14033 blockYText.applyDelta(deltaDiff.ops); 14034 } 14035 14036 // packages/core-data/build-module/utils/crdt-selection.mjs 14037 var import_data6 = __toESM(require_data(), 1); 14038 var import_block_editor4 = __toESM(require_block_editor(), 1); 14039 var import_blocks2 = __toESM(require_blocks(), 1); 14040 14041 // packages/core-data/build-module/utils/block-selection-history.mjs 14042 var SELECTION_HISTORY_DEFAULT_SIZE = 5; 14043 var YSelectionType = /* @__PURE__ */ ((YSelectionType2) => { 14044 YSelectionType2["RelativeSelection"] = "RelativeSelection"; 14045 YSelectionType2["BlockSelection"] = "BlockSelection"; 14046 return YSelectionType2; 14047 })(YSelectionType || {}); 14048 function createBlockSelectionHistory(ydoc, historySize = SELECTION_HISTORY_DEFAULT_SIZE) { 14049 let history = []; 14050 const getSelectionHistory2 = () => { 14051 return history.slice(0); 14052 }; 14053 const updateSelection = (newSelection) => { 14054 if (!newSelection?.selectionStart?.clientId || !newSelection?.selectionEnd?.clientId) { 14055 return; 14056 } 14057 const { selectionStart, selectionEnd } = newSelection; 14058 const start = convertWPBlockSelectionToSelection( 14059 selectionStart, 14060 ydoc 14061 ); 14062 const end = convertWPBlockSelectionToSelection(selectionEnd, ydoc); 14063 addToHistory({ start, end }); 14064 }; 14065 const addToHistory = (yFullSelection) => { 14066 const startClientId = yFullSelection.start.clientId; 14067 const endClientId = yFullSelection.end.clientId; 14068 history = history.filter((entry) => { 14069 const isSameBlockCombination = entry.start.clientId === startClientId && entry.end.clientId === endClientId; 14070 return !isSameBlockCombination; 14071 }); 14072 history.unshift(yFullSelection); 14073 if (history.length > historySize + 1) { 14074 history = history.slice(0, historySize + 1); 14075 } 14076 }; 14077 return { 14078 getSelectionHistory: getSelectionHistory2, 14079 updateSelection 14080 }; 14081 } 14082 function convertWPBlockSelectionToSelection(selection, ydoc) { 14083 const clientId = selection.clientId; 14084 const block = findBlockByClientIdInDoc(clientId, ydoc); 14085 const attributes = block?.get("attributes"); 14086 const attributeKey = selection.attributeKey; 14087 const changedYText = attributeKey ? attributes?.get(attributeKey) : void 0; 14088 const isYText = changedYText instanceof yjs_exports.Text; 14089 const isFullyDefinedSelection = attributeKey && clientId; 14090 if (!isYText || !isFullyDefinedSelection) { 14091 return { 14092 type: "BlockSelection", 14093 clientId 14094 }; 14095 } 14096 const offset = selection.offset ?? 0; 14097 const relativePosition = yjs_exports.createRelativePositionFromTypeIndex( 14098 changedYText, 14099 richTextOffsetToHtmlIndex(changedYText.toString(), offset) 14100 ); 14101 return { 14102 type: "RelativeSelection", 14103 attributeKey, 14104 relativePosition, 14105 clientId, 14106 offset 14107 }; 14108 } 14109 14110 // packages/core-data/build-module/utils/crdt-selection.mjs 14111 var selectionHistoryMap = /* @__PURE__ */ new WeakMap(); 14112 function getBlockSelectionHistory(ydoc) { 14113 let history = selectionHistoryMap.get(ydoc); 14114 if (!history) { 14115 history = createBlockSelectionHistory(ydoc); 14116 selectionHistoryMap.set(ydoc, history); 14117 } 14118 return history; 14119 } 14120 function getSelectionHistory(ydoc) { 14121 return getBlockSelectionHistory(ydoc).getSelectionHistory(); 14122 } 14123 function updateSelectionHistory(ydoc, wpSelection) { 14124 return getBlockSelectionHistory(ydoc).updateSelection(wpSelection); 14125 } 14126 function convertYSelectionToBlockSelection(ySelection, ydoc) { 14127 if (ySelection.type === YSelectionType.RelativeSelection) { 14128 const { relativePosition, attributeKey, clientId } = ySelection; 14129 const absolutePosition = yjs_exports.createAbsolutePositionFromRelativePosition( 14130 relativePosition, 14131 ydoc 14132 ); 14133 if (absolutePosition) { 14134 return { 14135 clientId, 14136 attributeKey, 14137 offset: htmlIndexToRichTextOffset( 14138 absolutePosition.type.toString(), 14139 absolutePosition.index 14140 ) 14141 }; 14142 } 14143 } else if (ySelection.type === YSelectionType.BlockSelection) { 14144 return { 14145 clientId: ySelection.clientId, 14146 attributeKey: void 0, 14147 offset: void 0 14148 }; 14149 } 14150 return null; 14151 } 14152 function convertYFullSelectionToWPSelection(yFullSelection, ydoc) { 14153 const { start, end } = yFullSelection; 14154 const startBlock = findBlockByClientIdInDoc(start.clientId, ydoc); 14155 const endBlock = findBlockByClientIdInDoc(end.clientId, ydoc); 14156 if (!startBlock || !endBlock) { 14157 return null; 14158 } 14159 const startBlockSelection = convertYSelectionToBlockSelection( 14160 start, 14161 ydoc 14162 ); 14163 const endBlockSelection = convertYSelectionToBlockSelection(end, ydoc); 14164 if (startBlockSelection === null || endBlockSelection === null) { 14165 return null; 14166 } 14167 return { 14168 selectionStart: startBlockSelection, 14169 selectionEnd: endBlockSelection 14170 }; 14171 } 14172 function findSelectionFromHistory(ydoc, selectionHistory) { 14173 for (const positionToTry of selectionHistory) { 14174 const result = convertYFullSelectionToWPSelection( 14175 positionToTry, 14176 ydoc 14177 ); 14178 if (result !== null) { 14179 return result; 14180 } 14181 } 14182 return null; 14183 } 14184 function restoreSelection(selectionHistory, ydoc) { 14185 const selectionToRestore = findSelectionFromHistory( 14186 ydoc, 14187 selectionHistory 14188 ); 14189 if (selectionToRestore === null) { 14190 return; 14191 } 14192 const { getBlock } = (0, import_data6.select)(import_block_editor4.store); 14193 const { resetSelection } = (0, import_data6.dispatch)(import_block_editor4.store); 14194 const { selectionStart, selectionEnd } = selectionToRestore; 14195 const isSelectionInSameBlock = selectionStart.clientId === selectionEnd.clientId; 14196 if (isSelectionInSameBlock) { 14197 const block = getBlock(selectionStart.clientId); 14198 const isBlockEmpty = block && (0, import_blocks2.isUnmodifiedBlock)(block); 14199 const isBeginningOfEmptyBlock = 0 === selectionStart.offset && 0 === selectionEnd.offset && isBlockEmpty && !selectionStart.attributeKey && !selectionEnd.attributeKey; 14200 if (isBeginningOfEmptyBlock) { 14201 const selectionStartWithoutOffset = { 14202 clientId: selectionStart.clientId 14203 }; 14204 const selectionEndWithoutOffset = { 14205 clientId: selectionEnd.clientId 14206 }; 14207 resetSelection( 14208 selectionStartWithoutOffset, 14209 selectionEndWithoutOffset, 14210 0 14211 ); 14212 } else { 14213 resetSelection(selectionStart, selectionEnd, 0); 14214 } 14215 } else { 14216 resetSelection(selectionEnd, selectionEnd, 0); 14217 } 14218 } 14219 function getShiftedSelection(ydoc, selectionHistory) { 14220 if (selectionHistory.length === 0) { 14221 return null; 14222 } 14223 const { start, end } = selectionHistory[0]; 14224 if (start.type === YSelectionType.BlockSelection || end.type === YSelectionType.BlockSelection) { 14225 return null; 14226 } 14227 const selectionStart = convertYSelectionToBlockSelection(start, ydoc); 14228 const selectionEnd = convertYSelectionToBlockSelection(end, ydoc); 14229 if (!selectionStart || !selectionEnd) { 14230 return null; 14231 } 14232 const startShifted = selectionStart.offset !== start.offset; 14233 const endShifted = selectionEnd.offset !== end.offset; 14234 if (!startShifted && !endShifted) { 14235 return null; 14236 } 14237 return { selectionStart, selectionEnd }; 14238 } 14239 14240 // packages/core-data/build-module/utils/crdt.mjs 14241 var POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE = "_crdt_document"; 14242 var disallowedPostMetaKeys = /* @__PURE__ */ new Set([ 14243 POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE 14244 ]); 14245 function defaultApplyChangesToCRDTDoc(ydoc, changes) { 14246 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY2); 14247 Object.entries(changes).forEach(([key, newValue]) => { 14248 if ("function" === typeof newValue) { 14249 return; 14250 } 14251 switch (key) { 14252 // Add support for additional data types here. 14253 default: { 14254 const currentValue = ymap.get(key); 14255 updateMapValue(ymap, key, currentValue, newValue); 14256 } 14257 } 14258 }); 14259 } 14260 function applyPostChangesToCRDTDoc(ydoc, changes, syncedProperties) { 14261 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY2); 14262 Object.keys(changes).forEach((key) => { 14263 if (!syncedProperties.has(key)) { 14264 return; 14265 } 14266 const newValue = changes[key]; 14267 if ("function" === typeof newValue) { 14268 return; 14269 } 14270 switch (key) { 14271 case "blocks": { 14272 if (!newValue) { 14273 ymap.set(key, void 0); 14274 break; 14275 } 14276 let currentBlocks = ymap.get(key); 14277 if (!(currentBlocks instanceof yjs_exports.Array)) { 14278 currentBlocks = new yjs_exports.Array(); 14279 ymap.set(key, currentBlocks); 14280 } 14281 const cursorPosition = changes.selection?.selectionStart?.offset ?? null; 14282 mergeCrdtBlocks(currentBlocks, newValue, cursorPosition); 14283 break; 14284 } 14285 case "content": 14286 case "excerpt": 14287 case "title": { 14288 const currentValue = ymap.get(key); 14289 let rawValue = getRawValue(newValue); 14290 if (key === "title" && !currentValue?.toString() && "Auto Draft" === rawValue) { 14291 rawValue = ""; 14292 } 14293 if (currentValue instanceof yjs_exports.Text) { 14294 mergeRichTextUpdate(currentValue, rawValue ?? ""); 14295 } else { 14296 const newYText = new yjs_exports.Text(rawValue ?? ""); 14297 ymap.set(key, newYText); 14298 } 14299 break; 14300 } 14301 // "Meta" is overloaded term; here, it refers to post meta. 14302 case "meta": { 14303 let metaMap = ymap.get("meta"); 14304 if (!isYMap(metaMap)) { 14305 metaMap = createYMap(); 14306 ymap.set("meta", metaMap); 14307 } 14308 Object.entries(newValue ?? {}).forEach( 14309 ([metaKey, metaValue]) => { 14310 if (disallowedPostMetaKeys.has(metaKey)) { 14311 return; 14312 } 14313 updateMapValue( 14314 metaMap, 14315 metaKey, 14316 metaMap.get(metaKey), 14317 // current value in CRDT 14318 metaValue 14319 // new value from changes 14320 ); 14321 } 14322 ); 14323 break; 14324 } 14325 case "slug": { 14326 if (!newValue) { 14327 break; 14328 } 14329 const currentValue = ymap.get(key); 14330 updateMapValue(ymap, key, currentValue, newValue); 14331 break; 14332 } 14333 // Add support for additional properties here. 14334 default: { 14335 const currentValue = ymap.get(key); 14336 updateMapValue(ymap, key, currentValue, newValue); 14337 } 14338 } 14339 }); 14340 if (changes.selection) { 14341 const selection = changes.selection; 14342 setTimeout(() => { 14343 updateSelectionHistory(ydoc, selection); 14344 }, 0); 14345 } 14346 } 14347 function defaultGetChangesFromCRDTDoc(crdtDoc) { 14348 return getRootMap(crdtDoc, CRDT_RECORD_MAP_KEY2).toJSON(); 14349 } 14350 function getPostChangesFromCRDTDoc(ydoc, editedRecord, syncedProperties) { 14351 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY2); 14352 let allowedMetaChanges = {}; 14353 const changes = Object.fromEntries( 14354 Object.entries(ymap.toJSON()).filter(([key, newValue]) => { 14355 if (!syncedProperties.has(key)) { 14356 return false; 14357 } 14358 const currentValue = editedRecord[key]; 14359 switch (key) { 14360 case "blocks": { 14361 if (ydoc.meta?.get(CRDT_DOC_META_PERSISTENCE_KEY2) && editedRecord.content) { 14362 const blocksJson = ymap.get("blocks")?.toJSON() ?? []; 14363 return (0, import_blocks3.__unstableSerializeAndClean)(blocksJson).trim() !== getRawValue(editedRecord.content); 14364 } 14365 return true; 14366 } 14367 case "date": { 14368 const currentDateIsFloating = null === currentValue || editedRecord.modified === currentValue; 14369 if (currentDateIsFloating) { 14370 return false; 14371 } 14372 return haveValuesChanged(currentValue, newValue); 14373 } 14374 case "meta": { 14375 const currentMeta = currentValue ?? {}; 14376 allowedMetaChanges = Object.fromEntries( 14377 Object.entries(newValue ?? {}).filter( 14378 ([metaKey]) => { 14379 if (disallowedPostMetaKeys.has(metaKey)) { 14380 return false; 14381 } 14382 return metaKey in currentMeta; 14383 } 14384 ) 14385 ); 14386 const mergedValue = { 14387 ...currentMeta, 14388 ...allowedMetaChanges 14389 }; 14390 return haveValuesChanged(currentValue, mergedValue); 14391 } 14392 case "status": { 14393 if ("auto-draft" === newValue) { 14394 return false; 14395 } 14396 return haveValuesChanged(currentValue, newValue); 14397 } 14398 case "content": 14399 case "excerpt": 14400 case "title": { 14401 return haveValuesChanged( 14402 getRawValue(currentValue), 14403 newValue 14404 ); 14405 } 14406 // Add support for additional data types here. 14407 default: { 14408 return haveValuesChanged(currentValue, newValue); 14409 } 14410 } 14411 }) 14412 ); 14413 if (changes.blocks) { 14414 changes.blocks = deserializeBlockAttributes( 14415 changes.blocks 14416 ); 14417 } 14418 if ("object" === typeof changes.meta) { 14419 changes.meta = { 14420 ...editedRecord.meta, 14421 ...allowedMetaChanges 14422 }; 14423 } 14424 const selectionHistory = getSelectionHistory(ydoc); 14425 const shiftedSelection = getShiftedSelection(ydoc, selectionHistory); 14426 if (shiftedSelection) { 14427 changes.selection = { 14428 ...shiftedSelection, 14429 initialPosition: 0 14430 }; 14431 } 14432 return changes; 14433 } 14434 var defaultSyncConfig = { 14435 applyChangesToCRDTDoc: defaultApplyChangesToCRDTDoc, 14436 createAwareness: (ydoc) => new BaseAwareness(ydoc), 14437 getChangesFromCRDTDoc: defaultGetChangesFromCRDTDoc 14438 }; 14439 var defaultCollectionSyncConfig = { 14440 applyChangesToCRDTDoc: () => { 14441 }, 14442 getChangesFromCRDTDoc: () => ({}), 14443 shouldSync: (_, objectId) => null === objectId 14444 }; 14445 function getRawValue(value) { 14446 if ("string" === typeof value) { 14447 return value; 14448 } 14449 if (value && "object" === typeof value && "raw" in value && "string" === typeof value.raw) { 14450 return value.raw; 14451 } 14452 return void 0; 14453 } 14454 function haveValuesChanged(currentValue, newValue) { 14455 return !(0, import_es65.default)(currentValue, newValue); 14456 } 14457 function updateMapValue(map2, key, currentValue, newValue) { 14458 if (void 0 === newValue) { 14459 map2.delete(key); 14460 return; 14461 } 14462 if (haveValuesChanged(currentValue, newValue)) { 14463 map2.set(key, newValue); 14464 } 14465 } 14466 14467 // packages/core-data/build-module/entities.mjs 14468 var DEFAULT_ENTITY_KEY = "id"; 14469 var POST_RAW_ATTRIBUTES = ["title", "excerpt", "content"]; 14470 var blocksTransientEdits = { 14471 blocks: { 14472 read: (record) => (0, import_blocks4.parse)(record.content?.raw ?? ""), 14473 write: (record) => ({ 14474 content: (0, import_blocks4.__unstableSerializeAndClean)(record.blocks) 14475 }) 14476 } 14477 }; 14478 var rootEntitiesConfig = [ 14479 { 14480 label: (0, import_i18n.__)("Base"), 14481 kind: "root", 14482 key: false, 14483 name: "__unstableBase", 14484 baseURL: "/", 14485 baseURLParams: { 14486 // Please also change the preload path when changing this. 14487 // @see lib/compat/wordpress-7.0/preload.php 14488 _fields: [ 14489 "description", 14490 "gmt_offset", 14491 "home", 14492 "image_sizes", 14493 "image_size_threshold", 14494 "image_output_formats", 14495 "jpeg_interlaced", 14496 "png_interlaced", 14497 "gif_interlaced", 14498 "name", 14499 "site_icon", 14500 "site_icon_url", 14501 "site_logo", 14502 "timezone_string", 14503 "url", 14504 "page_for_posts", 14505 "page_on_front", 14506 "show_on_front" 14507 ].join(",") 14508 }, 14509 // The entity doesn't support selecting multiple records. 14510 // The property is maintained for backward compatibility. 14511 plural: "__unstableBases" 14512 }, 14513 { 14514 label: (0, import_i18n.__)("Post Type"), 14515 name: "postType", 14516 kind: "root", 14517 key: "slug", 14518 baseURL: "/wp/v2/types", 14519 baseURLParams: { context: "edit" }, 14520 plural: "postTypes" 14521 }, 14522 { 14523 name: "media", 14524 kind: "root", 14525 baseURL: "/wp/v2/media", 14526 baseURLParams: { context: "edit" }, 14527 plural: "mediaItems", 14528 label: (0, import_i18n.__)("Media"), 14529 rawAttributes: ["caption", "title", "description"], 14530 supportsPagination: true 14531 }, 14532 { 14533 name: "taxonomy", 14534 kind: "root", 14535 key: "slug", 14536 baseURL: "/wp/v2/taxonomies", 14537 baseURLParams: { context: "edit" }, 14538 plural: "taxonomies", 14539 label: (0, import_i18n.__)("Taxonomy") 14540 }, 14541 { 14542 name: "sidebar", 14543 kind: "root", 14544 baseURL: "/wp/v2/sidebars", 14545 baseURLParams: { context: "edit" }, 14546 plural: "sidebars", 14547 transientEdits: { blocks: true }, 14548 label: (0, import_i18n.__)("Widget areas") 14549 }, 14550 { 14551 name: "widget", 14552 kind: "root", 14553 baseURL: "/wp/v2/widgets", 14554 baseURLParams: { context: "edit" }, 14555 plural: "widgets", 14556 transientEdits: { blocks: true }, 14557 label: (0, import_i18n.__)("Widgets") 14558 }, 14559 { 14560 name: "widgetType", 14561 kind: "root", 14562 baseURL: "/wp/v2/widget-types", 14563 baseURLParams: { context: "edit" }, 14564 plural: "widgetTypes", 14565 label: (0, import_i18n.__)("Widget types") 14566 }, 14567 { 14568 label: (0, import_i18n.__)("User"), 14569 name: "user", 14570 kind: "root", 14571 baseURL: "/wp/v2/users", 14572 getTitle: (record) => record?.name || record?.slug, 14573 baseURLParams: { context: "edit" }, 14574 plural: "users", 14575 supportsPagination: true 14576 }, 14577 { 14578 name: "comment", 14579 kind: "root", 14580 baseURL: "/wp/v2/comments", 14581 baseURLParams: { context: "edit" }, 14582 plural: "comments", 14583 label: (0, import_i18n.__)("Comment"), 14584 supportsPagination: true, 14585 syncConfig: defaultCollectionSyncConfig 14586 }, 14587 { 14588 name: "menu", 14589 kind: "root", 14590 baseURL: "/wp/v2/menus", 14591 baseURLParams: { context: "edit" }, 14592 plural: "menus", 14593 label: (0, import_i18n.__)("Menu"), 14594 supportsPagination: true 14595 }, 14596 { 14597 name: "menuItem", 14598 kind: "root", 14599 baseURL: "/wp/v2/menu-items", 14600 baseURLParams: { context: "edit" }, 14601 plural: "menuItems", 14602 label: (0, import_i18n.__)("Menu Item"), 14603 rawAttributes: ["title"], 14604 supportsPagination: true 14605 }, 14606 { 14607 name: "menuLocation", 14608 kind: "root", 14609 baseURL: "/wp/v2/menu-locations", 14610 baseURLParams: { context: "edit" }, 14611 plural: "menuLocations", 14612 label: (0, import_i18n.__)("Menu Location"), 14613 key: "name" 14614 }, 14615 { 14616 label: (0, import_i18n.__)("Global Styles"), 14617 name: "globalStyles", 14618 kind: "root", 14619 baseURL: "/wp/v2/global-styles", 14620 baseURLParams: { context: "edit" }, 14621 plural: "globalStylesVariations", 14622 // Should be different from name. 14623 getTitle: () => (0, import_i18n.__)("Custom Styles"), 14624 getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 14625 supportsPagination: true 14626 }, 14627 { 14628 label: (0, import_i18n.__)("Themes"), 14629 name: "theme", 14630 kind: "root", 14631 baseURL: "/wp/v2/themes", 14632 baseURLParams: { context: "edit" }, 14633 plural: "themes", 14634 key: "stylesheet" 14635 }, 14636 { 14637 label: (0, import_i18n.__)("Plugins"), 14638 name: "plugin", 14639 kind: "root", 14640 baseURL: "/wp/v2/plugins", 14641 baseURLParams: { context: "edit" }, 14642 plural: "plugins", 14643 key: "plugin" 14644 }, 14645 { 14646 label: (0, import_i18n.__)("Status"), 14647 name: "status", 14648 kind: "root", 14649 baseURL: "/wp/v2/statuses", 14650 baseURLParams: { context: "edit" }, 14651 plural: "statuses", 14652 key: "slug" 14653 }, 14654 { 14655 label: (0, import_i18n.__)("Registered Templates"), 14656 name: "registeredTemplate", 14657 kind: "root", 14658 baseURL: "/wp/v2/registered-templates", 14659 key: "id" 14660 }, 14661 { 14662 label: (0, import_i18n.__)("Font Collections"), 14663 name: "fontCollection", 14664 kind: "root", 14665 baseURL: "/wp/v2/font-collections", 14666 baseURLParams: { context: "view" }, 14667 plural: "fontCollections", 14668 key: "slug" 14669 }, 14670 { 14671 label: (0, import_i18n.__)("Icons"), 14672 name: "icon", 14673 kind: "root", 14674 baseURL: "/wp/v2/icons", 14675 baseURLParams: { context: "view" }, 14676 plural: "icons", 14677 key: "name" 14678 } 14679 ]; 14680 var deprecatedEntities = { 14681 root: { 14682 media: { 14683 since: "6.9", 14684 alternative: { 14685 kind: "postType", 14686 name: "attachment" 14687 } 14688 } 14689 } 14690 }; 14691 var additionalEntityConfigLoaders = [ 14692 { kind: "postType", loadEntities: loadPostTypeEntities }, 14693 { kind: "taxonomy", loadEntities: loadTaxonomyEntities }, 14694 { 14695 kind: "root", 14696 name: "site", 14697 plural: "sites", 14698 loadEntities: loadSiteEntity 14699 } 14700 ]; 14701 var prePersistPostType = async (persistedRecord, edits, name, isTemplate) => { 14702 const newEdits = {}; 14703 if (!isTemplate && persistedRecord?.status === "auto-draft") { 14704 if (!edits.status && !newEdits.status) { 14705 newEdits.status = "draft"; 14706 } 14707 if ((!edits.title || edits.title === "Auto Draft") && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === "Auto Draft")) { 14708 newEdits.title = ""; 14709 } 14710 } 14711 if (persistedRecord) { 14712 const objectType = `postType/$name}`; 14713 const objectId = persistedRecord.id; 14714 const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc( 14715 objectType, 14716 objectId 14717 ); 14718 if (serializedDoc) { 14719 newEdits.meta = { 14720 ...edits.meta, 14721 [POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE]: serializedDoc 14722 }; 14723 } 14724 } 14725 return newEdits; 14726 }; 14727 async function loadPostTypeEntities() { 14728 const postTypesPromise = (0, import_api_fetch2.default)({ path: "/wp/v2/types?context=view" }); 14729 const taxonomiesPromise = window._wpCollaborationEnabled ? (0, import_api_fetch2.default)({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({}); 14730 const [postTypes, taxonomies] = await Promise.all([ 14731 postTypesPromise, 14732 taxonomiesPromise 14733 ]); 14734 return Object.entries(postTypes ?? {}).map(([name, postType]) => { 14735 const isTemplate = ["wp_template", "wp_template_part"].includes( 14736 name 14737 ); 14738 const namespace = postType?.rest_namespace ?? "wp/v2"; 14739 const syncedProperties = /* @__PURE__ */ new Set([ 14740 "author", 14741 "blocks", 14742 "content", 14743 "comment_status", 14744 "date", 14745 "excerpt", 14746 "featured_media", 14747 "format", 14748 "meta", 14749 "ping_status", 14750 "slug", 14751 "status", 14752 "sticky", 14753 "template", 14754 "title", 14755 ...postType.taxonomies?.map((taxonomy) => taxonomies?.[taxonomy]?.rest_base)?.filter(Boolean) ?? [] 14756 ]); 14757 const entity2 = { 14758 kind: "postType", 14759 baseURL: `/$namespace}/$postType.rest_base}`, 14760 baseURLParams: { context: "edit" }, 14761 name, 14762 label: postType.name, 14763 transientEdits: { 14764 ...blocksTransientEdits, 14765 selection: true 14766 }, 14767 mergedEdits: { meta: true }, 14768 rawAttributes: POST_RAW_ATTRIBUTES, 14769 getTitle: (record) => record?.title?.rendered || record?.title || (isTemplate ? capitalCase(record.slug ?? "") : String(record.id)), 14770 __unstablePrePersist: (persistedRecord, edits) => prePersistPostType(persistedRecord, edits, name, isTemplate), 14771 __unstable_rest_base: postType.rest_base, 14772 supportsPagination: true, 14773 getRevisionsUrl: (parentId, revisionId) => `/$namespace}/$postType.rest_base}/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 14774 revisionKey: isTemplate && !window?.__experimentalTemplateActivate ? "wp_id" : DEFAULT_ENTITY_KEY 14775 }; 14776 entity2.syncConfig = { 14777 /** 14778 * Apply changes from the local editor to the local CRDT document so 14779 * that those changes can be synced to other peers (via the provider). 14780 * 14781 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 14782 * @param {Partial< import('@wordpress/sync').ObjectData >} changes 14783 * @return {void} 14784 */ 14785 applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, syncedProperties), 14786 /** 14787 * Create the awareness instance for the entity's CRDT document. 14788 * 14789 * @param {import('@wordpress/sync').CRDTDoc} ydoc 14790 * @param {import('@wordpress/sync').ObjectID} objectId 14791 * @return {import('@wordpress/sync').Awareness} Awareness instance 14792 */ 14793 createAwareness: (ydoc, objectId) => { 14794 const kind = "postType"; 14795 const id2 = parseInt(objectId, 10); 14796 return new PostEditorAwareness(ydoc, kind, name, id2); 14797 }, 14798 /** 14799 * Extract changes from a CRDT document that can be used to update the 14800 * local editor state. 14801 * 14802 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 14803 * @param {import('@wordpress/sync').ObjectData} editedRecord 14804 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 14805 */ 14806 getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc( 14807 crdtDoc, 14808 editedRecord, 14809 syncedProperties 14810 ), 14811 /** 14812 * Extract changes from a CRDT document that can be used to update the 14813 * local editor state. 14814 * 14815 * @param {import('@wordpress/sync').ObjectData} record 14816 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 14817 */ 14818 getPersistedCRDTDoc: (record) => { 14819 return record?.meta?.[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null; 14820 } 14821 }; 14822 return entity2; 14823 }); 14824 } 14825 async function loadTaxonomyEntities() { 14826 const taxonomies = await (0, import_api_fetch2.default)({ 14827 path: "/wp/v2/taxonomies?context=view" 14828 }); 14829 return Object.entries(taxonomies ?? {}).map(([name, taxonomy]) => { 14830 const namespace = taxonomy?.rest_namespace ?? "wp/v2"; 14831 const entity2 = { 14832 kind: "taxonomy", 14833 baseURL: `/$namespace}/$taxonomy.rest_base}`, 14834 baseURLParams: { context: "edit" }, 14835 name, 14836 label: taxonomy.name, 14837 getTitle: (record) => record?.name, 14838 supportsPagination: true 14839 }; 14840 entity2.syncConfig = defaultSyncConfig; 14841 return entity2; 14842 }); 14843 } 14844 async function loadSiteEntity() { 14845 const entity2 = { 14846 label: (0, import_i18n.__)("Site"), 14847 name: "site", 14848 kind: "root", 14849 key: false, 14850 baseURL: "/wp/v2/settings", 14851 meta: {} 14852 }; 14853 const site = await (0, import_api_fetch2.default)({ 14854 path: entity2.baseURL, 14855 method: "OPTIONS" 14856 }); 14857 const labels = {}; 14858 Object.entries(site?.schema?.properties ?? {}).forEach( 14859 ([key, value]) => { 14860 if (typeof value === "object" && value.title) { 14861 labels[key] = value.title; 14862 } 14863 } 14864 ); 14865 return [{ ...entity2, meta: { labels } }]; 14866 } 14867 var getMethodName = (kind, name, prefix = "get") => { 14868 const kindPrefix = kind === "root" ? "" : pascalCase(kind); 14869 const suffix = pascalCase(name); 14870 return `$prefix}$kindPrefix}$suffix}`; 14871 }; 14872 14873 // packages/core-data/build-module/queried-data/reducer.mjs 14874 function getContextFromAction(action) { 14875 const { query } = action; 14876 if (!query) { 14877 return "default"; 14878 } 14879 const queryParts = get_query_parts_default(query); 14880 return queryParts.context; 14881 } 14882 function getMergedItemIds(itemIds, nextItemIds, page, perPage) { 14883 const receivedAllIds = page === 1 && perPage === -1; 14884 if (receivedAllIds) { 14885 return nextItemIds; 14886 } 14887 const nextItemIdsStartIndex = (page - 1) * perPage; 14888 const size2 = Math.max( 14889 itemIds?.length ?? 0, 14890 nextItemIdsStartIndex + nextItemIds.length 14891 ); 14892 const mergedItemIds = new Array(size2); 14893 for (let i = 0; i < size2; i++) { 14894 const isInNextItemsRange = i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + perPage; 14895 mergedItemIds[i] = isInNextItemsRange ? nextItemIds[i - nextItemIdsStartIndex] : itemIds?.[i]; 14896 } 14897 return mergedItemIds; 14898 } 14899 function removeEntitiesById(entities2, ids) { 14900 return Object.fromEntries( 14901 Object.entries(entities2).filter( 14902 ([id2]) => !ids.some((itemId) => { 14903 if (Number.isInteger(itemId)) { 14904 return itemId === +id2; 14905 } 14906 return itemId === id2; 14907 }) 14908 ) 14909 ); 14910 } 14911 function items(state = {}, action) { 14912 switch (action.type) { 14913 case "RECEIVE_ITEMS": { 14914 const context = getContextFromAction(action); 14915 const key = action.key || DEFAULT_ENTITY_KEY; 14916 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 14917 return { 14918 ...state, 14919 [context]: { 14920 ...state[context], 14921 ...Object.fromEntries( 14922 itemsList.map((item) => [ 14923 item?.[key], 14924 conservativeMapItem( 14925 state?.[context]?.[item?.[key]], 14926 item 14927 ) 14928 ]) 14929 ) 14930 } 14931 }; 14932 } 14933 case "REMOVE_ITEMS": 14934 return Object.fromEntries( 14935 Object.entries(state).map(([itemId, contextState]) => [ 14936 itemId, 14937 removeEntitiesById(contextState, action.itemIds) 14938 ]) 14939 ); 14940 } 14941 return state; 14942 } 14943 function itemIsComplete(state = {}, action) { 14944 switch (action.type) { 14945 case "RECEIVE_ITEMS": { 14946 const context = getContextFromAction(action); 14947 const { query, key = DEFAULT_ENTITY_KEY } = action; 14948 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 14949 const queryParts = query ? get_query_parts_default(query) : {}; 14950 const isCompleteQuery = !query || !Array.isArray(queryParts.fields); 14951 return { 14952 ...state, 14953 [context]: { 14954 ...state[context], 14955 ...itemsList.reduce((result, item) => { 14956 const itemId = item?.[key]; 14957 result[itemId] = state?.[context]?.[itemId] || isCompleteQuery; 14958 return result; 14959 }, {}) 14960 } 14961 }; 14962 } 14963 case "REMOVE_ITEMS": 14964 return Object.fromEntries( 14965 Object.entries(state).map(([itemId, contextState]) => [ 14966 itemId, 14967 removeEntitiesById(contextState, action.itemIds) 14968 ]) 14969 ); 14970 } 14971 return state; 14972 } 14973 var receiveQueries = (0, import_compose.compose)([ 14974 // Limit to matching action type so we don't attempt to replace action on 14975 // an unhandled action. 14976 if_matching_action_default((action) => "query" in action), 14977 // Inject query parts into action for use both in `onSubKey` and reducer. 14978 replace_action_default((action) => { 14979 if (action.query) { 14980 return { 14981 ...action, 14982 ...get_query_parts_default(action.query) 14983 }; 14984 } 14985 return action; 14986 }), 14987 on_sub_key_default("context"), 14988 // Queries shape is shared, but keyed by query `stableKey` part. Original 14989 // reducer tracks only a single query object. 14990 on_sub_key_default("stableKey") 14991 ])((state = {}, action) => { 14992 if (action.type !== "RECEIVE_ITEMS") { 14993 return state; 14994 } 14995 if (!Array.isArray(action.items)) { 14996 return state; 14997 } 14998 const key = action.key ?? DEFAULT_ENTITY_KEY; 14999 return { 15000 itemIds: getMergedItemIds( 15001 state?.itemIds || [], 15002 action.items.map((item) => item?.[key]).filter(Boolean), 15003 action.page, 15004 action.perPage 15005 ), 15006 meta: action.meta 15007 }; 15008 }); 15009 var queries = (state = {}, action) => { 15010 switch (action.type) { 15011 case "RECEIVE_ITEMS": 15012 return receiveQueries(state, action); 15013 case "REMOVE_ITEMS": 15014 const removedItems = action.itemIds.reduce((result, itemId) => { 15015 result[itemId] = true; 15016 return result; 15017 }, {}); 15018 return Object.fromEntries( 15019 Object.entries(state).map( 15020 ([queryGroup, contextQueries]) => [ 15021 queryGroup, 15022 Object.fromEntries( 15023 Object.entries(contextQueries).map( 15024 ([query, queryItems]) => [ 15025 query, 15026 { 15027 ...queryItems, 15028 itemIds: queryItems.itemIds.filter( 15029 (queryId) => !removedItems[queryId] 15030 ) 15031 } 15032 ] 15033 ) 15034 ) 15035 ] 15036 ) 15037 ); 15038 default: 15039 return state; 15040 } 15041 }; 15042 var reducer_default = (0, import_data7.combineReducers)({ 15043 items, 15044 itemIsComplete, 15045 queries 15046 }); 15047 15048 // packages/core-data/build-module/reducer.mjs 15049 function users(state = { byId: {}, queries: {} }, action) { 15050 switch (action.type) { 15051 case "RECEIVE_USER_QUERY": 15052 return { 15053 byId: { 15054 ...state.byId, 15055 // Key users by their ID. 15056 ...action.users.reduce( 15057 (newUsers, user) => ({ 15058 ...newUsers, 15059 [user.id]: user 15060 }), 15061 {} 15062 ) 15063 }, 15064 queries: { 15065 ...state.queries, 15066 [action.queryID]: action.users.map((user) => user.id) 15067 } 15068 }; 15069 } 15070 return state; 15071 } 15072 function currentUser(state = {}, action) { 15073 switch (action.type) { 15074 case "RECEIVE_CURRENT_USER": 15075 return action.currentUser; 15076 } 15077 return state; 15078 } 15079 function currentTheme(state = void 0, action) { 15080 switch (action.type) { 15081 case "RECEIVE_CURRENT_THEME": 15082 return action.currentTheme.stylesheet; 15083 } 15084 return state; 15085 } 15086 function currentGlobalStylesId(state = void 0, action) { 15087 switch (action.type) { 15088 case "RECEIVE_CURRENT_GLOBAL_STYLES_ID": 15089 return action.id; 15090 } 15091 return state; 15092 } 15093 function themeBaseGlobalStyles(state = {}, action) { 15094 switch (action.type) { 15095 case "RECEIVE_THEME_GLOBAL_STYLES": 15096 return { 15097 ...state, 15098 [action.stylesheet]: action.globalStyles 15099 }; 15100 } 15101 return state; 15102 } 15103 function themeGlobalStyleVariations(state = {}, action) { 15104 switch (action.type) { 15105 case "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS": 15106 return { 15107 ...state, 15108 [action.stylesheet]: action.variations 15109 }; 15110 } 15111 return state; 15112 } 15113 var withMultiEntityRecordEdits = (reducer) => (state, action) => { 15114 if (action.type === "UNDO" || action.type === "REDO") { 15115 const { record } = action; 15116 let newState = state; 15117 record.forEach(({ id: { kind, name, recordId }, changes }) => { 15118 newState = reducer(newState, { 15119 type: "EDIT_ENTITY_RECORD", 15120 kind, 15121 name, 15122 recordId, 15123 edits: Object.entries(changes).reduce( 15124 (acc, [key, value]) => { 15125 acc[key] = action.type === "UNDO" ? value.from : value.to; 15126 return acc; 15127 }, 15128 {} 15129 ) 15130 }); 15131 }); 15132 return newState; 15133 } 15134 return reducer(state, action); 15135 }; 15136 function entity(entityConfig) { 15137 return (0, import_compose2.compose)([ 15138 withMultiEntityRecordEdits, 15139 // Limit to matching action type so we don't attempt to replace action on 15140 // an unhandled action. 15141 if_matching_action_default( 15142 (action) => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind 15143 ), 15144 // Inject the entity config into the action. 15145 replace_action_default((action) => { 15146 return { 15147 key: entityConfig.key || DEFAULT_ENTITY_KEY, 15148 ...action 15149 }; 15150 }) 15151 ])( 15152 (0, import_data8.combineReducers)({ 15153 queriedData: reducer_default, 15154 edits: (state = {}, action) => { 15155 switch (action.type) { 15156 case "RECEIVE_ITEMS": 15157 const context = action?.query?.context ?? "default"; 15158 if (context !== "default") { 15159 return state; 15160 } 15161 const nextState = { ...state }; 15162 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 15163 for (const record of itemsList) { 15164 const recordId = record?.[action.key]; 15165 const edits = nextState[recordId]; 15166 if (!edits) { 15167 continue; 15168 } 15169 const nextEdits2 = Object.keys(edits).reduce( 15170 (acc, key) => { 15171 if ( 15172 // Edits are the "raw" attribute values, but records may have 15173 // objects with more properties, so we use `get` here for the 15174 // comparison. 15175 !(0, import_es66.default)( 15176 edits[key], 15177 record[key]?.raw ?? record[key] 15178 ) && // Sometimes the server alters the sent value which means 15179 // we need to also remove the edits before the api request. 15180 (!action.persistedEdits || !(0, import_es66.default)( 15181 edits[key], 15182 action.persistedEdits[key] 15183 )) 15184 ) { 15185 acc[key] = edits[key]; 15186 } 15187 return acc; 15188 }, 15189 {} 15190 ); 15191 if (Object.keys(nextEdits2).length) { 15192 nextState[recordId] = nextEdits2; 15193 } else { 15194 delete nextState[recordId]; 15195 } 15196 } 15197 return nextState; 15198 case "EDIT_ENTITY_RECORD": 15199 const nextEdits = { 15200 ...state[action.recordId], 15201 ...action.edits 15202 }; 15203 Object.keys(nextEdits).forEach((key) => { 15204 if (nextEdits[key] === void 0) { 15205 delete nextEdits[key]; 15206 } 15207 }); 15208 return { 15209 ...state, 15210 [action.recordId]: nextEdits 15211 }; 15212 } 15213 return state; 15214 }, 15215 saving: (state = {}, action) => { 15216 switch (action.type) { 15217 case "SAVE_ENTITY_RECORD_START": 15218 case "SAVE_ENTITY_RECORD_FINISH": 15219 return { 15220 ...state, 15221 [action.recordId]: { 15222 pending: action.type === "SAVE_ENTITY_RECORD_START", 15223 error: action.error, 15224 isAutosave: action.isAutosave 15225 } 15226 }; 15227 } 15228 return state; 15229 }, 15230 deleting: (state = {}, action) => { 15231 switch (action.type) { 15232 case "DELETE_ENTITY_RECORD_START": 15233 case "DELETE_ENTITY_RECORD_FINISH": 15234 return { 15235 ...state, 15236 [action.recordId]: { 15237 pending: action.type === "DELETE_ENTITY_RECORD_START", 15238 error: action.error 15239 } 15240 }; 15241 } 15242 return state; 15243 }, 15244 revisions: (state = {}, action) => { 15245 if (action.type === "RECEIVE_ITEM_REVISIONS") { 15246 const recordKey = action.recordKey; 15247 delete action.recordKey; 15248 const newState = reducer_default(state[recordKey], { 15249 ...action, 15250 type: "RECEIVE_ITEMS" 15251 }); 15252 return { 15253 ...state, 15254 [recordKey]: newState 15255 }; 15256 } 15257 if (action.type === "REMOVE_ITEMS") { 15258 return Object.fromEntries( 15259 Object.entries(state).filter( 15260 ([id2]) => !action.itemIds.some((itemId) => { 15261 if (Number.isInteger(itemId)) { 15262 return itemId === +id2; 15263 } 15264 return itemId === id2; 15265 }) 15266 ) 15267 ); 15268 } 15269 return state; 15270 } 15271 }) 15272 ); 15273 } 15274 function entitiesConfig(state = rootEntitiesConfig, action) { 15275 switch (action.type) { 15276 case "ADD_ENTITIES": 15277 return [...state, ...action.entities]; 15278 } 15279 return state; 15280 } 15281 var entities = (state = {}, action) => { 15282 const newConfig = entitiesConfig(state.config, action); 15283 let entitiesDataReducer = state.reducer; 15284 if (!entitiesDataReducer || newConfig !== state.config) { 15285 const entitiesByKind = newConfig.reduce((acc, record) => { 15286 const { kind } = record; 15287 if (!acc[kind]) { 15288 acc[kind] = []; 15289 } 15290 acc[kind].push(record); 15291 return acc; 15292 }, {}); 15293 entitiesDataReducer = (0, import_data8.combineReducers)( 15294 Object.fromEntries( 15295 Object.entries(entitiesByKind).map( 15296 ([kind, subEntities]) => { 15297 const kindReducer = (0, import_data8.combineReducers)( 15298 Object.fromEntries( 15299 subEntities.map((entityConfig) => [ 15300 entityConfig.name, 15301 entity(entityConfig) 15302 ]) 15303 ) 15304 ); 15305 return [kind, kindReducer]; 15306 } 15307 ) 15308 ) 15309 ); 15310 } 15311 const newData = entitiesDataReducer(state.records, action); 15312 if (newData === state.records && newConfig === state.config && entitiesDataReducer === state.reducer) { 15313 return state; 15314 } 15315 return { 15316 reducer: entitiesDataReducer, 15317 records: newData, 15318 config: newConfig 15319 }; 15320 }; 15321 function undoManager(state = (0, import_undo_manager2.createUndoManager)()) { 15322 return state; 15323 } 15324 function editsReference(state = {}, action) { 15325 switch (action.type) { 15326 case "EDIT_ENTITY_RECORD": 15327 case "UNDO": 15328 case "REDO": 15329 return {}; 15330 } 15331 return state; 15332 } 15333 function embedPreviews(state = {}, action) { 15334 switch (action.type) { 15335 case "RECEIVE_EMBED_PREVIEW": 15336 const { url, preview } = action; 15337 return { 15338 ...state, 15339 [url]: preview 15340 }; 15341 } 15342 return state; 15343 } 15344 function userPermissions(state = {}, action) { 15345 switch (action.type) { 15346 case "RECEIVE_USER_PERMISSION": 15347 return { 15348 ...state, 15349 [action.key]: action.isAllowed 15350 }; 15351 case "RECEIVE_USER_PERMISSIONS": 15352 return { 15353 ...state, 15354 ...action.permissions 15355 }; 15356 } 15357 return state; 15358 } 15359 function autosaves(state = {}, action) { 15360 switch (action.type) { 15361 case "RECEIVE_AUTOSAVES": 15362 const { postId, autosaves: autosavesData } = action; 15363 return { 15364 ...state, 15365 [postId]: autosavesData 15366 }; 15367 } 15368 return state; 15369 } 15370 function blockPatterns(state = [], action) { 15371 switch (action.type) { 15372 case "RECEIVE_BLOCK_PATTERNS": 15373 return action.patterns; 15374 } 15375 return state; 15376 } 15377 function blockPatternCategories(state = [], action) { 15378 switch (action.type) { 15379 case "RECEIVE_BLOCK_PATTERN_CATEGORIES": 15380 return action.categories; 15381 } 15382 return state; 15383 } 15384 function userPatternCategories(state = [], action) { 15385 switch (action.type) { 15386 case "RECEIVE_USER_PATTERN_CATEGORIES": 15387 return action.patternCategories; 15388 } 15389 return state; 15390 } 15391 function navigationFallbackId(state = null, action) { 15392 switch (action.type) { 15393 case "RECEIVE_NAVIGATION_FALLBACK_ID": 15394 return action.fallbackId; 15395 } 15396 return state; 15397 } 15398 function themeGlobalStyleRevisions(state = {}, action) { 15399 switch (action.type) { 15400 case "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS": 15401 return { 15402 ...state, 15403 [action.currentId]: action.revisions 15404 }; 15405 } 15406 return state; 15407 } 15408 function defaultTemplates(state = {}, action) { 15409 switch (action.type) { 15410 case "RECEIVE_DEFAULT_TEMPLATE": 15411 return { 15412 ...state, 15413 [JSON.stringify(action.query)]: action.templateId 15414 }; 15415 } 15416 return state; 15417 } 15418 function registeredPostMeta(state = {}, action) { 15419 switch (action.type) { 15420 case "RECEIVE_REGISTERED_POST_META": 15421 return { 15422 ...state, 15423 [action.postType]: action.registeredPostMeta 15424 }; 15425 } 15426 return state; 15427 } 15428 function editorSettings(state = null, action) { 15429 switch (action.type) { 15430 case "RECEIVE_EDITOR_SETTINGS": 15431 return action.settings; 15432 } 15433 return state; 15434 } 15435 function editorAssets(state = null, action) { 15436 switch (action.type) { 15437 case "RECEIVE_EDITOR_ASSETS": 15438 return action.assets; 15439 } 15440 return state; 15441 } 15442 function syncConnectionStatuses(state = {}, action) { 15443 switch (action.type) { 15444 case "SET_SYNC_CONNECTION_STATUS": { 15445 const key = `$action.kind}/$action.name}:$action.key}`; 15446 return { 15447 ...state, 15448 [key]: action.status 15449 }; 15450 } 15451 case "CLEAR_SYNC_CONNECTION_STATUS": { 15452 const key = `$action.kind}/$action.name}:$action.key}`; 15453 const { [key]: _, ...rest } = state; 15454 return rest; 15455 } 15456 } 15457 return state; 15458 } 15459 function collaborationSupported(state = true, action) { 15460 switch (action.type) { 15461 case "SET_COLLABORATION_SUPPORTED": 15462 return action.supported; 15463 case "SET_SYNC_CONNECTION_STATUS": 15464 if (ConnectionErrorCode2.DOCUMENT_SIZE_LIMIT_EXCEEDED === action.status?.error?.code) { 15465 return false; 15466 } 15467 return state; 15468 } 15469 return state; 15470 } 15471 var reducer_default2 = (0, import_data8.combineReducers)({ 15472 users, 15473 currentTheme, 15474 currentGlobalStylesId, 15475 currentUser, 15476 themeGlobalStyleVariations, 15477 themeBaseGlobalStyles, 15478 themeGlobalStyleRevisions, 15479 entities, 15480 editsReference, 15481 undoManager, 15482 embedPreviews, 15483 userPermissions, 15484 autosaves, 15485 blockPatterns, 15486 blockPatternCategories, 15487 userPatternCategories, 15488 navigationFallbackId, 15489 defaultTemplates, 15490 registeredPostMeta, 15491 editorSettings, 15492 editorAssets, 15493 syncConnectionStatuses, 15494 collaborationSupported 15495 }); 15496 15497 // packages/core-data/build-module/selectors.mjs 15498 var selectors_exports = {}; 15499 __export(selectors_exports, { 15500 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId, 15501 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles, 15502 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations, 15503 __experimentalGetDirtyEntityRecords: () => __experimentalGetDirtyEntityRecords, 15504 __experimentalGetEntitiesBeingSaved: () => __experimentalGetEntitiesBeingSaved, 15505 __experimentalGetEntityRecordNoResolver: () => __experimentalGetEntityRecordNoResolver, 15506 canUser: () => canUser, 15507 canUserEditEntityRecord: () => canUserEditEntityRecord, 15508 getAuthors: () => getAuthors, 15509 getAutosave: () => getAutosave, 15510 getAutosaves: () => getAutosaves, 15511 getBlockPatternCategories: () => getBlockPatternCategories, 15512 getBlockPatterns: () => getBlockPatterns, 15513 getCurrentTheme: () => getCurrentTheme, 15514 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions, 15515 getCurrentUser: () => getCurrentUser, 15516 getDefaultTemplateId: () => getDefaultTemplateId, 15517 getEditedEntityRecord: () => getEditedEntityRecord, 15518 getEmbedPreview: () => getEmbedPreview, 15519 getEntitiesByKind: () => getEntitiesByKind, 15520 getEntitiesConfig: () => getEntitiesConfig, 15521 getEntity: () => getEntity, 15522 getEntityConfig: () => getEntityConfig, 15523 getEntityRecord: () => getEntityRecord, 15524 getEntityRecordEdits: () => getEntityRecordEdits, 15525 getEntityRecordNonTransientEdits: () => getEntityRecordNonTransientEdits, 15526 getEntityRecords: () => getEntityRecords, 15527 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems, 15528 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages, 15529 getLastEntityDeleteError: () => getLastEntityDeleteError, 15530 getLastEntitySaveError: () => getLastEntitySaveError, 15531 getRawEntityRecord: () => getRawEntityRecord, 15532 getRedoEdit: () => getRedoEdit, 15533 getReferenceByDistinctEdits: () => getReferenceByDistinctEdits, 15534 getRevision: () => getRevision, 15535 getRevisions: () => getRevisions, 15536 getThemeSupports: () => getThemeSupports, 15537 getUndoEdit: () => getUndoEdit, 15538 getUserPatternCategories: () => getUserPatternCategories, 15539 getUserQueryResults: () => getUserQueryResults, 15540 hasEditsForEntityRecord: () => hasEditsForEntityRecord, 15541 hasEntityRecord: () => hasEntityRecord, 15542 hasEntityRecords: () => hasEntityRecords, 15543 hasFetchedAutosaves: () => hasFetchedAutosaves, 15544 hasRedo: () => hasRedo, 15545 hasUndo: () => hasUndo, 15546 isAutosavingEntityRecord: () => isAutosavingEntityRecord, 15547 isDeletingEntityRecord: () => isDeletingEntityRecord, 15548 isPreviewEmbedFallback: () => isPreviewEmbedFallback, 15549 isRequestingEmbedPreview: () => isRequestingEmbedPreview, 15550 isSavingEntityRecord: () => isSavingEntityRecord 15551 }); 15552 var import_data10 = __toESM(require_data(), 1); 15553 var import_url2 = __toESM(require_url(), 1); 15554 var import_deprecated2 = __toESM(require_deprecated(), 1); 15555 15556 // packages/core-data/build-module/private-selectors.mjs 15557 var private_selectors_exports = {}; 15558 __export(private_selectors_exports, { 15559 getBlockPatternsForPostType: () => getBlockPatternsForPostType, 15560 getEditorAssets: () => getEditorAssets, 15561 getEditorSettings: () => getEditorSettings, 15562 getEntityRecordPermissions: () => getEntityRecordPermissions, 15563 getEntityRecordsPermissions: () => getEntityRecordsPermissions, 15564 getHomePage: () => getHomePage, 15565 getNavigationFallbackId: () => getNavigationFallbackId, 15566 getPostsPageId: () => getPostsPageId, 15567 getRegisteredPostMeta: () => getRegisteredPostMeta, 15568 getSyncConnectionStatus: () => getSyncConnectionStatus, 15569 getTemplateId: () => getTemplateId, 15570 getUndoManager: () => getUndoManager, 15571 isCollaborationSupported: () => isCollaborationSupported 15572 }); 15573 var import_data9 = __toESM(require_data(), 1); 15574 15575 // packages/core-data/build-module/utils/log-entity-deprecation.mjs 15576 var import_deprecated = __toESM(require_deprecated(), 1); 15577 var loggedAlready = false; 15578 function logEntityDeprecation(kind, name, functionName, { 15579 alternativeFunctionName, 15580 isShorthandSelector = false 15581 } = {}) { 15582 const deprecation = deprecatedEntities[kind]?.[name]; 15583 if (!deprecation) { 15584 return; 15585 } 15586 if (!loggedAlready) { 15587 const { alternative } = deprecation; 15588 const message = isShorthandSelector ? `'$functionName}'` : `The '$kind}', '$name}' entity (used via '$functionName}')`; 15589 let alternativeMessage = `the '$alternative.kind}', '$alternative.name}' entity`; 15590 if (alternativeFunctionName) { 15591 alternativeMessage += ` via the '$alternativeFunctionName}' function`; 15592 } 15593 (0, import_deprecated.default)(message, { 15594 ...deprecation, 15595 alternative: alternativeMessage 15596 }); 15597 } 15598 loggedAlready = true; 15599 setTimeout(() => { 15600 loggedAlready = false; 15601 }, 0); 15602 } 15603 15604 // packages/core-data/build-module/private-selectors.mjs 15605 function getUndoManager(state) { 15606 return getSyncManager()?.undoManager ?? state.undoManager; 15607 } 15608 function getNavigationFallbackId(state) { 15609 return state.navigationFallbackId; 15610 } 15611 var getBlockPatternsForPostType = (0, import_data9.createRegistrySelector)( 15612 (select5) => (0, import_data9.createSelector)( 15613 (state, postType) => select5(STORE_NAME).getBlockPatterns().filter( 15614 ({ postTypes }) => !postTypes || Array.isArray(postTypes) && postTypes.includes(postType) 15615 ), 15616 () => [select5(STORE_NAME).getBlockPatterns()] 15617 ) 15618 ); 15619 var getEntityRecordsPermissions = (0, import_data9.createRegistrySelector)( 15620 (select5) => (0, import_data9.createSelector)( 15621 (state, kind, name, ids) => { 15622 const normalizedIds = Array.isArray(ids) ? ids : [ids]; 15623 return normalizedIds.map((id2) => ({ 15624 delete: select5(STORE_NAME).canUser("delete", { 15625 kind, 15626 name, 15627 id: id2 15628 }), 15629 update: select5(STORE_NAME).canUser("update", { 15630 kind, 15631 name, 15632 id: id2 15633 }) 15634 })); 15635 }, 15636 (state) => [state.userPermissions] 15637 ) 15638 ); 15639 function getEntityRecordPermissions(state, kind, name, id2) { 15640 logEntityDeprecation(kind, name, "getEntityRecordPermissions"); 15641 return getEntityRecordsPermissions(state, kind, name, id2)[0]; 15642 } 15643 function getRegisteredPostMeta(state, postType) { 15644 return state.registeredPostMeta?.[postType] ?? {}; 15645 } 15646 function normalizePageId(value) { 15647 if (!value || !["number", "string"].includes(typeof value)) { 15648 return null; 15649 } 15650 if (Number(value) === 0) { 15651 return null; 15652 } 15653 return value.toString(); 15654 } 15655 var getHomePage = (0, import_data9.createRegistrySelector)( 15656 (select5) => (0, import_data9.createSelector)( 15657 () => { 15658 const siteData = select5(STORE_NAME).getEntityRecord( 15659 "root", 15660 "__unstableBase" 15661 ); 15662 if (!siteData) { 15663 return null; 15664 } 15665 const homepageId = siteData?.show_on_front === "page" ? normalizePageId(siteData.page_on_front) : null; 15666 if (homepageId) { 15667 return { postType: "page", postId: homepageId }; 15668 } 15669 const frontPageTemplateId = select5( 15670 STORE_NAME 15671 ).getDefaultTemplateId({ 15672 slug: "front-page" 15673 }); 15674 if (!frontPageTemplateId) { 15675 return null; 15676 } 15677 return { postType: "wp_template", postId: frontPageTemplateId }; 15678 }, 15679 (state) => [ 15680 // Even though getDefaultTemplateId.shouldInvalidate returns true when root/site changes, 15681 // it doesn't seem to invalidate this cache, I'm not sure why. 15682 getEntityRecord(state, "root", "site"), 15683 getEntityRecord(state, "root", "__unstableBase"), 15684 getDefaultTemplateId(state, { 15685 slug: "front-page" 15686 }) 15687 ] 15688 ) 15689 ); 15690 var getPostsPageId = (0, import_data9.createRegistrySelector)((select5) => () => { 15691 const siteData = select5(STORE_NAME).getEntityRecord( 15692 "root", 15693 "__unstableBase" 15694 ); 15695 return siteData?.show_on_front === "page" ? normalizePageId(siteData.page_for_posts) : null; 15696 }); 15697 var getTemplateId = (0, import_data9.createRegistrySelector)( 15698 (select5) => (state, postType, postId) => { 15699 const homepage = unlock2(select5(STORE_NAME)).getHomePage(); 15700 if (!homepage) { 15701 return; 15702 } 15703 if (postType === "page" && postType === homepage?.postType && postId.toString() === homepage?.postId) { 15704 const templates = select5(STORE_NAME).getEntityRecords( 15705 "postType", 15706 "wp_template", 15707 { 15708 per_page: -1 15709 } 15710 ); 15711 if (!templates) { 15712 return; 15713 } 15714 const id2 = templates.find(({ slug }) => slug === "front-page")?.id; 15715 if (id2) { 15716 return id2; 15717 } 15718 } 15719 const editedEntity = select5(STORE_NAME).getEditedEntityRecord( 15720 "postType", 15721 postType, 15722 postId 15723 ); 15724 if (!editedEntity) { 15725 return; 15726 } 15727 const postsPageId = unlock2(select5(STORE_NAME)).getPostsPageId(); 15728 if (postType === "page" && postsPageId === postId.toString()) { 15729 return select5(STORE_NAME).getDefaultTemplateId({ 15730 slug: "home" 15731 }); 15732 } 15733 const currentTemplateSlug = editedEntity.template; 15734 if (currentTemplateSlug) { 15735 const currentTemplate = select5(STORE_NAME).getEntityRecords("postType", "wp_template", { 15736 per_page: -1 15737 })?.find(({ slug }) => slug === currentTemplateSlug); 15738 if (currentTemplate) { 15739 return currentTemplate.id; 15740 } 15741 } 15742 let slugToCheck; 15743 if (editedEntity.slug) { 15744 slugToCheck = postType === "page" ? `$postType}-$editedEntity.slug}` : `single-$postType}-$editedEntity.slug}`; 15745 } else { 15746 slugToCheck = postType === "page" ? "page" : `single-$postType}`; 15747 } 15748 return select5(STORE_NAME).getDefaultTemplateId({ 15749 slug: slugToCheck 15750 }); 15751 } 15752 ); 15753 function getEditorSettings(state) { 15754 return state.editorSettings; 15755 } 15756 function getEditorAssets(state) { 15757 return state.editorAssets; 15758 } 15759 function isCollaborationSupported(state) { 15760 return state.collaborationSupported; 15761 } 15762 function getSyncConnectionStatus(state) { 15763 if (!state.syncConnectionStatuses) { 15764 return void 0; 15765 } 15766 const PRIORITIZED_STATUSES = ["disconnected", "connecting", "connected"]; 15767 let coalesced; 15768 for (const status of Object.values(state.syncConnectionStatuses)) { 15769 if (!coalesced || PRIORITIZED_STATUSES.indexOf(status.status) < PRIORITIZED_STATUSES.indexOf(coalesced.status)) { 15770 coalesced = status; 15771 } 15772 } 15773 return coalesced; 15774 } 15775 15776 // packages/core-data/build-module/selectors.mjs 15777 var EMPTY_OBJECT = {}; 15778 var isRequestingEmbedPreview = (0, import_data10.createRegistrySelector)( 15779 (select5) => (state, url) => { 15780 return select5(STORE_NAME).isResolving("getEmbedPreview", [ 15781 url 15782 ]); 15783 } 15784 ); 15785 function getAuthors(state, query) { 15786 (0, import_deprecated2.default)("select( 'core' ).getAuthors()", { 15787 since: "5.9", 15788 alternative: "select( 'core' ).getUsers({ who: 'authors' })" 15789 }); 15790 const path = (0, import_url2.addQueryArgs)( 15791 "/wp/v2/users/?who=authors&per_page=100", 15792 query 15793 ); 15794 return getUserQueryResults(state, path); 15795 } 15796 function getCurrentUser(state) { 15797 return state.currentUser; 15798 } 15799 var getUserQueryResults = (0, import_data10.createSelector)( 15800 (state, queryID) => { 15801 const queryResults = state.users.queries[queryID] ?? []; 15802 return queryResults.map((id2) => state.users.byId[id2]); 15803 }, 15804 (state, queryID) => [ 15805 state.users.queries[queryID], 15806 state.users.byId 15807 ] 15808 ); 15809 function getEntitiesByKind(state, kind) { 15810 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntitiesByKind()", { 15811 since: "6.0", 15812 alternative: "wp.data.select( 'core' ).getEntitiesConfig()" 15813 }); 15814 return getEntitiesConfig(state, kind); 15815 } 15816 var getEntitiesConfig = (0, import_data10.createSelector)( 15817 (state, kind) => state.entities.config.filter((entity2) => entity2.kind === kind), 15818 /* eslint-disable @typescript-eslint/no-unused-vars */ 15819 (state, kind) => state.entities.config 15820 /* eslint-enable @typescript-eslint/no-unused-vars */ 15821 ); 15822 function getEntity(state, kind, name) { 15823 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntity()", { 15824 since: "6.0", 15825 alternative: "wp.data.select( 'core' ).getEntityConfig()" 15826 }); 15827 return getEntityConfig(state, kind, name); 15828 } 15829 function getEntityConfig(state, kind, name) { 15830 logEntityDeprecation(kind, name, "getEntityConfig"); 15831 return state.entities.config?.find( 15832 (config) => config.kind === kind && config.name === name 15833 ); 15834 } 15835 var getEntityRecord = (0, import_data10.createSelector)( 15836 ((state, kind, name, key, query) => { 15837 logEntityDeprecation(kind, name, "getEntityRecord"); 15838 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 15839 if (!queriedState) { 15840 return void 0; 15841 } 15842 const context = query?.context ?? "default"; 15843 if (!query || !query._fields) { 15844 if (!queriedState.itemIsComplete[context]?.[key]) { 15845 return void 0; 15846 } 15847 return queriedState.items[context][key]; 15848 } 15849 const item = queriedState.items[context]?.[key]; 15850 if (!item) { 15851 return item; 15852 } 15853 const filteredItem = {}; 15854 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 15855 for (let f = 0; f < fields.length; f++) { 15856 const field = fields[f].split("."); 15857 let value = item; 15858 field.forEach((fieldName) => { 15859 value = value?.[fieldName]; 15860 }); 15861 setNestedValue(filteredItem, field, value); 15862 } 15863 return filteredItem; 15864 }), 15865 (state, kind, name, recordId, query) => { 15866 const context = query?.context ?? "default"; 15867 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 15868 return [ 15869 queriedState?.items[context]?.[recordId], 15870 queriedState?.itemIsComplete[context]?.[recordId] 15871 ]; 15872 } 15873 ); 15874 getEntityRecord.__unstableNormalizeArgs = (args2) => { 15875 const newArgs = [...args2]; 15876 const recordKey = newArgs?.[2]; 15877 newArgs[2] = isNumericID(recordKey) ? Number(recordKey) : recordKey; 15878 return newArgs; 15879 }; 15880 function hasEntityRecord(state, kind, name, key, query) { 15881 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 15882 if (!queriedState) { 15883 return false; 15884 } 15885 const context = query?.context ?? "default"; 15886 if (!query || !query._fields) { 15887 return !!queriedState.itemIsComplete[context]?.[key]; 15888 } 15889 const item = queriedState.items[context]?.[key]; 15890 if (!item) { 15891 return false; 15892 } 15893 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 15894 for (let i = 0; i < fields.length; i++) { 15895 const path = fields[i].split("."); 15896 let value = item; 15897 for (let p = 0; p < path.length; p++) { 15898 const part = path[p]; 15899 if (!value || !Object.hasOwn(value, part)) { 15900 return false; 15901 } 15902 value = value[part]; 15903 } 15904 } 15905 return true; 15906 } 15907 function __experimentalGetEntityRecordNoResolver(state, kind, name, key) { 15908 return getEntityRecord(state, kind, name, key); 15909 } 15910 var getRawEntityRecord = (0, import_data10.createSelector)( 15911 (state, kind, name, key) => { 15912 logEntityDeprecation(kind, name, "getRawEntityRecord"); 15913 const record = getEntityRecord( 15914 state, 15915 kind, 15916 name, 15917 key 15918 ); 15919 return record && Object.keys(record).reduce((accumulator, _key) => { 15920 if (isRawAttribute(getEntityConfig(state, kind, name), _key)) { 15921 accumulator[_key] = record[_key]?.raw !== void 0 ? record[_key]?.raw : record[_key]; 15922 } else { 15923 accumulator[_key] = record[_key]; 15924 } 15925 return accumulator; 15926 }, {}); 15927 }, 15928 (state, kind, name, recordId, query) => { 15929 const context = query?.context ?? "default"; 15930 return [ 15931 state.entities.config, 15932 state.entities.records?.[kind]?.[name]?.queriedData?.items[context]?.[recordId], 15933 state.entities.records?.[kind]?.[name]?.queriedData?.itemIsComplete[context]?.[recordId] 15934 ]; 15935 } 15936 ); 15937 function hasEntityRecords(state, kind, name, query) { 15938 logEntityDeprecation(kind, name, "hasEntityRecords"); 15939 return Array.isArray(getEntityRecords(state, kind, name, query)); 15940 } 15941 var getEntityRecords = ((state, kind, name, query) => { 15942 logEntityDeprecation(kind, name, "getEntityRecords"); 15943 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 15944 if (!queriedState) { 15945 return null; 15946 } 15947 return getQueriedItems(queriedState, query); 15948 }); 15949 var getEntityRecordsTotalItems = (state, kind, name, query) => { 15950 logEntityDeprecation(kind, name, "getEntityRecordsTotalItems"); 15951 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 15952 if (!queriedState) { 15953 return null; 15954 } 15955 return getQueriedTotalItems(queriedState, query); 15956 }; 15957 var getEntityRecordsTotalPages = (state, kind, name, query) => { 15958 logEntityDeprecation(kind, name, "getEntityRecordsTotalPages"); 15959 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 15960 if (!queriedState) { 15961 return null; 15962 } 15963 if (query?.per_page === -1) { 15964 return 1; 15965 } 15966 const totalItems = getQueriedTotalItems(queriedState, query); 15967 if (!totalItems) { 15968 return totalItems; 15969 } 15970 if (!query?.per_page) { 15971 return getQueriedTotalPages(queriedState, query); 15972 } 15973 return Math.ceil(totalItems / query.per_page); 15974 }; 15975 var __experimentalGetDirtyEntityRecords = (0, import_data10.createSelector)( 15976 (state) => { 15977 const { 15978 entities: { records } 15979 } = state; 15980 const dirtyRecords = []; 15981 Object.keys(records).forEach((kind) => { 15982 Object.keys(records[kind]).forEach((name) => { 15983 const primaryKeys = Object.keys(records[kind][name].edits).filter( 15984 (primaryKey) => ( 15985 // The entity record must exist (not be deleted), 15986 // and it must have edits. 15987 getEntityRecord(state, kind, name, primaryKey) && hasEditsForEntityRecord(state, kind, name, primaryKey) 15988 ) 15989 ); 15990 if (primaryKeys.length) { 15991 const entityConfig = getEntityConfig(state, kind, name); 15992 primaryKeys.forEach((primaryKey) => { 15993 const entityRecord = getEditedEntityRecord( 15994 state, 15995 kind, 15996 name, 15997 primaryKey 15998 ); 15999 dirtyRecords.push({ 16000 // We avoid using primaryKey because it's transformed into a string 16001 // when it's used as an object key. 16002 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 16003 title: entityConfig?.getTitle?.(entityRecord) || "", 16004 name, 16005 kind 16006 }); 16007 }); 16008 } 16009 }); 16010 }); 16011 return dirtyRecords; 16012 }, 16013 (state) => [state.entities.records] 16014 ); 16015 var __experimentalGetEntitiesBeingSaved = (0, import_data10.createSelector)( 16016 (state) => { 16017 const { 16018 entities: { records } 16019 } = state; 16020 const recordsBeingSaved = []; 16021 Object.keys(records).forEach((kind) => { 16022 Object.keys(records[kind]).forEach((name) => { 16023 const primaryKeys = Object.keys(records[kind][name].saving).filter( 16024 (primaryKey) => isSavingEntityRecord(state, kind, name, primaryKey) 16025 ); 16026 if (primaryKeys.length) { 16027 const entityConfig = getEntityConfig(state, kind, name); 16028 primaryKeys.forEach((primaryKey) => { 16029 const entityRecord = getEditedEntityRecord( 16030 state, 16031 kind, 16032 name, 16033 primaryKey 16034 ); 16035 recordsBeingSaved.push({ 16036 // We avoid using primaryKey because it's transformed into a string 16037 // when it's used as an object key. 16038 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 16039 title: entityConfig?.getTitle?.(entityRecord) || "", 16040 name, 16041 kind 16042 }); 16043 }); 16044 } 16045 }); 16046 }); 16047 return recordsBeingSaved; 16048 }, 16049 (state) => [state.entities.records] 16050 ); 16051 function getEntityRecordEdits(state, kind, name, recordId) { 16052 logEntityDeprecation(kind, name, "getEntityRecordEdits"); 16053 return state.entities.records?.[kind]?.[name]?.edits?.[recordId]; 16054 } 16055 var getEntityRecordNonTransientEdits = (0, import_data10.createSelector)( 16056 (state, kind, name, recordId) => { 16057 logEntityDeprecation(kind, name, "getEntityRecordNonTransientEdits"); 16058 const { transientEdits } = getEntityConfig(state, kind, name) || {}; 16059 const edits = getEntityRecordEdits(state, kind, name, recordId) || {}; 16060 if (!transientEdits) { 16061 return edits; 16062 } 16063 return Object.keys(edits).reduce((acc, key) => { 16064 if (!transientEdits[key]) { 16065 acc[key] = edits[key]; 16066 } 16067 return acc; 16068 }, {}); 16069 }, 16070 (state, kind, name, recordId) => [ 16071 state.entities.config, 16072 state.entities.records?.[kind]?.[name]?.edits?.[recordId] 16073 ] 16074 ); 16075 function hasEditsForEntityRecord(state, kind, name, recordId) { 16076 logEntityDeprecation(kind, name, "hasEditsForEntityRecord"); 16077 return isSavingEntityRecord(state, kind, name, recordId) || Object.keys( 16078 getEntityRecordNonTransientEdits(state, kind, name, recordId) 16079 ).length > 0; 16080 } 16081 var getEditedEntityRecord = (0, import_data10.createSelector)( 16082 (state, kind, name, recordId) => { 16083 logEntityDeprecation(kind, name, "getEditedEntityRecord"); 16084 const raw = getRawEntityRecord(state, kind, name, recordId); 16085 const edited = getEntityRecordEdits(state, kind, name, recordId); 16086 if (!raw && !edited) { 16087 return false; 16088 } 16089 return { 16090 ...raw, 16091 ...edited 16092 }; 16093 }, 16094 (state, kind, name, recordId, query) => { 16095 const context = query?.context ?? "default"; 16096 return [ 16097 state.entities.config, 16098 state.entities.records?.[kind]?.[name]?.queriedData.items[context]?.[recordId], 16099 state.entities.records?.[kind]?.[name]?.queriedData.itemIsComplete[context]?.[recordId], 16100 state.entities.records?.[kind]?.[name]?.edits?.[recordId] 16101 ]; 16102 } 16103 ); 16104 function isAutosavingEntityRecord(state, kind, name, recordId) { 16105 logEntityDeprecation(kind, name, "isAutosavingEntityRecord"); 16106 const { pending, isAutosave } = state.entities.records?.[kind]?.[name]?.saving?.[recordId] ?? {}; 16107 return Boolean(pending && isAutosave); 16108 } 16109 function isSavingEntityRecord(state, kind, name, recordId) { 16110 logEntityDeprecation(kind, name, "isSavingEntityRecord"); 16111 return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.pending ?? false; 16112 } 16113 function isDeletingEntityRecord(state, kind, name, recordId) { 16114 logEntityDeprecation(kind, name, "isDeletingEntityRecord"); 16115 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.pending ?? false; 16116 } 16117 function getLastEntitySaveError(state, kind, name, recordId) { 16118 logEntityDeprecation(kind, name, "getLastEntitySaveError"); 16119 return state.entities.records?.[kind]?.[name]?.saving?.[recordId]?.error; 16120 } 16121 function getLastEntityDeleteError(state, kind, name, recordId) { 16122 logEntityDeprecation(kind, name, "getLastEntityDeleteError"); 16123 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.error; 16124 } 16125 function getUndoEdit(state) { 16126 (0, import_deprecated2.default)("select( 'core' ).getUndoEdit()", { 16127 since: "6.3" 16128 }); 16129 return void 0; 16130 } 16131 function getRedoEdit(state) { 16132 (0, import_deprecated2.default)("select( 'core' ).getRedoEdit()", { 16133 since: "6.3" 16134 }); 16135 return void 0; 16136 } 16137 function hasUndo(state) { 16138 return getUndoManager(state).hasUndo(); 16139 } 16140 function hasRedo(state) { 16141 return getUndoManager(state).hasRedo(); 16142 } 16143 function getCurrentTheme(state) { 16144 if (!state.currentTheme) { 16145 return null; 16146 } 16147 return getEntityRecord(state, "root", "theme", state.currentTheme); 16148 } 16149 function __experimentalGetCurrentGlobalStylesId(state) { 16150 return state.currentGlobalStylesId; 16151 } 16152 function getThemeSupports(state) { 16153 return getCurrentTheme(state)?.theme_supports ?? EMPTY_OBJECT; 16154 } 16155 function getEmbedPreview(state, url) { 16156 return state.embedPreviews[url]; 16157 } 16158 function isPreviewEmbedFallback(state, url) { 16159 const preview = state.embedPreviews[url]; 16160 const oEmbedLinkCheck = '<a href="' + url + '">' + url + "</a>"; 16161 if (!preview) { 16162 return false; 16163 } 16164 return preview.html === oEmbedLinkCheck; 16165 } 16166 function canUser(state, action, resource, id2) { 16167 const isEntity = typeof resource === "object"; 16168 if (isEntity && (!resource.kind || !resource.name)) { 16169 return false; 16170 } 16171 if (isEntity) { 16172 logEntityDeprecation(resource.kind, resource.name, "canUser"); 16173 } 16174 const key = getUserPermissionCacheKey(action, resource, id2); 16175 return state.userPermissions[key]; 16176 } 16177 function canUserEditEntityRecord(state, kind, name, recordId) { 16178 (0, import_deprecated2.default)(`wp.data.select( 'core' ).canUserEditEntityRecord()`, { 16179 since: "6.7", 16180 alternative: `wp.data.select( 'core' ).canUser( 'update', { kind, name, id } )` 16181 }); 16182 return canUser(state, "update", { kind, name, id: recordId }); 16183 } 16184 function getAutosaves(state, postType, postId) { 16185 return state.autosaves[postId]; 16186 } 16187 function getAutosave(state, postType, postId, authorId) { 16188 if (authorId === void 0) { 16189 return; 16190 } 16191 const autosaves2 = state.autosaves[postId]; 16192 return autosaves2?.find( 16193 (autosave) => autosave.author === authorId 16194 ); 16195 } 16196 var hasFetchedAutosaves = (0, import_data10.createRegistrySelector)( 16197 (select5) => (state, postType, postId) => { 16198 return select5(STORE_NAME).hasFinishedResolution("getAutosaves", [ 16199 postType, 16200 postId 16201 ]); 16202 } 16203 ); 16204 function getReferenceByDistinctEdits(state) { 16205 return state.editsReference; 16206 } 16207 function __experimentalGetCurrentThemeBaseGlobalStyles(state) { 16208 const currentTheme2 = getCurrentTheme(state); 16209 if (!currentTheme2) { 16210 return null; 16211 } 16212 return state.themeBaseGlobalStyles[currentTheme2.stylesheet]; 16213 } 16214 function __experimentalGetCurrentThemeGlobalStylesVariations(state) { 16215 const currentTheme2 = getCurrentTheme(state); 16216 if (!currentTheme2) { 16217 return null; 16218 } 16219 return state.themeGlobalStyleVariations[currentTheme2.stylesheet]; 16220 } 16221 function getBlockPatterns(state) { 16222 return state.blockPatterns; 16223 } 16224 function getBlockPatternCategories(state) { 16225 return state.blockPatternCategories; 16226 } 16227 function getUserPatternCategories(state) { 16228 return state.userPatternCategories; 16229 } 16230 function getCurrentThemeGlobalStylesRevisions(state) { 16231 (0, import_deprecated2.default)("select( 'core' ).getCurrentThemeGlobalStylesRevisions()", { 16232 since: "6.5.0", 16233 alternative: "select( 'core' ).getRevisions( 'root', 'globalStyles', ${ recordKey } )" 16234 }); 16235 const currentGlobalStylesId2 = __experimentalGetCurrentGlobalStylesId(state); 16236 if (!currentGlobalStylesId2) { 16237 return null; 16238 } 16239 return state.themeGlobalStyleRevisions[currentGlobalStylesId2]; 16240 } 16241 function getDefaultTemplateId(state, query) { 16242 return state.defaultTemplates[JSON.stringify(query)]; 16243 } 16244 var getRevisions = (state, kind, name, recordKey, query) => { 16245 logEntityDeprecation(kind, name, "getRevisions"); 16246 const queriedStateRevisions = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 16247 if (!queriedStateRevisions) { 16248 return null; 16249 } 16250 return getQueriedItems(queriedStateRevisions, query); 16251 }; 16252 var getRevision = (0, import_data10.createSelector)( 16253 (state, kind, name, recordKey, revisionKey, query) => { 16254 logEntityDeprecation(kind, name, "getRevision"); 16255 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 16256 if (!queriedState) { 16257 return void 0; 16258 } 16259 const context = query?.context ?? "default"; 16260 if (!query || !query._fields) { 16261 if (!queriedState.itemIsComplete[context]?.[revisionKey]) { 16262 return void 0; 16263 } 16264 return queriedState.items[context][revisionKey]; 16265 } 16266 const item = queriedState.items[context]?.[revisionKey]; 16267 if (!item) { 16268 return item; 16269 } 16270 const filteredItem = {}; 16271 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 16272 for (let f = 0; f < fields.length; f++) { 16273 const field = fields[f].split("."); 16274 let value = item; 16275 field.forEach((fieldName) => { 16276 value = value?.[fieldName]; 16277 }); 16278 setNestedValue(filteredItem, field, value); 16279 } 16280 return filteredItem; 16281 }, 16282 (state, kind, name, recordKey, revisionKey, query) => { 16283 const context = query?.context ?? "default"; 16284 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 16285 return [ 16286 queriedState?.items?.[context]?.[revisionKey], 16287 queriedState?.itemIsComplete?.[context]?.[revisionKey] 16288 ]; 16289 } 16290 ); 16291 16292 // packages/core-data/build-module/actions.mjs 16293 var actions_exports = {}; 16294 __export(actions_exports, { 16295 __experimentalBatch: () => __experimentalBatch, 16296 __experimentalReceiveCurrentGlobalStylesId: () => __experimentalReceiveCurrentGlobalStylesId, 16297 __experimentalReceiveThemeBaseGlobalStyles: () => __experimentalReceiveThemeBaseGlobalStyles, 16298 __experimentalReceiveThemeGlobalStyleVariations: () => __experimentalReceiveThemeGlobalStyleVariations, 16299 __experimentalSaveSpecifiedEntityEdits: () => __experimentalSaveSpecifiedEntityEdits, 16300 __unstableCreateUndoLevel: () => __unstableCreateUndoLevel, 16301 addEntities: () => addEntities, 16302 clearEntityRecordEdits: () => clearEntityRecordEdits, 16303 deleteEntityRecord: () => deleteEntityRecord, 16304 editEntityRecord: () => editEntityRecord, 16305 receiveAutosaves: () => receiveAutosaves, 16306 receiveCurrentTheme: () => receiveCurrentTheme, 16307 receiveCurrentUser: () => receiveCurrentUser, 16308 receiveDefaultTemplateId: () => receiveDefaultTemplateId, 16309 receiveEmbedPreview: () => receiveEmbedPreview, 16310 receiveEntityRecords: () => receiveEntityRecords, 16311 receiveNavigationFallbackId: () => receiveNavigationFallbackId, 16312 receiveRevisions: () => receiveRevisions, 16313 receiveThemeGlobalStyleRevisions: () => receiveThemeGlobalStyleRevisions, 16314 receiveThemeSupports: () => receiveThemeSupports, 16315 receiveUploadPermissions: () => receiveUploadPermissions, 16316 receiveUserPermission: () => receiveUserPermission, 16317 receiveUserPermissions: () => receiveUserPermissions, 16318 receiveUserQuery: () => receiveUserQuery, 16319 redo: () => redo, 16320 saveEditedEntityRecord: () => saveEditedEntityRecord, 16321 saveEntityRecord: () => saveEntityRecord, 16322 undo: () => undo 16323 }); 16324 var import_es67 = __toESM(require_es6(), 1); 16325 var import_api_fetch4 = __toESM(require_api_fetch(), 1); 16326 var import_url3 = __toESM(require_url(), 1); 16327 var import_deprecated3 = __toESM(require_deprecated(), 1); 16328 16329 // packages/core-data/build-module/batch/default-processor.mjs 16330 var import_api_fetch3 = __toESM(require_api_fetch(), 1); 16331 var maxItems = null; 16332 function chunk(arr, chunkSize) { 16333 const tmp = [...arr]; 16334 const cache3 = []; 16335 while (tmp.length) { 16336 cache3.push(tmp.splice(0, chunkSize)); 16337 } 16338 return cache3; 16339 } 16340 async function defaultProcessor(requests) { 16341 if (maxItems === null) { 16342 const preflightResponse = await (0, import_api_fetch3.default)({ 16343 path: "/batch/v1", 16344 method: "OPTIONS" 16345 }); 16346 maxItems = preflightResponse.endpoints[0].args.requests.maxItems; 16347 } 16348 const results = []; 16349 for (const batchRequests of chunk(requests, maxItems)) { 16350 const batchResponse = await (0, import_api_fetch3.default)({ 16351 path: "/batch/v1", 16352 method: "POST", 16353 data: { 16354 validation: "require-all-validate", 16355 requests: batchRequests.map((request) => ({ 16356 path: request.path, 16357 body: request.data, 16358 // Rename 'data' to 'body'. 16359 method: request.method, 16360 headers: request.headers 16361 })) 16362 } 16363 }); 16364 let batchResults; 16365 if (batchResponse.failed) { 16366 batchResults = batchResponse.responses.map((response) => ({ 16367 error: response?.body 16368 })); 16369 } else { 16370 batchResults = batchResponse.responses.map((response) => { 16371 const result = {}; 16372 if (response.status >= 200 && response.status < 300) { 16373 result.output = response.body; 16374 } else { 16375 result.error = response.body; 16376 } 16377 return result; 16378 }); 16379 } 16380 results.push(...batchResults); 16381 } 16382 return results; 16383 } 16384 16385 // packages/core-data/build-module/batch/create-batch.mjs 16386 function createBatch(processor = defaultProcessor) { 16387 let lastId = 0; 16388 let queue = []; 16389 const pending = new ObservableSet(); 16390 return { 16391 /** 16392 * Adds an input to the batch and returns a promise that is resolved or 16393 * rejected when the input is processed by `batch.run()`. 16394 * 16395 * You may also pass a thunk which allows inputs to be added 16396 * asynchronously. 16397 * 16398 * ``` 16399 * // Both are allowed: 16400 * batch.add( { path: '/v1/books', ... } ); 16401 * batch.add( ( add ) => add( { path: '/v1/books', ... } ) ); 16402 * ``` 16403 * 16404 * If a thunk is passed, `batch.run()` will pause until either: 16405 * 16406 * - The thunk calls its `add` argument, or; 16407 * - The thunk returns a promise and that promise resolves, or; 16408 * - The thunk returns a non-promise. 16409 * 16410 * @param {any|Function} inputOrThunk Input to add or thunk to execute. 16411 * 16412 * @return {Promise|any} If given an input, returns a promise that 16413 * is resolved or rejected when the batch is 16414 * processed. If given a thunk, returns the return 16415 * value of that thunk. 16416 */ 16417 add(inputOrThunk) { 16418 const id2 = ++lastId; 16419 pending.add(id2); 16420 const add = (input) => new Promise((resolve, reject) => { 16421 queue.push({ 16422 input, 16423 resolve, 16424 reject 16425 }); 16426 pending.delete(id2); 16427 }); 16428 if (typeof inputOrThunk === "function") { 16429 return Promise.resolve(inputOrThunk(add)).finally(() => { 16430 pending.delete(id2); 16431 }); 16432 } 16433 return add(inputOrThunk); 16434 }, 16435 /** 16436 * Runs the batch. This calls `batchProcessor` and resolves or rejects 16437 * all promises returned by `add()`. 16438 * 16439 * @return {Promise<boolean>} A promise that resolves to a boolean that is true 16440 * if the processor returned no errors. 16441 */ 16442 async run() { 16443 if (pending.size) { 16444 await new Promise((resolve) => { 16445 const unsubscribe = pending.subscribe(() => { 16446 if (!pending.size) { 16447 unsubscribe(); 16448 resolve(void 0); 16449 } 16450 }); 16451 }); 16452 } 16453 let results; 16454 try { 16455 results = await processor( 16456 queue.map(({ input }) => input) 16457 ); 16458 if (results.length !== queue.length) { 16459 throw new Error( 16460 "run: Array returned by processor must be same size as input array." 16461 ); 16462 } 16463 } catch (error) { 16464 for (const { reject } of queue) { 16465 reject(error); 16466 } 16467 throw error; 16468 } 16469 let isSuccess = true; 16470 results.forEach((result, key) => { 16471 const queueItem = queue[key]; 16472 if (result?.error) { 16473 queueItem?.reject(result.error); 16474 isSuccess = false; 16475 } else { 16476 queueItem?.resolve(result?.output ?? result); 16477 } 16478 }); 16479 queue = []; 16480 return isSuccess; 16481 } 16482 }; 16483 } 16484 var ObservableSet = class { 16485 constructor(...args2) { 16486 this.set = new Set(...args2); 16487 this.subscribers = /* @__PURE__ */ new Set(); 16488 } 16489 get size() { 16490 return this.set.size; 16491 } 16492 add(value) { 16493 this.set.add(value); 16494 this.subscribers.forEach((subscriber) => subscriber()); 16495 return this; 16496 } 16497 delete(value) { 16498 const isSuccess = this.set.delete(value); 16499 this.subscribers.forEach((subscriber) => subscriber()); 16500 return isSuccess; 16501 } 16502 subscribe(subscriber) { 16503 this.subscribers.add(subscriber); 16504 return () => { 16505 this.subscribers.delete(subscriber); 16506 }; 16507 } 16508 }; 16509 16510 // packages/core-data/build-module/actions.mjs 16511 function addTitleToAutoDraft(record) { 16512 return record.status === "auto-draft" ? { ...record, title: "" } : record; 16513 } 16514 function receiveUserQuery(queryID, users2) { 16515 return { 16516 type: "RECEIVE_USER_QUERY", 16517 users: Array.isArray(users2) ? users2 : [users2], 16518 queryID 16519 }; 16520 } 16521 function receiveCurrentUser(currentUser2) { 16522 return { 16523 type: "RECEIVE_CURRENT_USER", 16524 currentUser: currentUser2 16525 }; 16526 } 16527 function addEntities(entities2) { 16528 return { 16529 type: "ADD_ENTITIES", 16530 entities: entities2 16531 }; 16532 } 16533 function receiveEntityRecords(kind, name, records, query = void 0, invalidateCache = false, edits = void 0, meta = void 0) { 16534 if (kind === "postType") { 16535 records = Array.isArray(records) ? records.map(addTitleToAutoDraft) : addTitleToAutoDraft(records); 16536 } 16537 let action; 16538 if (query) { 16539 action = receiveQueriedItems(records, query, edits, meta); 16540 } else { 16541 action = receiveItems(records, edits, meta); 16542 } 16543 return { 16544 ...action, 16545 kind, 16546 name, 16547 invalidateCache 16548 }; 16549 } 16550 function receiveCurrentTheme(currentTheme2) { 16551 return { 16552 type: "RECEIVE_CURRENT_THEME", 16553 currentTheme: currentTheme2 16554 }; 16555 } 16556 function __experimentalReceiveCurrentGlobalStylesId(currentGlobalStylesId2) { 16557 return { 16558 type: "RECEIVE_CURRENT_GLOBAL_STYLES_ID", 16559 id: currentGlobalStylesId2 16560 }; 16561 } 16562 function __experimentalReceiveThemeBaseGlobalStyles(stylesheet, globalStyles) { 16563 return { 16564 type: "RECEIVE_THEME_GLOBAL_STYLES", 16565 stylesheet, 16566 globalStyles 16567 }; 16568 } 16569 function __experimentalReceiveThemeGlobalStyleVariations(stylesheet, variations) { 16570 return { 16571 type: "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS", 16572 stylesheet, 16573 variations 16574 }; 16575 } 16576 function receiveThemeSupports() { 16577 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveThemeSupports", { 16578 since: "5.9" 16579 }); 16580 return { 16581 type: "DO_NOTHING" 16582 }; 16583 } 16584 function receiveThemeGlobalStyleRevisions(currentId, revisions) { 16585 (0, import_deprecated3.default)( 16586 "wp.data.dispatch( 'core' ).receiveThemeGlobalStyleRevisions()", 16587 { 16588 since: "6.5.0", 16589 alternative: "wp.data.dispatch( 'core' ).receiveRevisions" 16590 } 16591 ); 16592 return { 16593 type: "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS", 16594 currentId, 16595 revisions 16596 }; 16597 } 16598 function receiveEmbedPreview(url, preview) { 16599 return { 16600 type: "RECEIVE_EMBED_PREVIEW", 16601 url, 16602 preview 16603 }; 16604 } 16605 var deleteEntityRecord = (kind, name, recordId, query, { __unstableFetch = import_api_fetch4.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 16606 logEntityDeprecation(kind, name, "deleteEntityRecord"); 16607 const configs = await resolveSelect2.getEntitiesConfig(kind); 16608 const entityConfig = configs.find( 16609 (config) => config.kind === kind && config.name === name 16610 ); 16611 let error; 16612 let deletedRecord = false; 16613 if (!entityConfig) { 16614 return; 16615 } 16616 const lock3 = await dispatch3.__unstableAcquireStoreLock( 16617 STORE_NAME, 16618 ["entities", "records", kind, name, recordId], 16619 { exclusive: true } 16620 ); 16621 try { 16622 dispatch3({ 16623 type: "DELETE_ENTITY_RECORD_START", 16624 kind, 16625 name, 16626 recordId 16627 }); 16628 let hasError = false; 16629 let { baseURL } = entityConfig; 16630 if (kind === "postType" && name === "wp_template" && (recordId && typeof recordId === "string" && !/^\d+$/.test(recordId) || !window?.__experimentalTemplateActivate)) { 16631 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 16632 } 16633 try { 16634 let path = `$baseURL}/$recordId}`; 16635 if (query) { 16636 path = (0, import_url3.addQueryArgs)(path, query); 16637 } 16638 deletedRecord = await __unstableFetch({ 16639 path, 16640 method: "DELETE" 16641 }); 16642 await dispatch3(removeItems(kind, name, recordId, true)); 16643 if (entityConfig.syncConfig) { 16644 const objectType = `$kind}/$name}`; 16645 const objectId = recordId; 16646 getSyncManager()?.unload(objectType, objectId); 16647 } 16648 } catch (_error) { 16649 hasError = true; 16650 error = _error; 16651 } 16652 dispatch3({ 16653 type: "DELETE_ENTITY_RECORD_FINISH", 16654 kind, 16655 name, 16656 recordId, 16657 error 16658 }); 16659 if (hasError && throwOnError) { 16660 throw error; 16661 } 16662 return deletedRecord; 16663 } finally { 16664 dispatch3.__unstableReleaseStoreLock(lock3); 16665 } 16666 }; 16667 var editEntityRecord = (kind, name, recordId, edits, options = {}) => ({ select: select5, dispatch: dispatch3 }) => { 16668 logEntityDeprecation(kind, name, "editEntityRecord"); 16669 const entityConfig = select5.getEntityConfig(kind, name); 16670 if (!entityConfig) { 16671 throw new Error( 16672 `The entity being edited ($kind}, $name}) does not have a loaded config.` 16673 ); 16674 } 16675 const { mergedEdits = {} } = entityConfig; 16676 const record = select5.getRawEntityRecord(kind, name, recordId); 16677 const editedRecord = select5.getEditedEntityRecord( 16678 kind, 16679 name, 16680 recordId 16681 ); 16682 const editsWithMerges = Object.keys(edits).reduce((acc, key) => { 16683 acc[key] = mergedEdits[key] ? { ...editedRecord[key], ...edits[key] } : edits[key]; 16684 return acc; 16685 }, {}); 16686 const edit = { 16687 kind, 16688 name, 16689 recordId, 16690 // Clear edits when they are equal to their persisted counterparts 16691 // so that the property is not considered dirty. 16692 edits: Object.keys(edits).reduce((acc, key) => { 16693 const recordValue = record[key]; 16694 const value = editsWithMerges[key]; 16695 acc[key] = (0, import_es67.default)(recordValue, value) ? void 0 : value; 16696 return acc; 16697 }, {}) 16698 }; 16699 if (entityConfig.syncConfig) { 16700 const objectType = `$kind}/$name}`; 16701 const objectId = recordId; 16702 const isNewUndoLevel = options.undoIgnore ? false : !options.isCached; 16703 const origin2 = options.undoIgnore ? LOCAL_UNDO_IGNORED_ORIGIN2 : LOCAL_EDITOR_ORIGIN2; 16704 getSyncManager()?.update( 16705 objectType, 16706 objectId, 16707 editsWithMerges, 16708 origin2, 16709 { isNewUndoLevel } 16710 ); 16711 } 16712 if (!options.undoIgnore) { 16713 select5.getUndoManager().addRecord( 16714 [ 16715 { 16716 id: { kind, name, recordId }, 16717 changes: Object.keys(edits).reduce((acc, key) => { 16718 acc[key] = { 16719 from: editedRecord[key], 16720 to: edits[key] 16721 }; 16722 return acc; 16723 }, {}) 16724 } 16725 ], 16726 options.isCached 16727 ); 16728 } 16729 dispatch3({ 16730 type: "EDIT_ENTITY_RECORD", 16731 ...edit 16732 }); 16733 }; 16734 var clearEntityRecordEdits = (kind, name, recordId) => ({ select: select5, dispatch: dispatch3 }) => { 16735 const entityConfig = select5.getEntityConfig(kind, name); 16736 logEntityDeprecation(kind, name, "clearEntityRecordEdits"); 16737 if (!entityConfig) { 16738 throw new Error( 16739 `The entity being edited ($kind}, $name}) does not have a loaded config.` 16740 ); 16741 } 16742 const currentEdits = select5.getEntityRecordEdits( 16743 kind, 16744 name, 16745 recordId 16746 ); 16747 if (!currentEdits) { 16748 return; 16749 } 16750 const clearedEdits = Object.keys(currentEdits).reduce( 16751 (acc, key) => { 16752 acc[key] = void 0; 16753 return acc; 16754 }, 16755 {} 16756 ); 16757 dispatch3({ 16758 type: "EDIT_ENTITY_RECORD", 16759 kind, 16760 name, 16761 recordId, 16762 edits: clearedEdits 16763 }); 16764 }; 16765 var undo = () => ({ select: select5, dispatch: dispatch3 }) => { 16766 const undoRecord = select5.getUndoManager().undo(); 16767 if (!undoRecord) { 16768 return; 16769 } 16770 dispatch3({ 16771 type: "UNDO", 16772 record: undoRecord 16773 }); 16774 }; 16775 var redo = () => ({ select: select5, dispatch: dispatch3 }) => { 16776 const redoRecord = select5.getUndoManager().redo(); 16777 if (!redoRecord) { 16778 return; 16779 } 16780 dispatch3({ 16781 type: "REDO", 16782 record: redoRecord 16783 }); 16784 }; 16785 var __unstableCreateUndoLevel = () => ({ select: select5 }) => { 16786 select5.getUndoManager().addRecord(); 16787 }; 16788 var saveEntityRecord = (kind, name, record, { 16789 isAutosave = false, 16790 __unstableFetch = import_api_fetch4.default, 16791 throwOnError = false 16792 } = {}) => async ({ select: select5, resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 16793 logEntityDeprecation(kind, name, "saveEntityRecord"); 16794 const configs = await resolveSelect2.getEntitiesConfig(kind); 16795 const entityConfig = configs.find( 16796 (config) => config.kind === kind && config.name === name 16797 ); 16798 if (!entityConfig) { 16799 return; 16800 } 16801 const entityIdKey = entityConfig.key ?? DEFAULT_ENTITY_KEY; 16802 const recordId = record[entityIdKey]; 16803 const isNewRecord = !!entityIdKey && !recordId; 16804 const lock3 = await dispatch3.__unstableAcquireStoreLock( 16805 STORE_NAME, 16806 ["entities", "records", kind, name, recordId || v4_default()], 16807 { exclusive: true } 16808 ); 16809 try { 16810 for (const [key, value] of Object.entries(record)) { 16811 if (typeof value === "function") { 16812 const evaluatedValue = value( 16813 select5.getEditedEntityRecord(kind, name, recordId) 16814 ); 16815 dispatch3.editEntityRecord( 16816 kind, 16817 name, 16818 recordId, 16819 { 16820 [key]: evaluatedValue 16821 }, 16822 { undoIgnore: true } 16823 ); 16824 record[key] = evaluatedValue; 16825 } 16826 } 16827 dispatch3({ 16828 type: "SAVE_ENTITY_RECORD_START", 16829 kind, 16830 name, 16831 recordId, 16832 isAutosave 16833 }); 16834 let updatedRecord; 16835 let error; 16836 let hasError = false; 16837 let { baseURL } = entityConfig; 16838 if (kind === "postType" && name === "wp_template" && (recordId && typeof recordId === "string" && !/^\d+$/.test(recordId) || !window?.__experimentalTemplateActivate)) { 16839 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 16840 } 16841 try { 16842 const path = `$baseURL}$recordId ? "/" + recordId : ""}`; 16843 const persistedRecord = !isNewRecord ? select5.getRawEntityRecord(kind, name, recordId) : {}; 16844 if (isAutosave) { 16845 const currentUser2 = select5.getCurrentUser(); 16846 const currentUserId = currentUser2 ? currentUser2.id : void 0; 16847 const autosavePost = await resolveSelect2.getAutosave( 16848 persistedRecord.type, 16849 persistedRecord.id, 16850 currentUserId 16851 ); 16852 let data = { 16853 ...persistedRecord, 16854 ...autosavePost, 16855 ...record 16856 }; 16857 data = Object.keys(data).reduce( 16858 (acc, key) => { 16859 if ([ 16860 "title", 16861 "excerpt", 16862 "content", 16863 "meta" 16864 ].includes(key)) { 16865 acc[key] = data[key]; 16866 } 16867 return acc; 16868 }, 16869 { 16870 // Do not update the `status` if we have edited it when auto saving. 16871 // It's very important to let the user explicitly save this change, 16872 // because it can lead to unexpected results. An example would be to 16873 // have a draft post and change the status to publish. 16874 status: data.status === "auto-draft" ? "draft" : void 0 16875 } 16876 ); 16877 updatedRecord = await __unstableFetch({ 16878 path: `$path}/autosaves`, 16879 method: "POST", 16880 data 16881 }); 16882 if (persistedRecord.id === updatedRecord.id) { 16883 let newRecord = { 16884 ...persistedRecord, 16885 ...data, 16886 ...updatedRecord 16887 }; 16888 newRecord = Object.keys(newRecord).reduce( 16889 (acc, key) => { 16890 if (["title", "excerpt", "content"].includes( 16891 key 16892 )) { 16893 acc[key] = newRecord[key]; 16894 } else if (key === "status") { 16895 acc[key] = persistedRecord.status === "auto-draft" && newRecord.status === "draft" ? newRecord.status : persistedRecord.status; 16896 } else { 16897 acc[key] = persistedRecord[key]; 16898 } 16899 return acc; 16900 }, 16901 {} 16902 ); 16903 dispatch3.receiveEntityRecords( 16904 kind, 16905 name, 16906 newRecord, 16907 void 0, 16908 true 16909 ); 16910 } else { 16911 dispatch3.receiveAutosaves( 16912 persistedRecord.id, 16913 updatedRecord 16914 ); 16915 } 16916 } else { 16917 let edits = record; 16918 if (entityConfig.__unstablePrePersist) { 16919 edits = { 16920 ...edits, 16921 ...await entityConfig.__unstablePrePersist( 16922 persistedRecord, 16923 edits 16924 ) 16925 }; 16926 } 16927 updatedRecord = await __unstableFetch({ 16928 path, 16929 method: recordId ? "PUT" : "POST", 16930 data: edits 16931 }); 16932 dispatch3.receiveEntityRecords( 16933 kind, 16934 name, 16935 updatedRecord, 16936 void 0, 16937 true, 16938 edits 16939 ); 16940 if (entityConfig.syncConfig) { 16941 getSyncManager()?.update( 16942 `$kind}/$name}`, 16943 recordId, 16944 updatedRecord, 16945 LOCAL_UNDO_IGNORED_ORIGIN2, 16946 { isSave: true } 16947 ); 16948 } 16949 } 16950 } catch (_error) { 16951 hasError = true; 16952 error = _error; 16953 } 16954 dispatch3({ 16955 type: "SAVE_ENTITY_RECORD_FINISH", 16956 kind, 16957 name, 16958 recordId, 16959 error, 16960 isAutosave 16961 }); 16962 if (hasError && throwOnError) { 16963 throw error; 16964 } 16965 return updatedRecord; 16966 } finally { 16967 dispatch3.__unstableReleaseStoreLock(lock3); 16968 } 16969 }; 16970 var __experimentalBatch = (requests) => async ({ dispatch: dispatch3 }) => { 16971 const batch = createBatch(); 16972 const api = { 16973 saveEntityRecord(kind, name, record, options) { 16974 return batch.add( 16975 (add) => dispatch3.saveEntityRecord(kind, name, record, { 16976 ...options, 16977 __unstableFetch: add 16978 }) 16979 ); 16980 }, 16981 saveEditedEntityRecord(kind, name, recordId, options) { 16982 return batch.add( 16983 (add) => dispatch3.saveEditedEntityRecord(kind, name, recordId, { 16984 ...options, 16985 __unstableFetch: add 16986 }) 16987 ); 16988 }, 16989 deleteEntityRecord(kind, name, recordId, query, options) { 16990 return batch.add( 16991 (add) => dispatch3.deleteEntityRecord(kind, name, recordId, query, { 16992 ...options, 16993 __unstableFetch: add 16994 }) 16995 ); 16996 } 16997 }; 16998 const resultPromises = requests.map((request) => request(api)); 16999 const [, ...results] = await Promise.all([ 17000 batch.run(), 17001 ...resultPromises 17002 ]); 17003 return results; 17004 }; 17005 var saveEditedEntityRecord = (kind, name, recordId, options) => async ({ select: select5, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17006 logEntityDeprecation(kind, name, "saveEditedEntityRecord"); 17007 if (!select5.hasEditsForEntityRecord(kind, name, recordId)) { 17008 return; 17009 } 17010 const configs = await resolveSelect2.getEntitiesConfig(kind); 17011 const entityConfig = configs.find( 17012 (config) => config.kind === kind && config.name === name 17013 ); 17014 if (!entityConfig) { 17015 return; 17016 } 17017 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY; 17018 const edits = select5.getEntityRecordNonTransientEdits( 17019 kind, 17020 name, 17021 recordId 17022 ); 17023 const record = { [entityIdKey]: recordId, ...edits }; 17024 return await dispatch3.saveEntityRecord(kind, name, record, options); 17025 }; 17026 var __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({ select: select5, dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17027 logEntityDeprecation( 17028 kind, 17029 name, 17030 "__experimentalSaveSpecifiedEntityEdits" 17031 ); 17032 if (!select5.hasEditsForEntityRecord(kind, name, recordId)) { 17033 return; 17034 } 17035 const edits = select5.getEntityRecordNonTransientEdits( 17036 kind, 17037 name, 17038 recordId 17039 ); 17040 const editsToSave = {}; 17041 for (const item of itemsToSave) { 17042 setNestedValue(editsToSave, item, getNestedValue(edits, item)); 17043 } 17044 const configs = await resolveSelect2.getEntitiesConfig(kind); 17045 const entityConfig = configs.find( 17046 (config) => config.kind === kind && config.name === name 17047 ); 17048 const entityIdKey = entityConfig?.key || DEFAULT_ENTITY_KEY; 17049 if (recordId) { 17050 editsToSave[entityIdKey] = recordId; 17051 } 17052 return await dispatch3.saveEntityRecord( 17053 kind, 17054 name, 17055 editsToSave, 17056 options 17057 ); 17058 }; 17059 function receiveUploadPermissions(hasUploadPermissions) { 17060 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveUploadPermissions", { 17061 since: "5.9", 17062 alternative: "receiveUserPermission" 17063 }); 17064 return receiveUserPermission("create/media", hasUploadPermissions); 17065 } 17066 function receiveUserPermission(key, isAllowed) { 17067 return { 17068 type: "RECEIVE_USER_PERMISSION", 17069 key, 17070 isAllowed 17071 }; 17072 } 17073 function receiveUserPermissions(permissions) { 17074 return { 17075 type: "RECEIVE_USER_PERMISSIONS", 17076 permissions 17077 }; 17078 } 17079 function receiveAutosaves(postId, autosaves2) { 17080 return { 17081 type: "RECEIVE_AUTOSAVES", 17082 postId, 17083 autosaves: Array.isArray(autosaves2) ? autosaves2 : [autosaves2] 17084 }; 17085 } 17086 function receiveNavigationFallbackId(fallbackId) { 17087 return { 17088 type: "RECEIVE_NAVIGATION_FALLBACK_ID", 17089 fallbackId 17090 }; 17091 } 17092 function receiveDefaultTemplateId(query, templateId) { 17093 return { 17094 type: "RECEIVE_DEFAULT_TEMPLATE", 17095 query, 17096 templateId 17097 }; 17098 } 17099 var receiveRevisions = (kind, name, recordKey, records, query, invalidateCache = false, meta) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17100 logEntityDeprecation(kind, name, "receiveRevisions"); 17101 const configs = await resolveSelect2.getEntitiesConfig(kind); 17102 const entityConfig = configs.find( 17103 (config) => config.kind === kind && config.name === name 17104 ); 17105 const key = entityConfig && entityConfig?.revisionKey ? entityConfig.revisionKey : DEFAULT_ENTITY_KEY; 17106 dispatch3({ 17107 type: "RECEIVE_ITEM_REVISIONS", 17108 key, 17109 items: records, 17110 recordKey, 17111 meta, 17112 query, 17113 kind, 17114 name, 17115 invalidateCache 17116 }); 17117 }; 17118 17119 // packages/core-data/build-module/private-actions.mjs 17120 var private_actions_exports = {}; 17121 __export(private_actions_exports, { 17122 editMediaEntity: () => editMediaEntity, 17123 receiveEditorAssets: () => receiveEditorAssets, 17124 receiveEditorSettings: () => receiveEditorSettings, 17125 receiveRegisteredPostMeta: () => receiveRegisteredPostMeta, 17126 setCollaborationSupported: () => setCollaborationSupported, 17127 setSyncConnectionStatus: () => setSyncConnectionStatus 17128 }); 17129 var import_api_fetch5 = __toESM(require_api_fetch(), 1); 17130 function receiveRegisteredPostMeta(postType, registeredPostMeta2) { 17131 return { 17132 type: "RECEIVE_REGISTERED_POST_META", 17133 postType, 17134 registeredPostMeta: registeredPostMeta2 17135 }; 17136 } 17137 var editMediaEntity = (recordId, edits = {}, { __unstableFetch = import_api_fetch5.default, throwOnError = false } = {}) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17138 if (!recordId) { 17139 return; 17140 } 17141 const kind = "postType"; 17142 const name = "attachment"; 17143 const configs = await resolveSelect2.getEntitiesConfig(kind); 17144 const entityConfig = configs.find( 17145 (config) => config.kind === kind && config.name === name 17146 ); 17147 if (!entityConfig) { 17148 return; 17149 } 17150 const lock3 = await dispatch3.__unstableAcquireStoreLock( 17151 STORE_NAME, 17152 ["entities", "records", kind, name, recordId], 17153 { exclusive: true } 17154 ); 17155 let updatedRecord; 17156 let error; 17157 let hasError = false; 17158 try { 17159 dispatch3({ 17160 type: "SAVE_ENTITY_RECORD_START", 17161 kind, 17162 name, 17163 recordId 17164 }); 17165 try { 17166 const path = `$entityConfig.baseURL}/$recordId}/edit`; 17167 const newRecord = await __unstableFetch({ 17168 path, 17169 method: "POST", 17170 data: { 17171 ...edits 17172 } 17173 }); 17174 if (newRecord) { 17175 dispatch3.receiveEntityRecords( 17176 kind, 17177 name, 17178 newRecord, 17179 void 0, 17180 true, 17181 void 0, 17182 void 0 17183 ); 17184 updatedRecord = newRecord; 17185 } 17186 } catch (e) { 17187 error = e; 17188 hasError = true; 17189 } 17190 dispatch3({ 17191 type: "SAVE_ENTITY_RECORD_FINISH", 17192 kind, 17193 name, 17194 recordId, 17195 error 17196 }); 17197 if (hasError && throwOnError) { 17198 throw error; 17199 } 17200 return updatedRecord; 17201 } finally { 17202 dispatch3.__unstableReleaseStoreLock(lock3); 17203 } 17204 }; 17205 function receiveEditorSettings(settings) { 17206 return { 17207 type: "RECEIVE_EDITOR_SETTINGS", 17208 settings 17209 }; 17210 } 17211 function receiveEditorAssets(assets) { 17212 return { 17213 type: "RECEIVE_EDITOR_ASSETS", 17214 assets 17215 }; 17216 } 17217 var setCollaborationSupported = (supported) => ({ dispatch: dispatch3 }) => { 17218 dispatch3({ type: "SET_COLLABORATION_SUPPORTED", supported }); 17219 }; 17220 function setSyncConnectionStatus(kind, name, key, status) { 17221 if (!status) { 17222 return { 17223 type: "CLEAR_SYNC_CONNECTION_STATUS", 17224 kind, 17225 name, 17226 key 17227 }; 17228 } 17229 return { 17230 type: "SET_SYNC_CONNECTION_STATUS", 17231 kind, 17232 name, 17233 key, 17234 status 17235 }; 17236 } 17237 17238 // packages/core-data/build-module/resolvers.mjs 17239 var resolvers_exports = {}; 17240 __export(resolvers_exports, { 17241 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId2, 17242 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles2, 17243 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations2, 17244 canUser: () => canUser2, 17245 canUserEditEntityRecord: () => canUserEditEntityRecord2, 17246 getAuthors: () => getAuthors2, 17247 getAutosave: () => getAutosave2, 17248 getAutosaves: () => getAutosaves2, 17249 getBlockPatternCategories: () => getBlockPatternCategories2, 17250 getBlockPatterns: () => getBlockPatterns2, 17251 getCurrentTheme: () => getCurrentTheme2, 17252 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions2, 17253 getCurrentUser: () => getCurrentUser2, 17254 getDefaultTemplateId: () => getDefaultTemplateId2, 17255 getEditedEntityRecord: () => getEditedEntityRecord2, 17256 getEditorAssets: () => getEditorAssets2, 17257 getEditorSettings: () => getEditorSettings2, 17258 getEmbedPreview: () => getEmbedPreview2, 17259 getEntitiesConfig: () => getEntitiesConfig2, 17260 getEntityRecord: () => getEntityRecord2, 17261 getEntityRecords: () => getEntityRecords2, 17262 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems2, 17263 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages2, 17264 getNavigationFallbackId: () => getNavigationFallbackId2, 17265 getRawEntityRecord: () => getRawEntityRecord2, 17266 getRegisteredPostMeta: () => getRegisteredPostMeta2, 17267 getRevision: () => getRevision2, 17268 getRevisions: () => getRevisions2, 17269 getThemeSupports: () => getThemeSupports2, 17270 getUserPatternCategories: () => getUserPatternCategories2 17271 }); 17272 var import_url6 = __toESM(require_url(), 1); 17273 var import_html_entities2 = __toESM(require_html_entities(), 1); 17274 var import_api_fetch9 = __toESM(require_api_fetch(), 1); 17275 17276 // packages/core-data/build-module/fetch/index.mjs 17277 var import_api_fetch8 = __toESM(require_api_fetch(), 1); 17278 17279 // packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.mjs 17280 var import_api_fetch6 = __toESM(require_api_fetch(), 1); 17281 var import_url4 = __toESM(require_url(), 1); 17282 var import_html_entities = __toESM(require_html_entities(), 1); 17283 var import_i18n2 = __toESM(require_i18n(), 1); 17284 async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings2 = {}) { 17285 const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? { 17286 ...searchOptions, 17287 ...searchOptions.initialSuggestionsSearchOptions 17288 } : searchOptions; 17289 const { 17290 type, 17291 subtype, 17292 page, 17293 perPage = searchOptions.isInitialSuggestions ? 3 : 20 17294 } = searchOptionsToUse; 17295 const { disablePostFormats = false } = editorSettings2; 17296 const queries2 = []; 17297 if (!type || type === "post") { 17298 queries2.push( 17299 (0, import_api_fetch6.default)({ 17300 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 17301 search, 17302 page, 17303 per_page: perPage, 17304 type: "post", 17305 subtype 17306 }) 17307 }).then((results2) => { 17308 return results2.map((result) => { 17309 return { 17310 id: result.id, 17311 url: result.url, 17312 title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"), 17313 type: result.subtype || result.type, 17314 kind: "post-type" 17315 }; 17316 }); 17317 }).catch(() => []) 17318 // Fail by returning no results. 17319 ); 17320 } 17321 if (!type || type === "term") { 17322 queries2.push( 17323 (0, import_api_fetch6.default)({ 17324 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 17325 search, 17326 page, 17327 per_page: perPage, 17328 type: "term", 17329 subtype 17330 }) 17331 }).then((results2) => { 17332 return results2.map((result) => { 17333 return { 17334 id: result.id, 17335 url: result.url, 17336 title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"), 17337 type: result.subtype || result.type, 17338 kind: "taxonomy" 17339 }; 17340 }); 17341 }).catch(() => []) 17342 // Fail by returning no results. 17343 ); 17344 } 17345 if (!disablePostFormats && (!type || type === "post-format")) { 17346 queries2.push( 17347 (0, import_api_fetch6.default)({ 17348 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 17349 search, 17350 page, 17351 per_page: perPage, 17352 type: "post-format", 17353 subtype 17354 }) 17355 }).then((results2) => { 17356 return results2.map((result) => { 17357 return { 17358 id: result.id, 17359 url: result.url, 17360 title: (0, import_html_entities.decodeEntities)(result.title || "") || (0, import_i18n2.__)("(no title)"), 17361 type: result.subtype || result.type, 17362 kind: "taxonomy" 17363 }; 17364 }); 17365 }).catch(() => []) 17366 // Fail by returning no results. 17367 ); 17368 } 17369 if (!type || type === "attachment") { 17370 queries2.push( 17371 (0, import_api_fetch6.default)({ 17372 path: (0, import_url4.addQueryArgs)("/wp/v2/media", { 17373 search, 17374 page, 17375 per_page: perPage 17376 }) 17377 }).then((results2) => { 17378 return results2.map((result) => { 17379 return { 17380 id: result.id, 17381 url: result.source_url, 17382 title: (0, import_html_entities.decodeEntities)(result.title.rendered || "") || (0, import_i18n2.__)("(no title)"), 17383 type: result.type, 17384 kind: "media" 17385 }; 17386 }); 17387 }).catch(() => []) 17388 // Fail by returning no results. 17389 ); 17390 } 17391 const responses = await Promise.all(queries2); 17392 let results = responses.flat(); 17393 results = results.filter((result) => !!result.id); 17394 results = sortResults(results, search); 17395 results = results.slice(0, perPage); 17396 return results; 17397 } 17398 function sortResults(results, search) { 17399 const searchTokens = tokenize2(search); 17400 const scores = {}; 17401 for (const result of results) { 17402 if (result.title) { 17403 const titleTokens = tokenize2(result.title); 17404 const exactMatchingTokens = titleTokens.filter( 17405 (titleToken) => searchTokens.some( 17406 (searchToken) => titleToken === searchToken 17407 ) 17408 ); 17409 const subMatchingTokens = titleTokens.filter( 17410 (titleToken) => searchTokens.some( 17411 (searchToken) => titleToken !== searchToken && titleToken.includes(searchToken) 17412 ) 17413 ); 17414 const exactMatchScore = exactMatchingTokens.length / titleTokens.length * 10; 17415 const subMatchScore = subMatchingTokens.length / titleTokens.length; 17416 scores[result.id] = exactMatchScore + subMatchScore; 17417 } else { 17418 scores[result.id] = 0; 17419 } 17420 } 17421 return results.sort((a, b) => scores[b.id] - scores[a.id]); 17422 } 17423 function tokenize2(text2) { 17424 return text2.toLowerCase().match(/[\p{L}\p{N}]+/gu) || []; 17425 } 17426 17427 // packages/core-data/build-module/fetch/__experimental-fetch-url-data.mjs 17428 var import_api_fetch7 = __toESM(require_api_fetch(), 1); 17429 var import_url5 = __toESM(require_url(), 1); 17430 var CACHE = /* @__PURE__ */ new Map(); 17431 var fetchUrlData = async (url, options = {}) => { 17432 const endpoint = "/wp-block-editor/v1/url-details"; 17433 const args2 = { 17434 url: (0, import_url5.prependHTTP)(url) 17435 }; 17436 if (!(0, import_url5.isURL)(url)) { 17437 return Promise.reject(`$url} is not a valid URL.`); 17438 } 17439 const protocol = (0, import_url5.getProtocol)(url); 17440 if (!protocol || !(0, import_url5.isValidProtocol)(protocol) || !protocol.startsWith("http") || !/^https?:\/\/[^\/\s]/i.test(url)) { 17441 return Promise.reject( 17442 `$url} does not have a valid protocol. URLs must be "http" based` 17443 ); 17444 } 17445 if (CACHE.has(url)) { 17446 return CACHE.get(url); 17447 } 17448 return (0, import_api_fetch7.default)({ 17449 path: (0, import_url5.addQueryArgs)(endpoint, args2), 17450 ...options 17451 }).then((res) => { 17452 CACHE.set(url, res); 17453 return res; 17454 }); 17455 }; 17456 var experimental_fetch_url_data_default = fetchUrlData; 17457 17458 // packages/core-data/build-module/fetch/index.mjs 17459 async function fetchBlockPatterns() { 17460 const restPatterns = await (0, import_api_fetch8.default)({ 17461 path: "/wp/v2/block-patterns/patterns" 17462 }); 17463 if (!restPatterns) { 17464 return []; 17465 } 17466 return restPatterns.map( 17467 (pattern) => Object.fromEntries( 17468 Object.entries(pattern).map(([key, value]) => [ 17469 camelCase(key), 17470 value 17471 ]) 17472 ) 17473 ); 17474 } 17475 17476 // packages/core-data/build-module/resolvers.mjs 17477 var getAuthors2 = (query) => async ({ dispatch: dispatch3 }) => { 17478 const path = (0, import_url6.addQueryArgs)( 17479 "/wp/v2/users/?who=authors&per_page=100", 17480 query 17481 ); 17482 const users2 = await (0, import_api_fetch9.default)({ path }); 17483 dispatch3.receiveUserQuery(path, users2); 17484 }; 17485 var getCurrentUser2 = () => async ({ dispatch: dispatch3 }) => { 17486 const currentUser2 = await (0, import_api_fetch9.default)({ path: "/wp/v2/users/me" }); 17487 dispatch3.receiveCurrentUser(currentUser2); 17488 }; 17489 var getEntityRecord2 = (kind, name, key = "", query) => async ({ select: select5, dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 17490 const configs = await resolveSelect2.getEntitiesConfig(kind); 17491 const entityConfig = configs.find( 17492 (config) => config.name === name && config.kind === kind 17493 ); 17494 if (!entityConfig) { 17495 return; 17496 } 17497 const lock3 = await dispatch3.__unstableAcquireStoreLock( 17498 STORE_NAME, 17499 ["entities", "records", kind, name, key], 17500 { exclusive: false } 17501 ); 17502 try { 17503 if (query !== void 0 && query._fields) { 17504 query = { 17505 ...query, 17506 _fields: [ 17507 .../* @__PURE__ */ new Set([ 17508 ...get_normalized_comma_separable_default(query._fields) || [], 17509 entityConfig.key || DEFAULT_ENTITY_KEY 17510 ]) 17511 ].join() 17512 }; 17513 } 17514 if (query !== void 0 && query._fields) { 17515 const hasRecord = select5.hasEntityRecord( 17516 kind, 17517 name, 17518 key, 17519 query 17520 ); 17521 if (hasRecord) { 17522 return; 17523 } 17524 } 17525 let { baseURL } = entityConfig; 17526 if (kind === "postType" && name === "wp_template" && (key && typeof key === "string" && !/^\d+$/.test(key) || !window?.__experimentalTemplateActivate)) { 17527 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 17528 } 17529 const path = (0, import_url6.addQueryArgs)(baseURL + (key ? "/" + key : ""), { 17530 ...entityConfig.baseURLParams, 17531 ...query 17532 }); 17533 const response = await (0, import_api_fetch9.default)({ path, parse: false }); 17534 const record = await response.json(); 17535 const permissions = getUserPermissionsFromAllowHeader( 17536 response.headers?.get("allow") 17537 ); 17538 const canUserResolutionsArgs = []; 17539 const receiveUserPermissionArgs = {}; 17540 for (const action of ALLOWED_RESOURCE_ACTIONS) { 17541 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 17542 kind, 17543 name, 17544 id: key 17545 })] = permissions[action]; 17546 canUserResolutionsArgs.push([ 17547 action, 17548 { kind, name, id: key } 17549 ]); 17550 } 17551 if (entityConfig.syncConfig && isNumericID(key) && !query) { 17552 const objectType = `$kind}/$name}`; 17553 const objectId = key; 17554 const recordWithTransients = { ...record }; 17555 Object.entries(entityConfig.transientEdits ?? {}).filter( 17556 ([propName, transientConfig]) => void 0 === recordWithTransients[propName] && transientConfig && "object" === typeof transientConfig && "read" in transientConfig && "function" === typeof transientConfig.read 17557 ).forEach(([propName, transientConfig]) => { 17558 recordWithTransients[propName] = transientConfig.read(recordWithTransients); 17559 }); 17560 void getSyncManager()?.load( 17561 entityConfig.syncConfig, 17562 objectType, 17563 objectId, 17564 recordWithTransients, 17565 { 17566 // Handle edits sourced from the sync manager. 17567 editRecord: (edits, options = {}) => { 17568 if (!Object.keys(edits).length) { 17569 return; 17570 } 17571 dispatch3({ 17572 type: "EDIT_ENTITY_RECORD", 17573 kind, 17574 name, 17575 recordId: key, 17576 edits, 17577 meta: { 17578 undo: void 0 17579 }, 17580 options 17581 }); 17582 }, 17583 // Get the current entity record (with edits) 17584 getEditedRecord: async () => await resolveSelect2.getEditedEntityRecord( 17585 kind, 17586 name, 17587 key 17588 ), 17589 // Handle sync connection status changes. 17590 onStatusChange: (status) => { 17591 dispatch3.setSyncConnectionStatus( 17592 kind, 17593 name, 17594 key, 17595 status 17596 ); 17597 }, 17598 // Refetch the current entity record from the database. 17599 refetchRecord: async () => { 17600 dispatch3.receiveEntityRecords( 17601 kind, 17602 name, 17603 await (0, import_api_fetch9.default)({ path, parse: true }), 17604 query 17605 ); 17606 }, 17607 // Persist the CRDT document. 17608 // 17609 // TODO: Currently, persisted CRDT documents are stored in post meta. 17610 // This effectively means that only post entities support CRDT 17611 // persistence. As we add support for syncing additional entity, 17612 // we'll need to revisit where persisted CRDT documents are stored. 17613 persistCRDTDoc: () => { 17614 resolveSelect2.getEditedEntityRecord(kind, name, key).then((editedRecord) => { 17615 const { meta, status } = editedRecord; 17616 if ("auto-draft" === status || !meta) { 17617 return; 17618 } 17619 dispatch3.saveEntityRecord( 17620 kind, 17621 name, 17622 editedRecord 17623 ); 17624 }); 17625 }, 17626 addUndoMeta: (ydoc, meta) => { 17627 const selectionHistory = getSelectionHistory(ydoc); 17628 if (selectionHistory) { 17629 meta.set( 17630 "selectionHistory", 17631 selectionHistory 17632 ); 17633 } 17634 }, 17635 restoreUndoMeta: (ydoc, meta) => { 17636 const selectionHistory = meta.get("selectionHistory"); 17637 if (selectionHistory) { 17638 setTimeout(() => { 17639 restoreSelection(selectionHistory, ydoc); 17640 }, 0); 17641 } 17642 } 17643 } 17644 ); 17645 } 17646 registry.batch(() => { 17647 dispatch3.receiveEntityRecords(kind, name, record, query); 17648 dispatch3.receiveUserPermissions(receiveUserPermissionArgs); 17649 dispatch3.finishResolutions("canUser", canUserResolutionsArgs); 17650 }); 17651 } finally { 17652 dispatch3.__unstableReleaseStoreLock(lock3); 17653 } 17654 }; 17655 getEntityRecord2.shouldInvalidate = (action, kind, name) => { 17656 return kind === "root" && name === "site" && (action.type === "RECEIVE_ITEMS" && // Making sure persistedEdits is set seems to be the only way of 17657 // knowing whether it's an update or fetch. Only an update would 17658 // have persistedEdits. 17659 action.persistedEdits && action.persistedEdits.status !== "auto-draft" || action.type === "REMOVE_ITEMS") && action.kind === "postType" && action.name === "wp_template"; 17660 }; 17661 var getRawEntityRecord2 = forward_resolver_default("getEntityRecord"); 17662 var getEditedEntityRecord2 = forward_resolver_default("getEntityRecord"); 17663 var getEntityRecords2 = (kind, name, query = {}) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 17664 const configs = await resolveSelect2.getEntitiesConfig(kind); 17665 const entityConfig = configs.find( 17666 (config) => config.name === name && config.kind === kind 17667 ); 17668 if (!entityConfig) { 17669 return; 17670 } 17671 const lock3 = await dispatch3.__unstableAcquireStoreLock( 17672 STORE_NAME, 17673 ["entities", "records", kind, name], 17674 { exclusive: false } 17675 ); 17676 const rawQuery = { ...query }; 17677 const key = entityConfig.key || DEFAULT_ENTITY_KEY; 17678 function getResolutionsArgs(records, recordsQuery) { 17679 const queryArgs = Object.fromEntries( 17680 Object.entries(recordsQuery).filter(([k, v]) => { 17681 return ["context", "_fields"].includes(k) && !!v; 17682 }) 17683 ); 17684 return records.filter((record) => record?.[key]).map((record) => [ 17685 kind, 17686 name, 17687 record[key], 17688 Object.keys(queryArgs).length > 0 ? queryArgs : void 0 17689 ]); 17690 } 17691 try { 17692 if (query._fields) { 17693 query = { 17694 ...query, 17695 _fields: [ 17696 .../* @__PURE__ */ new Set([ 17697 ...get_normalized_comma_separable_default(query._fields) || [], 17698 key 17699 ]) 17700 ].join() 17701 }; 17702 } 17703 let { baseURL } = entityConfig; 17704 const { combinedTemplates = true } = query; 17705 if (kind === "postType" && name === "wp_template" && combinedTemplates) { 17706 baseURL = baseURL.slice(0, baseURL.lastIndexOf("/")) + "/templates"; 17707 } 17708 const path = (0, import_url6.addQueryArgs)(baseURL, { 17709 ...entityConfig.baseURLParams, 17710 ...query 17711 }); 17712 let records = [], meta; 17713 if (entityConfig.supportsPagination && query.per_page !== -1) { 17714 const response = await (0, import_api_fetch9.default)({ path, parse: false }); 17715 records = Object.values(await response.json()); 17716 meta = { 17717 totalItems: parseInt( 17718 response.headers.get("X-WP-Total") 17719 ), 17720 totalPages: parseInt( 17721 response.headers.get("X-WP-TotalPages") 17722 ) 17723 }; 17724 } else if (query.per_page === -1 && query[RECEIVE_INTERMEDIATE_RESULTS] === true) { 17725 let page = 1; 17726 let totalPages; 17727 do { 17728 const response = await (0, import_api_fetch9.default)({ 17729 path: (0, import_url6.addQueryArgs)(path, { page, per_page: 100 }), 17730 parse: false 17731 }); 17732 const pageRecords = Object.values(await response.json()); 17733 totalPages = parseInt( 17734 response.headers.get("X-WP-TotalPages") 17735 ); 17736 if (!meta) { 17737 meta = { 17738 totalItems: parseInt( 17739 response.headers.get("X-WP-Total") 17740 ), 17741 totalPages: 1 17742 }; 17743 } 17744 records.push(...pageRecords); 17745 registry.batch(() => { 17746 dispatch3.receiveEntityRecords( 17747 kind, 17748 name, 17749 records, 17750 query, 17751 false, 17752 void 0, 17753 meta 17754 ); 17755 dispatch3.finishResolutions( 17756 "getEntityRecord", 17757 getResolutionsArgs(pageRecords, rawQuery) 17758 ); 17759 }); 17760 page++; 17761 } while (page <= totalPages); 17762 } else { 17763 records = Object.values(await (0, import_api_fetch9.default)({ path })); 17764 meta = { 17765 totalItems: records.length, 17766 totalPages: 1 17767 }; 17768 } 17769 if (entityConfig.syncConfig && -1 === query.per_page) { 17770 const objectType = `$kind}/$name}`; 17771 getSyncManager()?.loadCollection( 17772 entityConfig.syncConfig, 17773 objectType, 17774 { 17775 onStatusChange: (status) => { 17776 dispatch3.setSyncConnectionStatus( 17777 kind, 17778 name, 17779 null, 17780 status 17781 ); 17782 }, 17783 refetchRecords: async () => { 17784 dispatch3.receiveEntityRecords( 17785 kind, 17786 name, 17787 await (0, import_api_fetch9.default)({ path, parse: true }), 17788 query 17789 ); 17790 } 17791 } 17792 ); 17793 } 17794 if (query._fields) { 17795 records = records.map((record) => { 17796 query._fields.split(",").forEach((field) => { 17797 if (!record.hasOwnProperty(field)) { 17798 record[field] = void 0; 17799 } 17800 }); 17801 return record; 17802 }); 17803 } 17804 registry.batch(() => { 17805 dispatch3.receiveEntityRecords( 17806 kind, 17807 name, 17808 records, 17809 query, 17810 false, 17811 void 0, 17812 meta 17813 ); 17814 const targetHints = records.filter( 17815 (record) => !!record?.[key] && !!record?._links?.self?.[0]?.targetHints?.allow 17816 ).map((record) => ({ 17817 id: record[key], 17818 permissions: getUserPermissionsFromAllowHeader( 17819 record._links.self[0].targetHints.allow 17820 ) 17821 })); 17822 const canUserResolutionsArgs = []; 17823 const receiveUserPermissionArgs = {}; 17824 for (const targetHint of targetHints) { 17825 for (const action of ALLOWED_RESOURCE_ACTIONS) { 17826 canUserResolutionsArgs.push([ 17827 action, 17828 { kind, name, id: targetHint.id } 17829 ]); 17830 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 17831 kind, 17832 name, 17833 id: targetHint.id 17834 })] = targetHint.permissions[action]; 17835 } 17836 } 17837 if (targetHints.length > 0) { 17838 dispatch3.receiveUserPermissions( 17839 receiveUserPermissionArgs 17840 ); 17841 dispatch3.finishResolutions( 17842 "canUser", 17843 canUserResolutionsArgs 17844 ); 17845 } 17846 dispatch3.finishResolutions( 17847 "getEntityRecord", 17848 getResolutionsArgs(records, rawQuery) 17849 ); 17850 dispatch3.__unstableReleaseStoreLock(lock3); 17851 }); 17852 } catch (e) { 17853 dispatch3.__unstableReleaseStoreLock(lock3); 17854 } 17855 }; 17856 getEntityRecords2.shouldInvalidate = (action, kind, name) => { 17857 return (action.type === "RECEIVE_ITEMS" || action.type === "REMOVE_ITEMS") && action.invalidateCache && kind === action.kind && name === action.name; 17858 }; 17859 var getEntityRecordsTotalItems2 = forward_resolver_default("getEntityRecords"); 17860 var getEntityRecordsTotalPages2 = forward_resolver_default("getEntityRecords"); 17861 var getCurrentTheme2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17862 const activeThemes = await resolveSelect2.getEntityRecords( 17863 "root", 17864 "theme", 17865 { status: "active" } 17866 ); 17867 dispatch3.receiveCurrentTheme(activeThemes[0]); 17868 }; 17869 var getThemeSupports2 = forward_resolver_default("getCurrentTheme"); 17870 var getEmbedPreview2 = (url) => async ({ dispatch: dispatch3 }) => { 17871 try { 17872 const embedProxyResponse = await (0, import_api_fetch9.default)({ 17873 path: (0, import_url6.addQueryArgs)("/oembed/1.0/proxy", { url }) 17874 }); 17875 dispatch3.receiveEmbedPreview(url, embedProxyResponse); 17876 } catch (error) { 17877 dispatch3.receiveEmbedPreview(url, false); 17878 } 17879 }; 17880 var canUser2 = (requestedAction, resource, id2) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 17881 if (!ALLOWED_RESOURCE_ACTIONS.includes(requestedAction)) { 17882 throw new Error(`'$requestedAction}' is not a valid action.`); 17883 } 17884 const { hasStartedResolution } = registry.select(STORE_NAME); 17885 for (const relatedAction of ALLOWED_RESOURCE_ACTIONS) { 17886 if (relatedAction === requestedAction) { 17887 continue; 17888 } 17889 const isAlreadyResolving = hasStartedResolution("canUser", [ 17890 relatedAction, 17891 resource, 17892 id2 17893 ]); 17894 if (isAlreadyResolving) { 17895 return; 17896 } 17897 } 17898 let resourcePath = null; 17899 if (typeof resource === "object") { 17900 if (!resource.kind || !resource.name) { 17901 throw new Error("The entity resource object is not valid."); 17902 } 17903 const configs = await resolveSelect2.getEntitiesConfig( 17904 resource.kind 17905 ); 17906 const entityConfig = configs.find( 17907 (config) => config.name === resource.name && config.kind === resource.kind 17908 ); 17909 if (!entityConfig) { 17910 return; 17911 } 17912 resourcePath = entityConfig.baseURL + (resource.id ? "/" + resource.id : ""); 17913 } else { 17914 resourcePath = `/wp/v2/$resource}` + (id2 ? "/" + id2 : ""); 17915 } 17916 let response; 17917 try { 17918 response = await (0, import_api_fetch9.default)({ 17919 path: resourcePath, 17920 method: "OPTIONS", 17921 parse: false 17922 }); 17923 } catch (error) { 17924 return; 17925 } 17926 const permissions = getUserPermissionsFromAllowHeader( 17927 response.headers?.get("allow") 17928 ); 17929 registry.batch(() => { 17930 for (const action of ALLOWED_RESOURCE_ACTIONS) { 17931 const key = getUserPermissionCacheKey(action, resource, id2); 17932 dispatch3.receiveUserPermission(key, permissions[action]); 17933 if (action !== requestedAction) { 17934 dispatch3.finishResolution("canUser", [ 17935 action, 17936 resource, 17937 id2 17938 ]); 17939 } 17940 } 17941 }); 17942 }; 17943 var canUserEditEntityRecord2 = (kind, name, recordId) => async ({ dispatch: dispatch3 }) => { 17944 await dispatch3(canUser2("update", { kind, name, id: recordId })); 17945 }; 17946 var getAutosaves2 = (postType, postId) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17947 const { 17948 rest_base: restBase, 17949 rest_namespace: restNamespace = "wp/v2", 17950 supports 17951 } = await resolveSelect2.getPostType(postType); 17952 if (!supports?.autosave) { 17953 return; 17954 } 17955 const autosaves2 = await (0, import_api_fetch9.default)({ 17956 path: `/$restNamespace}/$restBase}/$postId}/autosaves?context=edit` 17957 }); 17958 if (autosaves2 && autosaves2.length) { 17959 dispatch3.receiveAutosaves(postId, autosaves2); 17960 } 17961 }; 17962 var getAutosave2 = (postType, postId) => async ({ resolveSelect: resolveSelect2 }) => { 17963 await resolveSelect2.getAutosaves(postType, postId); 17964 }; 17965 var __experimentalGetCurrentGlobalStylesId2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 17966 const activeThemes = await resolveSelect2.getEntityRecords( 17967 "root", 17968 "theme", 17969 { status: "active" } 17970 ); 17971 const globalStylesURL = activeThemes?.[0]?._links?.["wp:user-global-styles"]?.[0]?.href; 17972 if (!globalStylesURL) { 17973 return; 17974 } 17975 const matches = globalStylesURL.match(/\/(\d+)(?:\?|$)/); 17976 const id2 = matches ? Number(matches[1]) : null; 17977 if (id2) { 17978 dispatch3.__experimentalReceiveCurrentGlobalStylesId(id2); 17979 } 17980 }; 17981 var __experimentalGetCurrentThemeBaseGlobalStyles2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 17982 const currentTheme2 = await resolveSelect2.getCurrentTheme(); 17983 const themeGlobalStyles = await (0, import_api_fetch9.default)({ 17984 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}?context=view` 17985 }); 17986 dispatch3.__experimentalReceiveThemeBaseGlobalStyles( 17987 currentTheme2.stylesheet, 17988 themeGlobalStyles 17989 ); 17990 }; 17991 var __experimentalGetCurrentThemeGlobalStylesVariations2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 17992 const currentTheme2 = await resolveSelect2.getCurrentTheme(); 17993 const variations = await (0, import_api_fetch9.default)({ 17994 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}/variations?context=view` 17995 }); 17996 dispatch3.__experimentalReceiveThemeGlobalStyleVariations( 17997 currentTheme2.stylesheet, 17998 variations 17999 ); 18000 }; 18001 var getCurrentThemeGlobalStylesRevisions2 = () => async ({ resolveSelect: resolveSelect2, dispatch: dispatch3 }) => { 18002 const globalStylesId = await resolveSelect2.__experimentalGetCurrentGlobalStylesId(); 18003 const record = globalStylesId ? await resolveSelect2.getEntityRecord( 18004 "root", 18005 "globalStyles", 18006 globalStylesId 18007 ) : void 0; 18008 const revisionsURL = record?._links?.["version-history"]?.[0]?.href; 18009 if (revisionsURL) { 18010 const resetRevisions = await (0, import_api_fetch9.default)({ 18011 url: revisionsURL 18012 }); 18013 const revisions = resetRevisions?.map( 18014 (revision) => Object.fromEntries( 18015 Object.entries(revision).map(([key, value]) => [ 18016 camelCase(key), 18017 value 18018 ]) 18019 ) 18020 ); 18021 dispatch3.receiveThemeGlobalStyleRevisions( 18022 globalStylesId, 18023 revisions 18024 ); 18025 } 18026 }; 18027 getCurrentThemeGlobalStylesRevisions2.shouldInvalidate = (action) => { 18028 return action.type === "SAVE_ENTITY_RECORD_FINISH" && action.kind === "root" && !action.error && action.name === "globalStyles"; 18029 }; 18030 var getBlockPatterns2 = () => async ({ dispatch: dispatch3 }) => { 18031 const patterns = await fetchBlockPatterns(); 18032 dispatch3({ type: "RECEIVE_BLOCK_PATTERNS", patterns }); 18033 }; 18034 var getBlockPatternCategories2 = () => async ({ dispatch: dispatch3 }) => { 18035 const categories = await (0, import_api_fetch9.default)({ 18036 path: "/wp/v2/block-patterns/categories" 18037 }); 18038 dispatch3({ type: "RECEIVE_BLOCK_PATTERN_CATEGORIES", categories }); 18039 }; 18040 var getUserPatternCategories2 = () => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 18041 const patternCategories = await resolveSelect2.getEntityRecords( 18042 "taxonomy", 18043 "wp_pattern_category", 18044 { 18045 per_page: -1, 18046 _fields: "id,name,description,slug", 18047 context: "view" 18048 } 18049 ); 18050 const mappedPatternCategories = patternCategories?.map((userCategory) => ({ 18051 ...userCategory, 18052 label: (0, import_html_entities2.decodeEntities)(userCategory.name), 18053 name: userCategory.slug 18054 })) || []; 18055 dispatch3({ 18056 type: "RECEIVE_USER_PATTERN_CATEGORIES", 18057 patternCategories: mappedPatternCategories 18058 }); 18059 }; 18060 var getNavigationFallbackId2 = () => async ({ dispatch: dispatch3, select: select5, registry }) => { 18061 const fallback = await (0, import_api_fetch9.default)({ 18062 path: (0, import_url6.addQueryArgs)("/wp-block-editor/v1/navigation-fallback", { 18063 _embed: true 18064 }) 18065 }); 18066 const record = fallback?._embedded?.self; 18067 registry.batch(() => { 18068 dispatch3.receiveNavigationFallbackId(fallback?.id); 18069 if (!record) { 18070 return; 18071 } 18072 const existingFallbackEntityRecord = select5.getEntityRecord( 18073 "postType", 18074 "wp_navigation", 18075 fallback.id 18076 ); 18077 const invalidateNavigationQueries = !existingFallbackEntityRecord; 18078 dispatch3.receiveEntityRecords( 18079 "postType", 18080 "wp_navigation", 18081 record, 18082 void 0, 18083 invalidateNavigationQueries 18084 ); 18085 dispatch3.finishResolution("getEntityRecord", [ 18086 "postType", 18087 "wp_navigation", 18088 fallback.id 18089 ]); 18090 }); 18091 }; 18092 var getDefaultTemplateId2 = (query) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 18093 const template = await (0, import_api_fetch9.default)({ 18094 path: (0, import_url6.addQueryArgs)("/wp/v2/templates/lookup", query) 18095 }); 18096 await resolveSelect2.getEntitiesConfig("postType"); 18097 const id2 = window?.__experimentalTemplateActivate ? template?.wp_id || template?.id : template?.id; 18098 if (id2) { 18099 template.id = id2; 18100 registry.batch(() => { 18101 dispatch3.receiveDefaultTemplateId(query, id2); 18102 dispatch3.receiveEntityRecords( 18103 "postType", 18104 template.type, 18105 template 18106 ); 18107 dispatch3.finishResolution("getEntityRecord", [ 18108 "postType", 18109 template.type, 18110 id2 18111 ]); 18112 }); 18113 } 18114 }; 18115 getDefaultTemplateId2.shouldInvalidate = (action) => { 18116 return action.type === "RECEIVE_ITEMS" && action.kind === "root" && action.name === "site"; 18117 }; 18118 var getRevisions2 = (kind, name, recordKey, query = {}) => async ({ dispatch: dispatch3, registry, resolveSelect: resolveSelect2 }) => { 18119 const configs = await resolveSelect2.getEntitiesConfig(kind); 18120 const entityConfig = configs.find( 18121 (config) => config.name === name && config.kind === kind 18122 ); 18123 if (!entityConfig) { 18124 return; 18125 } 18126 if (query._fields) { 18127 query = { 18128 ...query, 18129 _fields: [ 18130 .../* @__PURE__ */ new Set([ 18131 ...get_normalized_comma_separable_default(query._fields) || [], 18132 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 18133 ]) 18134 ].join() 18135 }; 18136 } 18137 const path = (0, import_url6.addQueryArgs)( 18138 entityConfig.getRevisionsUrl(recordKey), 18139 query 18140 ); 18141 let records, response; 18142 const meta = {}; 18143 const isPaginated = entityConfig.supportsPagination && query.per_page !== -1; 18144 try { 18145 response = await (0, import_api_fetch9.default)({ path, parse: !isPaginated }); 18146 } catch (error) { 18147 return; 18148 } 18149 if (response) { 18150 if (isPaginated) { 18151 records = Object.values(await response.json()); 18152 meta.totalItems = parseInt( 18153 response.headers.get("X-WP-Total") 18154 ); 18155 } else { 18156 records = Object.values(response); 18157 } 18158 if (query._fields) { 18159 records = records.map((record) => { 18160 query._fields.split(",").forEach((field) => { 18161 if (!record.hasOwnProperty(field)) { 18162 record[field] = void 0; 18163 } 18164 }); 18165 return record; 18166 }); 18167 } 18168 registry.batch(() => { 18169 dispatch3.receiveRevisions( 18170 kind, 18171 name, 18172 recordKey, 18173 records, 18174 query, 18175 false, 18176 meta 18177 ); 18178 if (!query?._fields && !query.context) { 18179 const key = entityConfig.revisionKey || DEFAULT_ENTITY_KEY; 18180 const resolutionsArgs = records.filter((record) => record[key]).map((record) => [ 18181 kind, 18182 name, 18183 recordKey, 18184 record[key] 18185 ]); 18186 dispatch3.finishResolutions( 18187 "getRevision", 18188 resolutionsArgs 18189 ); 18190 } 18191 }); 18192 } 18193 }; 18194 getRevisions2.shouldInvalidate = (action, kind, name, recordKey) => action.type === "SAVE_ENTITY_RECORD_FINISH" && name === action.name && kind === action.kind && !action.error && recordKey === action.recordId; 18195 var getRevision2 = (kind, name, recordKey, revisionKey, query) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 18196 const configs = await resolveSelect2.getEntitiesConfig(kind); 18197 const entityConfig = configs.find( 18198 (config) => config.name === name && config.kind === kind 18199 ); 18200 if (!entityConfig) { 18201 return; 18202 } 18203 if (query !== void 0 && query._fields) { 18204 query = { 18205 ...query, 18206 _fields: [ 18207 .../* @__PURE__ */ new Set([ 18208 ...get_normalized_comma_separable_default(query._fields) || [], 18209 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 18210 ]) 18211 ].join() 18212 }; 18213 } 18214 const path = (0, import_url6.addQueryArgs)( 18215 entityConfig.getRevisionsUrl(recordKey, revisionKey), 18216 query 18217 ); 18218 let record; 18219 try { 18220 record = await (0, import_api_fetch9.default)({ path }); 18221 } catch (error) { 18222 return; 18223 } 18224 if (record) { 18225 dispatch3.receiveRevisions(kind, name, recordKey, record, query); 18226 } 18227 }; 18228 var getRegisteredPostMeta2 = (postType) => async ({ dispatch: dispatch3, resolveSelect: resolveSelect2 }) => { 18229 let options; 18230 try { 18231 const { 18232 rest_namespace: restNamespace = "wp/v2", 18233 rest_base: restBase 18234 } = await resolveSelect2.getPostType(postType) || {}; 18235 options = await (0, import_api_fetch9.default)({ 18236 path: `$restNamespace}/$restBase}/?context=edit`, 18237 method: "OPTIONS" 18238 }); 18239 } catch (error) { 18240 return; 18241 } 18242 if (options) { 18243 dispatch3.receiveRegisteredPostMeta( 18244 postType, 18245 options?.schema?.properties?.meta?.properties 18246 ); 18247 } 18248 }; 18249 var getEntitiesConfig2 = (kind) => async ({ dispatch: dispatch3 }) => { 18250 const loader = additionalEntityConfigLoaders.find( 18251 (l) => l.kind === kind 18252 ); 18253 if (!loader) { 18254 return; 18255 } 18256 try { 18257 const configs = await loader.loadEntities(); 18258 if (!configs.length) { 18259 return; 18260 } 18261 dispatch3.addEntities(configs); 18262 } catch { 18263 } 18264 }; 18265 var getEditorSettings2 = () => async ({ dispatch: dispatch3 }) => { 18266 const settings = await (0, import_api_fetch9.default)({ 18267 path: "/wp-block-editor/v1/settings" 18268 }); 18269 dispatch3.receiveEditorSettings(settings); 18270 }; 18271 var getEditorAssets2 = () => async ({ dispatch: dispatch3 }) => { 18272 const assets = await (0, import_api_fetch9.default)({ 18273 path: "/wp-block-editor/v1/assets" 18274 }); 18275 dispatch3.receiveEditorAssets(assets); 18276 }; 18277 18278 // packages/core-data/build-module/locks/utils.mjs 18279 function deepCopyLocksTreePath(tree, path) { 18280 const newTree = { ...tree }; 18281 let currentNode = newTree; 18282 for (const branchName of path) { 18283 currentNode.children = { 18284 ...currentNode.children, 18285 [branchName]: { 18286 locks: [], 18287 children: {}, 18288 ...currentNode.children[branchName] 18289 } 18290 }; 18291 currentNode = currentNode.children[branchName]; 18292 } 18293 return newTree; 18294 } 18295 function getNode(tree, path) { 18296 let currentNode = tree; 18297 for (const branchName of path) { 18298 const nextNode = currentNode.children[branchName]; 18299 if (!nextNode) { 18300 return null; 18301 } 18302 currentNode = nextNode; 18303 } 18304 return currentNode; 18305 } 18306 function* iteratePath(tree, path) { 18307 let currentNode = tree; 18308 yield currentNode; 18309 for (const branchName of path) { 18310 const nextNode = currentNode.children[branchName]; 18311 if (!nextNode) { 18312 break; 18313 } 18314 yield nextNode; 18315 currentNode = nextNode; 18316 } 18317 } 18318 function* iterateDescendants(node) { 18319 const stack = Object.values(node.children); 18320 while (stack.length) { 18321 const childNode = stack.pop(); 18322 yield childNode; 18323 stack.push(...Object.values(childNode.children)); 18324 } 18325 } 18326 function hasConflictingLock({ exclusive }, locks2) { 18327 if (exclusive && locks2.length) { 18328 return true; 18329 } 18330 if (!exclusive && locks2.filter((lock3) => lock3.exclusive).length) { 18331 return true; 18332 } 18333 return false; 18334 } 18335 18336 // packages/core-data/build-module/locks/reducer.mjs 18337 var DEFAULT_STATE = { 18338 requests: [], 18339 tree: { 18340 locks: [], 18341 children: {} 18342 } 18343 }; 18344 function locks(state = DEFAULT_STATE, action) { 18345 switch (action.type) { 18346 case "ENQUEUE_LOCK_REQUEST": { 18347 const { request } = action; 18348 return { 18349 ...state, 18350 requests: [request, ...state.requests] 18351 }; 18352 } 18353 case "GRANT_LOCK_REQUEST": { 18354 const { lock: lock3, request } = action; 18355 const { store: store2, path } = request; 18356 const storePath = [store2, ...path]; 18357 const newTree = deepCopyLocksTreePath(state.tree, storePath); 18358 const node = getNode(newTree, storePath); 18359 node.locks = [...node.locks, lock3]; 18360 return { 18361 ...state, 18362 requests: state.requests.filter((r) => r !== request), 18363 tree: newTree 18364 }; 18365 } 18366 case "RELEASE_LOCK": { 18367 const { lock: lock3 } = action; 18368 const storePath = [lock3.store, ...lock3.path]; 18369 const newTree = deepCopyLocksTreePath(state.tree, storePath); 18370 const node = getNode(newTree, storePath); 18371 node.locks = node.locks.filter((l) => l !== lock3); 18372 return { 18373 ...state, 18374 tree: newTree 18375 }; 18376 } 18377 } 18378 return state; 18379 } 18380 18381 // packages/core-data/build-module/locks/selectors.mjs 18382 function getPendingLockRequests(state) { 18383 return state.requests; 18384 } 18385 function isLockAvailable(state, store2, path, { exclusive }) { 18386 const storePath = [store2, ...path]; 18387 const locks2 = state.tree; 18388 for (const node2 of iteratePath(locks2, storePath)) { 18389 if (hasConflictingLock({ exclusive }, node2.locks)) { 18390 return false; 18391 } 18392 } 18393 const node = getNode(locks2, storePath); 18394 if (!node) { 18395 return true; 18396 } 18397 for (const descendant of iterateDescendants(node)) { 18398 if (hasConflictingLock({ exclusive }, descendant.locks)) { 18399 return false; 18400 } 18401 } 18402 return true; 18403 } 18404 18405 // packages/core-data/build-module/locks/engine.mjs 18406 function createLocks() { 18407 let state = locks(void 0, { type: "@@INIT" }); 18408 function processPendingLockRequests() { 18409 for (const request of getPendingLockRequests(state)) { 18410 const { store: store2, path, exclusive, notifyAcquired } = request; 18411 if (isLockAvailable(state, store2, path, { exclusive })) { 18412 const lock3 = { store: store2, path, exclusive }; 18413 state = locks(state, { 18414 type: "GRANT_LOCK_REQUEST", 18415 lock: lock3, 18416 request 18417 }); 18418 notifyAcquired(lock3); 18419 } 18420 } 18421 } 18422 function acquire(store2, path, exclusive) { 18423 return new Promise((resolve) => { 18424 state = locks(state, { 18425 type: "ENQUEUE_LOCK_REQUEST", 18426 request: { store: store2, path, exclusive, notifyAcquired: resolve } 18427 }); 18428 processPendingLockRequests(); 18429 }); 18430 } 18431 function release(lock3) { 18432 state = locks(state, { 18433 type: "RELEASE_LOCK", 18434 lock: lock3 18435 }); 18436 processPendingLockRequests(); 18437 } 18438 return { acquire, release }; 18439 } 18440 18441 // packages/core-data/build-module/locks/actions.mjs 18442 function createLocksActions() { 18443 const locks2 = createLocks(); 18444 function __unstableAcquireStoreLock(store2, path, { exclusive }) { 18445 return () => locks2.acquire(store2, path, exclusive); 18446 } 18447 function __unstableReleaseStoreLock(lock3) { 18448 return () => locks2.release(lock3); 18449 } 18450 return { __unstableAcquireStoreLock, __unstableReleaseStoreLock }; 18451 } 18452 18453 // packages/core-data/build-module/dynamic-entities.mjs 18454 var dynamicActions; 18455 var dynamicSelectors; 18456 18457 // packages/core-data/build-module/entity-provider.mjs 18458 var import_element2 = __toESM(require_element(), 1); 18459 18460 // packages/core-data/build-module/entity-context.mjs 18461 var import_element = __toESM(require_element(), 1); 18462 var EntityContext = (0, import_element.createContext)({}); 18463 EntityContext.displayName = "EntityContext"; 18464 18465 // packages/core-data/build-module/entity-provider.mjs 18466 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); 18467 function EntityProvider({ 18468 kind, 18469 type: name, 18470 id: id2, 18471 revisionId, 18472 children 18473 }) { 18474 const parent = (0, import_element2.useContext)(EntityContext); 18475 const childContext = (0, import_element2.useMemo)( 18476 () => ({ 18477 ...parent, 18478 ...kind && { 18479 [kind]: { 18480 ...parent?.[kind], 18481 [name]: id2 18482 } 18483 }, 18484 ...revisionId !== void 0 && { revisionId } 18485 }), 18486 [parent, kind, name, id2, revisionId] 18487 ); 18488 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EntityContext.Provider, { value: childContext, children }); 18489 } 18490 18491 // packages/core-data/build-module/hooks/use-entity-record.mjs 18492 var import_data12 = __toESM(require_data(), 1); 18493 var import_deprecated4 = __toESM(require_deprecated(), 1); 18494 var import_element3 = __toESM(require_element(), 1); 18495 18496 // packages/core-data/build-module/hooks/use-query-select.mjs 18497 var import_data11 = __toESM(require_data(), 1); 18498 18499 // node_modules/memize/dist/index.js 18500 function memize(fn, options) { 18501 var size2 = 0; 18502 var head; 18503 var tail; 18504 options = options || {}; 18505 function memoized() { 18506 var node = head, len = arguments.length, args2, i; 18507 searchCache: while (node) { 18508 if (node.args.length !== arguments.length) { 18509 node = node.next; 18510 continue; 18511 } 18512 for (i = 0; i < len; i++) { 18513 if (node.args[i] !== arguments[i]) { 18514 node = node.next; 18515 continue searchCache; 18516 } 18517 } 18518 if (node !== head) { 18519 if (node === tail) { 18520 tail = node.prev; 18521 } 18522 node.prev.next = node.next; 18523 if (node.next) { 18524 node.next.prev = node.prev; 18525 } 18526 node.next = head; 18527 node.prev = null; 18528 head.prev = node; 18529 head = node; 18530 } 18531 return node.val; 18532 } 18533 args2 = new Array(len); 18534 for (i = 0; i < len; i++) { 18535 args2[i] = arguments[i]; 18536 } 18537 node = { 18538 args: args2, 18539 // Generate the result from original function 18540 val: fn.apply(null, args2) 18541 }; 18542 if (head) { 18543 head.prev = node; 18544 node.next = head; 18545 } else { 18546 tail = node; 18547 } 18548 if (size2 === /** @type {MemizeOptions} */ 18549 options.maxSize) { 18550 tail = /** @type {MemizeCacheNode} */ 18551 tail.prev; 18552 tail.next = null; 18553 } else { 18554 size2++; 18555 } 18556 head = node; 18557 return node.val; 18558 } 18559 memoized.clear = function() { 18560 head = null; 18561 tail = null; 18562 size2 = 0; 18563 }; 18564 return memoized; 18565 } 18566 18567 // packages/core-data/build-module/hooks/memoize.mjs 18568 var memoize_default = memize; 18569 18570 // packages/core-data/build-module/hooks/constants.mjs 18571 var Status = /* @__PURE__ */ ((Status2) => { 18572 Status2["Idle"] = "IDLE"; 18573 Status2["Resolving"] = "RESOLVING"; 18574 Status2["Error"] = "ERROR"; 18575 Status2["Success"] = "SUCCESS"; 18576 return Status2; 18577 })(Status || {}); 18578 18579 // packages/core-data/build-module/hooks/use-query-select.mjs 18580 var META_SELECTORS = [ 18581 "getIsResolving", 18582 "hasStartedResolution", 18583 "hasFinishedResolution", 18584 "isResolving", 18585 "getCachedResolvers" 18586 ]; 18587 function useQuerySelect(mapQuerySelect, deps) { 18588 return (0, import_data11.useSelect)((select5, registry) => { 18589 const resolve = (store2) => enrichSelectors(select5(store2)); 18590 return mapQuerySelect(resolve, registry); 18591 }, deps); 18592 } 18593 var enrichSelectors = memoize_default(((selectors) => { 18594 const resolvers = {}; 18595 for (const selectorName in selectors) { 18596 if (META_SELECTORS.includes(selectorName)) { 18597 continue; 18598 } 18599 Object.defineProperty(resolvers, selectorName, { 18600 get: () => (...args2) => { 18601 const data = selectors[selectorName](...args2); 18602 const resolutionStatus = selectors.getResolutionState( 18603 selectorName, 18604 args2 18605 )?.status; 18606 let status; 18607 switch (resolutionStatus) { 18608 case "resolving": 18609 status = Status.Resolving; 18610 break; 18611 case "finished": 18612 status = Status.Success; 18613 break; 18614 case "error": 18615 status = Status.Error; 18616 break; 18617 case void 0: 18618 status = Status.Idle; 18619 break; 18620 } 18621 return { 18622 data, 18623 status, 18624 isResolving: status === Status.Resolving, 18625 hasStarted: status !== Status.Idle, 18626 hasResolved: status === Status.Success || status === Status.Error 18627 }; 18628 } 18629 }); 18630 } 18631 return resolvers; 18632 })); 18633 18634 // packages/core-data/build-module/hooks/use-entity-record.mjs 18635 var EMPTY_OBJECT2 = {}; 18636 function useEntityRecord(kind, name, recordId, options = { enabled: true }) { 18637 const { editEntityRecord: editEntityRecord2, saveEditedEntityRecord: saveEditedEntityRecord2 } = (0, import_data12.useDispatch)(store); 18638 const mutations = (0, import_element3.useMemo)( 18639 () => ({ 18640 edit: (record2, editOptions = {}) => editEntityRecord2(kind, name, recordId, record2, editOptions), 18641 save: (saveOptions = {}) => saveEditedEntityRecord2(kind, name, recordId, { 18642 throwOnError: true, 18643 ...saveOptions 18644 }) 18645 }), 18646 [editEntityRecord2, kind, name, recordId, saveEditedEntityRecord2] 18647 ); 18648 const { editedRecord, hasEdits, edits } = (0, import_data12.useSelect)( 18649 (select5) => { 18650 if (!options.enabled) { 18651 return { 18652 editedRecord: EMPTY_OBJECT2, 18653 hasEdits: false, 18654 edits: EMPTY_OBJECT2 18655 }; 18656 } 18657 return { 18658 editedRecord: select5(store).getEditedEntityRecord( 18659 kind, 18660 name, 18661 recordId 18662 ), 18663 hasEdits: select5(store).hasEditsForEntityRecord( 18664 kind, 18665 name, 18666 recordId 18667 ), 18668 edits: select5(store).getEntityRecordNonTransientEdits( 18669 kind, 18670 name, 18671 recordId 18672 ) 18673 }; 18674 }, 18675 [kind, name, recordId, options.enabled] 18676 ); 18677 const { data: record, ...querySelectRest } = useQuerySelect( 18678 (query) => { 18679 if (!options.enabled) { 18680 return { 18681 data: null 18682 }; 18683 } 18684 return query(store).getEntityRecord(kind, name, recordId); 18685 }, 18686 [kind, name, recordId, options.enabled] 18687 ); 18688 return { 18689 record, 18690 editedRecord, 18691 hasEdits, 18692 edits, 18693 ...querySelectRest, 18694 ...mutations 18695 }; 18696 } 18697 function __experimentalUseEntityRecord(kind, name, recordId, options) { 18698 (0, import_deprecated4.default)(`wp.data.__experimentalUseEntityRecord`, { 18699 alternative: "wp.data.useEntityRecord", 18700 since: "6.1" 18701 }); 18702 return useEntityRecord(kind, name, recordId, options); 18703 } 18704 18705 // packages/core-data/build-module/hooks/use-entity-records.mjs 18706 var import_url7 = __toESM(require_url(), 1); 18707 var import_deprecated5 = __toESM(require_deprecated(), 1); 18708 var import_data13 = __toESM(require_data(), 1); 18709 var import_element4 = __toESM(require_element(), 1); 18710 var EMPTY_ARRAY = []; 18711 function useEntityRecords(kind, name, queryArgs = {}, options = { enabled: true }) { 18712 const queryAsString = (0, import_url7.addQueryArgs)("", queryArgs); 18713 const { data: records, ...rest } = useQuerySelect( 18714 (query) => { 18715 if (!options.enabled) { 18716 return { 18717 // Avoiding returning a new reference on every execution. 18718 data: EMPTY_ARRAY 18719 }; 18720 } 18721 return query(store).getEntityRecords(kind, name, queryArgs); 18722 }, 18723 [kind, name, queryAsString, options.enabled] 18724 ); 18725 const { totalItems, totalPages } = (0, import_data13.useSelect)( 18726 (select5) => { 18727 if (!options.enabled) { 18728 return { 18729 totalItems: null, 18730 totalPages: null 18731 }; 18732 } 18733 return { 18734 totalItems: select5(store).getEntityRecordsTotalItems( 18735 kind, 18736 name, 18737 queryArgs 18738 ), 18739 totalPages: select5(store).getEntityRecordsTotalPages( 18740 kind, 18741 name, 18742 queryArgs 18743 ) 18744 }; 18745 }, 18746 [kind, name, queryAsString, options.enabled] 18747 ); 18748 return { 18749 records, 18750 totalItems, 18751 totalPages, 18752 ...rest 18753 }; 18754 } 18755 function __experimentalUseEntityRecords(kind, name, queryArgs, options) { 18756 (0, import_deprecated5.default)(`wp.data.__experimentalUseEntityRecords`, { 18757 alternative: "wp.data.useEntityRecords", 18758 since: "6.1" 18759 }); 18760 return useEntityRecords(kind, name, queryArgs, options); 18761 } 18762 function useEntityRecordsWithPermissions(kind, name, queryArgs = {}, options = { enabled: true }) { 18763 const entityConfig = (0, import_data13.useSelect)( 18764 (select5) => select5(store).getEntityConfig(kind, name), 18765 [kind, name] 18766 ); 18767 const { records: data, ...ret } = useEntityRecords( 18768 kind, 18769 name, 18770 { 18771 ...queryArgs, 18772 // If _fields is provided, we need to include _links in the request for permission caching to work. 18773 ...queryArgs._fields ? { 18774 _fields: [ 18775 .../* @__PURE__ */ new Set([ 18776 ...get_normalized_comma_separable_default( 18777 queryArgs._fields 18778 ) || [], 18779 "_links" 18780 ]) 18781 ].join() 18782 } : {} 18783 }, 18784 options 18785 ); 18786 const ids = (0, import_element4.useMemo)( 18787 () => data?.map( 18788 // @ts-ignore 18789 (record) => record[entityConfig?.key ?? "id"] 18790 ) ?? [], 18791 [data, entityConfig?.key] 18792 ); 18793 const permissions = (0, import_data13.useSelect)( 18794 (select5) => { 18795 const { getEntityRecordsPermissions: getEntityRecordsPermissions2 } = unlock2( 18796 select5(store) 18797 ); 18798 return getEntityRecordsPermissions2(kind, name, ids); 18799 }, 18800 [ids, kind, name] 18801 ); 18802 const dataWithPermissions = (0, import_element4.useMemo)( 18803 () => data?.map((record, index) => ({ 18804 // @ts-ignore 18805 ...record, 18806 permissions: permissions[index] 18807 })) ?? [], 18808 [data, permissions] 18809 ); 18810 return { records: dataWithPermissions, ...ret }; 18811 } 18812 18813 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 18814 var import_deprecated6 = __toESM(require_deprecated(), 1); 18815 var import_warning = __toESM(require_warning(), 1); 18816 function useResourcePermissions(resource, id2) { 18817 const isEntity = typeof resource === "object"; 18818 const resourceAsString = isEntity ? JSON.stringify(resource) : resource; 18819 if (isEntity && typeof id2 !== "undefined") { 18820 (0, import_warning.default)( 18821 `When 'resource' is an entity object, passing 'id' as a separate argument isn't supported.` 18822 ); 18823 } 18824 return useQuerySelect( 18825 (resolve) => { 18826 const hasId = isEntity ? !!resource.id : !!id2; 18827 const { canUser: canUser3 } = resolve(store); 18828 const create9 = canUser3( 18829 "create", 18830 isEntity ? { kind: resource.kind, name: resource.name } : resource 18831 ); 18832 if (!hasId) { 18833 const read2 = canUser3("read", resource); 18834 const isResolving2 = create9.isResolving || read2.isResolving; 18835 const hasResolved2 = create9.hasResolved && read2.hasResolved; 18836 let status2 = Status.Idle; 18837 if (isResolving2) { 18838 status2 = Status.Resolving; 18839 } else if (hasResolved2) { 18840 status2 = Status.Success; 18841 } 18842 return { 18843 status: status2, 18844 isResolving: isResolving2, 18845 hasResolved: hasResolved2, 18846 canCreate: create9.hasResolved && create9.data, 18847 canRead: read2.hasResolved && read2.data 18848 }; 18849 } 18850 const read = canUser3("read", resource, id2); 18851 const update = canUser3("update", resource, id2); 18852 const _delete = canUser3("delete", resource, id2); 18853 const isResolving = read.isResolving || create9.isResolving || update.isResolving || _delete.isResolving; 18854 const hasResolved = read.hasResolved && create9.hasResolved && update.hasResolved && _delete.hasResolved; 18855 let status = Status.Idle; 18856 if (isResolving) { 18857 status = Status.Resolving; 18858 } else if (hasResolved) { 18859 status = Status.Success; 18860 } 18861 return { 18862 status, 18863 isResolving, 18864 hasResolved, 18865 canRead: hasResolved && read.data, 18866 canCreate: hasResolved && create9.data, 18867 canUpdate: hasResolved && update.data, 18868 canDelete: hasResolved && _delete.data 18869 }; 18870 }, 18871 [resourceAsString, id2] 18872 ); 18873 } 18874 var use_resource_permissions_default = useResourcePermissions; 18875 function __experimentalUseResourcePermissions(resource, id2) { 18876 (0, import_deprecated6.default)(`wp.data.__experimentalUseResourcePermissions`, { 18877 alternative: "wp.data.useResourcePermissions", 18878 since: "6.1" 18879 }); 18880 return useResourcePermissions(resource, id2); 18881 } 18882 18883 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 18884 var import_element6 = __toESM(require_element(), 1); 18885 var import_data14 = __toESM(require_data(), 1); 18886 var import_blocks5 = __toESM(require_blocks(), 1); 18887 18888 // packages/core-data/build-module/hooks/use-entity-id.mjs 18889 var import_element5 = __toESM(require_element(), 1); 18890 function useEntityId(kind, name) { 18891 const context = (0, import_element5.useContext)(EntityContext); 18892 return context?.[kind]?.[name]; 18893 } 18894 18895 // packages/core-data/build-module/footnotes/index.mjs 18896 var import_rich_text4 = __toESM(require_rich_text(), 1); 18897 18898 // packages/core-data/build-module/footnotes/get-rich-text-values-cached.mjs 18899 var import_block_editor5 = __toESM(require_block_editor(), 1); 18900 var unlockedApis; 18901 var cache = /* @__PURE__ */ new WeakMap(); 18902 function getRichTextValuesCached(block) { 18903 if (!unlockedApis) { 18904 unlockedApis = unlock2(import_block_editor5.privateApis); 18905 } 18906 if (!cache.has(block)) { 18907 const values = unlockedApis.getRichTextValues([block]); 18908 cache.set(block, values); 18909 } 18910 return cache.get(block); 18911 } 18912 18913 // packages/core-data/build-module/footnotes/get-footnotes-order.mjs 18914 var cache2 = /* @__PURE__ */ new WeakMap(); 18915 function getBlockFootnotesOrder(block) { 18916 if (!cache2.has(block)) { 18917 const order = []; 18918 for (const value of getRichTextValuesCached(block)) { 18919 if (!value) { 18920 continue; 18921 } 18922 value.replacements.forEach(({ type, attributes }) => { 18923 if (type === "core/footnote") { 18924 order.push(attributes["data-fn"]); 18925 } 18926 }); 18927 } 18928 cache2.set(block, order); 18929 } 18930 return cache2.get(block); 18931 } 18932 function getFootnotesOrder(blocks) { 18933 return blocks.flatMap(getBlockFootnotesOrder); 18934 } 18935 18936 // packages/core-data/build-module/footnotes/index.mjs 18937 var oldFootnotes = {}; 18938 function updateFootnotesFromMeta(blocks, meta) { 18939 const output = { blocks }; 18940 if (!meta) { 18941 return output; 18942 } 18943 if (meta.footnotes === void 0) { 18944 return output; 18945 } 18946 const newOrder = getFootnotesOrder(blocks); 18947 const footnotes = meta.footnotes ? JSON.parse(meta.footnotes) : []; 18948 const currentOrder = footnotes.map((fn) => fn.id); 18949 if (currentOrder.join("") === newOrder.join("")) { 18950 return output; 18951 } 18952 const newFootnotes = newOrder.map( 18953 (fnId) => footnotes.find((fn) => fn.id === fnId) || oldFootnotes[fnId] || { 18954 id: fnId, 18955 content: "" 18956 } 18957 ); 18958 function updateAttributes(attributes) { 18959 if (!attributes || Array.isArray(attributes) || typeof attributes !== "object") { 18960 return attributes; 18961 } 18962 attributes = { ...attributes }; 18963 for (const key in attributes) { 18964 const value = attributes[key]; 18965 if (Array.isArray(value)) { 18966 attributes[key] = value.map(updateAttributes); 18967 continue; 18968 } 18969 if (typeof value !== "string" && !(value instanceof import_rich_text4.RichTextData)) { 18970 continue; 18971 } 18972 const richTextValue = typeof value === "string" ? import_rich_text4.RichTextData.fromHTMLString(value) : new import_rich_text4.RichTextData(value); 18973 let hasFootnotes = false; 18974 richTextValue.replacements.forEach((replacement) => { 18975 if (replacement.type === "core/footnote") { 18976 const id2 = replacement.attributes["data-fn"]; 18977 const index = newOrder.indexOf(id2); 18978 const countValue = (0, import_rich_text4.create)({ 18979 html: replacement.innerHTML 18980 }); 18981 countValue.text = String(index + 1); 18982 countValue.formats = Array.from( 18983 { length: countValue.text.length }, 18984 () => countValue.formats[0] 18985 ); 18986 countValue.replacements = Array.from( 18987 { length: countValue.text.length }, 18988 () => countValue.replacements[0] 18989 ); 18990 replacement.innerHTML = (0, import_rich_text4.toHTMLString)({ 18991 value: countValue 18992 }); 18993 hasFootnotes = true; 18994 } 18995 }); 18996 if (hasFootnotes) { 18997 attributes[key] = typeof value === "string" ? richTextValue.toHTMLString() : richTextValue; 18998 } 18999 } 19000 return attributes; 19001 } 19002 function updateBlocksAttributes(__blocks) { 19003 return __blocks.map((block) => { 19004 return { 19005 ...block, 19006 attributes: updateAttributes(block.attributes), 19007 innerBlocks: updateBlocksAttributes(block.innerBlocks) 19008 }; 19009 }); 19010 } 19011 const newBlocks = updateBlocksAttributes(blocks); 19012 oldFootnotes = { 19013 ...oldFootnotes, 19014 ...footnotes.reduce((acc, fn) => { 19015 if (!newOrder.includes(fn.id)) { 19016 acc[fn.id] = fn; 19017 } 19018 return acc; 19019 }, {}) 19020 }; 19021 return { 19022 meta: { 19023 ...meta, 19024 footnotes: JSON.stringify(newFootnotes) 19025 }, 19026 blocks: newBlocks 19027 }; 19028 } 19029 19030 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 19031 var EMPTY_ARRAY2 = []; 19032 var parsedBlocksCache = /* @__PURE__ */ new Map(); 19033 function useEntityBlockEditor(kind, name, { id: _id } = {}) { 19034 const providerId = useEntityId(kind, name); 19035 const id2 = _id ?? providerId; 19036 const { content, editedBlocks, meta } = (0, import_data14.useSelect)( 19037 (select5) => { 19038 if (!id2) { 19039 return {}; 19040 } 19041 const { getEditedEntityRecord: getEditedEntityRecord3 } = select5(STORE_NAME); 19042 const editedRecord = getEditedEntityRecord3(kind, name, id2); 19043 return { 19044 editedBlocks: editedRecord.blocks, 19045 content: editedRecord.content, 19046 meta: editedRecord.meta 19047 }; 19048 }, 19049 [kind, name, id2] 19050 ); 19051 const { __unstableCreateUndoLevel: __unstableCreateUndoLevel2, editEntityRecord: editEntityRecord2 } = (0, import_data14.useDispatch)(STORE_NAME); 19052 const blocks = (0, import_element6.useMemo)(() => { 19053 if (!id2) { 19054 return void 0; 19055 } 19056 if (editedBlocks) { 19057 return editedBlocks; 19058 } 19059 if (!content || typeof content !== "string") { 19060 return EMPTY_ARRAY2; 19061 } 19062 const cacheKey = `$kind}:$name}:$id2}`; 19063 const cached = parsedBlocksCache.get(cacheKey); 19064 let _blocks; 19065 if (cached && cached.content === content) { 19066 _blocks = cached.blocks; 19067 } else { 19068 _blocks = (0, import_blocks5.parse)(content); 19069 parsedBlocksCache.set(cacheKey, { content, blocks: _blocks }); 19070 } 19071 return _blocks; 19072 }, [kind, name, id2, editedBlocks, content]); 19073 const onChange = (0, import_element6.useCallback)( 19074 (newBlocks, options) => { 19075 const noChange = blocks === newBlocks; 19076 if (noChange) { 19077 return __unstableCreateUndoLevel2(kind, name, id2); 19078 } 19079 const { selection, ...rest } = options; 19080 const edits = { 19081 selection, 19082 content: ({ blocks: blocksForSerialization = [] }) => (0, import_blocks5.__unstableSerializeAndClean)(blocksForSerialization), 19083 ...updateFootnotesFromMeta(newBlocks, meta) 19084 }; 19085 editEntityRecord2(kind, name, id2, edits, { 19086 isCached: false, 19087 ...rest 19088 }); 19089 }, 19090 [ 19091 kind, 19092 name, 19093 id2, 19094 blocks, 19095 meta, 19096 __unstableCreateUndoLevel2, 19097 editEntityRecord2 19098 ] 19099 ); 19100 const onInput = (0, import_element6.useCallback)( 19101 (newBlocks, options) => { 19102 const { selection, ...rest } = options; 19103 const edits = { 19104 selection, 19105 ...updateFootnotesFromMeta(newBlocks, meta) 19106 }; 19107 editEntityRecord2(kind, name, id2, edits, { 19108 isCached: true, 19109 ...rest 19110 }); 19111 }, 19112 [kind, name, id2, meta, editEntityRecord2] 19113 ); 19114 return [blocks, onInput, onChange]; 19115 } 19116 19117 // packages/core-data/build-module/hooks/use-entity-prop.mjs 19118 var import_element7 = __toESM(require_element(), 1); 19119 var import_data15 = __toESM(require_data(), 1); 19120 function useEntityProp(kind, name, prop, _id) { 19121 const providerId = useEntityId(kind, name); 19122 const id2 = _id ?? providerId; 19123 const context = (0, import_element7.useContext)(EntityContext); 19124 const revisionId = context?.revisionId; 19125 const { value, fullValue } = (0, import_data15.useSelect)( 19126 (select5) => { 19127 if (revisionId) { 19128 const revisions = select5(STORE_NAME).getRevisions( 19129 kind, 19130 name, 19131 id2, 19132 { 19133 per_page: -1, 19134 context: "edit", 19135 _fields: "id,date,author,meta,title.raw,excerpt.raw,content.raw" 19136 } 19137 ); 19138 const entityConfig = select5(STORE_NAME).getEntityConfig( 19139 kind, 19140 name 19141 ); 19142 const revKey = entityConfig?.revisionKey || DEFAULT_ENTITY_KEY; 19143 const revision = revisions?.find( 19144 (r) => r[revKey] === revisionId 19145 ); 19146 return revision ? { 19147 value: revision[prop]?.raw ?? revision[prop], 19148 fullValue: revision[prop] 19149 } : {}; 19150 } 19151 const { getEntityRecord: getEntityRecord3, getEditedEntityRecord: getEditedEntityRecord3 } = select5(STORE_NAME); 19152 const record = getEntityRecord3(kind, name, id2); 19153 const editedRecord = getEditedEntityRecord3(kind, name, id2); 19154 return record && editedRecord ? { 19155 value: editedRecord[prop], 19156 fullValue: record[prop] 19157 } : {}; 19158 }, 19159 [kind, name, id2, prop, revisionId] 19160 ); 19161 const { editEntityRecord: editEntityRecord2 } = (0, import_data15.useDispatch)(STORE_NAME); 19162 const setValue = (0, import_element7.useCallback)( 19163 (newValue) => { 19164 if (revisionId) { 19165 return; 19166 } 19167 editEntityRecord2(kind, name, id2, { 19168 [prop]: newValue 19169 }); 19170 }, 19171 [editEntityRecord2, kind, name, id2, prop, revisionId] 19172 ); 19173 return [value, setValue, fullValue]; 19174 } 19175 19176 // packages/core-data/build-module/hooks/use-post-editor-awareness-state.mjs 19177 var import_compose3 = __toESM(require_compose(), 1); 19178 var import_element8 = __toESM(require_element(), 1); 19179 var defaultResolvedSelection = { 19180 richTextOffset: null, 19181 localClientId: null 19182 }; 19183 var defaultState = { 19184 activeCollaborators: [], 19185 resolveSelection: () => defaultResolvedSelection, 19186 getDebugData: () => ({ 19187 doc: {}, 19188 clients: {}, 19189 collaboratorMap: {} 19190 }), 19191 isCurrentCollaboratorDisconnected: false 19192 }; 19193 function getAwarenessState(awareness, newState) { 19194 const activeCollaborators = newState ?? awareness.getCurrentState(); 19195 return { 19196 activeCollaborators, 19197 resolveSelection: (selection) => awareness.convertSelectionStateToAbsolute(selection), 19198 getDebugData: () => awareness.getDebugData(), 19199 isCurrentCollaboratorDisconnected: activeCollaborators.find((collaborator) => collaborator.isMe)?.isConnected === false 19200 }; 19201 } 19202 function usePostEditorAwarenessState(postId, postType) { 19203 const [state, setState] = (0, import_element8.useState)(defaultState); 19204 (0, import_element8.useEffect)(() => { 19205 if (null === postId || null === postType) { 19206 setState(defaultState); 19207 return; 19208 } 19209 const objectType = `postType/$postType}`; 19210 const objectId = postId.toString(); 19211 const awareness = getSyncManager()?.getAwareness( 19212 objectType, 19213 objectId 19214 ); 19215 if (!awareness) { 19216 setState(defaultState); 19217 return; 19218 } 19219 awareness.setUp(); 19220 setState(getAwarenessState(awareness)); 19221 const unsubscribe = awareness?.onStateChange( 19222 (newState) => { 19223 setState(getAwarenessState(awareness, newState)); 19224 } 19225 ); 19226 return unsubscribe; 19227 }, [postId, postType]); 19228 return state; 19229 } 19230 function useActiveCollaborators(postId, postType) { 19231 return usePostEditorAwarenessState(postId, postType).activeCollaborators; 19232 } 19233 function useResolvedSelection(postId, postType) { 19234 return usePostEditorAwarenessState(postId, postType).resolveSelection; 19235 } 19236 function useLastPostSave(postId, postType) { 19237 const [lastSave, setLastSave] = (0, import_element8.useState)(null); 19238 (0, import_element8.useEffect)(() => { 19239 if (null === postId || null === postType) { 19240 setLastSave(null); 19241 return; 19242 } 19243 const awareness = getSyncManager()?.getAwareness( 19244 `postType/$postType}`, 19245 postId.toString() 19246 ); 19247 if (!awareness) { 19248 setLastSave(null); 19249 return; 19250 } 19251 awareness.setUp(); 19252 const stateMap = awareness.doc.getMap("state"); 19253 const recordMap = awareness.doc.getMap("document"); 19254 const setupTime = Date.now(); 19255 const observer = (event) => { 19256 if (event.keysChanged.has("savedAt")) { 19257 const savedAt = stateMap.get("savedAt"); 19258 const savedByClientId = stateMap.get("savedBy"); 19259 if (typeof savedAt === "number" && typeof savedByClientId === "number" && savedAt > setupTime) { 19260 const postStatus = recordMap.get("status"); 19261 setLastSave({ savedAt, savedByClientId, postStatus }); 19262 } 19263 } 19264 }; 19265 stateMap.observe(observer); 19266 return () => { 19267 stateMap.unobserve(observer); 19268 }; 19269 }, [postId, postType]); 19270 return lastSave; 19271 } 19272 function useOnCollaboratorJoin(postId, postType, callback) { 19273 const { activeCollaborators } = usePostEditorAwarenessState( 19274 postId, 19275 postType 19276 ); 19277 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 19278 (0, import_element8.useEffect)(() => { 19279 if (!prevCollaborators || prevCollaborators.length === 0) { 19280 return; 19281 } 19282 const prevMap = new Map( 19283 prevCollaborators.map((collaborator) => [ 19284 collaborator.clientId, 19285 collaborator 19286 ]) 19287 ); 19288 const me = activeCollaborators.find( 19289 (collaborator) => collaborator.isMe 19290 ); 19291 for (const collaborator of activeCollaborators) { 19292 if (!prevMap.has(collaborator.clientId) && !collaborator.isMe) { 19293 callback(collaborator, me); 19294 } 19295 } 19296 }, [activeCollaborators, prevCollaborators, callback]); 19297 } 19298 function useOnCollaboratorLeave(postId, postType, callback) { 19299 const { activeCollaborators } = usePostEditorAwarenessState( 19300 postId, 19301 postType 19302 ); 19303 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 19304 (0, import_element8.useEffect)(() => { 19305 if (!prevCollaborators || prevCollaborators.length === 0) { 19306 return; 19307 } 19308 const newMap = new Map( 19309 activeCollaborators.map((collaborator) => [ 19310 collaborator.clientId, 19311 collaborator 19312 ]) 19313 ); 19314 for (const prevCollab of prevCollaborators) { 19315 if (prevCollab.isMe || !prevCollab.isConnected) { 19316 continue; 19317 } 19318 const newCollab = newMap.get(prevCollab.clientId); 19319 if (!newCollab?.isConnected) { 19320 callback(prevCollab); 19321 } 19322 } 19323 }, [activeCollaborators, prevCollaborators, callback]); 19324 } 19325 function useOnPostSave(postId, postType, callback) { 19326 const { activeCollaborators } = usePostEditorAwarenessState( 19327 postId, 19328 postType 19329 ); 19330 const lastPostSave = useLastPostSave(postId, postType); 19331 const prevPostSave = (0, import_compose3.usePrevious)(lastPostSave); 19332 (0, import_element8.useEffect)(() => { 19333 if (!lastPostSave) { 19334 return; 19335 } 19336 if (prevPostSave && lastPostSave.savedAt === prevPostSave.savedAt) { 19337 return; 19338 } 19339 const saver = activeCollaborators.find( 19340 (collaborator) => collaborator.clientId === lastPostSave.savedByClientId && !collaborator.isMe 19341 ); 19342 if (!saver) { 19343 return; 19344 } 19345 callback(lastPostSave, saver, prevPostSave ?? null); 19346 }, [lastPostSave, prevPostSave, activeCollaborators, callback]); 19347 } 19348 19349 // packages/core-data/build-module/private-apis.mjs 19350 var lockedApis = { 19351 useEntityRecordsWithPermissions, 19352 RECEIVE_INTERMEDIATE_RESULTS, 19353 retrySyncConnection, 19354 useActiveCollaborators, 19355 useResolvedSelection, 19356 useOnCollaboratorJoin, 19357 useOnCollaboratorLeave, 19358 useOnPostSave, 19359 SelectionType, 19360 SelectionDirection 19361 }; 19362 var privateApis2 = {}; 19363 lock2(privateApis2, lockedApis); 19364 19365 // packages/core-data/build-module/index.mjs 19366 var entitiesConfig2 = [ 19367 ...rootEntitiesConfig, 19368 ...additionalEntityConfigLoaders.filter((config) => !!config.name) 19369 ]; 19370 var entitySelectors = entitiesConfig2.reduce((result, entity2) => { 19371 const { kind, name, plural } = entity2; 19372 const getEntityRecordMethodName = getMethodName(kind, name); 19373 result[getEntityRecordMethodName] = (state, key, query) => { 19374 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 19375 isShorthandSelector: true, 19376 alternativeFunctionName: "getEntityRecord" 19377 }); 19378 return getEntityRecord(state, kind, name, key, query); 19379 }; 19380 if (plural) { 19381 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 19382 result[getEntityRecordsMethodName] = (state, query) => { 19383 logEntityDeprecation(kind, name, getEntityRecordsMethodName, { 19384 isShorthandSelector: true, 19385 alternativeFunctionName: "getEntityRecords" 19386 }); 19387 return getEntityRecords(state, kind, name, query); 19388 }; 19389 } 19390 return result; 19391 }, {}); 19392 var entityResolvers = entitiesConfig2.reduce((result, entity2) => { 19393 const { kind, name, plural } = entity2; 19394 const getEntityRecordMethodName = getMethodName(kind, name); 19395 result[getEntityRecordMethodName] = (key, query) => { 19396 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 19397 isShorthandSelector: true, 19398 alternativeFunctionName: "getEntityRecord" 19399 }); 19400 return getEntityRecord2(kind, name, key, query); 19401 }; 19402 if (plural) { 19403 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 19404 result[getEntityRecordsMethodName] = (...args2) => { 19405 logEntityDeprecation(kind, plural, getEntityRecordsMethodName, { 19406 isShorthandSelector: true, 19407 alternativeFunctionName: "getEntityRecords" 19408 }); 19409 return getEntityRecords2(kind, name, ...args2); 19410 }; 19411 result[getEntityRecordsMethodName].shouldInvalidate = (action) => getEntityRecords2.shouldInvalidate(action, kind, name); 19412 } 19413 return result; 19414 }, {}); 19415 var entityActions = entitiesConfig2.reduce((result, entity2) => { 19416 const { kind, name } = entity2; 19417 const saveEntityRecordMethodName = getMethodName(kind, name, "save"); 19418 result[saveEntityRecordMethodName] = (record, options) => { 19419 logEntityDeprecation(kind, name, saveEntityRecordMethodName, { 19420 isShorthandSelector: true, 19421 alternativeFunctionName: "saveEntityRecord" 19422 }); 19423 return saveEntityRecord(kind, name, record, options); 19424 }; 19425 const deleteEntityRecordMethodName = getMethodName(kind, name, "delete"); 19426 result[deleteEntityRecordMethodName] = (key, query, options) => { 19427 logEntityDeprecation(kind, name, deleteEntityRecordMethodName, { 19428 isShorthandSelector: true, 19429 alternativeFunctionName: "deleteEntityRecord" 19430 }); 19431 return deleteEntityRecord(kind, name, key, query, options); 19432 }; 19433 return result; 19434 }, {}); 19435 var storeConfig = () => ({ 19436 reducer: reducer_default2, 19437 actions: { 19438 ...dynamicActions, 19439 ...actions_exports, 19440 ...entityActions, 19441 ...createLocksActions() 19442 }, 19443 selectors: { 19444 ...dynamicSelectors, 19445 ...selectors_exports, 19446 ...entitySelectors 19447 }, 19448 resolvers: { ...resolvers_exports, ...entityResolvers } 19449 }); 19450 var store = (0, import_data16.createReduxStore)(STORE_NAME, storeConfig()); 19451 unlock2(store).registerPrivateSelectors(private_selectors_exports); 19452 unlock2(store).registerPrivateActions(private_actions_exports); 19453 (0, import_data16.register)(store); 19454 return __toCommonJS(index_exports); 19455 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Fri Jun 26 08:20:11 2026 | Cross-referenced by PHPXref |