| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 (function() { 2 "use strict"; 3 var wp; 4 (wp ||= {}).coreData = (() => { 5 var __create = Object.create; 6 var __defProp = Object.defineProperty; 7 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 8 var __getOwnPropNames = Object.getOwnPropertyNames; 9 var __getProtoOf = Object.getPrototypeOf; 10 var __hasOwnProp = Object.prototype.hasOwnProperty; 11 var __commonJS = (cb, mod) => function __require() { 12 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 13 }; 14 var __export = (target, all2) => { 15 for (var name in all2) 16 __defProp(target, name, { get: all2[name], enumerable: true }); 17 }; 18 var __copyProps = (to, from2, except, desc) => { 19 if (from2 && typeof from2 === "object" || typeof from2 === "function") { 20 for (let key of __getOwnPropNames(from2)) 21 if (!__hasOwnProp.call(to, key) && key !== except) 22 __defProp(to, key, { get: () => from2[key], enumerable: !(desc = __getOwnPropDesc(from2, key)) || desc.enumerable }); 23 } 24 return to; 25 }; 26 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 27 // If the importer is in node compatibility mode or this is not an ESM 28 // file that has been converted to a CommonJS file using a Babel- 29 // compatible transform (i.e. "__esModule" has not been set), then set 30 // "default" to the CommonJS "module.exports" for node compatibility. 31 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 32 mod 33 )); 34 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); 35 36 // package-external:@wordpress/data 37 var require_data = __commonJS({ 38 "package-external:@wordpress/data"(exports, module) { 39 module.exports = window.wp.data; 40 } 41 }); 42 43 // node_modules/.store/fast-deep-equal@3.1.3-Dk0kpzcWCOUHE1bkOO2LLA/node_modules/fast-deep-equal/es6/index.js 44 var require_es6 = __commonJS({ 45 "node_modules/.store/fast-deep-equal@3.1.3-Dk0kpzcWCOUHE1bkOO2LLA/node_modules/fast-deep-equal/es6/index.js"(exports, module) { 46 "use strict"; 47 module.exports = function equal(a, b) { 48 if (a === b) return true; 49 if (a && b && typeof a == "object" && typeof b == "object") { 50 if (a.constructor !== b.constructor) return false; 51 var length2, i, keys2; 52 if (Array.isArray(a)) { 53 length2 = a.length; 54 if (length2 != b.length) return false; 55 for (i = length2; i-- !== 0; ) 56 if (!equal(a[i], b[i])) return false; 57 return true; 58 } 59 if (a instanceof Map && b instanceof Map) { 60 if (a.size !== b.size) return false; 61 for (i of a.entries()) 62 if (!b.has(i[0])) return false; 63 for (i of a.entries()) 64 if (!equal(i[1], b.get(i[0]))) return false; 65 return true; 66 } 67 if (a instanceof Set && b instanceof Set) { 68 if (a.size !== b.size) return false; 69 for (i of a.entries()) 70 if (!b.has(i[0])) return false; 71 return true; 72 } 73 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 74 length2 = a.length; 75 if (length2 != b.length) return false; 76 for (i = length2; i-- !== 0; ) 77 if (a[i] !== b[i]) return false; 78 return true; 79 } 80 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 81 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 82 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 83 keys2 = Object.keys(a); 84 length2 = keys2.length; 85 if (length2 !== Object.keys(b).length) return false; 86 for (i = length2; i-- !== 0; ) 87 if (!Object.prototype.hasOwnProperty.call(b, keys2[i])) return false; 88 for (i = length2; i-- !== 0; ) { 89 var key = keys2[i]; 90 if (!equal(a[key], b[key])) return false; 91 } 92 return true; 93 } 94 return a !== a && b !== b; 95 }; 96 } 97 }); 98 99 // package-external:@wordpress/compose 100 var require_compose = __commonJS({ 101 "package-external:@wordpress/compose"(exports, module) { 102 module.exports = window.wp.compose; 103 } 104 }); 105 106 // package-external:@wordpress/undo-manager 107 var require_undo_manager = __commonJS({ 108 "package-external:@wordpress/undo-manager"(exports, module) { 109 module.exports = window.wp.undoManager; 110 } 111 }); 112 113 // package-external:@wordpress/api-fetch 114 var require_api_fetch = __commonJS({ 115 "package-external:@wordpress/api-fetch"(exports, module) { 116 module.exports = window.wp.apiFetch; 117 } 118 }); 119 120 // package-external:@wordpress/hooks 121 var require_hooks = __commonJS({ 122 "package-external:@wordpress/hooks"(exports, module) { 123 module.exports = window.wp.hooks; 124 } 125 }); 126 127 // package-external:@wordpress/warning 128 var require_warning = __commonJS({ 129 "package-external:@wordpress/warning"(exports, module) { 130 module.exports = window.wp.warning; 131 } 132 }); 133 134 // package-external:@wordpress/blocks 135 var require_blocks = __commonJS({ 136 "package-external:@wordpress/blocks"(exports, module) { 137 module.exports = window.wp.blocks; 138 } 139 }); 140 141 // package-external:@wordpress/i18n 142 var require_i18n = __commonJS({ 143 "package-external:@wordpress/i18n"(exports, module) { 144 module.exports = window.wp.i18n; 145 } 146 }); 147 148 // package-external:@wordpress/block-editor 149 var require_block_editor = __commonJS({ 150 "package-external:@wordpress/block-editor"(exports, module) { 151 module.exports = window.wp.blockEditor; 152 } 153 }); 154 155 // package-external:@wordpress/private-apis 156 var require_private_apis = __commonJS({ 157 "package-external:@wordpress/private-apis"(exports, module) { 158 module.exports = window.wp.privateApis; 159 } 160 }); 161 162 // package-external:@wordpress/rich-text 163 var require_rich_text = __commonJS({ 164 "package-external:@wordpress/rich-text"(exports, module) { 165 module.exports = window.wp.richText; 166 } 167 }); 168 169 // node_modules/.store/equivalent-key-map@0.2.2-x2CcnsHOWgXkLrIdkTeNmg/node_modules/equivalent-key-map/equivalent-key-map.js 170 var require_equivalent_key_map = __commonJS({ 171 "node_modules/.store/equivalent-key-map@0.2.2-x2CcnsHOWgXkLrIdkTeNmg/node_modules/equivalent-key-map/equivalent-key-map.js"(exports, module) { 172 "use strict"; 173 function _typeof(obj) { 174 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 175 _typeof = function(obj2) { 176 return typeof obj2; 177 }; 178 } else { 179 _typeof = function(obj2) { 180 return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; 181 }; 182 } 183 return _typeof(obj); 184 } 185 function _classCallCheck(instance, Constructor) { 186 if (!(instance instanceof Constructor)) { 187 throw new TypeError("Cannot call a class as a function"); 188 } 189 } 190 function _defineProperties(target, props) { 191 for (var i = 0; i < props.length; i++) { 192 var descriptor = props[i]; 193 descriptor.enumerable = descriptor.enumerable || false; 194 descriptor.configurable = true; 195 if ("value" in descriptor) descriptor.writable = true; 196 Object.defineProperty(target, descriptor.key, descriptor); 197 } 198 } 199 function _createClass(Constructor, protoProps, staticProps) { 200 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 201 if (staticProps) _defineProperties(Constructor, staticProps); 202 return Constructor; 203 } 204 function getValuePair(instance, key) { 205 var _map = instance._map, _arrayTreeMap = instance._arrayTreeMap, _objectTreeMap = instance._objectTreeMap; 206 if (_map.has(key)) { 207 return _map.get(key); 208 } 209 var properties = Object.keys(key).sort(); 210 var map2 = Array.isArray(key) ? _arrayTreeMap : _objectTreeMap; 211 for (var i = 0; i < properties.length; i++) { 212 var property = properties[i]; 213 map2 = map2.get(property); 214 if (map2 === void 0) { 215 return; 216 } 217 var propertyValue = key[property]; 218 map2 = map2.get(propertyValue); 219 if (map2 === void 0) { 220 return; 221 } 222 } 223 var valuePair = map2.get("_ekm_value"); 224 if (!valuePair) { 225 return; 226 } 227 _map.delete(valuePair[0]); 228 valuePair[0] = key; 229 map2.set("_ekm_value", valuePair); 230 _map.set(key, valuePair); 231 return valuePair; 232 } 233 var EquivalentKeyMap2 = /* @__PURE__ */ (function() { 234 function EquivalentKeyMap3(iterable) { 235 _classCallCheck(this, EquivalentKeyMap3); 236 this.clear(); 237 if (iterable instanceof EquivalentKeyMap3) { 238 var iterablePairs = []; 239 iterable.forEach(function(value, key) { 240 iterablePairs.push([key, value]); 241 }); 242 iterable = iterablePairs; 243 } 244 if (iterable != null) { 245 for (var i = 0; i < iterable.length; i++) { 246 this.set(iterable[i][0], iterable[i][1]); 247 } 248 } 249 } 250 _createClass(EquivalentKeyMap3, [{ 251 key: "set", 252 /** 253 * Add or update an element with a specified key and value. 254 * 255 * @param {*} key The key of the element to add. 256 * @param {*} value The value of the element to add. 257 * 258 * @return {EquivalentKeyMap} Map instance. 259 */ 260 value: function set(key, value) { 261 if (key === null || _typeof(key) !== "object") { 262 this._map.set(key, value); 263 return this; 264 } 265 var properties = Object.keys(key).sort(); 266 var valuePair = [key, value]; 267 var map2 = Array.isArray(key) ? this._arrayTreeMap : this._objectTreeMap; 268 for (var i = 0; i < properties.length; i++) { 269 var property = properties[i]; 270 if (!map2.has(property)) { 271 map2.set(property, new EquivalentKeyMap3()); 272 } 273 map2 = map2.get(property); 274 var propertyValue = key[property]; 275 if (!map2.has(propertyValue)) { 276 map2.set(propertyValue, new EquivalentKeyMap3()); 277 } 278 map2 = map2.get(propertyValue); 279 } 280 var previousValuePair = map2.get("_ekm_value"); 281 if (previousValuePair) { 282 this._map.delete(previousValuePair[0]); 283 } 284 map2.set("_ekm_value", valuePair); 285 this._map.set(key, valuePair); 286 return this; 287 } 288 /** 289 * Returns a specified element. 290 * 291 * @param {*} key The key of the element to return. 292 * 293 * @return {?*} The element associated with the specified key or undefined 294 * if the key can't be found. 295 */ 296 }, { 297 key: "get", 298 value: function get(key) { 299 if (key === null || _typeof(key) !== "object") { 300 return this._map.get(key); 301 } 302 var valuePair = getValuePair(this, key); 303 if (valuePair) { 304 return valuePair[1]; 305 } 306 } 307 /** 308 * Returns a boolean indicating whether an element with the specified key 309 * exists or not. 310 * 311 * @param {*} key The key of the element to test for presence. 312 * 313 * @return {boolean} Whether an element with the specified key exists. 314 */ 315 }, { 316 key: "has", 317 value: function has(key) { 318 if (key === null || _typeof(key) !== "object") { 319 return this._map.has(key); 320 } 321 return getValuePair(this, key) !== void 0; 322 } 323 /** 324 * Removes the specified element. 325 * 326 * @param {*} key The key of the element to remove. 327 * 328 * @return {boolean} Returns true if an element existed and has been 329 * removed, or false if the element does not exist. 330 */ 331 }, { 332 key: "delete", 333 value: function _delete(key) { 334 if (!this.has(key)) { 335 return false; 336 } 337 this.set(key, void 0); 338 return true; 339 } 340 /** 341 * Executes a provided function once per each key/value pair, in insertion 342 * order. 343 * 344 * @param {Function} callback Function to execute for each element. 345 * @param {*} thisArg Value to use as `this` when executing 346 * `callback`. 347 */ 348 }, { 349 key: "forEach", 350 value: function forEach2(callback) { 351 var _this = this; 352 var thisArg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : this; 353 this._map.forEach(function(value, key) { 354 if (key !== null && _typeof(key) === "object") { 355 value = value[1]; 356 } 357 callback.call(thisArg, value, key, _this); 358 }); 359 } 360 /** 361 * Removes all elements. 362 */ 363 }, { 364 key: "clear", 365 value: function clear() { 366 this._map = /* @__PURE__ */ new Map(); 367 this._arrayTreeMap = /* @__PURE__ */ new Map(); 368 this._objectTreeMap = /* @__PURE__ */ new Map(); 369 } 370 }, { 371 key: "size", 372 get: function get() { 373 return this._map.size; 374 } 375 }]); 376 return EquivalentKeyMap3; 377 })(); 378 module.exports = EquivalentKeyMap2; 379 } 380 }); 381 382 // package-external:@wordpress/url 383 var require_url = __commonJS({ 384 "package-external:@wordpress/url"(exports, module) { 385 module.exports = window.wp.url; 386 } 387 }); 388 389 // package-external:@wordpress/deprecated 390 var require_deprecated = __commonJS({ 391 "package-external:@wordpress/deprecated"(exports, module) { 392 module.exports = window.wp.deprecated; 393 } 394 }); 395 396 // package-external:@wordpress/notices 397 var require_notices = __commonJS({ 398 "package-external:@wordpress/notices"(exports, module) { 399 module.exports = window.wp.notices; 400 } 401 }); 402 403 // package-external:@wordpress/html-entities 404 var require_html_entities = __commonJS({ 405 "package-external:@wordpress/html-entities"(exports, module) { 406 module.exports = window.wp.htmlEntities; 407 } 408 }); 409 410 // package-external:@wordpress/element 411 var require_element = __commonJS({ 412 "package-external:@wordpress/element"(exports, module) { 413 module.exports = window.wp.element; 414 } 415 }); 416 417 // vendor-external:react/jsx-runtime 418 var require_jsx_runtime = __commonJS({ 419 "vendor-external:react/jsx-runtime"(exports, module) { 420 module.exports = window.ReactJSXRuntime; 421 } 422 }); 423 424 // package-external:@wordpress/primitives 425 var require_primitives = __commonJS({ 426 "package-external:@wordpress/primitives"(exports, module) { 427 module.exports = window.wp.primitives; 428 } 429 }); 430 431 // package-external:@wordpress/components 432 var require_components = __commonJS({ 433 "package-external:@wordpress/components"(exports, module) { 434 module.exports = window.wp.components; 435 } 436 }); 437 438 // packages/core-data/build-module/index.mjs 439 var index_exports = {}; 440 __export(index_exports, { 441 EntityProvider: () => EntityProvider, 442 PrivateEntityProvider: () => PrivateEntityProvider, 443 __experimentalFetchLinkSuggestions: () => fetchLinkSuggestions, 444 __experimentalFetchUrlData: () => experimental_fetch_url_data_default, 445 __experimentalUseEntityRecord: () => useDeprecatedEntityRecord, 446 __experimentalUseEntityRecords: () => useDeprecatedEntityRecords, 447 __experimentalUseResourcePermissions: () => useDeprecatedResourcePermissions, 448 fetchBlockPatterns: () => fetchBlockPatterns, 449 privateApis: () => privateApis, 450 store: () => store, 451 useEntityBlockEditor: () => useEntityBlockEditor, 452 useEntityId: () => useEntityId, 453 useEntityProp: () => useEntityProp, 454 useEntityRecord: () => useEntityRecord, 455 useEntityRecords: () => useEntityRecords, 456 useResourcePermissions: () => use_resource_permissions_default 457 }); 458 var import_data21 = __toESM(require_data(), 1); 459 460 // packages/core-data/build-module/reducer.mjs 461 var import_es68 = __toESM(require_es6(), 1); 462 var import_compose2 = __toESM(require_compose(), 1); 463 var import_data8 = __toESM(require_data(), 1); 464 var import_undo_manager2 = __toESM(require_undo_manager(), 1); 465 466 // packages/core-data/build-module/utils/clear-unchanged-edits.mjs 467 var import_es6 = __toESM(require_es6(), 1); 468 function clearUnchangedEdits(edits, persistedRecord) { 469 if (!persistedRecord) { 470 return edits; 471 } 472 return Object.fromEntries( 473 Object.entries(edits).map(([key, value]) => { 474 const persisted = persistedRecord[key]?.raw ?? persistedRecord[key]; 475 return [ 476 key, 477 (0, import_es6.default)(value, persisted) ? void 0 : value 478 ]; 479 }) 480 ); 481 } 482 483 // packages/core-data/build-module/utils/conservative-map-item.mjs 484 var import_es62 = __toESM(require_es6(), 1); 485 function conservativeMapItem(item, nextItem) { 486 if (!item) { 487 return nextItem; 488 } 489 let hasChanges = false; 490 const result = {}; 491 for (const key in nextItem) { 492 if ((0, import_es62.default)(item[key], nextItem[key])) { 493 result[key] = item[key]; 494 } else { 495 hasChanges = true; 496 result[key] = nextItem[key]; 497 } 498 } 499 if (!hasChanges) { 500 return item; 501 } 502 for (const key in item) { 503 if (!result.hasOwnProperty(key)) { 504 result[key] = item[key]; 505 } 506 } 507 return result; 508 } 509 510 // packages/core-data/build-module/utils/get-normalized-comma-separable.mjs 511 function getNormalizedCommaSeparable(value) { 512 if (typeof value === "string") { 513 return value.split(","); 514 } else if (Array.isArray(value)) { 515 return value; 516 } 517 return null; 518 } 519 var get_normalized_comma_separable_default = getNormalizedCommaSeparable; 520 521 // packages/core-data/build-module/utils/set-nested-value.mjs 522 function setNestedValue(object, path, value) { 523 if (!object || typeof object !== "object") { 524 return object; 525 } 526 const normalizedPath = Array.isArray(path) ? path : path.split("."); 527 normalizedPath.reduce((acc, key, idx) => { 528 if (acc[key] === void 0) { 529 if (Number.isInteger(normalizedPath[idx + 1])) { 530 acc[key] = []; 531 } else { 532 acc[key] = {}; 533 } 534 } 535 if (idx === normalizedPath.length - 1) { 536 acc[key] = value; 537 } 538 return acc[key]; 539 }, object); 540 return object; 541 } 542 543 // packages/core-data/build-module/utils/get-filtered-item.mjs 544 var filteredItemCache = /* @__PURE__ */ new WeakMap(); 545 function getFilteredItem(item, _fields) { 546 const fields = get_normalized_comma_separable_default(_fields) ?? []; 547 const fieldsKey = fields.join(","); 548 let itemCache = filteredItemCache.get(item); 549 if (itemCache) { 550 const filtered = itemCache.get(fieldsKey); 551 if (filtered !== void 0) { 552 return filtered; 553 } 554 } else if (item !== null && typeof item === "object") { 555 itemCache = /* @__PURE__ */ new Map(); 556 filteredItemCache.set(item, itemCache); 557 } 558 const filteredItem = {}; 559 for (let f = 0; f < fields.length; f++) { 560 const field = fields[f].split("."); 561 let value = item; 562 field.forEach((fieldName) => { 563 value = value?.[fieldName]; 564 }); 565 setNestedValue(filteredItem, field, value); 566 } 567 itemCache?.set(fieldsKey, filteredItem); 568 return filteredItem; 569 } 570 571 // packages/core-data/build-module/utils/if-matching-action.mjs 572 var ifMatchingAction = (isMatch) => (reducer) => (state, action) => { 573 if (state === void 0 || isMatch(action)) { 574 return reducer(state, action); 575 } 576 return state; 577 }; 578 var if_matching_action_default = ifMatchingAction; 579 580 // packages/core-data/build-module/utils/forward-resolver.mjs 581 var forwardResolver = (resolverName) => (...args2) => async ({ resolveSelect: resolveSelect3 }) => { 582 await resolveSelect3[resolverName](...args2); 583 }; 584 var forward_resolver_default = forwardResolver; 585 586 // packages/core-data/build-module/utils/replace-action.mjs 587 var replaceAction = (replacer) => (reducer) => (state, action) => { 588 return reducer(state, replacer(action)); 589 }; 590 var replace_action_default = replaceAction; 591 592 // packages/core-data/build-module/utils/with-weak-map-cache.mjs 593 function withWeakMapCache(fn) { 594 const cache3 = /* @__PURE__ */ new WeakMap(); 595 return (key) => { 596 let value; 597 if (cache3.has(key)) { 598 value = cache3.get(key); 599 } else { 600 value = fn(key); 601 if (key !== null && typeof key === "object") { 602 cache3.set(key, value); 603 } 604 } 605 return value; 606 }; 607 } 608 var with_weak_map_cache_default = withWeakMapCache; 609 610 // packages/core-data/build-module/utils/get-nested-value.mjs 611 function getNestedValue(object, path, defaultValue) { 612 if (!object || typeof object !== "object" || typeof path !== "string" && !Array.isArray(path)) { 613 return object; 614 } 615 const normalizedPath = Array.isArray(path) ? path : path.split("."); 616 let value = object; 617 normalizedPath.forEach((fieldName) => { 618 value = value?.[fieldName]; 619 }); 620 return value !== void 0 ? value : defaultValue; 621 } 622 623 // packages/core-data/build-module/utils/is-numeric-id.mjs 624 function isNumericID(id2) { 625 return /^\s*\d+\s*$/.test(id2); 626 } 627 628 // packages/core-data/build-module/utils/user-permissions.mjs 629 var ALLOWED_RESOURCE_ACTIONS = [ 630 "create", 631 "read", 632 "update", 633 "delete" 634 ]; 635 function getUserPermissionsFromAllowHeader(allowedMethods) { 636 const permissions = {}; 637 const methods = { 638 create: "POST", 639 read: "GET", 640 update: "PUT", 641 delete: "DELETE" 642 }; 643 for (const [actionName, methodName] of Object.entries(methods)) { 644 permissions[actionName] = allowedMethods ? allowedMethods.includes(methodName) : false; 645 } 646 return permissions; 647 } 648 function getUserPermissionCacheKey(action, resource, id2) { 649 const key = (typeof resource === "object" ? [action, resource.kind, resource.name, resource.id] : [action, resource, id2]).filter(Boolean).join("/"); 650 return key; 651 } 652 653 // packages/core-data/build-module/utils/receive-intermediate-results.mjs 654 var RECEIVE_INTERMEDIATE_RESULTS = /* @__PURE__ */ Symbol( 655 "RECEIVE_INTERMEDIATE_RESULTS" 656 ); 657 658 // packages/core-data/build-module/utils/normalize-query-for-resolution.mjs 659 function normalizeQueryForResolution(query) { 660 if (!query) { 661 return void 0; 662 } 663 const entries = Object.entries(query).filter( 664 ([k, v]) => (k === "context" || k === "_fields") && v !== void 0 && v !== null 665 ); 666 return entries.length > 0 ? Object.fromEntries(entries) : void 0; 667 } 668 669 // packages/core-data/build-module/utils/save-crdt-doc.mjs 670 var import_api_fetch3 = __toESM(require_api_fetch(), 1); 671 672 // packages/core-data/build-module/sync.mjs 673 var import_es67 = __toESM(require_es6(), 1); 674 var import_data6 = __toESM(require_data(), 1); 675 676 // node_modules/.store/yjs@13.6.29-TJYJpNVE3l2_hFsy5BI5FA/node_modules/yjs/dist/yjs.mjs 677 var yjs_exports = {}; 678 __export(yjs_exports, { 679 AbsolutePosition: () => AbsolutePosition, 680 AbstractConnector: () => AbstractConnector, 681 AbstractStruct: () => AbstractStruct, 682 AbstractType: () => AbstractType, 683 Array: () => YArray, 684 ContentAny: () => ContentAny, 685 ContentBinary: () => ContentBinary, 686 ContentDeleted: () => ContentDeleted, 687 ContentDoc: () => ContentDoc, 688 ContentEmbed: () => ContentEmbed, 689 ContentFormat: () => ContentFormat, 690 ContentJSON: () => ContentJSON, 691 ContentString: () => ContentString, 692 ContentType: () => ContentType, 693 Doc: () => Doc, 694 GC: () => GC, 695 ID: () => ID, 696 Item: () => Item, 697 Map: () => YMap, 698 PermanentUserData: () => PermanentUserData, 699 RelativePosition: () => RelativePosition, 700 Skip: () => Skip, 701 Snapshot: () => Snapshot, 702 Text: () => YText, 703 Transaction: () => Transaction, 704 UndoManager: () => UndoManager, 705 UpdateDecoderV1: () => UpdateDecoderV1, 706 UpdateDecoderV2: () => UpdateDecoderV2, 707 UpdateEncoderV1: () => UpdateEncoderV1, 708 UpdateEncoderV2: () => UpdateEncoderV2, 709 XmlElement: () => YXmlElement, 710 XmlFragment: () => YXmlFragment, 711 XmlHook: () => YXmlHook, 712 XmlText: () => YXmlText, 713 YArrayEvent: () => YArrayEvent, 714 YEvent: () => YEvent, 715 YMapEvent: () => YMapEvent, 716 YTextEvent: () => YTextEvent, 717 YXmlEvent: () => YXmlEvent, 718 applyUpdate: () => applyUpdate, 719 applyUpdateV2: () => applyUpdateV2, 720 cleanupYTextFormatting: () => cleanupYTextFormatting, 721 compareIDs: () => compareIDs, 722 compareRelativePositions: () => compareRelativePositions, 723 convertUpdateFormatV1ToV2: () => convertUpdateFormatV1ToV2, 724 convertUpdateFormatV2ToV1: () => convertUpdateFormatV2ToV1, 725 createAbsolutePositionFromRelativePosition: () => createAbsolutePositionFromRelativePosition, 726 createDeleteSet: () => createDeleteSet, 727 createDeleteSetFromStructStore: () => createDeleteSetFromStructStore, 728 createDocFromSnapshot: () => createDocFromSnapshot, 729 createID: () => createID, 730 createRelativePositionFromJSON: () => createRelativePositionFromJSON, 731 createRelativePositionFromTypeIndex: () => createRelativePositionFromTypeIndex, 732 createSnapshot: () => createSnapshot, 733 decodeRelativePosition: () => decodeRelativePosition, 734 decodeSnapshot: () => decodeSnapshot, 735 decodeSnapshotV2: () => decodeSnapshotV2, 736 decodeStateVector: () => decodeStateVector, 737 decodeUpdate: () => decodeUpdate, 738 decodeUpdateV2: () => decodeUpdateV2, 739 diffUpdate: () => diffUpdate, 740 diffUpdateV2: () => diffUpdateV2, 741 emptySnapshot: () => emptySnapshot, 742 encodeRelativePosition: () => encodeRelativePosition, 743 encodeSnapshot: () => encodeSnapshot, 744 encodeSnapshotV2: () => encodeSnapshotV2, 745 encodeStateAsUpdate: () => encodeStateAsUpdate, 746 encodeStateAsUpdateV2: () => encodeStateAsUpdateV2, 747 encodeStateVector: () => encodeStateVector, 748 encodeStateVectorFromUpdate: () => encodeStateVectorFromUpdate, 749 encodeStateVectorFromUpdateV2: () => encodeStateVectorFromUpdateV2, 750 equalDeleteSets: () => equalDeleteSets, 751 equalSnapshots: () => equalSnapshots, 752 findIndexSS: () => findIndexSS, 753 findRootTypeKey: () => findRootTypeKey, 754 getItem: () => getItem, 755 getItemCleanEnd: () => getItemCleanEnd, 756 getItemCleanStart: () => getItemCleanStart, 757 getState: () => getState, 758 getTypeChildren: () => getTypeChildren, 759 isDeleted: () => isDeleted, 760 isParentOf: () => isParentOf, 761 iterateDeletedStructs: () => iterateDeletedStructs, 762 logType: () => logType, 763 logUpdate: () => logUpdate, 764 logUpdateV2: () => logUpdateV2, 765 mergeDeleteSets: () => mergeDeleteSets, 766 mergeUpdates: () => mergeUpdates, 767 mergeUpdatesV2: () => mergeUpdatesV2, 768 obfuscateUpdate: () => obfuscateUpdate, 769 obfuscateUpdateV2: () => obfuscateUpdateV2, 770 parseUpdateMeta: () => parseUpdateMeta, 771 parseUpdateMetaV2: () => parseUpdateMetaV2, 772 readUpdate: () => readUpdate, 773 readUpdateV2: () => readUpdateV2, 774 relativePositionToJSON: () => relativePositionToJSON, 775 snapshot: () => snapshot, 776 snapshotContainsUpdate: () => snapshotContainsUpdate, 777 transact: () => transact, 778 tryGc: () => tryGc, 779 typeListToArraySnapshot: () => typeListToArraySnapshot, 780 typeMapGetAllSnapshot: () => typeMapGetAllSnapshot, 781 typeMapGetSnapshot: () => typeMapGetSnapshot 782 }); 783 784 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/map.js 785 var create = () => /* @__PURE__ */ new Map(); 786 var copy = (m) => { 787 const r2 = create(); 788 m.forEach((v, k) => { 789 r2.set(k, v); 790 }); 791 return r2; 792 }; 793 var setIfUndefined = (map2, key, createT) => { 794 let set = map2.get(key); 795 if (set === void 0) { 796 map2.set(key, set = createT()); 797 } 798 return set; 799 }; 800 var map = (m, f) => { 801 const res = []; 802 for (const [key, value] of m) { 803 res.push(f(value, key)); 804 } 805 return res; 806 }; 807 var any = (m, f) => { 808 for (const [key, value] of m) { 809 if (f(value, key)) { 810 return true; 811 } 812 } 813 return false; 814 }; 815 816 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/set.js 817 var create2 = () => /* @__PURE__ */ new Set(); 818 819 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/array.js 820 var last = (arr) => arr[arr.length - 1]; 821 var appendTo = (dest, src) => { 822 for (let i = 0; i < src.length; i++) { 823 dest.push(src[i]); 824 } 825 }; 826 var from = Array.from; 827 var every = (arr, f) => { 828 for (let i = 0; i < arr.length; i++) { 829 if (!f(arr[i], i, arr)) { 830 return false; 831 } 832 } 833 return true; 834 }; 835 var some = (arr, f) => { 836 for (let i = 0; i < arr.length; i++) { 837 if (f(arr[i], i, arr)) { 838 return true; 839 } 840 } 841 return false; 842 }; 843 var unfold = (len, f) => { 844 const array = new Array(len); 845 for (let i = 0; i < len; i++) { 846 array[i] = f(i, array); 847 } 848 return array; 849 }; 850 var isArray = Array.isArray; 851 852 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/observable.js 853 var ObservableV2 = class { 854 constructor() { 855 this._observers = create(); 856 } 857 /** 858 * @template {keyof EVENTS & string} NAME 859 * @param {NAME} name 860 * @param {EVENTS[NAME]} f 861 */ 862 on(name, f) { 863 setIfUndefined( 864 this._observers, 865 /** @type {string} */ 866 name, 867 create2 868 ).add(f); 869 return f; 870 } 871 /** 872 * @template {keyof EVENTS & string} NAME 873 * @param {NAME} name 874 * @param {EVENTS[NAME]} f 875 */ 876 once(name, f) { 877 const _f = (...args2) => { 878 this.off( 879 name, 880 /** @type {any} */ 881 _f 882 ); 883 f(...args2); 884 }; 885 this.on( 886 name, 887 /** @type {any} */ 888 _f 889 ); 890 } 891 /** 892 * @template {keyof EVENTS & string} NAME 893 * @param {NAME} name 894 * @param {EVENTS[NAME]} f 895 */ 896 off(name, f) { 897 const observers = this._observers.get(name); 898 if (observers !== void 0) { 899 observers.delete(f); 900 if (observers.size === 0) { 901 this._observers.delete(name); 902 } 903 } 904 } 905 /** 906 * Emit a named event. All registered event listeners that listen to the 907 * specified name will receive the event. 908 * 909 * @todo This should catch exceptions 910 * 911 * @template {keyof EVENTS & string} NAME 912 * @param {NAME} name The event name. 913 * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener. 914 */ 915 emit(name, args2) { 916 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 917 } 918 destroy() { 919 this._observers = create(); 920 } 921 }; 922 var Observable = class { 923 constructor() { 924 this._observers = create(); 925 } 926 /** 927 * @param {N} name 928 * @param {function} f 929 */ 930 on(name, f) { 931 setIfUndefined(this._observers, name, create2).add(f); 932 } 933 /** 934 * @param {N} name 935 * @param {function} f 936 */ 937 once(name, f) { 938 const _f = (...args2) => { 939 this.off(name, _f); 940 f(...args2); 941 }; 942 this.on(name, _f); 943 } 944 /** 945 * @param {N} name 946 * @param {function} f 947 */ 948 off(name, f) { 949 const observers = this._observers.get(name); 950 if (observers !== void 0) { 951 observers.delete(f); 952 if (observers.size === 0) { 953 this._observers.delete(name); 954 } 955 } 956 } 957 /** 958 * Emit a named event. All registered event listeners that listen to the 959 * specified name will receive the event. 960 * 961 * @todo This should catch exceptions 962 * 963 * @param {N} name The event name. 964 * @param {Array<any>} args The arguments that are applied to the event listener. 965 */ 966 emit(name, args2) { 967 return from((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); 968 } 969 destroy() { 970 this._observers = create(); 971 } 972 }; 973 974 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/math.js 975 var floor = Math.floor; 976 var abs = Math.abs; 977 var min = (a, b) => a < b ? a : b; 978 var max = (a, b) => a > b ? a : b; 979 var isNaN2 = Number.isNaN; 980 var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; 981 982 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/binary.js 983 var BIT1 = 1; 984 var BIT2 = 2; 985 var BIT3 = 4; 986 var BIT4 = 8; 987 var BIT6 = 32; 988 var BIT7 = 64; 989 var BIT8 = 128; 990 var BIT18 = 1 << 17; 991 var BIT19 = 1 << 18; 992 var BIT20 = 1 << 19; 993 var BIT21 = 1 << 20; 994 var BIT22 = 1 << 21; 995 var BIT23 = 1 << 22; 996 var BIT24 = 1 << 23; 997 var BIT25 = 1 << 24; 998 var BIT26 = 1 << 25; 999 var BIT27 = 1 << 26; 1000 var BIT28 = 1 << 27; 1001 var BIT29 = 1 << 28; 1002 var BIT30 = 1 << 29; 1003 var BIT31 = 1 << 30; 1004 var BIT32 = 1 << 31; 1005 var BITS5 = 31; 1006 var BITS6 = 63; 1007 var BITS7 = 127; 1008 var BITS17 = BIT18 - 1; 1009 var BITS18 = BIT19 - 1; 1010 var BITS19 = BIT20 - 1; 1011 var BITS20 = BIT21 - 1; 1012 var BITS21 = BIT22 - 1; 1013 var BITS22 = BIT23 - 1; 1014 var BITS23 = BIT24 - 1; 1015 var BITS24 = BIT25 - 1; 1016 var BITS25 = BIT26 - 1; 1017 var BITS26 = BIT27 - 1; 1018 var BITS27 = BIT28 - 1; 1019 var BITS28 = BIT29 - 1; 1020 var BITS29 = BIT30 - 1; 1021 var BITS30 = BIT31 - 1; 1022 var BITS31 = 2147483647; 1023 1024 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/number.js 1025 var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; 1026 var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; 1027 var LOWEST_INT32 = 1 << 31; 1028 var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); 1029 var isNaN3 = Number.isNaN; 1030 var parseInt2 = Number.parseInt; 1031 1032 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/string.js 1033 var fromCharCode = String.fromCharCode; 1034 var fromCodePoint = String.fromCodePoint; 1035 var MAX_UTF16_CHARACTER = fromCharCode(65535); 1036 var toLowerCase = (s) => s.toLowerCase(); 1037 var trimLeftRegex = /^\s*/g; 1038 var trimLeft = (s) => s.replace(trimLeftRegex, ""); 1039 var fromCamelCaseRegex = /([A-Z])/g; 1040 var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match2) => `$separator}$toLowerCase(match2)}`)); 1041 var _encodeUtf8Polyfill = (str) => { 1042 const encodedString = unescape(encodeURIComponent(str)); 1043 const len = encodedString.length; 1044 const buf = new Uint8Array(len); 1045 for (let i = 0; i < len; i++) { 1046 buf[i] = /** @type {number} */ 1047 encodedString.codePointAt(i); 1048 } 1049 return buf; 1050 }; 1051 var utf8TextEncoder = ( 1052 /** @type {TextEncoder} */ 1053 typeof TextEncoder !== "undefined" ? new TextEncoder() : null 1054 ); 1055 var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); 1056 var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; 1057 var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); 1058 if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { 1059 utf8TextDecoder = null; 1060 } 1061 var repeat = (source, n) => unfold(n, () => source).join(""); 1062 1063 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/encoding.js 1064 var Encoder = class { 1065 constructor() { 1066 this.cpos = 0; 1067 this.cbuf = new Uint8Array(100); 1068 this.bufs = []; 1069 } 1070 }; 1071 var createEncoder = () => new Encoder(); 1072 var length = (encoder) => { 1073 let len = encoder.cpos; 1074 for (let i = 0; i < encoder.bufs.length; i++) { 1075 len += encoder.bufs[i].length; 1076 } 1077 return len; 1078 }; 1079 var toUint8Array = (encoder) => { 1080 const uint8arr = new Uint8Array(length(encoder)); 1081 let curPos = 0; 1082 for (let i = 0; i < encoder.bufs.length; i++) { 1083 const d = encoder.bufs[i]; 1084 uint8arr.set(d, curPos); 1085 curPos += d.length; 1086 } 1087 uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); 1088 return uint8arr; 1089 }; 1090 var verifyLen = (encoder, len) => { 1091 const bufferLen = encoder.cbuf.length; 1092 if (bufferLen - encoder.cpos < len) { 1093 encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); 1094 encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); 1095 encoder.cpos = 0; 1096 } 1097 }; 1098 var write = (encoder, num) => { 1099 const bufferLen = encoder.cbuf.length; 1100 if (encoder.cpos === bufferLen) { 1101 encoder.bufs.push(encoder.cbuf); 1102 encoder.cbuf = new Uint8Array(bufferLen * 2); 1103 encoder.cpos = 0; 1104 } 1105 encoder.cbuf[encoder.cpos++] = num; 1106 }; 1107 var writeUint8 = write; 1108 var writeVarUint = (encoder, num) => { 1109 while (num > BITS7) { 1110 write(encoder, BIT8 | BITS7 & num); 1111 num = floor(num / 128); 1112 } 1113 write(encoder, BITS7 & num); 1114 }; 1115 var writeVarInt = (encoder, num) => { 1116 const isNegative = isNegativeZero(num); 1117 if (isNegative) { 1118 num = -num; 1119 } 1120 write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); 1121 num = floor(num / 64); 1122 while (num > 0) { 1123 write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); 1124 num = floor(num / 128); 1125 } 1126 }; 1127 var _strBuffer = new Uint8Array(3e4); 1128 var _maxStrBSize = _strBuffer.length / 3; 1129 var _writeVarStringNative = (encoder, str) => { 1130 if (str.length < _maxStrBSize) { 1131 const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; 1132 writeVarUint(encoder, written); 1133 for (let i = 0; i < written; i++) { 1134 write(encoder, _strBuffer[i]); 1135 } 1136 } else { 1137 writeVarUint8Array(encoder, encodeUtf8(str)); 1138 } 1139 }; 1140 var _writeVarStringPolyfill = (encoder, str) => { 1141 const encodedString = unescape(encodeURIComponent(str)); 1142 const len = encodedString.length; 1143 writeVarUint(encoder, len); 1144 for (let i = 0; i < len; i++) { 1145 write( 1146 encoder, 1147 /** @type {number} */ 1148 encodedString.codePointAt(i) 1149 ); 1150 } 1151 }; 1152 var writeVarString = utf8TextEncoder && /** @type {any} */ 1153 utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; 1154 var writeBinaryEncoder = (encoder, append2) => writeUint8Array(encoder, toUint8Array(append2)); 1155 var writeUint8Array = (encoder, uint8Array) => { 1156 const bufferLen = encoder.cbuf.length; 1157 const cpos = encoder.cpos; 1158 const leftCopyLen = min(bufferLen - cpos, uint8Array.length); 1159 const rightCopyLen = uint8Array.length - leftCopyLen; 1160 encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); 1161 encoder.cpos += leftCopyLen; 1162 if (rightCopyLen > 0) { 1163 encoder.bufs.push(encoder.cbuf); 1164 encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); 1165 encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); 1166 encoder.cpos = rightCopyLen; 1167 } 1168 }; 1169 var writeVarUint8Array = (encoder, uint8Array) => { 1170 writeVarUint(encoder, uint8Array.byteLength); 1171 writeUint8Array(encoder, uint8Array); 1172 }; 1173 var writeOnDataView = (encoder, len) => { 1174 verifyLen(encoder, len); 1175 const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); 1176 encoder.cpos += len; 1177 return dview; 1178 }; 1179 var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); 1180 var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); 1181 var writeBigInt64 = (encoder, num) => ( 1182 /** @type {any} */ 1183 writeOnDataView(encoder, 8).setBigInt64(0, num, false) 1184 ); 1185 var floatTestBed = new DataView(new ArrayBuffer(4)); 1186 var isFloat32 = (num) => { 1187 floatTestBed.setFloat32(0, num); 1188 return floatTestBed.getFloat32(0) === num; 1189 }; 1190 var writeAny = (encoder, data) => { 1191 switch (typeof data) { 1192 case "string": 1193 write(encoder, 119); 1194 writeVarString(encoder, data); 1195 break; 1196 case "number": 1197 if (isInteger(data) && abs(data) <= BITS31) { 1198 write(encoder, 125); 1199 writeVarInt(encoder, data); 1200 } else if (isFloat32(data)) { 1201 write(encoder, 124); 1202 writeFloat32(encoder, data); 1203 } else { 1204 write(encoder, 123); 1205 writeFloat64(encoder, data); 1206 } 1207 break; 1208 case "bigint": 1209 write(encoder, 122); 1210 writeBigInt64(encoder, data); 1211 break; 1212 case "object": 1213 if (data === null) { 1214 write(encoder, 126); 1215 } else if (isArray(data)) { 1216 write(encoder, 117); 1217 writeVarUint(encoder, data.length); 1218 for (let i = 0; i < data.length; i++) { 1219 writeAny(encoder, data[i]); 1220 } 1221 } else if (data instanceof Uint8Array) { 1222 write(encoder, 116); 1223 writeVarUint8Array(encoder, data); 1224 } else { 1225 write(encoder, 118); 1226 const keys2 = Object.keys(data); 1227 writeVarUint(encoder, keys2.length); 1228 for (let i = 0; i < keys2.length; i++) { 1229 const key = keys2[i]; 1230 writeVarString(encoder, key); 1231 writeAny(encoder, data[key]); 1232 } 1233 } 1234 break; 1235 case "boolean": 1236 write(encoder, data ? 120 : 121); 1237 break; 1238 default: 1239 write(encoder, 127); 1240 } 1241 }; 1242 var RleEncoder = class extends Encoder { 1243 /** 1244 * @param {function(Encoder, T):void} writer 1245 */ 1246 constructor(writer) { 1247 super(); 1248 this.w = writer; 1249 this.s = null; 1250 this.count = 0; 1251 } 1252 /** 1253 * @param {T} v 1254 */ 1255 write(v) { 1256 if (this.s === v) { 1257 this.count++; 1258 } else { 1259 if (this.count > 0) { 1260 writeVarUint(this, this.count - 1); 1261 } 1262 this.count = 1; 1263 this.w(this, v); 1264 this.s = v; 1265 } 1266 } 1267 }; 1268 var flushUintOptRleEncoder = (encoder) => { 1269 if (encoder.count > 0) { 1270 writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); 1271 if (encoder.count > 1) { 1272 writeVarUint(encoder.encoder, encoder.count - 2); 1273 } 1274 } 1275 }; 1276 var UintOptRleEncoder = class { 1277 constructor() { 1278 this.encoder = new Encoder(); 1279 this.s = 0; 1280 this.count = 0; 1281 } 1282 /** 1283 * @param {number} v 1284 */ 1285 write(v) { 1286 if (this.s === v) { 1287 this.count++; 1288 } else { 1289 flushUintOptRleEncoder(this); 1290 this.count = 1; 1291 this.s = v; 1292 } 1293 } 1294 /** 1295 * Flush the encoded state and transform this to a Uint8Array. 1296 * 1297 * Note that this should only be called once. 1298 */ 1299 toUint8Array() { 1300 flushUintOptRleEncoder(this); 1301 return toUint8Array(this.encoder); 1302 } 1303 }; 1304 var flushIntDiffOptRleEncoder = (encoder) => { 1305 if (encoder.count > 0) { 1306 const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); 1307 writeVarInt(encoder.encoder, encodedDiff); 1308 if (encoder.count > 1) { 1309 writeVarUint(encoder.encoder, encoder.count - 2); 1310 } 1311 } 1312 }; 1313 var IntDiffOptRleEncoder = class { 1314 constructor() { 1315 this.encoder = new Encoder(); 1316 this.s = 0; 1317 this.count = 0; 1318 this.diff = 0; 1319 } 1320 /** 1321 * @param {number} v 1322 */ 1323 write(v) { 1324 if (this.diff === v - this.s) { 1325 this.s = v; 1326 this.count++; 1327 } else { 1328 flushIntDiffOptRleEncoder(this); 1329 this.count = 1; 1330 this.diff = v - this.s; 1331 this.s = v; 1332 } 1333 } 1334 /** 1335 * Flush the encoded state and transform this to a Uint8Array. 1336 * 1337 * Note that this should only be called once. 1338 */ 1339 toUint8Array() { 1340 flushIntDiffOptRleEncoder(this); 1341 return toUint8Array(this.encoder); 1342 } 1343 }; 1344 var StringEncoder = class { 1345 constructor() { 1346 this.sarr = []; 1347 this.s = ""; 1348 this.lensE = new UintOptRleEncoder(); 1349 } 1350 /** 1351 * @param {string} string 1352 */ 1353 write(string) { 1354 this.s += string; 1355 if (this.s.length > 19) { 1356 this.sarr.push(this.s); 1357 this.s = ""; 1358 } 1359 this.lensE.write(string.length); 1360 } 1361 toUint8Array() { 1362 const encoder = new Encoder(); 1363 this.sarr.push(this.s); 1364 this.s = ""; 1365 writeVarString(encoder, this.sarr.join("")); 1366 writeUint8Array(encoder, this.lensE.toUint8Array()); 1367 return toUint8Array(encoder); 1368 } 1369 }; 1370 1371 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/error.js 1372 var create3 = (s) => new Error(s); 1373 var methodUnimplemented = () => { 1374 throw create3("Method unimplemented"); 1375 }; 1376 var unexpectedCase = () => { 1377 throw create3("Unexpected case"); 1378 }; 1379 1380 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/decoding.js 1381 var errorUnexpectedEndOfArray = create3("Unexpected end of array"); 1382 var errorIntegerOutOfRange = create3("Integer out of Range"); 1383 var Decoder = class { 1384 /** 1385 * @param {Uint8Array<Buf>} uint8Array Binary data to decode 1386 */ 1387 constructor(uint8Array) { 1388 this.arr = uint8Array; 1389 this.pos = 0; 1390 } 1391 }; 1392 var createDecoder = (uint8Array) => new Decoder(uint8Array); 1393 var hasContent = (decoder) => decoder.pos !== decoder.arr.length; 1394 var readUint8Array = (decoder, len) => { 1395 const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); 1396 decoder.pos += len; 1397 return view; 1398 }; 1399 var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); 1400 var readUint8 = (decoder) => decoder.arr[decoder.pos++]; 1401 var readVarUint = (decoder) => { 1402 let num = 0; 1403 let mult = 1; 1404 const len = decoder.arr.length; 1405 while (decoder.pos < len) { 1406 const r2 = decoder.arr[decoder.pos++]; 1407 num = num + (r2 & BITS7) * mult; 1408 mult *= 128; 1409 if (r2 < BIT8) { 1410 return num; 1411 } 1412 if (num > MAX_SAFE_INTEGER) { 1413 throw errorIntegerOutOfRange; 1414 } 1415 } 1416 throw errorUnexpectedEndOfArray; 1417 }; 1418 var readVarInt = (decoder) => { 1419 let r2 = decoder.arr[decoder.pos++]; 1420 let num = r2 & BITS6; 1421 let mult = 64; 1422 const sign = (r2 & BIT7) > 0 ? -1 : 1; 1423 if ((r2 & BIT8) === 0) { 1424 return sign * num; 1425 } 1426 const len = decoder.arr.length; 1427 while (decoder.pos < len) { 1428 r2 = decoder.arr[decoder.pos++]; 1429 num = num + (r2 & BITS7) * mult; 1430 mult *= 128; 1431 if (r2 < BIT8) { 1432 return sign * num; 1433 } 1434 if (num > MAX_SAFE_INTEGER) { 1435 throw errorIntegerOutOfRange; 1436 } 1437 } 1438 throw errorUnexpectedEndOfArray; 1439 }; 1440 var _readVarStringPolyfill = (decoder) => { 1441 let remainingLen = readVarUint(decoder); 1442 if (remainingLen === 0) { 1443 return ""; 1444 } else { 1445 let encodedString = String.fromCodePoint(readUint8(decoder)); 1446 if (--remainingLen < 100) { 1447 while (remainingLen--) { 1448 encodedString += String.fromCodePoint(readUint8(decoder)); 1449 } 1450 } else { 1451 while (remainingLen > 0) { 1452 const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; 1453 const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); 1454 decoder.pos += nextLen; 1455 encodedString += String.fromCodePoint.apply( 1456 null, 1457 /** @type {any} */ 1458 bytes 1459 ); 1460 remainingLen -= nextLen; 1461 } 1462 } 1463 return decodeURIComponent(escape(encodedString)); 1464 } 1465 }; 1466 var _readVarStringNative = (decoder) => ( 1467 /** @type any */ 1468 utf8TextDecoder.decode(readVarUint8Array(decoder)) 1469 ); 1470 var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; 1471 var readFromDataView = (decoder, len) => { 1472 const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); 1473 decoder.pos += len; 1474 return dv; 1475 }; 1476 var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); 1477 var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); 1478 var readBigInt64 = (decoder) => ( 1479 /** @type {any} */ 1480 readFromDataView(decoder, 8).getBigInt64(0, false) 1481 ); 1482 var readAnyLookupTable = [ 1483 (decoder) => void 0, 1484 // CASE 127: undefined 1485 (decoder) => null, 1486 // CASE 126: null 1487 readVarInt, 1488 // CASE 125: integer 1489 readFloat32, 1490 // CASE 124: float32 1491 readFloat64, 1492 // CASE 123: float64 1493 readBigInt64, 1494 // CASE 122: bigint 1495 (decoder) => false, 1496 // CASE 121: boolean (false) 1497 (decoder) => true, 1498 // CASE 120: boolean (true) 1499 readVarString, 1500 // CASE 119: string 1501 (decoder) => { 1502 const len = readVarUint(decoder); 1503 const obj = {}; 1504 for (let i = 0; i < len; i++) { 1505 const key = readVarString(decoder); 1506 obj[key] = readAny(decoder); 1507 } 1508 return obj; 1509 }, 1510 (decoder) => { 1511 const len = readVarUint(decoder); 1512 const arr = []; 1513 for (let i = 0; i < len; i++) { 1514 arr.push(readAny(decoder)); 1515 } 1516 return arr; 1517 }, 1518 readVarUint8Array 1519 // CASE 116: Uint8Array 1520 ]; 1521 var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); 1522 var RleDecoder = class extends Decoder { 1523 /** 1524 * @param {Uint8Array} uint8Array 1525 * @param {function(Decoder):T} reader 1526 */ 1527 constructor(uint8Array, reader) { 1528 super(uint8Array); 1529 this.reader = reader; 1530 this.s = null; 1531 this.count = 0; 1532 } 1533 read() { 1534 if (this.count === 0) { 1535 this.s = this.reader(this); 1536 if (hasContent(this)) { 1537 this.count = readVarUint(this) + 1; 1538 } else { 1539 this.count = -1; 1540 } 1541 } 1542 this.count--; 1543 return ( 1544 /** @type {T} */ 1545 this.s 1546 ); 1547 } 1548 }; 1549 var UintOptRleDecoder = class extends Decoder { 1550 /** 1551 * @param {Uint8Array} uint8Array 1552 */ 1553 constructor(uint8Array) { 1554 super(uint8Array); 1555 this.s = 0; 1556 this.count = 0; 1557 } 1558 read() { 1559 if (this.count === 0) { 1560 this.s = readVarInt(this); 1561 const isNegative = isNegativeZero(this.s); 1562 this.count = 1; 1563 if (isNegative) { 1564 this.s = -this.s; 1565 this.count = readVarUint(this) + 2; 1566 } 1567 } 1568 this.count--; 1569 return ( 1570 /** @type {number} */ 1571 this.s 1572 ); 1573 } 1574 }; 1575 var IntDiffOptRleDecoder = class extends Decoder { 1576 /** 1577 * @param {Uint8Array} uint8Array 1578 */ 1579 constructor(uint8Array) { 1580 super(uint8Array); 1581 this.s = 0; 1582 this.count = 0; 1583 this.diff = 0; 1584 } 1585 /** 1586 * @return {number} 1587 */ 1588 read() { 1589 if (this.count === 0) { 1590 const diff = readVarInt(this); 1591 const hasCount = diff & 1; 1592 this.diff = floor(diff / 2); 1593 this.count = 1; 1594 if (hasCount) { 1595 this.count = readVarUint(this) + 2; 1596 } 1597 } 1598 this.s += this.diff; 1599 this.count--; 1600 return this.s; 1601 } 1602 }; 1603 var StringDecoder = class { 1604 /** 1605 * @param {Uint8Array} uint8Array 1606 */ 1607 constructor(uint8Array) { 1608 this.decoder = new UintOptRleDecoder(uint8Array); 1609 this.str = readVarString(this.decoder); 1610 this.spos = 0; 1611 } 1612 /** 1613 * @return {string} 1614 */ 1615 read() { 1616 const end = this.spos + this.decoder.read(); 1617 const res = this.str.slice(this.spos, end); 1618 this.spos = end; 1619 return res; 1620 } 1621 }; 1622 1623 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/webcrypto.js 1624 var subtle = crypto.subtle; 1625 var getRandomValues = crypto.getRandomValues.bind(crypto); 1626 1627 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/random.js 1628 var uint32 = () => getRandomValues(new Uint32Array(1))[0]; 1629 var uuidv4Template = "10000000-1000-4000-8000" + -1e11; 1630 var uuidv4 = () => uuidv4Template.replace( 1631 /[018]/g, 1632 /** @param {number} c */ 1633 (c) => (c ^ uint32() & 15 >> c / 4).toString(16) 1634 ); 1635 1636 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/time.js 1637 var getUnixTime = Date.now; 1638 1639 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/promise.js 1640 var create4 = (f) => ( 1641 /** @type {Promise<T>} */ 1642 new Promise(f) 1643 ); 1644 var all = Promise.all.bind(Promise); 1645 1646 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/conditions.js 1647 var undefinedToNull = (v) => v === void 0 ? null : v; 1648 1649 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/storage.js 1650 var VarStoragePolyfill = class { 1651 constructor() { 1652 this.map = /* @__PURE__ */ new Map(); 1653 } 1654 /** 1655 * @param {string} key 1656 * @param {any} newValue 1657 */ 1658 setItem(key, newValue) { 1659 this.map.set(key, newValue); 1660 } 1661 /** 1662 * @param {string} key 1663 */ 1664 getItem(key) { 1665 return this.map.get(key); 1666 } 1667 }; 1668 var _localStorage = new VarStoragePolyfill(); 1669 var usePolyfill = true; 1670 try { 1671 if (typeof localStorage !== "undefined" && localStorage) { 1672 _localStorage = localStorage; 1673 usePolyfill = false; 1674 } 1675 } catch (e) { 1676 } 1677 var varStorage = _localStorage; 1678 1679 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/trait/equality.js 1680 var EqualityTraitSymbol = /* @__PURE__ */ Symbol("Equality"); 1681 var equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false; 1682 1683 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/object.js 1684 var isObject = (o) => typeof o === "object"; 1685 var assign = Object.assign; 1686 var keys = Object.keys; 1687 var forEach = (obj, f) => { 1688 for (const key in obj) { 1689 f(obj[key], key); 1690 } 1691 }; 1692 var size = (obj) => keys(obj).length; 1693 var isEmpty = (obj) => { 1694 for (const _k in obj) { 1695 return false; 1696 } 1697 return true; 1698 }; 1699 var every2 = (obj, f) => { 1700 for (const key in obj) { 1701 if (!f(obj[key], key)) { 1702 return false; 1703 } 1704 } 1705 return true; 1706 }; 1707 var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); 1708 var equalFlat = (a, b) => a === b || size(a) === size(b) && every2(a, (val, key) => (val !== void 0 || hasProperty(b, key)) && equals(b[key], val)); 1709 var freeze = Object.freeze; 1710 var deepFreeze = (o) => { 1711 for (const key in o) { 1712 const c = o[key]; 1713 if (typeof c === "object" || typeof c === "function") { 1714 deepFreeze(o[key]); 1715 } 1716 } 1717 return freeze(o); 1718 }; 1719 1720 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/function.js 1721 var callAll = (fs, args2, i = 0) => { 1722 try { 1723 for (; i < fs.length; i++) { 1724 fs[i](...args2); 1725 } 1726 } finally { 1727 if (i < fs.length) { 1728 callAll(fs, args2, i + 1); 1729 } 1730 } 1731 }; 1732 var id = (a) => a; 1733 var equalityDeep = (a, b) => { 1734 if (a === b) { 1735 return true; 1736 } 1737 if (a == null || b == null || a.constructor !== b.constructor && (a.constructor || Object) !== (b.constructor || Object)) { 1738 return false; 1739 } 1740 if (a[EqualityTraitSymbol] != null) { 1741 return a[EqualityTraitSymbol](b); 1742 } 1743 switch (a.constructor) { 1744 case ArrayBuffer: 1745 a = new Uint8Array(a); 1746 b = new Uint8Array(b); 1747 // eslint-disable-next-line no-fallthrough 1748 case Uint8Array: { 1749 if (a.byteLength !== b.byteLength) { 1750 return false; 1751 } 1752 for (let i = 0; i < a.length; i++) { 1753 if (a[i] !== b[i]) { 1754 return false; 1755 } 1756 } 1757 break; 1758 } 1759 case Set: { 1760 if (a.size !== b.size) { 1761 return false; 1762 } 1763 for (const value of a) { 1764 if (!b.has(value)) { 1765 return false; 1766 } 1767 } 1768 break; 1769 } 1770 case Map: { 1771 if (a.size !== b.size) { 1772 return false; 1773 } 1774 for (const key of a.keys()) { 1775 if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) { 1776 return false; 1777 } 1778 } 1779 break; 1780 } 1781 case void 0: 1782 case Object: 1783 if (size(a) !== size(b)) { 1784 return false; 1785 } 1786 for (const key in a) { 1787 if (!hasProperty(a, key) || !equalityDeep(a[key], b[key])) { 1788 return false; 1789 } 1790 } 1791 break; 1792 case Array: 1793 if (a.length !== b.length) { 1794 return false; 1795 } 1796 for (let i = 0; i < a.length; i++) { 1797 if (!equalityDeep(a[i], b[i])) { 1798 return false; 1799 } 1800 } 1801 break; 1802 default: 1803 return false; 1804 } 1805 return true; 1806 }; 1807 var isOneOf = (value, options) => options.includes(value); 1808 1809 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/environment.js 1810 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]"; 1811 var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; 1812 var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; 1813 var params; 1814 var args = []; 1815 var computeParams = () => { 1816 if (params === void 0) { 1817 if (isNode) { 1818 params = create(); 1819 const pargs = process.argv; 1820 let currParamName = null; 1821 for (let i = 0; i < pargs.length; i++) { 1822 const parg = pargs[i]; 1823 if (parg[0] === "-") { 1824 if (currParamName !== null) { 1825 params.set(currParamName, ""); 1826 } 1827 currParamName = parg; 1828 } else { 1829 if (currParamName !== null) { 1830 params.set(currParamName, parg); 1831 currParamName = null; 1832 } else { 1833 args.push(parg); 1834 } 1835 } 1836 } 1837 if (currParamName !== null) { 1838 params.set(currParamName, ""); 1839 } 1840 } else if (typeof location === "object") { 1841 params = create(); 1842 (location.search || "?").slice(1).split("&").forEach((kv) => { 1843 if (kv.length !== 0) { 1844 const [key, value] = kv.split("="); 1845 params.set(`--$fromCamelCase(key, "-")}`, value); 1846 params.set(`-$fromCamelCase(key, "-")}`, value); 1847 } 1848 }); 1849 } else { 1850 params = create(); 1851 } 1852 } 1853 return params; 1854 }; 1855 var hasParam = (name) => computeParams().has(name); 1856 var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); 1857 var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; 1858 var production = hasConf("production"); 1859 var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); 1860 var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors 1861 !hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); 1862 1863 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/buffer.js 1864 var createUint8ArrayFromLen = (len) => new Uint8Array(len); 1865 var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length2) => new Uint8Array(buffer, byteOffset, length2); 1866 var toBase64Browser = (bytes) => { 1867 let s = ""; 1868 for (let i = 0; i < bytes.byteLength; i++) { 1869 s += fromCharCode(bytes[i]); 1870 } 1871 return btoa(s); 1872 }; 1873 var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); 1874 var fromBase64Browser = (s) => { 1875 const a = atob(s); 1876 const bytes = createUint8ArrayFromLen(a.length); 1877 for (let i = 0; i < a.length; i++) { 1878 bytes[i] = a.charCodeAt(i); 1879 } 1880 return bytes; 1881 }; 1882 var fromBase64Node = (s) => { 1883 const buf = Buffer.from(s, "base64"); 1884 return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); 1885 }; 1886 var toBase64 = isBrowser ? toBase64Browser : toBase64Node; 1887 var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; 1888 var copyUint8Array = (uint8Array) => { 1889 const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); 1890 newBuf.set(uint8Array); 1891 return newBuf; 1892 }; 1893 1894 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/pair.js 1895 var Pair = class { 1896 /** 1897 * @param {L} left 1898 * @param {R} right 1899 */ 1900 constructor(left, right) { 1901 this.left = left; 1902 this.right = right; 1903 } 1904 }; 1905 var create5 = (left, right) => new Pair(left, right); 1906 1907 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/prng.js 1908 var bool = (gen) => gen.next() >= 0.5; 1909 var int53 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); 1910 var int32 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); 1911 var int31 = (gen, min2, max2) => int32(gen, min2, max2); 1912 var letter = (gen) => fromCharCode(int31(gen, 97, 122)); 1913 var word = (gen, minLen = 0, maxLen = 20) => { 1914 const len = int31(gen, minLen, maxLen); 1915 let str = ""; 1916 for (let i = 0; i < len; i++) { 1917 str += letter(gen); 1918 } 1919 return str; 1920 }; 1921 var oneOf = (gen, array) => array[int31(gen, 0, array.length - 1)]; 1922 1923 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/schema.js 1924 var schemaSymbol = /* @__PURE__ */ Symbol("0schema"); 1925 var ValidationError = class { 1926 constructor() { 1927 this._rerrs = []; 1928 } 1929 /** 1930 * @param {string?} path 1931 * @param {string} expected 1932 * @param {string} has 1933 * @param {string?} message 1934 */ 1935 extend(path, expected, has, message = null) { 1936 this._rerrs.push({ path, expected, has, message }); 1937 } 1938 toString() { 1939 const s = []; 1940 for (let i = this._rerrs.length - 1; i > 0; i--) { 1941 const r2 = this._rerrs[i]; 1942 s.push(repeat(" ", (this._rerrs.length - i) * 2) + `$r2.path != null ? `[$r2.path}] ` : ""}$r2.has} doesn't match $r2.expected}. $r2.message}`); 1943 } 1944 return s.join("\n"); 1945 } 1946 }; 1947 var shapeExtends = (a, b) => { 1948 if (a === b) return true; 1949 if (a == null || b == null || a.constructor !== b.constructor) return false; 1950 if (a[EqualityTraitSymbol]) return equals(a, b); 1951 if (isArray(a)) { 1952 return every( 1953 a, 1954 (aitem) => some(b, (bitem) => shapeExtends(aitem, bitem)) 1955 ); 1956 } else if (isObject(a)) { 1957 return every2( 1958 a, 1959 (aitem, akey) => shapeExtends(aitem, b[akey]) 1960 ); 1961 } 1962 return false; 1963 }; 1964 var Schema = class { 1965 // this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore 1966 /** 1967 * If true, the more things are added to the shape the more objects this schema will accept (e.g. 1968 * union). By default, the more objects are added, the the fewer objects this schema will accept. 1969 * @protected 1970 */ 1971 static _dilutes = false; 1972 /** 1973 * @param {Schema<any>} other 1974 */ 1975 extends(other) { 1976 let [a, b] = [ 1977 /** @type {any} */ 1978 this.shape, 1979 /** @type {any} */ 1980 other.shape 1981 ]; 1982 if ( 1983 /** @type {typeof Schema<any>} */ 1984 this.constructor._dilutes 1985 ) [b, a] = [a, b]; 1986 return shapeExtends(a, b); 1987 } 1988 /** 1989 * Overwrite this when necessary. By default, we only check the `shape` property which every shape 1990 * should have. 1991 * @param {Schema<any>} other 1992 */ 1993 equals(other) { 1994 return this.constructor === other.constructor && equalityDeep(this.shape, other.shape); 1995 } 1996 [schemaSymbol]() { 1997 return true; 1998 } 1999 /** 2000 * @param {object} other 2001 */ 2002 [EqualityTraitSymbol](other) { 2003 return this.equals( 2004 /** @type {any} */ 2005 other 2006 ); 2007 } 2008 /** 2009 * Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of 2010 * Schema. Validate will check the structure of the parameter and return true iff the instance 2011 * really is an instance of Schema. 2012 * 2013 * @param {T} o 2014 * @return {boolean} 2015 */ 2016 validate(o) { 2017 return this.check(o); 2018 } 2019 /* c8 ignore start */ 2020 /** 2021 * Similar to validate, but this method accepts untyped parameters. 2022 * 2023 * @param {any} _o 2024 * @param {ValidationError} [_err] 2025 * @return {_o is T} 2026 */ 2027 check(_o, _err) { 2028 methodUnimplemented(); 2029 } 2030 /* c8 ignore stop */ 2031 /** 2032 * @type {Schema<T?>} 2033 */ 2034 get nullable() { 2035 return $union(this, $null); 2036 } 2037 /** 2038 * @type {$Optional<Schema<T>>} 2039 */ 2040 get optional() { 2041 return new $Optional( 2042 /** @type {Schema<T>} */ 2043 this 2044 ); 2045 } 2046 /** 2047 * Cast a variable to a specific type. Returns the casted value, or throws an exception otherwise. 2048 * Use this if you know that the type is of a specific type and you just want to convince the type 2049 * system. 2050 * 2051 * **Do not rely on these error messages!** 2052 * Performs an assertion check only if not in a production environment. 2053 * 2054 * @template OO 2055 * @param {OO} o 2056 * @return {Extract<OO, T> extends never ? T : (OO extends Array<never> ? T : Extract<OO,T>)} 2057 */ 2058 cast(o) { 2059 assert(o, this); 2060 return ( 2061 /** @type {any} */ 2062 o 2063 ); 2064 } 2065 /** 2066 * EXPECTO PATRONUM!! 🪄 2067 * This function protects against type errors. Though it may not work in the real world. 2068 * 2069 * "After all this time?" 2070 * "Always." - Snape, talking about type safety 2071 * 2072 * Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed. 2073 * Use this if you know that the type is of a specific type and you just want to convince the type 2074 * system. 2075 * 2076 * Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).expect((n) => n + 1)` 2077 * 2078 * **Do not rely on these error messages!** 2079 * Performs an assertion check if not in a production environment. 2080 * 2081 * @param {T} o 2082 * @return {o extends T ? T : never} 2083 */ 2084 expect(o) { 2085 assert(o, this); 2086 return o; 2087 } 2088 }; 2089 var $ConstructedBy = class extends Schema { 2090 /** 2091 * @param {C} c 2092 * @param {((o:Instance<C>)=>boolean)|null} check 2093 */ 2094 constructor(c, check) { 2095 super(); 2096 this.shape = c; 2097 this._c = check; 2098 } 2099 /** 2100 * @param {any} o 2101 * @param {ValidationError} [err] 2102 * @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType<C> : never)} o 2103 */ 2104 check(o, err = void 0) { 2105 const c = o?.constructor === this.shape && (this._c == null || this._c(o)); 2106 !c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? "Constructor match failed" : "Check failed"); 2107 return c; 2108 } 2109 }; 2110 var $constructedBy = (c, check = null) => new $ConstructedBy(c, check); 2111 var $$constructedBy = $constructedBy($ConstructedBy); 2112 var $Custom = class extends Schema { 2113 /** 2114 * @param {(o:any) => boolean} check 2115 */ 2116 constructor(check) { 2117 super(); 2118 this.shape = check; 2119 } 2120 /** 2121 * @param {any} o 2122 * @param {ValidationError} err 2123 * @return {o is any} 2124 */ 2125 check(o, err) { 2126 const c = this.shape(o); 2127 !c && err?.extend(null, "custom prop", o?.constructor.name, "failed to check custom prop"); 2128 return c; 2129 } 2130 }; 2131 var $custom = (check) => new $Custom(check); 2132 var $$custom = $constructedBy($Custom); 2133 var $Literal = class extends Schema { 2134 /** 2135 * @param {Array<T>} literals 2136 */ 2137 constructor(literals) { 2138 super(); 2139 this.shape = literals; 2140 } 2141 /** 2142 * 2143 * @param {any} o 2144 * @param {ValidationError} [err] 2145 * @return {o is T} 2146 */ 2147 check(o, err) { 2148 const c = this.shape.some((a) => a === o); 2149 !c && err?.extend(null, this.shape.join(" | "), o.toString()); 2150 return c; 2151 } 2152 }; 2153 var $literal = (...literals) => new $Literal(literals); 2154 var $$literal = $constructedBy($Literal); 2155 var _regexEscape = ( 2156 /** @type {any} */ 2157 RegExp.escape || /** @type {(str:string) => string} */ 2158 ((str) => str.replace(/[().|&,$^[\]]/g, (s) => "\\" + s)) 2159 ); 2160 var _schemaStringTemplateToRegex = (s) => { 2161 if ($string.check(s)) { 2162 return [_regexEscape(s)]; 2163 } 2164 if ($$literal.check(s)) { 2165 return ( 2166 /** @type {Array<string|number>} */ 2167 s.shape.map((v) => v + "") 2168 ); 2169 } 2170 if ($$number.check(s)) { 2171 return ["[+-]?\\d+.?\\d*"]; 2172 } 2173 if ($$string.check(s)) { 2174 return [".*"]; 2175 } 2176 if ($$union.check(s)) { 2177 return s.shape.map(_schemaStringTemplateToRegex).flat(1); 2178 } 2179 unexpectedCase(); 2180 }; 2181 var $StringTemplate = class extends Schema { 2182 /** 2183 * @param {T} shape 2184 */ 2185 constructor(shape) { 2186 super(); 2187 this.shape = shape; 2188 this._r = new RegExp("^" + shape.map(_schemaStringTemplateToRegex).map((opts) => `($opts.join("|")})`).join("") + "$"); 2189 } 2190 /** 2191 * @param {any} o 2192 * @param {ValidationError} [err] 2193 * @return {o is CastStringTemplateArgsToTemplate<T>} 2194 */ 2195 check(o, err) { 2196 const c = this._r.exec(o) != null; 2197 !c && err?.extend(null, this._r.toString(), o.toString(), "String doesn't match string template."); 2198 return c; 2199 } 2200 }; 2201 var $$stringTemplate = $constructedBy($StringTemplate); 2202 var isOptionalSymbol = /* @__PURE__ */ Symbol("optional"); 2203 var $Optional = class extends Schema { 2204 /** 2205 * @param {S} shape 2206 */ 2207 constructor(shape) { 2208 super(); 2209 this.shape = shape; 2210 } 2211 /** 2212 * @param {any} o 2213 * @param {ValidationError} [err] 2214 * @return {o is (Unwrap<S>|undefined)} 2215 */ 2216 check(o, err) { 2217 const c = o === void 0 || this.shape.check(o); 2218 !c && err?.extend(null, "undefined (optional)", "()"); 2219 return c; 2220 } 2221 get [isOptionalSymbol]() { 2222 return true; 2223 } 2224 }; 2225 var $$optional = $constructedBy($Optional); 2226 var $Never = class extends Schema { 2227 /** 2228 * @param {any} _o 2229 * @param {ValidationError} [err] 2230 * @return {_o is never} 2231 */ 2232 check(_o, err) { 2233 err?.extend(null, "never", typeof _o); 2234 return false; 2235 } 2236 }; 2237 var $never = new $Never(); 2238 var $$never = $constructedBy($Never); 2239 var $Object = class _$Object extends Schema { 2240 /** 2241 * @param {S} shape 2242 * @param {boolean} partial 2243 */ 2244 constructor(shape, partial = false) { 2245 super(); 2246 this.shape = shape; 2247 this._isPartial = partial; 2248 } 2249 static _dilutes = true; 2250 /** 2251 * @type {Schema<Partial<$ObjectToType<S>>>} 2252 */ 2253 get partial() { 2254 return new _$Object(this.shape, true); 2255 } 2256 /** 2257 * @param {any} o 2258 * @param {ValidationError} err 2259 * @return {o is $ObjectToType<S>} 2260 */ 2261 check(o, err) { 2262 if (o == null) { 2263 err?.extend(null, "object", "null"); 2264 return false; 2265 } 2266 return every2(this.shape, (vv, vk) => { 2267 const c = this._isPartial && !hasProperty(o, vk) || vv.check(o[vk], err); 2268 !c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], "Object property does not match"); 2269 return c; 2270 }); 2271 } 2272 }; 2273 var $object = (def) => ( 2274 /** @type {any} */ 2275 new $Object(def) 2276 ); 2277 var $$object = $constructedBy($Object); 2278 var $objectAny = $custom((o) => o != null && (o.constructor === Object || o.constructor == null)); 2279 var $Record = class extends Schema { 2280 /** 2281 * @param {Keys} keys 2282 * @param {Values} values 2283 */ 2284 constructor(keys2, values) { 2285 super(); 2286 this.shape = { 2287 keys: keys2, 2288 values 2289 }; 2290 } 2291 /** 2292 * @param {any} o 2293 * @param {ValidationError} err 2294 * @return {o is { [key in Unwrap<Keys>]: Unwrap<Values> }} 2295 */ 2296 check(o, err) { 2297 return o != null && every2(o, (vv, vk) => { 2298 const ck = this.shape.keys.check(vk, err); 2299 !ck && err?.extend(vk + "", "Record", typeof o, ck ? "Key doesn't match schema" : "Value doesn't match value"); 2300 return ck && this.shape.values.check(vv, err); 2301 }); 2302 } 2303 }; 2304 var $record = (keys2, values) => new $Record(keys2, values); 2305 var $$record = $constructedBy($Record); 2306 var $Tuple = class extends Schema { 2307 /** 2308 * @param {S} shape 2309 */ 2310 constructor(shape) { 2311 super(); 2312 this.shape = shape; 2313 } 2314 /** 2315 * @param {any} o 2316 * @param {ValidationError} err 2317 * @return {o is { [K in keyof S]: S[K] extends Schema<infer Type> ? Type : never }} 2318 */ 2319 check(o, err) { 2320 return o != null && every2(this.shape, (vv, vk) => { 2321 const c = ( 2322 /** @type {Schema<any>} */ 2323 vv.check(o[vk], err) 2324 ); 2325 !c && err?.extend(vk.toString(), "Tuple", typeof vv); 2326 return c; 2327 }); 2328 } 2329 }; 2330 var $tuple = (...def) => new $Tuple(def); 2331 var $$tuple = $constructedBy($Tuple); 2332 var $Array = class extends Schema { 2333 /** 2334 * @param {Array<S>} v 2335 */ 2336 constructor(v) { 2337 super(); 2338 this.shape = v.length === 1 ? v[0] : new $Union(v); 2339 } 2340 /** 2341 * @param {any} o 2342 * @param {ValidationError} [err] 2343 * @return {o is Array<S extends Schema<infer T> ? T : never>} o 2344 */ 2345 check(o, err) { 2346 const c = isArray(o) && every(o, (oi) => this.shape.check(oi)); 2347 !c && err?.extend(null, "Array", ""); 2348 return c; 2349 } 2350 }; 2351 var $array = (...def) => new $Array(def); 2352 var $$array = $constructedBy($Array); 2353 var $arrayAny = $custom((o) => isArray(o)); 2354 var $InstanceOf = class extends Schema { 2355 /** 2356 * @param {new (...args:any) => T} constructor 2357 * @param {((o:T) => boolean)|null} check 2358 */ 2359 constructor(constructor, check) { 2360 super(); 2361 this.shape = constructor; 2362 this._c = check; 2363 } 2364 /** 2365 * @param {any} o 2366 * @param {ValidationError} err 2367 * @return {o is T} 2368 */ 2369 check(o, err) { 2370 const c = o instanceof this.shape && (this._c == null || this._c(o)); 2371 !c && err?.extend(null, this.shape.name, o?.constructor.name); 2372 return c; 2373 } 2374 }; 2375 var $instanceOf = (c, check = null) => new $InstanceOf(c, check); 2376 var $$instanceOf = $constructedBy($InstanceOf); 2377 var $$schema = $instanceOf(Schema); 2378 var $Lambda = class extends Schema { 2379 /** 2380 * @param {Args} args 2381 */ 2382 constructor(args2) { 2383 super(); 2384 this.len = args2.length - 1; 2385 this.args = $tuple(...args2.slice(-1)); 2386 this.res = args2[this.len]; 2387 } 2388 /** 2389 * @param {any} f 2390 * @param {ValidationError} err 2391 * @return {f is _LArgsToLambdaDef<Args>} 2392 */ 2393 check(f, err) { 2394 const c = f.constructor === Function && f.length <= this.len; 2395 !c && err?.extend(null, "function", typeof f); 2396 return c; 2397 } 2398 }; 2399 var $$lambda = $constructedBy($Lambda); 2400 var $function = $custom((o) => typeof o === "function"); 2401 var $Intersection = class extends Schema { 2402 /** 2403 * @param {T} v 2404 */ 2405 constructor(v) { 2406 super(); 2407 this.shape = v; 2408 } 2409 /** 2410 * @param {any} o 2411 * @param {ValidationError} [err] 2412 * @return {o is Intersect<UnwrapArray<T>>} 2413 */ 2414 check(o, err) { 2415 const c = every(this.shape, (check) => check.check(o, err)); 2416 !c && err?.extend(null, "Intersectinon", typeof o); 2417 return c; 2418 } 2419 }; 2420 var $$intersect = $constructedBy($Intersection, (o) => o.shape.length > 0); 2421 var $Union = class extends Schema { 2422 static _dilutes = true; 2423 /** 2424 * @param {Array<Schema<S>>} v 2425 */ 2426 constructor(v) { 2427 super(); 2428 this.shape = v; 2429 } 2430 /** 2431 * @param {any} o 2432 * @param {ValidationError} [err] 2433 * @return {o is S} 2434 */ 2435 check(o, err) { 2436 const c = some(this.shape, (vv) => vv.check(o, err)); 2437 err?.extend(null, "Union", typeof o); 2438 return c; 2439 } 2440 }; 2441 var $union = (...schemas) => schemas.findIndex(($s) => $$union.check($s)) >= 0 ? $union(...schemas.map(($s) => $($s)).map(($s) => $$union.check($s) ? $s.shape : [$s]).flat(1)) : schemas.length === 1 ? schemas[0] : new $Union(schemas); 2442 var $$union = ( 2443 /** @type {Schema<$Union<any>>} */ 2444 $constructedBy($Union) 2445 ); 2446 var _t = () => true; 2447 var $any = $custom(_t); 2448 var $$any = ( 2449 /** @type {Schema<Schema<any>>} */ 2450 $constructedBy($Custom, (o) => o.shape === _t) 2451 ); 2452 var $bigint = $custom((o) => typeof o === "bigint"); 2453 var $$bigint = ( 2454 /** @type {Schema<Schema<BigInt>>} */ 2455 $custom((o) => o === $bigint) 2456 ); 2457 var $symbol = $custom((o) => typeof o === "symbol"); 2458 var $$symbol = ( 2459 /** @type {Schema<Schema<Symbol>>} */ 2460 $custom((o) => o === $symbol) 2461 ); 2462 var $number = $custom((o) => typeof o === "number"); 2463 var $$number = ( 2464 /** @type {Schema<Schema<number>>} */ 2465 $custom((o) => o === $number) 2466 ); 2467 var $string = $custom((o) => typeof o === "string"); 2468 var $$string = ( 2469 /** @type {Schema<Schema<string>>} */ 2470 $custom((o) => o === $string) 2471 ); 2472 var $boolean = $custom((o) => typeof o === "boolean"); 2473 var $$boolean = ( 2474 /** @type {Schema<Schema<Boolean>>} */ 2475 $custom((o) => o === $boolean) 2476 ); 2477 var $undefined = $literal(void 0); 2478 var $$undefined = ( 2479 /** @type {Schema<Schema<undefined>>} */ 2480 $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === void 0) 2481 ); 2482 var $void = $literal(void 0); 2483 var $null = $literal(null); 2484 var $$null = ( 2485 /** @type {Schema<Schema<null>>} */ 2486 $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === null) 2487 ); 2488 var $uint8Array = $constructedBy(Uint8Array); 2489 var $$uint8Array = ( 2490 /** @type {Schema<Schema<Uint8Array>>} */ 2491 $constructedBy($ConstructedBy, (o) => o.shape === Uint8Array) 2492 ); 2493 var $primitive = $union($number, $string, $null, $undefined, $bigint, $boolean, $symbol); 2494 var $json = (() => { 2495 const $jsonArr = ( 2496 /** @type {$Array<$any>} */ 2497 $array($any) 2498 ); 2499 const $jsonRecord = ( 2500 /** @type {$Record<$string,$any>} */ 2501 $record($string, $any) 2502 ); 2503 const $json2 = $union($number, $string, $null, $boolean, $jsonArr, $jsonRecord); 2504 $jsonArr.shape = $json2; 2505 $jsonRecord.shape.values = $json2; 2506 return $json2; 2507 })(); 2508 var $ = (o) => { 2509 if ($$schema.check(o)) { 2510 return ( 2511 /** @type {any} */ 2512 o 2513 ); 2514 } else if ($objectAny.check(o)) { 2515 const o2 = {}; 2516 for (const k in o) { 2517 o2[k] = $(o[k]); 2518 } 2519 return ( 2520 /** @type {any} */ 2521 $object(o2) 2522 ); 2523 } else if ($arrayAny.check(o)) { 2524 return ( 2525 /** @type {any} */ 2526 $union(...o.map($)) 2527 ); 2528 } else if ($primitive.check(o)) { 2529 return ( 2530 /** @type {any} */ 2531 $literal(o) 2532 ); 2533 } else if ($function.check(o)) { 2534 return ( 2535 /** @type {any} */ 2536 $constructedBy( 2537 /** @type {any} */ 2538 o 2539 ) 2540 ); 2541 } 2542 unexpectedCase(); 2543 }; 2544 var assert = production ? () => { 2545 } : (o, schema) => { 2546 const err = new ValidationError(); 2547 if (!schema.check(o, err)) { 2548 throw create3(`Expected value to be of type $schema.constructor.name}. 2549 $err.toString()}`); 2550 } 2551 }; 2552 var PatternMatcher = class { 2553 /** 2554 * @param {Schema<State>} [$state] 2555 */ 2556 constructor($state) { 2557 this.patterns = []; 2558 this.$state = $state; 2559 } 2560 /** 2561 * @template P 2562 * @template R 2563 * @param {P} pattern 2564 * @param {(o:NoInfer<Unwrap<ReadSchema<P>>>,s:State)=>R} handler 2565 * @return {PatternMatcher<State,Patterns|Pattern<Unwrap<ReadSchema<P>>,R>>} 2566 */ 2567 if(pattern, handler) { 2568 this.patterns.push({ if: $(pattern), h: handler }); 2569 return this; 2570 } 2571 /** 2572 * @template R 2573 * @param {(o:any,s:State)=>R} h 2574 */ 2575 else(h) { 2576 return this.if($any, h); 2577 } 2578 /** 2579 * @return {State extends undefined 2580 * ? <In extends Unwrap<Patterns['if']>>(o:In,state?:undefined)=>PatternMatchResult<Patterns,In> 2581 * : <In extends Unwrap<Patterns['if']>>(o:In,state:State)=>PatternMatchResult<Patterns,In>} 2582 */ 2583 done() { 2584 return ( 2585 /** @type {any} */ 2586 (o, s) => { 2587 for (let i = 0; i < this.patterns.length; i++) { 2588 const p = this.patterns[i]; 2589 if (p.if.check(o)) { 2590 return p.h(o, s); 2591 } 2592 } 2593 throw create3("Unhandled pattern"); 2594 } 2595 ); 2596 } 2597 }; 2598 var match = (state) => new PatternMatcher( 2599 /** @type {any} */ 2600 state 2601 ); 2602 var _random = ( 2603 /** @type {any} */ 2604 match( 2605 /** @type {Schema<prng.PRNG>} */ 2606 $any 2607 ).if($$number, (_o, gen) => int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER)).if($$string, (_o, gen) => word(gen)).if($$boolean, (_o, gen) => bool(gen)).if($$bigint, (_o, gen) => BigInt(int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER))).if($$union, (o, gen) => random(gen, oneOf(gen, o.shape))).if($$object, (o, gen) => { 2608 const res = {}; 2609 for (const k in o.shape) { 2610 let prop = o.shape[k]; 2611 if ($$optional.check(prop)) { 2612 if (bool(gen)) { 2613 continue; 2614 } 2615 prop = prop.shape; 2616 } 2617 res[k] = _random(prop, gen); 2618 } 2619 return res; 2620 }).if($$array, (o, gen) => { 2621 const arr = []; 2622 const n = int32(gen, 0, 42); 2623 for (let i = 0; i < n; i++) { 2624 arr.push(random(gen, o.shape)); 2625 } 2626 return arr; 2627 }).if($$literal, (o, gen) => { 2628 return oneOf(gen, o.shape); 2629 }).if($$null, (o, gen) => { 2630 return null; 2631 }).if($$lambda, (o, gen) => { 2632 const res = random(gen, o.res); 2633 return () => res; 2634 }).if($$any, (o, gen) => random(gen, oneOf(gen, [ 2635 $number, 2636 $string, 2637 $null, 2638 $undefined, 2639 $bigint, 2640 $boolean, 2641 $array($number), 2642 $record($union("a", "b", "c"), $number) 2643 ]))).if($$record, (o, gen) => { 2644 const res = {}; 2645 const keysN = int53(gen, 0, 3); 2646 for (let i = 0; i < keysN; i++) { 2647 const key = random(gen, o.shape.keys); 2648 const val = random(gen, o.shape.values); 2649 res[key] = val; 2650 } 2651 return res; 2652 }).done() 2653 ); 2654 var random = (gen, schema) => ( 2655 /** @type {any} */ 2656 _random($(schema), gen) 2657 ); 2658 2659 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/dom.js 2660 var doc = ( 2661 /** @type {Document} */ 2662 typeof document !== "undefined" ? document : {} 2663 ); 2664 var $fragment = $custom((el) => el.nodeType === DOCUMENT_FRAGMENT_NODE); 2665 var domParser = ( 2666 /** @type {DOMParser} */ 2667 typeof DOMParser !== "undefined" ? new DOMParser() : null 2668 ); 2669 var $element = $custom((el) => el.nodeType === ELEMENT_NODE); 2670 var $text = $custom((el) => el.nodeType === TEXT_NODE); 2671 var mapToStyleString = (m) => map(m, (value, key) => `$key}:$value};`).join(""); 2672 var ELEMENT_NODE = doc.ELEMENT_NODE; 2673 var TEXT_NODE = doc.TEXT_NODE; 2674 var CDATA_SECTION_NODE = doc.CDATA_SECTION_NODE; 2675 var COMMENT_NODE = doc.COMMENT_NODE; 2676 var DOCUMENT_NODE = doc.DOCUMENT_NODE; 2677 var DOCUMENT_TYPE_NODE = doc.DOCUMENT_TYPE_NODE; 2678 var DOCUMENT_FRAGMENT_NODE = doc.DOCUMENT_FRAGMENT_NODE; 2679 var $node = $custom((el) => el.nodeType === DOCUMENT_NODE); 2680 2681 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/symbol.js 2682 var create6 = Symbol; 2683 2684 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/logging.common.js 2685 var BOLD = create6(); 2686 var UNBOLD = create6(); 2687 var BLUE = create6(); 2688 var GREY = create6(); 2689 var GREEN = create6(); 2690 var RED = create6(); 2691 var PURPLE = create6(); 2692 var ORANGE = create6(); 2693 var UNCOLOR = create6(); 2694 var computeNoColorLoggingArgs = (args2) => { 2695 if (args2.length === 1 && args2[0]?.constructor === Function) { 2696 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2697 /** @type {[function]} */ 2698 args2[0](); 2699 } 2700 const strBuilder = []; 2701 const logArgs = []; 2702 let i = 0; 2703 for (; i < args2.length; i++) { 2704 const arg = args2[i]; 2705 if (arg === void 0) { 2706 break; 2707 } else if (arg.constructor === String || arg.constructor === Number) { 2708 strBuilder.push(arg); 2709 } else if (arg.constructor === Object) { 2710 break; 2711 } 2712 } 2713 if (i > 0) { 2714 logArgs.push(strBuilder.join("")); 2715 } 2716 for (; i < args2.length; i++) { 2717 const arg = args2[i]; 2718 if (!(arg instanceof Symbol)) { 2719 logArgs.push(arg); 2720 } 2721 } 2722 return logArgs; 2723 }; 2724 var lastLoggingTime = getUnixTime(); 2725 2726 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/logging.js 2727 var _browserStyleMap = { 2728 [BOLD]: create5("font-weight", "bold"), 2729 [UNBOLD]: create5("font-weight", "normal"), 2730 [BLUE]: create5("color", "blue"), 2731 [GREEN]: create5("color", "green"), 2732 [GREY]: create5("color", "grey"), 2733 [RED]: create5("color", "red"), 2734 [PURPLE]: create5("color", "purple"), 2735 [ORANGE]: create5("color", "orange"), 2736 // not well supported in chrome when debugging node with inspector - TODO: deprecate 2737 [UNCOLOR]: create5("color", "black") 2738 }; 2739 var computeBrowserLoggingArgs = (args2) => { 2740 if (args2.length === 1 && args2[0]?.constructor === Function) { 2741 args2 = /** @type {Array<string|Symbol|Object|number>} */ 2742 /** @type {[function]} */ 2743 args2[0](); 2744 } 2745 const strBuilder = []; 2746 const styles = []; 2747 const currentStyle = create(); 2748 let logArgs = []; 2749 let i = 0; 2750 for (; i < args2.length; i++) { 2751 const arg = args2[i]; 2752 const style = _browserStyleMap[arg]; 2753 if (style !== void 0) { 2754 currentStyle.set(style.left, style.right); 2755 } else { 2756 if (arg === void 0) { 2757 break; 2758 } 2759 if (arg.constructor === String || arg.constructor === Number) { 2760 const style2 = mapToStyleString(currentStyle); 2761 if (i > 0 || style2.length > 0) { 2762 strBuilder.push("%c" + arg); 2763 styles.push(style2); 2764 } else { 2765 strBuilder.push(arg); 2766 } 2767 } else { 2768 break; 2769 } 2770 } 2771 } 2772 if (i > 0) { 2773 logArgs = styles; 2774 logArgs.unshift(strBuilder.join("")); 2775 } 2776 for (; i < args2.length; i++) { 2777 const arg = args2[i]; 2778 if (!(arg instanceof Symbol)) { 2779 logArgs.push(arg); 2780 } 2781 } 2782 return logArgs; 2783 }; 2784 var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; 2785 var print = (...args2) => { 2786 console.log(...computeLoggingArgs(args2)); 2787 vconsoles.forEach((vc) => vc.print(args2)); 2788 }; 2789 var warn = (...args2) => { 2790 console.warn(...computeLoggingArgs(args2)); 2791 args2.unshift(ORANGE); 2792 vconsoles.forEach((vc) => vc.print(args2)); 2793 }; 2794 var vconsoles = create2(); 2795 2796 // node_modules/.store/lib0@0.2.117-AWthJenbqlRhwK8dg2Xkww/node_modules/lib0/iterator.js 2797 var createIterator = (next) => ({ 2798 /** 2799 * @return {IterableIterator<T>} 2800 */ 2801 [Symbol.iterator]() { 2802 return this; 2803 }, 2804 // @ts-ignore 2805 next 2806 }); 2807 var iteratorFilter = (iterator, filter) => createIterator(() => { 2808 let res; 2809 do { 2810 res = iterator.next(); 2811 } while (!res.done && !filter(res.value)); 2812 return res; 2813 }); 2814 var iteratorMap = (iterator, fmap) => createIterator(() => { 2815 const { done, value } = iterator.next(); 2816 return { done, value: done ? void 0 : fmap(value) }; 2817 }); 2818 2819 // node_modules/.store/yjs@13.6.29-TJYJpNVE3l2_hFsy5BI5FA/node_modules/yjs/dist/yjs.mjs 2820 var AbstractConnector = class extends ObservableV2 { 2821 /** 2822 * @param {Doc} ydoc 2823 * @param {any} awareness 2824 */ 2825 constructor(ydoc, awareness) { 2826 super(); 2827 this.doc = ydoc; 2828 this.awareness = awareness; 2829 } 2830 }; 2831 var DeleteItem = class { 2832 /** 2833 * @param {number} clock 2834 * @param {number} len 2835 */ 2836 constructor(clock, len) { 2837 this.clock = clock; 2838 this.len = len; 2839 } 2840 }; 2841 var DeleteSet = class { 2842 constructor() { 2843 this.clients = /* @__PURE__ */ new Map(); 2844 } 2845 }; 2846 var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { 2847 const structs = ( 2848 /** @type {Array<GC|Item>} */ 2849 transaction.doc.store.clients.get(clientid) 2850 ); 2851 if (structs != null) { 2852 const lastStruct = structs[structs.length - 1]; 2853 const clockState = lastStruct.id.clock + lastStruct.length; 2854 for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) { 2855 iterateStructs(transaction, structs, del.clock, del.len, f); 2856 } 2857 } 2858 }); 2859 var findIndexDS = (dis, clock) => { 2860 let left = 0; 2861 let right = dis.length - 1; 2862 while (left <= right) { 2863 const midindex = floor((left + right) / 2); 2864 const mid = dis[midindex]; 2865 const midclock = mid.clock; 2866 if (midclock <= clock) { 2867 if (clock < midclock + mid.len) { 2868 return midindex; 2869 } 2870 left = midindex + 1; 2871 } else { 2872 right = midindex - 1; 2873 } 2874 } 2875 return null; 2876 }; 2877 var isDeleted = (ds, id2) => { 2878 const dis = ds.clients.get(id2.client); 2879 return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; 2880 }; 2881 var sortAndMergeDeleteSet = (ds) => { 2882 ds.clients.forEach((dels) => { 2883 dels.sort((a, b) => a.clock - b.clock); 2884 let i, j; 2885 for (i = 1, j = 1; i < dels.length; i++) { 2886 const left = dels[j - 1]; 2887 const right = dels[i]; 2888 if (left.clock + left.len >= right.clock) { 2889 left.len = max(left.len, right.clock + right.len - left.clock); 2890 } else { 2891 if (j < i) { 2892 dels[j] = right; 2893 } 2894 j++; 2895 } 2896 } 2897 dels.length = j; 2898 }); 2899 }; 2900 var mergeDeleteSets = (dss) => { 2901 const merged = new DeleteSet(); 2902 for (let dssI = 0; dssI < dss.length; dssI++) { 2903 dss[dssI].clients.forEach((delsLeft, client) => { 2904 if (!merged.clients.has(client)) { 2905 const dels = delsLeft.slice(); 2906 for (let i = dssI + 1; i < dss.length; i++) { 2907 appendTo(dels, dss[i].clients.get(client) || []); 2908 } 2909 merged.clients.set(client, dels); 2910 } 2911 }); 2912 } 2913 sortAndMergeDeleteSet(merged); 2914 return merged; 2915 }; 2916 var addToDeleteSet = (ds, client, clock, length2) => { 2917 setIfUndefined(ds.clients, client, () => ( 2918 /** @type {Array<DeleteItem>} */ 2919 [] 2920 )).push(new DeleteItem(clock, length2)); 2921 }; 2922 var createDeleteSet = () => new DeleteSet(); 2923 var createDeleteSetFromStructStore = (ss) => { 2924 const ds = createDeleteSet(); 2925 ss.clients.forEach((structs, client) => { 2926 const dsitems = []; 2927 for (let i = 0; i < structs.length; i++) { 2928 const struct = structs[i]; 2929 if (struct.deleted) { 2930 const clock = struct.id.clock; 2931 let len = struct.length; 2932 if (i + 1 < structs.length) { 2933 for (let next = structs[i + 1]; i + 1 < structs.length && next.deleted; next = structs[++i + 1]) { 2934 len += next.length; 2935 } 2936 } 2937 dsitems.push(new DeleteItem(clock, len)); 2938 } 2939 } 2940 if (dsitems.length > 0) { 2941 ds.clients.set(client, dsitems); 2942 } 2943 }); 2944 return ds; 2945 }; 2946 var writeDeleteSet = (encoder, ds) => { 2947 writeVarUint(encoder.restEncoder, ds.clients.size); 2948 from(ds.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, dsitems]) => { 2949 encoder.resetDsCurVal(); 2950 writeVarUint(encoder.restEncoder, client); 2951 const len = dsitems.length; 2952 writeVarUint(encoder.restEncoder, len); 2953 for (let i = 0; i < len; i++) { 2954 const item = dsitems[i]; 2955 encoder.writeDsClock(item.clock); 2956 encoder.writeDsLen(item.len); 2957 } 2958 }); 2959 }; 2960 var readDeleteSet = (decoder) => { 2961 const ds = new DeleteSet(); 2962 const numClients = readVarUint(decoder.restDecoder); 2963 for (let i = 0; i < numClients; i++) { 2964 decoder.resetDsCurVal(); 2965 const client = readVarUint(decoder.restDecoder); 2966 const numberOfDeletes = readVarUint(decoder.restDecoder); 2967 if (numberOfDeletes > 0) { 2968 const dsField = setIfUndefined(ds.clients, client, () => ( 2969 /** @type {Array<DeleteItem>} */ 2970 [] 2971 )); 2972 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2973 dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); 2974 } 2975 } 2976 } 2977 return ds; 2978 }; 2979 var readAndApplyDeleteSet = (decoder, transaction, store2) => { 2980 const unappliedDS = new DeleteSet(); 2981 const numClients = readVarUint(decoder.restDecoder); 2982 for (let i = 0; i < numClients; i++) { 2983 decoder.resetDsCurVal(); 2984 const client = readVarUint(decoder.restDecoder); 2985 const numberOfDeletes = readVarUint(decoder.restDecoder); 2986 const structs = store2.clients.get(client) || []; 2987 const state = getState(store2, client); 2988 for (let i2 = 0; i2 < numberOfDeletes; i2++) { 2989 const clock = decoder.readDsClock(); 2990 const clockEnd = clock + decoder.readDsLen(); 2991 if (clock < state) { 2992 if (state < clockEnd) { 2993 addToDeleteSet(unappliedDS, client, state, clockEnd - state); 2994 } 2995 let index = findIndexSS(structs, clock); 2996 let struct = structs[index]; 2997 if (!struct.deleted && struct.id.clock < clock) { 2998 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 2999 index++; 3000 } 3001 while (index < structs.length) { 3002 struct = structs[index++]; 3003 if (struct.id.clock < clockEnd) { 3004 if (!struct.deleted) { 3005 if (clockEnd < struct.id.clock + struct.length) { 3006 structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); 3007 } 3008 struct.delete(transaction); 3009 } 3010 } else { 3011 break; 3012 } 3013 } 3014 } else { 3015 addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); 3016 } 3017 } 3018 } 3019 if (unappliedDS.clients.size > 0) { 3020 const ds = new UpdateEncoderV2(); 3021 writeVarUint(ds.restEncoder, 0); 3022 writeDeleteSet(ds, unappliedDS); 3023 return ds.toUint8Array(); 3024 } 3025 return null; 3026 }; 3027 var equalDeleteSets = (ds1, ds2) => { 3028 if (ds1.clients.size !== ds2.clients.size) return false; 3029 for (const [client, deleteItems1] of ds1.clients.entries()) { 3030 const deleteItems2 = ( 3031 /** @type {Array<import('../internals.js').DeleteItem>} */ 3032 ds2.clients.get(client) 3033 ); 3034 if (deleteItems2 === void 0 || deleteItems1.length !== deleteItems2.length) return false; 3035 for (let i = 0; i < deleteItems1.length; i++) { 3036 const di1 = deleteItems1[i]; 3037 const di2 = deleteItems2[i]; 3038 if (di1.clock !== di2.clock || di1.len !== di2.len) { 3039 return false; 3040 } 3041 } 3042 } 3043 return true; 3044 }; 3045 var generateNewClientId = uint32; 3046 var Doc = class _Doc extends ObservableV2 { 3047 /** 3048 * @param {DocOpts} opts configuration 3049 */ 3050 constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { 3051 super(); 3052 this.gc = gc; 3053 this.gcFilter = gcFilter; 3054 this.clientID = generateNewClientId(); 3055 this.guid = guid; 3056 this.collectionid = collectionid; 3057 this.share = /* @__PURE__ */ new Map(); 3058 this.store = new StructStore(); 3059 this._transaction = null; 3060 this._transactionCleanups = []; 3061 this.subdocs = /* @__PURE__ */ new Set(); 3062 this._item = null; 3063 this.shouldLoad = shouldLoad; 3064 this.autoLoad = autoLoad; 3065 this.meta = meta; 3066 this.isLoaded = false; 3067 this.isSynced = false; 3068 this.isDestroyed = false; 3069 this.whenLoaded = create4((resolve) => { 3070 this.on("load", () => { 3071 this.isLoaded = true; 3072 resolve(this); 3073 }); 3074 }); 3075 const provideSyncedPromise = () => create4((resolve) => { 3076 const eventHandler = (isSynced) => { 3077 if (isSynced === void 0 || isSynced === true) { 3078 this.off("sync", eventHandler); 3079 resolve(); 3080 } 3081 }; 3082 this.on("sync", eventHandler); 3083 }); 3084 this.on("sync", (isSynced) => { 3085 if (isSynced === false && this.isSynced) { 3086 this.whenSynced = provideSyncedPromise(); 3087 } 3088 this.isSynced = isSynced === void 0 || isSynced === true; 3089 if (this.isSynced && !this.isLoaded) { 3090 this.emit("load", [this]); 3091 } 3092 }); 3093 this.whenSynced = provideSyncedPromise(); 3094 } 3095 /** 3096 * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). 3097 * 3098 * `load()` might be used in the future to request any provider to load the most current data. 3099 * 3100 * It is safe to call `load()` multiple times. 3101 */ 3102 load() { 3103 const item = this._item; 3104 if (item !== null && !this.shouldLoad) { 3105 transact( 3106 /** @type {any} */ 3107 item.parent.doc, 3108 (transaction) => { 3109 transaction.subdocsLoaded.add(this); 3110 }, 3111 null, 3112 true 3113 ); 3114 } 3115 this.shouldLoad = true; 3116 } 3117 getSubdocs() { 3118 return this.subdocs; 3119 } 3120 getSubdocGuids() { 3121 return new Set(from(this.subdocs).map((doc2) => doc2.guid)); 3122 } 3123 /** 3124 * Changes that happen inside of a transaction are bundled. This means that 3125 * the observer fires _after_ the transaction is finished and that all changes 3126 * that happened inside of the transaction are sent as one message to the 3127 * other peers. 3128 * 3129 * @template T 3130 * @param {function(Transaction):T} f The function that should be executed as a transaction 3131 * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin 3132 * @return T 3133 * 3134 * @public 3135 */ 3136 transact(f, origin2 = null) { 3137 return transact(this, f, origin2); 3138 } 3139 /** 3140 * Define a shared data type. 3141 * 3142 * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result 3143 * and do not overwrite each other. I.e. 3144 * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` 3145 * 3146 * After this method is called, the type is also available on `ydoc.share.get(name)`. 3147 * 3148 * *Best Practices:* 3149 * Define all types right after the Y.Doc instance is created and store them in a separate object. 3150 * Also use the typed methods `getText(name)`, `getArray(name)`, .. 3151 * 3152 * @template {typeof AbstractType<any>} Type 3153 * @example 3154 * const ydoc = new Y.Doc(..) 3155 * const appState = { 3156 * document: ydoc.getText('document') 3157 * comments: ydoc.getArray('comments') 3158 * } 3159 * 3160 * @param {string} name 3161 * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... 3162 * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor 3163 * 3164 * @public 3165 */ 3166 get(name, TypeConstructor = ( 3167 /** @type {any} */ 3168 AbstractType 3169 )) { 3170 const type = setIfUndefined(this.share, name, () => { 3171 const t = new TypeConstructor(); 3172 t._integrate(this, null); 3173 return t; 3174 }); 3175 const Constr = type.constructor; 3176 if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { 3177 if (Constr === AbstractType) { 3178 const t = new TypeConstructor(); 3179 t._map = type._map; 3180 type._map.forEach( 3181 /** @param {Item?} n */ 3182 (n) => { 3183 for (; n !== null; n = n.left) { 3184 n.parent = t; 3185 } 3186 } 3187 ); 3188 t._start = type._start; 3189 for (let n = t._start; n !== null; n = n.right) { 3190 n.parent = t; 3191 } 3192 t._length = type._length; 3193 this.share.set(name, t); 3194 t._integrate(this, null); 3195 return ( 3196 /** @type {InstanceType<Type>} */ 3197 t 3198 ); 3199 } else { 3200 throw new Error(`Type with the name $name} has already been defined with a different constructor`); 3201 } 3202 } 3203 return ( 3204 /** @type {InstanceType<Type>} */ 3205 type 3206 ); 3207 } 3208 /** 3209 * @template T 3210 * @param {string} [name] 3211 * @return {YArray<T>} 3212 * 3213 * @public 3214 */ 3215 getArray(name = "") { 3216 return ( 3217 /** @type {YArray<T>} */ 3218 this.get(name, YArray) 3219 ); 3220 } 3221 /** 3222 * @param {string} [name] 3223 * @return {YText} 3224 * 3225 * @public 3226 */ 3227 getText(name = "") { 3228 return this.get(name, YText); 3229 } 3230 /** 3231 * @template T 3232 * @param {string} [name] 3233 * @return {YMap<T>} 3234 * 3235 * @public 3236 */ 3237 getMap(name = "") { 3238 return ( 3239 /** @type {YMap<T>} */ 3240 this.get(name, YMap) 3241 ); 3242 } 3243 /** 3244 * @param {string} [name] 3245 * @return {YXmlElement} 3246 * 3247 * @public 3248 */ 3249 getXmlElement(name = "") { 3250 return ( 3251 /** @type {YXmlElement<{[key:string]:string}>} */ 3252 this.get(name, YXmlElement) 3253 ); 3254 } 3255 /** 3256 * @param {string} [name] 3257 * @return {YXmlFragment} 3258 * 3259 * @public 3260 */ 3261 getXmlFragment(name = "") { 3262 return this.get(name, YXmlFragment); 3263 } 3264 /** 3265 * Converts the entire document into a js object, recursively traversing each yjs type 3266 * Doesn't log types that have not been defined (using ydoc.getType(..)). 3267 * 3268 * @deprecated Do not use this method and rather call toJSON directly on the shared types. 3269 * 3270 * @return {Object<string, any>} 3271 */ 3272 toJSON() { 3273 const doc2 = {}; 3274 this.share.forEach((value, key) => { 3275 doc2[key] = value.toJSON(); 3276 }); 3277 return doc2; 3278 } 3279 /** 3280 * Emit `destroy` event and unregister all event handlers. 3281 */ 3282 destroy() { 3283 this.isDestroyed = true; 3284 from(this.subdocs).forEach((subdoc) => subdoc.destroy()); 3285 const item = this._item; 3286 if (item !== null) { 3287 this._item = null; 3288 const content = ( 3289 /** @type {ContentDoc} */ 3290 item.content 3291 ); 3292 content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); 3293 content.doc._item = item; 3294 transact( 3295 /** @type {any} */ 3296 item.parent.doc, 3297 (transaction) => { 3298 const doc2 = content.doc; 3299 if (!item.deleted) { 3300 transaction.subdocsAdded.add(doc2); 3301 } 3302 transaction.subdocsRemoved.add(this); 3303 }, 3304 null, 3305 true 3306 ); 3307 } 3308 this.emit("destroyed", [true]); 3309 this.emit("destroy", [this]); 3310 super.destroy(); 3311 } 3312 }; 3313 var DSDecoderV1 = class { 3314 /** 3315 * @param {decoding.Decoder} decoder 3316 */ 3317 constructor(decoder) { 3318 this.restDecoder = decoder; 3319 } 3320 resetDsCurVal() { 3321 } 3322 /** 3323 * @return {number} 3324 */ 3325 readDsClock() { 3326 return readVarUint(this.restDecoder); 3327 } 3328 /** 3329 * @return {number} 3330 */ 3331 readDsLen() { 3332 return readVarUint(this.restDecoder); 3333 } 3334 }; 3335 var UpdateDecoderV1 = class extends DSDecoderV1 { 3336 /** 3337 * @return {ID} 3338 */ 3339 readLeftID() { 3340 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 3341 } 3342 /** 3343 * @return {ID} 3344 */ 3345 readRightID() { 3346 return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); 3347 } 3348 /** 3349 * Read the next client id. 3350 * Use this in favor of readID whenever possible to reduce the number of objects created. 3351 */ 3352 readClient() { 3353 return readVarUint(this.restDecoder); 3354 } 3355 /** 3356 * @return {number} info An unsigned 8-bit integer 3357 */ 3358 readInfo() { 3359 return readUint8(this.restDecoder); 3360 } 3361 /** 3362 * @return {string} 3363 */ 3364 readString() { 3365 return readVarString(this.restDecoder); 3366 } 3367 /** 3368 * @return {boolean} isKey 3369 */ 3370 readParentInfo() { 3371 return readVarUint(this.restDecoder) === 1; 3372 } 3373 /** 3374 * @return {number} info An unsigned 8-bit integer 3375 */ 3376 readTypeRef() { 3377 return readVarUint(this.restDecoder); 3378 } 3379 /** 3380 * Write len of a struct - well suited for Opt RLE encoder. 3381 * 3382 * @return {number} len 3383 */ 3384 readLen() { 3385 return readVarUint(this.restDecoder); 3386 } 3387 /** 3388 * @return {any} 3389 */ 3390 readAny() { 3391 return readAny(this.restDecoder); 3392 } 3393 /** 3394 * @return {Uint8Array} 3395 */ 3396 readBuf() { 3397 return copyUint8Array(readVarUint8Array(this.restDecoder)); 3398 } 3399 /** 3400 * Legacy implementation uses JSON parse. We use any-decoding in v2. 3401 * 3402 * @return {any} 3403 */ 3404 readJSON() { 3405 return JSON.parse(readVarString(this.restDecoder)); 3406 } 3407 /** 3408 * @return {string} 3409 */ 3410 readKey() { 3411 return readVarString(this.restDecoder); 3412 } 3413 }; 3414 var DSDecoderV2 = class { 3415 /** 3416 * @param {decoding.Decoder} decoder 3417 */ 3418 constructor(decoder) { 3419 this.dsCurrVal = 0; 3420 this.restDecoder = decoder; 3421 } 3422 resetDsCurVal() { 3423 this.dsCurrVal = 0; 3424 } 3425 /** 3426 * @return {number} 3427 */ 3428 readDsClock() { 3429 this.dsCurrVal += readVarUint(this.restDecoder); 3430 return this.dsCurrVal; 3431 } 3432 /** 3433 * @return {number} 3434 */ 3435 readDsLen() { 3436 const diff = readVarUint(this.restDecoder) + 1; 3437 this.dsCurrVal += diff; 3438 return diff; 3439 } 3440 }; 3441 var UpdateDecoderV2 = class extends DSDecoderV2 { 3442 /** 3443 * @param {decoding.Decoder} decoder 3444 */ 3445 constructor(decoder) { 3446 super(decoder); 3447 this.keys = []; 3448 readVarUint(decoder); 3449 this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 3450 this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 3451 this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 3452 this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); 3453 this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 3454 this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); 3455 this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); 3456 this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 3457 this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); 3458 } 3459 /** 3460 * @return {ID} 3461 */ 3462 readLeftID() { 3463 return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); 3464 } 3465 /** 3466 * @return {ID} 3467 */ 3468 readRightID() { 3469 return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); 3470 } 3471 /** 3472 * Read the next client id. 3473 * Use this in favor of readID whenever possible to reduce the number of objects created. 3474 */ 3475 readClient() { 3476 return this.clientDecoder.read(); 3477 } 3478 /** 3479 * @return {number} info An unsigned 8-bit integer 3480 */ 3481 readInfo() { 3482 return ( 3483 /** @type {number} */ 3484 this.infoDecoder.read() 3485 ); 3486 } 3487 /** 3488 * @return {string} 3489 */ 3490 readString() { 3491 return this.stringDecoder.read(); 3492 } 3493 /** 3494 * @return {boolean} 3495 */ 3496 readParentInfo() { 3497 return this.parentInfoDecoder.read() === 1; 3498 } 3499 /** 3500 * @return {number} An unsigned 8-bit integer 3501 */ 3502 readTypeRef() { 3503 return this.typeRefDecoder.read(); 3504 } 3505 /** 3506 * Write len of a struct - well suited for Opt RLE encoder. 3507 * 3508 * @return {number} 3509 */ 3510 readLen() { 3511 return this.lenDecoder.read(); 3512 } 3513 /** 3514 * @return {any} 3515 */ 3516 readAny() { 3517 return readAny(this.restDecoder); 3518 } 3519 /** 3520 * @return {Uint8Array} 3521 */ 3522 readBuf() { 3523 return readVarUint8Array(this.restDecoder); 3524 } 3525 /** 3526 * This is mainly here for legacy purposes. 3527 * 3528 * 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. 3529 * 3530 * @return {any} 3531 */ 3532 readJSON() { 3533 return readAny(this.restDecoder); 3534 } 3535 /** 3536 * @return {string} 3537 */ 3538 readKey() { 3539 const keyClock = this.keyClockDecoder.read(); 3540 if (keyClock < this.keys.length) { 3541 return this.keys[keyClock]; 3542 } else { 3543 const key = this.stringDecoder.read(); 3544 this.keys.push(key); 3545 return key; 3546 } 3547 } 3548 }; 3549 var DSEncoderV1 = class { 3550 constructor() { 3551 this.restEncoder = createEncoder(); 3552 } 3553 toUint8Array() { 3554 return toUint8Array(this.restEncoder); 3555 } 3556 resetDsCurVal() { 3557 } 3558 /** 3559 * @param {number} clock 3560 */ 3561 writeDsClock(clock) { 3562 writeVarUint(this.restEncoder, clock); 3563 } 3564 /** 3565 * @param {number} len 3566 */ 3567 writeDsLen(len) { 3568 writeVarUint(this.restEncoder, len); 3569 } 3570 }; 3571 var UpdateEncoderV1 = class extends DSEncoderV1 { 3572 /** 3573 * @param {ID} id 3574 */ 3575 writeLeftID(id2) { 3576 writeVarUint(this.restEncoder, id2.client); 3577 writeVarUint(this.restEncoder, id2.clock); 3578 } 3579 /** 3580 * @param {ID} id 3581 */ 3582 writeRightID(id2) { 3583 writeVarUint(this.restEncoder, id2.client); 3584 writeVarUint(this.restEncoder, id2.clock); 3585 } 3586 /** 3587 * Use writeClient and writeClock instead of writeID if possible. 3588 * @param {number} client 3589 */ 3590 writeClient(client) { 3591 writeVarUint(this.restEncoder, client); 3592 } 3593 /** 3594 * @param {number} info An unsigned 8-bit integer 3595 */ 3596 writeInfo(info) { 3597 writeUint8(this.restEncoder, info); 3598 } 3599 /** 3600 * @param {string} s 3601 */ 3602 writeString(s) { 3603 writeVarString(this.restEncoder, s); 3604 } 3605 /** 3606 * @param {boolean} isYKey 3607 */ 3608 writeParentInfo(isYKey) { 3609 writeVarUint(this.restEncoder, isYKey ? 1 : 0); 3610 } 3611 /** 3612 * @param {number} info An unsigned 8-bit integer 3613 */ 3614 writeTypeRef(info) { 3615 writeVarUint(this.restEncoder, info); 3616 } 3617 /** 3618 * Write len of a struct - well suited for Opt RLE encoder. 3619 * 3620 * @param {number} len 3621 */ 3622 writeLen(len) { 3623 writeVarUint(this.restEncoder, len); 3624 } 3625 /** 3626 * @param {any} any 3627 */ 3628 writeAny(any2) { 3629 writeAny(this.restEncoder, any2); 3630 } 3631 /** 3632 * @param {Uint8Array} buf 3633 */ 3634 writeBuf(buf) { 3635 writeVarUint8Array(this.restEncoder, buf); 3636 } 3637 /** 3638 * @param {any} embed 3639 */ 3640 writeJSON(embed) { 3641 writeVarString(this.restEncoder, JSON.stringify(embed)); 3642 } 3643 /** 3644 * @param {string} key 3645 */ 3646 writeKey(key) { 3647 writeVarString(this.restEncoder, key); 3648 } 3649 }; 3650 var DSEncoderV2 = class { 3651 constructor() { 3652 this.restEncoder = createEncoder(); 3653 this.dsCurrVal = 0; 3654 } 3655 toUint8Array() { 3656 return toUint8Array(this.restEncoder); 3657 } 3658 resetDsCurVal() { 3659 this.dsCurrVal = 0; 3660 } 3661 /** 3662 * @param {number} clock 3663 */ 3664 writeDsClock(clock) { 3665 const diff = clock - this.dsCurrVal; 3666 this.dsCurrVal = clock; 3667 writeVarUint(this.restEncoder, diff); 3668 } 3669 /** 3670 * @param {number} len 3671 */ 3672 writeDsLen(len) { 3673 if (len === 0) { 3674 unexpectedCase(); 3675 } 3676 writeVarUint(this.restEncoder, len - 1); 3677 this.dsCurrVal += len; 3678 } 3679 }; 3680 var UpdateEncoderV2 = class extends DSEncoderV2 { 3681 constructor() { 3682 super(); 3683 this.keyMap = /* @__PURE__ */ new Map(); 3684 this.keyClock = 0; 3685 this.keyClockEncoder = new IntDiffOptRleEncoder(); 3686 this.clientEncoder = new UintOptRleEncoder(); 3687 this.leftClockEncoder = new IntDiffOptRleEncoder(); 3688 this.rightClockEncoder = new IntDiffOptRleEncoder(); 3689 this.infoEncoder = new RleEncoder(writeUint8); 3690 this.stringEncoder = new StringEncoder(); 3691 this.parentInfoEncoder = new RleEncoder(writeUint8); 3692 this.typeRefEncoder = new UintOptRleEncoder(); 3693 this.lenEncoder = new UintOptRleEncoder(); 3694 } 3695 toUint8Array() { 3696 const encoder = createEncoder(); 3697 writeVarUint(encoder, 0); 3698 writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); 3699 writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); 3700 writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); 3701 writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); 3702 writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); 3703 writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); 3704 writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); 3705 writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); 3706 writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); 3707 writeUint8Array(encoder, toUint8Array(this.restEncoder)); 3708 return toUint8Array(encoder); 3709 } 3710 /** 3711 * @param {ID} id 3712 */ 3713 writeLeftID(id2) { 3714 this.clientEncoder.write(id2.client); 3715 this.leftClockEncoder.write(id2.clock); 3716 } 3717 /** 3718 * @param {ID} id 3719 */ 3720 writeRightID(id2) { 3721 this.clientEncoder.write(id2.client); 3722 this.rightClockEncoder.write(id2.clock); 3723 } 3724 /** 3725 * @param {number} client 3726 */ 3727 writeClient(client) { 3728 this.clientEncoder.write(client); 3729 } 3730 /** 3731 * @param {number} info An unsigned 8-bit integer 3732 */ 3733 writeInfo(info) { 3734 this.infoEncoder.write(info); 3735 } 3736 /** 3737 * @param {string} s 3738 */ 3739 writeString(s) { 3740 this.stringEncoder.write(s); 3741 } 3742 /** 3743 * @param {boolean} isYKey 3744 */ 3745 writeParentInfo(isYKey) { 3746 this.parentInfoEncoder.write(isYKey ? 1 : 0); 3747 } 3748 /** 3749 * @param {number} info An unsigned 8-bit integer 3750 */ 3751 writeTypeRef(info) { 3752 this.typeRefEncoder.write(info); 3753 } 3754 /** 3755 * Write len of a struct - well suited for Opt RLE encoder. 3756 * 3757 * @param {number} len 3758 */ 3759 writeLen(len) { 3760 this.lenEncoder.write(len); 3761 } 3762 /** 3763 * @param {any} any 3764 */ 3765 writeAny(any2) { 3766 writeAny(this.restEncoder, any2); 3767 } 3768 /** 3769 * @param {Uint8Array} buf 3770 */ 3771 writeBuf(buf) { 3772 writeVarUint8Array(this.restEncoder, buf); 3773 } 3774 /** 3775 * This is mainly here for legacy purposes. 3776 * 3777 * 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. 3778 * 3779 * @param {any} embed 3780 */ 3781 writeJSON(embed) { 3782 writeAny(this.restEncoder, embed); 3783 } 3784 /** 3785 * Property keys are often reused. For example, in y-prosemirror the key `bold` might 3786 * occur very often. For a 3d application, the key `position` might occur very often. 3787 * 3788 * We cache these keys in a Map and refer to them via a unique number. 3789 * 3790 * @param {string} key 3791 */ 3792 writeKey(key) { 3793 const clock = this.keyMap.get(key); 3794 if (clock === void 0) { 3795 this.keyClockEncoder.write(this.keyClock++); 3796 this.stringEncoder.write(key); 3797 } else { 3798 this.keyClockEncoder.write(clock); 3799 } 3800 } 3801 }; 3802 var writeStructs = (encoder, structs, client, clock) => { 3803 clock = max(clock, structs[0].id.clock); 3804 const startNewStructs = findIndexSS(structs, clock); 3805 writeVarUint(encoder.restEncoder, structs.length - startNewStructs); 3806 encoder.writeClient(client); 3807 writeVarUint(encoder.restEncoder, clock); 3808 const firstStruct = structs[startNewStructs]; 3809 firstStruct.write(encoder, clock - firstStruct.id.clock); 3810 for (let i = startNewStructs + 1; i < structs.length; i++) { 3811 structs[i].write(encoder, 0); 3812 } 3813 }; 3814 var writeClientsStructs = (encoder, store2, _sm) => { 3815 const sm = /* @__PURE__ */ new Map(); 3816 _sm.forEach((clock, client) => { 3817 if (getState(store2, client) > clock) { 3818 sm.set(client, clock); 3819 } 3820 }); 3821 getStateVector(store2).forEach((_clock, client) => { 3822 if (!_sm.has(client)) { 3823 sm.set(client, 0); 3824 } 3825 }); 3826 writeVarUint(encoder.restEncoder, sm.size); 3827 from(sm.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 3828 writeStructs( 3829 encoder, 3830 /** @type {Array<GC|Item>} */ 3831 store2.clients.get(client), 3832 client, 3833 clock 3834 ); 3835 }); 3836 }; 3837 var readClientsStructRefs = (decoder, doc2) => { 3838 const clientRefs = create(); 3839 const numOfStateUpdates = readVarUint(decoder.restDecoder); 3840 for (let i = 0; i < numOfStateUpdates; i++) { 3841 const numberOfStructs = readVarUint(decoder.restDecoder); 3842 const refs = new Array(numberOfStructs); 3843 const client = decoder.readClient(); 3844 let clock = readVarUint(decoder.restDecoder); 3845 clientRefs.set(client, { i: 0, refs }); 3846 for (let i2 = 0; i2 < numberOfStructs; i2++) { 3847 const info = decoder.readInfo(); 3848 switch (BITS5 & info) { 3849 case 0: { 3850 const len = decoder.readLen(); 3851 refs[i2] = new GC(createID(client, clock), len); 3852 clock += len; 3853 break; 3854 } 3855 case 10: { 3856 const len = readVarUint(decoder.restDecoder); 3857 refs[i2] = new Skip(createID(client, clock), len); 3858 clock += len; 3859 break; 3860 } 3861 default: { 3862 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 3863 const struct = new Item( 3864 createID(client, clock), 3865 null, 3866 // left 3867 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 3868 // origin 3869 null, 3870 // right 3871 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 3872 // right origin 3873 cantCopyParentInfo ? decoder.readParentInfo() ? doc2.get(decoder.readString()) : decoder.readLeftID() : null, 3874 // parent 3875 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 3876 // parentSub 3877 readItemContent(decoder, info) 3878 // item content 3879 ); 3880 refs[i2] = struct; 3881 clock += struct.length; 3882 } 3883 } 3884 } 3885 } 3886 return clientRefs; 3887 }; 3888 var integrateStructs = (transaction, store2, clientsStructRefs) => { 3889 const stack = []; 3890 let clientsStructRefsIds = from(clientsStructRefs.keys()).sort((a, b) => a - b); 3891 if (clientsStructRefsIds.length === 0) { 3892 return null; 3893 } 3894 const getNextStructTarget = () => { 3895 if (clientsStructRefsIds.length === 0) { 3896 return null; 3897 } 3898 let nextStructsTarget = ( 3899 /** @type {{i:number,refs:Array<GC|Item>}} */ 3900 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) 3901 ); 3902 while (nextStructsTarget.refs.length === nextStructsTarget.i) { 3903 clientsStructRefsIds.pop(); 3904 if (clientsStructRefsIds.length > 0) { 3905 nextStructsTarget = /** @type {{i:number,refs:Array<GC|Item>}} */ 3906 clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); 3907 } else { 3908 return null; 3909 } 3910 } 3911 return nextStructsTarget; 3912 }; 3913 let curStructsTarget = getNextStructTarget(); 3914 if (curStructsTarget === null) { 3915 return null; 3916 } 3917 const restStructs = new StructStore(); 3918 const missingSV = /* @__PURE__ */ new Map(); 3919 const updateMissingSv = (client, clock) => { 3920 const mclock = missingSV.get(client); 3921 if (mclock == null || mclock > clock) { 3922 missingSV.set(client, clock); 3923 } 3924 }; 3925 let stackHead = ( 3926 /** @type {any} */ 3927 curStructsTarget.refs[ 3928 /** @type {any} */ 3929 curStructsTarget.i++ 3930 ] 3931 ); 3932 const state = /* @__PURE__ */ new Map(); 3933 const addStackToRestSS = () => { 3934 for (const item of stack) { 3935 const client = item.id.client; 3936 const inapplicableItems = clientsStructRefs.get(client); 3937 if (inapplicableItems) { 3938 inapplicableItems.i--; 3939 restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); 3940 clientsStructRefs.delete(client); 3941 inapplicableItems.i = 0; 3942 inapplicableItems.refs = []; 3943 } else { 3944 restStructs.clients.set(client, [item]); 3945 } 3946 clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); 3947 } 3948 stack.length = 0; 3949 }; 3950 while (true) { 3951 if (stackHead.constructor !== Skip) { 3952 const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store2, stackHead.id.client)); 3953 const offset = localClock - stackHead.id.clock; 3954 if (offset < 0) { 3955 stack.push(stackHead); 3956 updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); 3957 addStackToRestSS(); 3958 } else { 3959 const missing = stackHead.getMissing(transaction, store2); 3960 if (missing !== null) { 3961 stack.push(stackHead); 3962 const structRefs = clientsStructRefs.get( 3963 /** @type {number} */ 3964 missing 3965 ) || { refs: [], i: 0 }; 3966 if (structRefs.refs.length === structRefs.i) { 3967 updateMissingSv( 3968 /** @type {number} */ 3969 missing, 3970 getState(store2, missing) 3971 ); 3972 addStackToRestSS(); 3973 } else { 3974 stackHead = structRefs.refs[structRefs.i++]; 3975 continue; 3976 } 3977 } else if (offset === 0 || offset < stackHead.length) { 3978 stackHead.integrate(transaction, offset); 3979 state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); 3980 } 3981 } 3982 } 3983 if (stack.length > 0) { 3984 stackHead = /** @type {GC|Item} */ 3985 stack.pop(); 3986 } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { 3987 stackHead = /** @type {GC|Item} */ 3988 curStructsTarget.refs[curStructsTarget.i++]; 3989 } else { 3990 curStructsTarget = getNextStructTarget(); 3991 if (curStructsTarget === null) { 3992 break; 3993 } else { 3994 stackHead = /** @type {GC|Item} */ 3995 curStructsTarget.refs[curStructsTarget.i++]; 3996 } 3997 } 3998 } 3999 if (restStructs.clients.size > 0) { 4000 const encoder = new UpdateEncoderV2(); 4001 writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); 4002 writeVarUint(encoder.restEncoder, 0); 4003 return { missing: missingSV, update: encoder.toUint8Array() }; 4004 } 4005 return null; 4006 }; 4007 var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); 4008 var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { 4009 transaction.local = false; 4010 let retry = false; 4011 const doc2 = transaction.doc; 4012 const store2 = doc2.store; 4013 const ss = readClientsStructRefs(structDecoder, doc2); 4014 const restStructs = integrateStructs(transaction, store2, ss); 4015 const pending = store2.pendingStructs; 4016 if (pending) { 4017 for (const [client, clock] of pending.missing) { 4018 if (clock < getState(store2, client)) { 4019 retry = true; 4020 break; 4021 } 4022 } 4023 if (restStructs) { 4024 for (const [client, clock] of restStructs.missing) { 4025 const mclock = pending.missing.get(client); 4026 if (mclock == null || mclock > clock) { 4027 pending.missing.set(client, clock); 4028 } 4029 } 4030 pending.update = mergeUpdatesV2([pending.update, restStructs.update]); 4031 } 4032 } else { 4033 store2.pendingStructs = restStructs; 4034 } 4035 const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store2); 4036 if (store2.pendingDs) { 4037 const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store2.pendingDs)); 4038 readVarUint(pendingDSUpdate.restDecoder); 4039 const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store2); 4040 if (dsRest && dsRest2) { 4041 store2.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); 4042 } else { 4043 store2.pendingDs = dsRest || dsRest2; 4044 } 4045 } else { 4046 store2.pendingDs = dsRest; 4047 } 4048 if (retry) { 4049 const update = ( 4050 /** @type {{update: Uint8Array}} */ 4051 store2.pendingStructs.update 4052 ); 4053 store2.pendingStructs = null; 4054 applyUpdateV2(transaction.doc, update); 4055 } 4056 }, transactionOrigin, false); 4057 var readUpdate = (decoder, ydoc, transactionOrigin) => readUpdateV2(decoder, ydoc, transactionOrigin, new UpdateDecoderV1(decoder)); 4058 var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { 4059 const decoder = createDecoder(update); 4060 readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); 4061 }; 4062 var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); 4063 var writeStateAsUpdate = (encoder, doc2, targetStateVector = /* @__PURE__ */ new Map()) => { 4064 writeClientsStructs(encoder, doc2.store, targetStateVector); 4065 writeDeleteSet(encoder, createDeleteSetFromStructStore(doc2.store)); 4066 }; 4067 var encodeStateAsUpdateV2 = (doc2, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { 4068 const targetStateVector = decodeStateVector(encodedTargetStateVector); 4069 writeStateAsUpdate(encoder, doc2, targetStateVector); 4070 const updates = [encoder.toUint8Array()]; 4071 if (doc2.store.pendingDs) { 4072 updates.push(doc2.store.pendingDs); 4073 } 4074 if (doc2.store.pendingStructs) { 4075 updates.push(diffUpdateV2(doc2.store.pendingStructs.update, encodedTargetStateVector)); 4076 } 4077 if (updates.length > 1) { 4078 if (encoder.constructor === UpdateEncoderV1) { 4079 return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); 4080 } else if (encoder.constructor === UpdateEncoderV2) { 4081 return mergeUpdatesV2(updates); 4082 } 4083 } 4084 return updates[0]; 4085 }; 4086 var encodeStateAsUpdate = (doc2, encodedTargetStateVector) => encodeStateAsUpdateV2(doc2, encodedTargetStateVector, new UpdateEncoderV1()); 4087 var readStateVector = (decoder) => { 4088 const ss = /* @__PURE__ */ new Map(); 4089 const ssLength = readVarUint(decoder.restDecoder); 4090 for (let i = 0; i < ssLength; i++) { 4091 const client = readVarUint(decoder.restDecoder); 4092 const clock = readVarUint(decoder.restDecoder); 4093 ss.set(client, clock); 4094 } 4095 return ss; 4096 }; 4097 var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); 4098 var writeStateVector = (encoder, sv) => { 4099 writeVarUint(encoder.restEncoder, sv.size); 4100 from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => { 4101 writeVarUint(encoder.restEncoder, client); 4102 writeVarUint(encoder.restEncoder, clock); 4103 }); 4104 return encoder; 4105 }; 4106 var writeDocumentStateVector = (encoder, doc2) => writeStateVector(encoder, getStateVector(doc2.store)); 4107 var encodeStateVectorV2 = (doc2, encoder = new DSEncoderV2()) => { 4108 if (doc2 instanceof Map) { 4109 writeStateVector(encoder, doc2); 4110 } else { 4111 writeDocumentStateVector(encoder, doc2); 4112 } 4113 return encoder.toUint8Array(); 4114 }; 4115 var encodeStateVector = (doc2) => encodeStateVectorV2(doc2, new DSEncoderV1()); 4116 var EventHandler = class { 4117 constructor() { 4118 this.l = []; 4119 } 4120 }; 4121 var createEventHandler = () => new EventHandler(); 4122 var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); 4123 var removeEventHandlerListener = (eventHandler, f) => { 4124 const l = eventHandler.l; 4125 const len = l.length; 4126 eventHandler.l = l.filter((g) => f !== g); 4127 if (len === eventHandler.l.length) { 4128 console.error("[yjs] Tried to remove event handler that doesn't exist."); 4129 } 4130 }; 4131 var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); 4132 var ID = class { 4133 /** 4134 * @param {number} client client id 4135 * @param {number} clock unique per client id, continuous number 4136 */ 4137 constructor(client, clock) { 4138 this.client = client; 4139 this.clock = clock; 4140 } 4141 }; 4142 var compareIDs = (a, b) => a === b || a !== null && b !== null && a.client === b.client && a.clock === b.clock; 4143 var createID = (client, clock) => new ID(client, clock); 4144 var writeID = (encoder, id2) => { 4145 writeVarUint(encoder, id2.client); 4146 writeVarUint(encoder, id2.clock); 4147 }; 4148 var readID = (decoder) => createID(readVarUint(decoder), readVarUint(decoder)); 4149 var findRootTypeKey = (type) => { 4150 for (const [key, value] of type.doc.share.entries()) { 4151 if (value === type) { 4152 return key; 4153 } 4154 } 4155 throw unexpectedCase(); 4156 }; 4157 var isParentOf = (parent, child) => { 4158 while (child !== null) { 4159 if (child.parent === parent) { 4160 return true; 4161 } 4162 child = /** @type {AbstractType<any>} */ 4163 child.parent._item; 4164 } 4165 return false; 4166 }; 4167 var logType = (type) => { 4168 const res = []; 4169 let n = type._start; 4170 while (n) { 4171 res.push(n); 4172 n = n.right; 4173 } 4174 console.log("Children: ", res); 4175 console.log("Children content: ", res.filter((m) => !m.deleted).map((m) => m.content)); 4176 }; 4177 var PermanentUserData = class { 4178 /** 4179 * @param {Doc} doc 4180 * @param {YMap<any>} [storeType] 4181 */ 4182 constructor(doc2, storeType = doc2.getMap("users")) { 4183 const dss = /* @__PURE__ */ new Map(); 4184 this.yusers = storeType; 4185 this.doc = doc2; 4186 this.clients = /* @__PURE__ */ new Map(); 4187 this.dss = dss; 4188 const initUser = (user, userDescription) => { 4189 const ds = user.get("ds"); 4190 const ids = user.get("ids"); 4191 const addClientId = ( 4192 /** @param {number} clientid */ 4193 (clientid) => this.clients.set(clientid, userDescription) 4194 ); 4195 ds.observe( 4196 /** @param {YArrayEvent<any>} event */ 4197 (event) => { 4198 event.changes.added.forEach((item) => { 4199 item.content.getContent().forEach((encodedDs) => { 4200 if (encodedDs instanceof Uint8Array) { 4201 this.dss.set(userDescription, mergeDeleteSets([this.dss.get(userDescription) || createDeleteSet(), readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))])); 4202 } 4203 }); 4204 }); 4205 } 4206 ); 4207 this.dss.set(userDescription, mergeDeleteSets(ds.map((encodedDs) => readDeleteSet(new DSDecoderV1(createDecoder(encodedDs)))))); 4208 ids.observe( 4209 /** @param {YArrayEvent<any>} event */ 4210 (event) => event.changes.added.forEach((item) => item.content.getContent().forEach(addClientId)) 4211 ); 4212 ids.forEach(addClientId); 4213 }; 4214 storeType.observe((event) => { 4215 event.keysChanged.forEach( 4216 (userDescription) => initUser(storeType.get(userDescription), userDescription) 4217 ); 4218 }); 4219 storeType.forEach(initUser); 4220 } 4221 /** 4222 * @param {Doc} doc 4223 * @param {number} clientid 4224 * @param {string} userDescription 4225 * @param {Object} conf 4226 * @param {function(Transaction, DeleteSet):boolean} [conf.filter] 4227 */ 4228 setUserMapping(doc2, clientid, userDescription, { filter = () => true } = {}) { 4229 const users2 = this.yusers; 4230 let user = users2.get(userDescription); 4231 if (!user) { 4232 user = new YMap(); 4233 user.set("ids", new YArray()); 4234 user.set("ds", new YArray()); 4235 users2.set(userDescription, user); 4236 } 4237 user.get("ids").push([clientid]); 4238 users2.observe((_event) => { 4239 setTimeout(() => { 4240 const userOverwrite = users2.get(userDescription); 4241 if (userOverwrite !== user) { 4242 user = userOverwrite; 4243 this.clients.forEach((_userDescription, clientid2) => { 4244 if (userDescription === _userDescription) { 4245 user.get("ids").push([clientid2]); 4246 } 4247 }); 4248 const encoder = new DSEncoderV1(); 4249 const ds = this.dss.get(userDescription); 4250 if (ds) { 4251 writeDeleteSet(encoder, ds); 4252 user.get("ds").push([encoder.toUint8Array()]); 4253 } 4254 } 4255 }, 0); 4256 }); 4257 doc2.on( 4258 "afterTransaction", 4259 /** @param {Transaction} transaction */ 4260 (transaction) => { 4261 setTimeout(() => { 4262 const yds = user.get("ds"); 4263 const ds = transaction.deleteSet; 4264 if (transaction.local && ds.clients.size > 0 && filter(transaction, ds)) { 4265 const encoder = new DSEncoderV1(); 4266 writeDeleteSet(encoder, ds); 4267 yds.push([encoder.toUint8Array()]); 4268 } 4269 }); 4270 } 4271 ); 4272 } 4273 /** 4274 * @param {number} clientid 4275 * @return {any} 4276 */ 4277 getUserByClientId(clientid) { 4278 return this.clients.get(clientid) || null; 4279 } 4280 /** 4281 * @param {ID} id 4282 * @return {string | null} 4283 */ 4284 getUserByDeletedId(id2) { 4285 for (const [userDescription, ds] of this.dss.entries()) { 4286 if (isDeleted(ds, id2)) { 4287 return userDescription; 4288 } 4289 } 4290 return null; 4291 } 4292 }; 4293 var RelativePosition = class { 4294 /** 4295 * @param {ID|null} type 4296 * @param {string|null} tname 4297 * @param {ID|null} item 4298 * @param {number} assoc 4299 */ 4300 constructor(type, tname, item, assoc = 0) { 4301 this.type = type; 4302 this.tname = tname; 4303 this.item = item; 4304 this.assoc = assoc; 4305 } 4306 }; 4307 var relativePositionToJSON = (rpos) => { 4308 const json = {}; 4309 if (rpos.type) { 4310 json.type = rpos.type; 4311 } 4312 if (rpos.tname) { 4313 json.tname = rpos.tname; 4314 } 4315 if (rpos.item) { 4316 json.item = rpos.item; 4317 } 4318 if (rpos.assoc != null) { 4319 json.assoc = rpos.assoc; 4320 } 4321 return json; 4322 }; 4323 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); 4324 var AbsolutePosition = class { 4325 /** 4326 * @param {AbstractType<any>} type 4327 * @param {number} index 4328 * @param {number} [assoc] 4329 */ 4330 constructor(type, index, assoc = 0) { 4331 this.type = type; 4332 this.index = index; 4333 this.assoc = assoc; 4334 } 4335 }; 4336 var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); 4337 var createRelativePosition = (type, item, assoc) => { 4338 let typeid = null; 4339 let tname = null; 4340 if (type._item === null) { 4341 tname = findRootTypeKey(type); 4342 } else { 4343 typeid = createID(type._item.id.client, type._item.id.clock); 4344 } 4345 return new RelativePosition(typeid, tname, item, assoc); 4346 }; 4347 var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { 4348 let t = type._start; 4349 if (assoc < 0) { 4350 if (index === 0) { 4351 return createRelativePosition(type, null, assoc); 4352 } 4353 index--; 4354 } 4355 while (t !== null) { 4356 if (!t.deleted && t.countable) { 4357 if (t.length > index) { 4358 return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); 4359 } 4360 index -= t.length; 4361 } 4362 if (t.right === null && assoc < 0) { 4363 return createRelativePosition(type, t.lastId, assoc); 4364 } 4365 t = t.right; 4366 } 4367 return createRelativePosition(type, null, assoc); 4368 }; 4369 var writeRelativePosition = (encoder, rpos) => { 4370 const { type, tname, item, assoc } = rpos; 4371 if (item !== null) { 4372 writeVarUint(encoder, 0); 4373 writeID(encoder, item); 4374 } else if (tname !== null) { 4375 writeUint8(encoder, 1); 4376 writeVarString(encoder, tname); 4377 } else if (type !== null) { 4378 writeUint8(encoder, 2); 4379 writeID(encoder, type); 4380 } else { 4381 throw unexpectedCase(); 4382 } 4383 writeVarInt(encoder, assoc); 4384 return encoder; 4385 }; 4386 var encodeRelativePosition = (rpos) => { 4387 const encoder = createEncoder(); 4388 writeRelativePosition(encoder, rpos); 4389 return toUint8Array(encoder); 4390 }; 4391 var readRelativePosition = (decoder) => { 4392 let type = null; 4393 let tname = null; 4394 let itemID = null; 4395 switch (readVarUint(decoder)) { 4396 case 0: 4397 itemID = readID(decoder); 4398 break; 4399 case 1: 4400 tname = readVarString(decoder); 4401 break; 4402 case 2: { 4403 type = readID(decoder); 4404 } 4405 } 4406 const assoc = hasContent(decoder) ? readVarInt(decoder) : 0; 4407 return new RelativePosition(type, tname, itemID, assoc); 4408 }; 4409 var decodeRelativePosition = (uint8Array) => readRelativePosition(createDecoder(uint8Array)); 4410 var getItemWithOffset = (store2, id2) => { 4411 const item = getItem(store2, id2); 4412 const diff = id2.clock - item.id.clock; 4413 return { 4414 item, 4415 diff 4416 }; 4417 }; 4418 var createAbsolutePositionFromRelativePosition = (rpos, doc2, followUndoneDeletions = true) => { 4419 const store2 = doc2.store; 4420 const rightID = rpos.item; 4421 const typeID = rpos.type; 4422 const tname = rpos.tname; 4423 const assoc = rpos.assoc; 4424 let type = null; 4425 let index = 0; 4426 if (rightID !== null) { 4427 if (getState(store2, rightID.client) <= rightID.clock) { 4428 return null; 4429 } 4430 const res = followUndoneDeletions ? followRedone(store2, rightID) : getItemWithOffset(store2, rightID); 4431 const right = res.item; 4432 if (!(right instanceof Item)) { 4433 return null; 4434 } 4435 type = /** @type {AbstractType<any>} */ 4436 right.parent; 4437 if (type._item === null || !type._item.deleted) { 4438 index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); 4439 let n = right.left; 4440 while (n !== null) { 4441 if (!n.deleted && n.countable) { 4442 index += n.length; 4443 } 4444 n = n.left; 4445 } 4446 } 4447 } else { 4448 if (tname !== null) { 4449 type = doc2.get(tname); 4450 } else if (typeID !== null) { 4451 if (getState(store2, typeID.client) <= typeID.clock) { 4452 return null; 4453 } 4454 const { item } = followUndoneDeletions ? followRedone(store2, typeID) : { item: getItem(store2, typeID) }; 4455 if (item instanceof Item && item.content instanceof ContentType) { 4456 type = item.content.type; 4457 } else { 4458 return null; 4459 } 4460 } else { 4461 throw unexpectedCase(); 4462 } 4463 if (assoc >= 0) { 4464 index = type._length; 4465 } else { 4466 index = 0; 4467 } 4468 } 4469 return createAbsolutePosition(type, index, rpos.assoc); 4470 }; 4471 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; 4472 var Snapshot = class { 4473 /** 4474 * @param {DeleteSet} ds 4475 * @param {Map<number,number>} sv state map 4476 */ 4477 constructor(ds, sv) { 4478 this.ds = ds; 4479 this.sv = sv; 4480 } 4481 }; 4482 var equalSnapshots = (snap1, snap2) => { 4483 const ds1 = snap1.ds.clients; 4484 const ds2 = snap2.ds.clients; 4485 const sv1 = snap1.sv; 4486 const sv2 = snap2.sv; 4487 if (sv1.size !== sv2.size || ds1.size !== ds2.size) { 4488 return false; 4489 } 4490 for (const [key, value] of sv1.entries()) { 4491 if (sv2.get(key) !== value) { 4492 return false; 4493 } 4494 } 4495 for (const [client, dsitems1] of ds1.entries()) { 4496 const dsitems2 = ds2.get(client) || []; 4497 if (dsitems1.length !== dsitems2.length) { 4498 return false; 4499 } 4500 for (let i = 0; i < dsitems1.length; i++) { 4501 const dsitem1 = dsitems1[i]; 4502 const dsitem2 = dsitems2[i]; 4503 if (dsitem1.clock !== dsitem2.clock || dsitem1.len !== dsitem2.len) { 4504 return false; 4505 } 4506 } 4507 } 4508 return true; 4509 }; 4510 var encodeSnapshotV2 = (snapshot2, encoder = new DSEncoderV2()) => { 4511 writeDeleteSet(encoder, snapshot2.ds); 4512 writeStateVector(encoder, snapshot2.sv); 4513 return encoder.toUint8Array(); 4514 }; 4515 var encodeSnapshot = (snapshot2) => encodeSnapshotV2(snapshot2, new DSEncoderV1()); 4516 var decodeSnapshotV2 = (buf, decoder = new DSDecoderV2(createDecoder(buf))) => { 4517 return new Snapshot(readDeleteSet(decoder), readStateVector(decoder)); 4518 }; 4519 var decodeSnapshot = (buf) => decodeSnapshotV2(buf, new DSDecoderV1(createDecoder(buf))); 4520 var createSnapshot = (ds, sm) => new Snapshot(ds, sm); 4521 var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); 4522 var snapshot = (doc2) => createSnapshot(createDeleteSetFromStructStore(doc2.store), getStateVector(doc2.store)); 4523 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); 4524 var splitSnapshotAffectedStructs = (transaction, snapshot2) => { 4525 const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); 4526 const store2 = transaction.doc.store; 4527 if (!meta.has(snapshot2)) { 4528 snapshot2.sv.forEach((clock, client) => { 4529 if (clock < getState(store2, client)) { 4530 getItemCleanStart(transaction, createID(client, clock)); 4531 } 4532 }); 4533 iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { 4534 }); 4535 meta.add(snapshot2); 4536 } 4537 }; 4538 var createDocFromSnapshot = (originDoc, snapshot2, newDoc = new Doc()) => { 4539 if (originDoc.gc) { 4540 throw new Error("Garbage-collection must be disabled in `originDoc`!"); 4541 } 4542 const { sv, ds } = snapshot2; 4543 const encoder = new UpdateEncoderV2(); 4544 originDoc.transact((transaction) => { 4545 let size2 = 0; 4546 sv.forEach((clock) => { 4547 if (clock > 0) { 4548 size2++; 4549 } 4550 }); 4551 writeVarUint(encoder.restEncoder, size2); 4552 for (const [client, clock] of sv) { 4553 if (clock === 0) { 4554 continue; 4555 } 4556 if (clock < getState(originDoc.store, client)) { 4557 getItemCleanStart(transaction, createID(client, clock)); 4558 } 4559 const structs = originDoc.store.clients.get(client) || []; 4560 const lastStructIndex = findIndexSS(structs, clock - 1); 4561 writeVarUint(encoder.restEncoder, lastStructIndex + 1); 4562 encoder.writeClient(client); 4563 writeVarUint(encoder.restEncoder, 0); 4564 for (let i = 0; i <= lastStructIndex; i++) { 4565 structs[i].write(encoder, 0); 4566 } 4567 } 4568 writeDeleteSet(encoder, ds); 4569 }); 4570 applyUpdateV2(newDoc, encoder.toUint8Array(), "snapshot"); 4571 return newDoc; 4572 }; 4573 var snapshotContainsUpdateV2 = (snapshot2, update, YDecoder = UpdateDecoderV2) => { 4574 const updateDecoder = new YDecoder(createDecoder(update)); 4575 const lazyDecoder = new LazyStructReader(updateDecoder, false); 4576 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 4577 if ((snapshot2.sv.get(curr.id.client) || 0) < curr.id.clock + curr.length) { 4578 return false; 4579 } 4580 } 4581 const mergedDS = mergeDeleteSets([snapshot2.ds, readDeleteSet(updateDecoder)]); 4582 return equalDeleteSets(snapshot2.ds, mergedDS); 4583 }; 4584 var snapshotContainsUpdate = (snapshot2, update) => snapshotContainsUpdateV2(snapshot2, update, UpdateDecoderV1); 4585 var StructStore = class { 4586 constructor() { 4587 this.clients = /* @__PURE__ */ new Map(); 4588 this.pendingStructs = null; 4589 this.pendingDs = null; 4590 } 4591 }; 4592 var getStateVector = (store2) => { 4593 const sm = /* @__PURE__ */ new Map(); 4594 store2.clients.forEach((structs, client) => { 4595 const struct = structs[structs.length - 1]; 4596 sm.set(client, struct.id.clock + struct.length); 4597 }); 4598 return sm; 4599 }; 4600 var getState = (store2, client) => { 4601 const structs = store2.clients.get(client); 4602 if (structs === void 0) { 4603 return 0; 4604 } 4605 const lastStruct = structs[structs.length - 1]; 4606 return lastStruct.id.clock + lastStruct.length; 4607 }; 4608 var addStruct = (store2, struct) => { 4609 let structs = store2.clients.get(struct.id.client); 4610 if (structs === void 0) { 4611 structs = []; 4612 store2.clients.set(struct.id.client, structs); 4613 } else { 4614 const lastStruct = structs[structs.length - 1]; 4615 if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { 4616 throw unexpectedCase(); 4617 } 4618 } 4619 structs.push(struct); 4620 }; 4621 var findIndexSS = (structs, clock) => { 4622 let left = 0; 4623 let right = structs.length - 1; 4624 let mid = structs[right]; 4625 let midclock = mid.id.clock; 4626 if (midclock === clock) { 4627 return right; 4628 } 4629 let midindex = floor(clock / (midclock + mid.length - 1) * right); 4630 while (left <= right) { 4631 mid = structs[midindex]; 4632 midclock = mid.id.clock; 4633 if (midclock <= clock) { 4634 if (clock < midclock + mid.length) { 4635 return midindex; 4636 } 4637 left = midindex + 1; 4638 } else { 4639 right = midindex - 1; 4640 } 4641 midindex = floor((left + right) / 2); 4642 } 4643 throw unexpectedCase(); 4644 }; 4645 var find = (store2, id2) => { 4646 const structs = store2.clients.get(id2.client); 4647 return structs[findIndexSS(structs, id2.clock)]; 4648 }; 4649 var getItem = ( 4650 /** @type {function(StructStore,ID):Item} */ 4651 find 4652 ); 4653 var findIndexCleanStart = (transaction, structs, clock) => { 4654 const index = findIndexSS(structs, clock); 4655 const struct = structs[index]; 4656 if (struct.id.clock < clock && struct instanceof Item) { 4657 structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); 4658 return index + 1; 4659 } 4660 return index; 4661 }; 4662 var getItemCleanStart = (transaction, id2) => { 4663 const structs = ( 4664 /** @type {Array<Item>} */ 4665 transaction.doc.store.clients.get(id2.client) 4666 ); 4667 return structs[findIndexCleanStart(transaction, structs, id2.clock)]; 4668 }; 4669 var getItemCleanEnd = (transaction, store2, id2) => { 4670 const structs = store2.clients.get(id2.client); 4671 const index = findIndexSS(structs, id2.clock); 4672 const struct = structs[index]; 4673 if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { 4674 structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); 4675 } 4676 return struct; 4677 }; 4678 var replaceStruct = (store2, struct, newStruct) => { 4679 const structs = ( 4680 /** @type {Array<GC|Item>} */ 4681 store2.clients.get(struct.id.client) 4682 ); 4683 structs[findIndexSS(structs, struct.id.clock)] = newStruct; 4684 }; 4685 var iterateStructs = (transaction, structs, clockStart, len, f) => { 4686 if (len === 0) { 4687 return; 4688 } 4689 const clockEnd = clockStart + len; 4690 let index = findIndexCleanStart(transaction, structs, clockStart); 4691 let struct; 4692 do { 4693 struct = structs[index++]; 4694 if (clockEnd < struct.id.clock + struct.length) { 4695 findIndexCleanStart(transaction, structs, clockEnd); 4696 } 4697 f(struct); 4698 } while (index < structs.length && structs[index].id.clock < clockEnd); 4699 }; 4700 var Transaction = class { 4701 /** 4702 * @param {Doc} doc 4703 * @param {any} origin 4704 * @param {boolean} local 4705 */ 4706 constructor(doc2, origin2, local) { 4707 this.doc = doc2; 4708 this.deleteSet = new DeleteSet(); 4709 this.beforeState = getStateVector(doc2.store); 4710 this.afterState = /* @__PURE__ */ new Map(); 4711 this.changed = /* @__PURE__ */ new Map(); 4712 this.changedParentTypes = /* @__PURE__ */ new Map(); 4713 this._mergeStructs = []; 4714 this.origin = origin2; 4715 this.meta = /* @__PURE__ */ new Map(); 4716 this.local = local; 4717 this.subdocsAdded = /* @__PURE__ */ new Set(); 4718 this.subdocsRemoved = /* @__PURE__ */ new Set(); 4719 this.subdocsLoaded = /* @__PURE__ */ new Set(); 4720 this._needFormattingCleanup = false; 4721 } 4722 }; 4723 var writeUpdateMessageFromTransaction = (encoder, transaction) => { 4724 if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { 4725 return false; 4726 } 4727 sortAndMergeDeleteSet(transaction.deleteSet); 4728 writeStructsFromTransaction(encoder, transaction); 4729 writeDeleteSet(encoder, transaction.deleteSet); 4730 return true; 4731 }; 4732 var addChangedTypeToTransaction = (transaction, type, parentSub) => { 4733 const item = type._item; 4734 if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { 4735 setIfUndefined(transaction.changed, type, create2).add(parentSub); 4736 } 4737 }; 4738 var tryToMergeWithLefts = (structs, pos) => { 4739 let right = structs[pos]; 4740 let left = structs[pos - 1]; 4741 let i = pos; 4742 for (; i > 0; right = left, left = structs[--i - 1]) { 4743 if (left.deleted === right.deleted && left.constructor === right.constructor) { 4744 if (left.mergeWith(right)) { 4745 if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ 4746 right.parent._map.get(right.parentSub) === right) { 4747 right.parent._map.set( 4748 right.parentSub, 4749 /** @type {Item} */ 4750 left 4751 ); 4752 } 4753 continue; 4754 } 4755 } 4756 break; 4757 } 4758 const merged = pos - i; 4759 if (merged) { 4760 structs.splice(pos + 1 - merged, merged); 4761 } 4762 return merged; 4763 }; 4764 var tryGcDeleteSet = (ds, store2, gcFilter) => { 4765 for (const [client, deleteItems] of ds.clients.entries()) { 4766 const structs = ( 4767 /** @type {Array<GC|Item>} */ 4768 store2.clients.get(client) 4769 ); 4770 for (let di = deleteItems.length - 1; di >= 0; di--) { 4771 const deleteItem = deleteItems[di]; 4772 const endDeleteItemClock = deleteItem.clock + deleteItem.len; 4773 for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { 4774 const struct2 = structs[si]; 4775 if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { 4776 break; 4777 } 4778 if (struct2 instanceof Item && struct2.deleted && !struct2.keep && gcFilter(struct2)) { 4779 struct2.gc(store2, false); 4780 } 4781 } 4782 } 4783 } 4784 }; 4785 var tryMergeDeleteSet = (ds, store2) => { 4786 ds.clients.forEach((deleteItems, client) => { 4787 const structs = ( 4788 /** @type {Array<GC|Item>} */ 4789 store2.clients.get(client) 4790 ); 4791 for (let di = deleteItems.length - 1; di >= 0; di--) { 4792 const deleteItem = deleteItems[di]; 4793 const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); 4794 for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { 4795 si -= 1 + tryToMergeWithLefts(structs, si); 4796 } 4797 } 4798 }); 4799 }; 4800 var tryGc = (ds, store2, gcFilter) => { 4801 tryGcDeleteSet(ds, store2, gcFilter); 4802 tryMergeDeleteSet(ds, store2); 4803 }; 4804 var cleanupTransactions = (transactionCleanups, i) => { 4805 if (i < transactionCleanups.length) { 4806 const transaction = transactionCleanups[i]; 4807 const doc2 = transaction.doc; 4808 const store2 = doc2.store; 4809 const ds = transaction.deleteSet; 4810 const mergeStructs = transaction._mergeStructs; 4811 try { 4812 sortAndMergeDeleteSet(ds); 4813 transaction.afterState = getStateVector(transaction.doc.store); 4814 doc2.emit("beforeObserverCalls", [transaction, doc2]); 4815 const fs = []; 4816 transaction.changed.forEach( 4817 (subs, itemtype) => fs.push(() => { 4818 if (itemtype._item === null || !itemtype._item.deleted) { 4819 itemtype._callObserver(transaction, subs); 4820 } 4821 }) 4822 ); 4823 fs.push(() => { 4824 transaction.changedParentTypes.forEach((events, type) => { 4825 if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { 4826 events = events.filter( 4827 (event) => event.target._item === null || !event.target._item.deleted 4828 ); 4829 events.forEach((event) => { 4830 event.currentTarget = type; 4831 event._path = null; 4832 }); 4833 events.sort((event1, event2) => event1.path.length - event2.path.length); 4834 fs.push(() => { 4835 callEventHandlerListeners(type._dEH, events, transaction); 4836 }); 4837 } 4838 }); 4839 fs.push(() => doc2.emit("afterTransaction", [transaction, doc2])); 4840 fs.push(() => { 4841 if (transaction._needFormattingCleanup) { 4842 cleanupYTextAfterTransaction(transaction); 4843 } 4844 }); 4845 }); 4846 callAll(fs, []); 4847 } finally { 4848 if (doc2.gc) { 4849 tryGcDeleteSet(ds, store2, doc2.gcFilter); 4850 } 4851 tryMergeDeleteSet(ds, store2); 4852 transaction.afterState.forEach((clock, client) => { 4853 const beforeClock = transaction.beforeState.get(client) || 0; 4854 if (beforeClock !== clock) { 4855 const structs = ( 4856 /** @type {Array<GC|Item>} */ 4857 store2.clients.get(client) 4858 ); 4859 const firstChangePos = max(findIndexSS(structs, beforeClock), 1); 4860 for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { 4861 i2 -= 1 + tryToMergeWithLefts(structs, i2); 4862 } 4863 } 4864 }); 4865 for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { 4866 const { client, clock } = mergeStructs[i2].id; 4867 const structs = ( 4868 /** @type {Array<GC|Item>} */ 4869 store2.clients.get(client) 4870 ); 4871 const replacedStructPos = findIndexSS(structs, clock); 4872 if (replacedStructPos + 1 < structs.length) { 4873 if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { 4874 continue; 4875 } 4876 } 4877 if (replacedStructPos > 0) { 4878 tryToMergeWithLefts(structs, replacedStructPos); 4879 } 4880 } 4881 if (!transaction.local && transaction.afterState.get(doc2.clientID) !== transaction.beforeState.get(doc2.clientID)) { 4882 print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); 4883 doc2.clientID = generateNewClientId(); 4884 } 4885 doc2.emit("afterTransactionCleanup", [transaction, doc2]); 4886 if (doc2._observers.has("update")) { 4887 const encoder = new UpdateEncoderV1(); 4888 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4889 if (hasContent2) { 4890 doc2.emit("update", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4891 } 4892 } 4893 if (doc2._observers.has("updateV2")) { 4894 const encoder = new UpdateEncoderV2(); 4895 const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); 4896 if (hasContent2) { 4897 doc2.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc2, transaction]); 4898 } 4899 } 4900 const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; 4901 if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { 4902 subdocsAdded.forEach((subdoc) => { 4903 subdoc.clientID = doc2.clientID; 4904 if (subdoc.collectionid == null) { 4905 subdoc.collectionid = doc2.collectionid; 4906 } 4907 doc2.subdocs.add(subdoc); 4908 }); 4909 subdocsRemoved.forEach((subdoc) => doc2.subdocs.delete(subdoc)); 4910 doc2.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc2, transaction]); 4911 subdocsRemoved.forEach((subdoc) => subdoc.destroy()); 4912 } 4913 if (transactionCleanups.length <= i + 1) { 4914 doc2._transactionCleanups = []; 4915 doc2.emit("afterAllTransactions", [doc2, transactionCleanups]); 4916 } else { 4917 cleanupTransactions(transactionCleanups, i + 1); 4918 } 4919 } 4920 } 4921 }; 4922 var transact = (doc2, f, origin2 = null, local = true) => { 4923 const transactionCleanups = doc2._transactionCleanups; 4924 let initialCall = false; 4925 let result = null; 4926 if (doc2._transaction === null) { 4927 initialCall = true; 4928 doc2._transaction = new Transaction(doc2, origin2, local); 4929 transactionCleanups.push(doc2._transaction); 4930 if (transactionCleanups.length === 1) { 4931 doc2.emit("beforeAllTransactions", [doc2]); 4932 } 4933 doc2.emit("beforeTransaction", [doc2._transaction, doc2]); 4934 } 4935 try { 4936 result = f(doc2._transaction); 4937 } finally { 4938 if (initialCall) { 4939 const finishCleanup = doc2._transaction === transactionCleanups[0]; 4940 doc2._transaction = null; 4941 if (finishCleanup) { 4942 cleanupTransactions(transactionCleanups, 0); 4943 } 4944 } 4945 } 4946 return result; 4947 }; 4948 var StackItem = class { 4949 /** 4950 * @param {DeleteSet} deletions 4951 * @param {DeleteSet} insertions 4952 */ 4953 constructor(deletions, insertions) { 4954 this.insertions = insertions; 4955 this.deletions = deletions; 4956 this.meta = /* @__PURE__ */ new Map(); 4957 } 4958 }; 4959 var clearUndoManagerStackItem = (tr, um, stackItem) => { 4960 iterateDeletedStructs(tr, stackItem.deletions, (item) => { 4961 if (item instanceof Item && um.scope.some((type) => type === tr.doc || isParentOf( 4962 /** @type {AbstractType<any>} */ 4963 type, 4964 item 4965 ))) { 4966 keepItem(item, false); 4967 } 4968 }); 4969 }; 4970 var popStackItem = (undoManager2, stack, eventType) => { 4971 let _tr = null; 4972 const doc2 = undoManager2.doc; 4973 const scope = undoManager2.scope; 4974 transact(doc2, (transaction) => { 4975 while (stack.length > 0 && undoManager2.currStackItem === null) { 4976 const store2 = doc2.store; 4977 const stackItem = ( 4978 /** @type {StackItem} */ 4979 stack.pop() 4980 ); 4981 const itemsToRedo = /* @__PURE__ */ new Set(); 4982 const itemsToDelete = []; 4983 let performedChange = false; 4984 iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { 4985 if (struct instanceof Item) { 4986 if (struct.redone !== null) { 4987 let { item, diff } = followRedone(store2, struct.id); 4988 if (diff > 0) { 4989 item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); 4990 } 4991 struct = item; 4992 } 4993 if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( 4994 /** @type {AbstractType<any>} */ 4995 type, 4996 /** @type {Item} */ 4997 struct 4998 ))) { 4999 itemsToDelete.push(struct); 5000 } 5001 } 5002 }); 5003 iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { 5004 if (struct instanceof Item && scope.some((type) => type === transaction.doc || isParentOf( 5005 /** @type {AbstractType<any>} */ 5006 type, 5007 struct 5008 )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. 5009 !isDeleted(stackItem.insertions, struct.id)) { 5010 itemsToRedo.add(struct); 5011 } 5012 }); 5013 itemsToRedo.forEach((struct) => { 5014 performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager2.ignoreRemoteMapChanges, undoManager2) !== null || performedChange; 5015 }); 5016 for (let i = itemsToDelete.length - 1; i >= 0; i--) { 5017 const item = itemsToDelete[i]; 5018 if (undoManager2.deleteFilter(item)) { 5019 item.delete(transaction); 5020 performedChange = true; 5021 } 5022 } 5023 undoManager2.currStackItem = performedChange ? stackItem : null; 5024 } 5025 transaction.changed.forEach((subProps, type) => { 5026 if (subProps.has(null) && type._searchMarker) { 5027 type._searchMarker.length = 0; 5028 } 5029 }); 5030 _tr = transaction; 5031 }, undoManager2); 5032 const res = undoManager2.currStackItem; 5033 if (res != null) { 5034 const changedParentTypes = _tr.changedParentTypes; 5035 undoManager2.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager2 }, undoManager2]); 5036 undoManager2.currStackItem = null; 5037 } 5038 return res; 5039 }; 5040 var UndoManager = class extends ObservableV2 { 5041 /** 5042 * @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. 5043 * @param {UndoManagerOptions} options 5044 */ 5045 constructor(typeScope, { 5046 captureTimeout = 500, 5047 captureTransaction = (_tr) => true, 5048 deleteFilter = () => true, 5049 trackedOrigins = /* @__PURE__ */ new Set([null]), 5050 ignoreRemoteMapChanges = false, 5051 doc: doc2 = ( 5052 /** @type {Doc} */ 5053 isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc 5054 ) 5055 } = {}) { 5056 super(); 5057 this.scope = []; 5058 this.doc = doc2; 5059 this.addToScope(typeScope); 5060 this.deleteFilter = deleteFilter; 5061 trackedOrigins.add(this); 5062 this.trackedOrigins = trackedOrigins; 5063 this.captureTransaction = captureTransaction; 5064 this.undoStack = []; 5065 this.redoStack = []; 5066 this.undoing = false; 5067 this.redoing = false; 5068 this.currStackItem = null; 5069 this.lastChange = 0; 5070 this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; 5071 this.captureTimeout = captureTimeout; 5072 this.afterTransactionHandler = (transaction) => { 5073 if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( 5074 /** @type {AbstractType<any>} */ 5075 type 5076 ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { 5077 return; 5078 } 5079 const undoing = this.undoing; 5080 const redoing = this.redoing; 5081 const stack = undoing ? this.redoStack : this.undoStack; 5082 if (undoing) { 5083 this.stopCapturing(); 5084 } else if (!redoing) { 5085 this.clear(false, true); 5086 } 5087 const insertions = new DeleteSet(); 5088 transaction.afterState.forEach((endClock, client) => { 5089 const startClock = transaction.beforeState.get(client) || 0; 5090 const len = endClock - startClock; 5091 if (len > 0) { 5092 addToDeleteSet(insertions, client, startClock, len); 5093 } 5094 }); 5095 const now = getUnixTime(); 5096 let didAdd = false; 5097 if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { 5098 const lastOp = stack[stack.length - 1]; 5099 lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); 5100 lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); 5101 } else { 5102 stack.push(new StackItem(transaction.deleteSet, insertions)); 5103 didAdd = true; 5104 } 5105 if (!undoing && !redoing) { 5106 this.lastChange = now; 5107 } 5108 iterateDeletedStructs( 5109 transaction, 5110 transaction.deleteSet, 5111 /** @param {Item|GC} item */ 5112 (item) => { 5113 if (item instanceof Item && this.scope.some((type) => type === transaction.doc || isParentOf( 5114 /** @type {AbstractType<any>} */ 5115 type, 5116 item 5117 ))) { 5118 keepItem(item, true); 5119 } 5120 } 5121 ); 5122 const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; 5123 if (didAdd) { 5124 this.emit("stack-item-added", changeEvent); 5125 } else { 5126 this.emit("stack-item-updated", changeEvent); 5127 } 5128 }; 5129 this.doc.on("afterTransaction", this.afterTransactionHandler); 5130 this.doc.on("destroy", () => { 5131 this.destroy(); 5132 }); 5133 } 5134 /** 5135 * Extend the scope. 5136 * 5137 * @param {Array<AbstractType<any> | Doc> | AbstractType<any> | Doc} ytypes 5138 */ 5139 addToScope(ytypes) { 5140 const tmpSet = new Set(this.scope); 5141 ytypes = isArray(ytypes) ? ytypes : [ytypes]; 5142 ytypes.forEach((ytype) => { 5143 if (!tmpSet.has(ytype)) { 5144 tmpSet.add(ytype); 5145 if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn("[yjs#509] Not same Y.Doc"); 5146 this.scope.push(ytype); 5147 } 5148 }); 5149 } 5150 /** 5151 * @param {any} origin 5152 */ 5153 addTrackedOrigin(origin2) { 5154 this.trackedOrigins.add(origin2); 5155 } 5156 /** 5157 * @param {any} origin 5158 */ 5159 removeTrackedOrigin(origin2) { 5160 this.trackedOrigins.delete(origin2); 5161 } 5162 clear(clearUndoStack = true, clearRedoStack = true) { 5163 if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { 5164 this.doc.transact((tr) => { 5165 if (clearUndoStack) { 5166 this.undoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 5167 this.undoStack = []; 5168 } 5169 if (clearRedoStack) { 5170 this.redoStack.forEach((item) => clearUndoManagerStackItem(tr, this, item)); 5171 this.redoStack = []; 5172 } 5173 this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); 5174 }); 5175 } 5176 } 5177 /** 5178 * UndoManager merges Undo-StackItem if they are created within time-gap 5179 * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next 5180 * StackItem won't be merged. 5181 * 5182 * 5183 * @example 5184 * // without stopCapturing 5185 * ytext.insert(0, 'a') 5186 * ytext.insert(1, 'b') 5187 * um.undo() 5188 * ytext.toString() // => '' (note that 'ab' was removed) 5189 * // with stopCapturing 5190 * ytext.insert(0, 'a') 5191 * um.stopCapturing() 5192 * ytext.insert(0, 'b') 5193 * um.undo() 5194 * ytext.toString() // => 'a' (note that only 'b' was removed) 5195 * 5196 */ 5197 stopCapturing() { 5198 this.lastChange = 0; 5199 } 5200 /** 5201 * Undo last changes on type. 5202 * 5203 * @return {StackItem?} Returns StackItem if a change was applied 5204 */ 5205 undo() { 5206 this.undoing = true; 5207 let res; 5208 try { 5209 res = popStackItem(this, this.undoStack, "undo"); 5210 } finally { 5211 this.undoing = false; 5212 } 5213 return res; 5214 } 5215 /** 5216 * Redo last undo operation. 5217 * 5218 * @return {StackItem?} Returns StackItem if a change was applied 5219 */ 5220 redo() { 5221 this.redoing = true; 5222 let res; 5223 try { 5224 res = popStackItem(this, this.redoStack, "redo"); 5225 } finally { 5226 this.redoing = false; 5227 } 5228 return res; 5229 } 5230 /** 5231 * Are undo steps available? 5232 * 5233 * @return {boolean} `true` if undo is possible 5234 */ 5235 canUndo() { 5236 return this.undoStack.length > 0; 5237 } 5238 /** 5239 * Are redo steps available? 5240 * 5241 * @return {boolean} `true` if redo is possible 5242 */ 5243 canRedo() { 5244 return this.redoStack.length > 0; 5245 } 5246 destroy() { 5247 this.trackedOrigins.delete(this); 5248 this.doc.off("afterTransaction", this.afterTransactionHandler); 5249 super.destroy(); 5250 } 5251 }; 5252 function* lazyStructReaderGenerator(decoder) { 5253 const numOfStateUpdates = readVarUint(decoder.restDecoder); 5254 for (let i = 0; i < numOfStateUpdates; i++) { 5255 const numberOfStructs = readVarUint(decoder.restDecoder); 5256 const client = decoder.readClient(); 5257 let clock = readVarUint(decoder.restDecoder); 5258 for (let i2 = 0; i2 < numberOfStructs; i2++) { 5259 const info = decoder.readInfo(); 5260 if (info === 10) { 5261 const len = readVarUint(decoder.restDecoder); 5262 yield new Skip(createID(client, clock), len); 5263 clock += len; 5264 } else if ((BITS5 & info) !== 0) { 5265 const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; 5266 const struct = new Item( 5267 createID(client, clock), 5268 null, 5269 // left 5270 (info & BIT8) === BIT8 ? decoder.readLeftID() : null, 5271 // origin 5272 null, 5273 // right 5274 (info & BIT7) === BIT7 ? decoder.readRightID() : null, 5275 // right origin 5276 // @ts-ignore Force writing a string here. 5277 cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, 5278 // parent 5279 cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, 5280 // parentSub 5281 readItemContent(decoder, info) 5282 // item content 5283 ); 5284 yield struct; 5285 clock += struct.length; 5286 } else { 5287 const len = decoder.readLen(); 5288 yield new GC(createID(client, clock), len); 5289 clock += len; 5290 } 5291 } 5292 } 5293 } 5294 var LazyStructReader = class { 5295 /** 5296 * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder 5297 * @param {boolean} filterSkips 5298 */ 5299 constructor(decoder, filterSkips) { 5300 this.gen = lazyStructReaderGenerator(decoder); 5301 this.curr = null; 5302 this.done = false; 5303 this.filterSkips = filterSkips; 5304 this.next(); 5305 } 5306 /** 5307 * @return {Item | GC | Skip |null} 5308 */ 5309 next() { 5310 do { 5311 this.curr = this.gen.next().value || null; 5312 } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); 5313 return this.curr; 5314 } 5315 }; 5316 var logUpdate = (update) => logUpdateV2(update, UpdateDecoderV1); 5317 var logUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 5318 const structs = []; 5319 const updateDecoder = new YDecoder(createDecoder(update)); 5320 const lazyDecoder = new LazyStructReader(updateDecoder, false); 5321 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 5322 structs.push(curr); 5323 } 5324 print("Structs: ", structs); 5325 const ds = readDeleteSet(updateDecoder); 5326 print("DeleteSet: ", ds); 5327 }; 5328 var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1); 5329 var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => { 5330 const structs = []; 5331 const updateDecoder = new YDecoder(createDecoder(update)); 5332 const lazyDecoder = new LazyStructReader(updateDecoder, false); 5333 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 5334 structs.push(curr); 5335 } 5336 return { 5337 structs, 5338 ds: readDeleteSet(updateDecoder) 5339 }; 5340 }; 5341 var LazyStructWriter = class { 5342 /** 5343 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 5344 */ 5345 constructor(encoder) { 5346 this.currClient = 0; 5347 this.startClock = 0; 5348 this.written = 0; 5349 this.encoder = encoder; 5350 this.clientStructs = []; 5351 } 5352 }; 5353 var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); 5354 var encodeStateVectorFromUpdateV2 = (update, YEncoder = DSEncoderV2, YDecoder = UpdateDecoderV2) => { 5355 const encoder = new YEncoder(); 5356 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 5357 let curr = updateDecoder.curr; 5358 if (curr !== null) { 5359 let size2 = 0; 5360 let currClient = curr.id.client; 5361 let stopCounting = curr.id.clock !== 0; 5362 let currClock = stopCounting ? 0 : curr.id.clock + curr.length; 5363 for (; curr !== null; curr = updateDecoder.next()) { 5364 if (currClient !== curr.id.client) { 5365 if (currClock !== 0) { 5366 size2++; 5367 writeVarUint(encoder.restEncoder, currClient); 5368 writeVarUint(encoder.restEncoder, currClock); 5369 } 5370 currClient = curr.id.client; 5371 currClock = 0; 5372 stopCounting = curr.id.clock !== 0; 5373 } 5374 if (curr.constructor === Skip) { 5375 stopCounting = true; 5376 } 5377 if (!stopCounting) { 5378 currClock = curr.id.clock + curr.length; 5379 } 5380 } 5381 if (currClock !== 0) { 5382 size2++; 5383 writeVarUint(encoder.restEncoder, currClient); 5384 writeVarUint(encoder.restEncoder, currClock); 5385 } 5386 const enc = createEncoder(); 5387 writeVarUint(enc, size2); 5388 writeBinaryEncoder(enc, encoder.restEncoder); 5389 encoder.restEncoder = enc; 5390 return encoder.toUint8Array(); 5391 } else { 5392 writeVarUint(encoder.restEncoder, 0); 5393 return encoder.toUint8Array(); 5394 } 5395 }; 5396 var encodeStateVectorFromUpdate = (update) => encodeStateVectorFromUpdateV2(update, DSEncoderV1, UpdateDecoderV1); 5397 var parseUpdateMetaV2 = (update, YDecoder = UpdateDecoderV2) => { 5398 const from2 = /* @__PURE__ */ new Map(); 5399 const to = /* @__PURE__ */ new Map(); 5400 const updateDecoder = new LazyStructReader(new YDecoder(createDecoder(update)), false); 5401 let curr = updateDecoder.curr; 5402 if (curr !== null) { 5403 let currClient = curr.id.client; 5404 let currClock = curr.id.clock; 5405 from2.set(currClient, currClock); 5406 for (; curr !== null; curr = updateDecoder.next()) { 5407 if (currClient !== curr.id.client) { 5408 to.set(currClient, currClock); 5409 from2.set(curr.id.client, curr.id.clock); 5410 currClient = curr.id.client; 5411 } 5412 currClock = curr.id.clock + curr.length; 5413 } 5414 to.set(currClient, currClock); 5415 } 5416 return { from: from2, to }; 5417 }; 5418 var parseUpdateMeta = (update) => parseUpdateMetaV2(update, UpdateDecoderV1); 5419 var sliceStruct = (left, diff) => { 5420 if (left.constructor === GC) { 5421 const { client, clock } = left.id; 5422 return new GC(createID(client, clock + diff), left.length - diff); 5423 } else if (left.constructor === Skip) { 5424 const { client, clock } = left.id; 5425 return new Skip(createID(client, clock + diff), left.length - diff); 5426 } else { 5427 const leftItem = ( 5428 /** @type {Item} */ 5429 left 5430 ); 5431 const { client, clock } = leftItem.id; 5432 return new Item( 5433 createID(client, clock + diff), 5434 null, 5435 createID(client, clock + diff - 1), 5436 null, 5437 leftItem.rightOrigin, 5438 leftItem.parent, 5439 leftItem.parentSub, 5440 leftItem.content.splice(diff) 5441 ); 5442 } 5443 }; 5444 var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 5445 if (updates.length === 1) { 5446 return updates[0]; 5447 } 5448 const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); 5449 let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); 5450 let currWrite = null; 5451 const updateEncoder = new YEncoder(); 5452 const lazyStructEncoder = new LazyStructWriter(updateEncoder); 5453 while (true) { 5454 lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); 5455 lazyStructDecoders.sort( 5456 /** @type {function(any,any):number} */ 5457 (dec1, dec2) => { 5458 if (dec1.curr.id.client === dec2.curr.id.client) { 5459 const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; 5460 if (clockDiff === 0) { 5461 return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; 5462 } else { 5463 return clockDiff; 5464 } 5465 } else { 5466 return dec2.curr.id.client - dec1.curr.id.client; 5467 } 5468 } 5469 ); 5470 if (lazyStructDecoders.length === 0) { 5471 break; 5472 } 5473 const currDecoder = lazyStructDecoders[0]; 5474 const firstClient = ( 5475 /** @type {Item | GC} */ 5476 currDecoder.curr.id.client 5477 ); 5478 if (currWrite !== null) { 5479 let curr = ( 5480 /** @type {Item | GC | null} */ 5481 currDecoder.curr 5482 ); 5483 let iterated = false; 5484 while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { 5485 curr = currDecoder.next(); 5486 iterated = true; 5487 } 5488 if (curr === null || // current decoder is empty 5489 curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` 5490 iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { 5491 continue; 5492 } 5493 if (firstClient !== currWrite.struct.id.client) { 5494 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 5495 currWrite = { struct: curr, offset: 0 }; 5496 currDecoder.next(); 5497 } else { 5498 if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { 5499 if (currWrite.struct.constructor === Skip) { 5500 currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; 5501 } else { 5502 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 5503 const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; 5504 const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); 5505 currWrite = { struct, offset: 0 }; 5506 } 5507 } else { 5508 const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; 5509 if (diff > 0) { 5510 if (currWrite.struct.constructor === Skip) { 5511 currWrite.struct.length -= diff; 5512 } else { 5513 curr = sliceStruct(curr, diff); 5514 } 5515 } 5516 if (!currWrite.struct.mergeWith( 5517 /** @type {any} */ 5518 curr 5519 )) { 5520 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 5521 currWrite = { struct: curr, offset: 0 }; 5522 currDecoder.next(); 5523 } 5524 } 5525 } 5526 } else { 5527 currWrite = { struct: ( 5528 /** @type {Item | GC} */ 5529 currDecoder.curr 5530 ), offset: 0 }; 5531 currDecoder.next(); 5532 } 5533 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()) { 5534 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 5535 currWrite = { struct: next, offset: 0 }; 5536 } 5537 } 5538 if (currWrite !== null) { 5539 writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); 5540 currWrite = null; 5541 } 5542 finishLazyStructWriting(lazyStructEncoder); 5543 const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); 5544 const ds = mergeDeleteSets(dss); 5545 writeDeleteSet(updateEncoder, ds); 5546 return updateEncoder.toUint8Array(); 5547 }; 5548 var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { 5549 const state = decodeStateVector(sv); 5550 const encoder = new YEncoder(); 5551 const lazyStructWriter = new LazyStructWriter(encoder); 5552 const decoder = new YDecoder(createDecoder(update)); 5553 const reader = new LazyStructReader(decoder, false); 5554 while (reader.curr) { 5555 const curr = reader.curr; 5556 const currClient = curr.id.client; 5557 const svClock = state.get(currClient) || 0; 5558 if (reader.curr.constructor === Skip) { 5559 reader.next(); 5560 continue; 5561 } 5562 if (curr.id.clock + curr.length > svClock) { 5563 writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); 5564 reader.next(); 5565 while (reader.curr && reader.curr.id.client === currClient) { 5566 writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); 5567 reader.next(); 5568 } 5569 } else { 5570 while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { 5571 reader.next(); 5572 } 5573 } 5574 } 5575 finishLazyStructWriting(lazyStructWriter); 5576 const ds = readDeleteSet(decoder); 5577 writeDeleteSet(encoder, ds); 5578 return encoder.toUint8Array(); 5579 }; 5580 var diffUpdate = (update, sv) => diffUpdateV2(update, sv, UpdateDecoderV1, UpdateEncoderV1); 5581 var flushLazyStructWriter = (lazyWriter) => { 5582 if (lazyWriter.written > 0) { 5583 lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); 5584 lazyWriter.encoder.restEncoder = createEncoder(); 5585 lazyWriter.written = 0; 5586 } 5587 }; 5588 var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { 5589 if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { 5590 flushLazyStructWriter(lazyWriter); 5591 } 5592 if (lazyWriter.written === 0) { 5593 lazyWriter.currClient = struct.id.client; 5594 lazyWriter.encoder.writeClient(struct.id.client); 5595 writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); 5596 } 5597 struct.write(lazyWriter.encoder, offset); 5598 lazyWriter.written++; 5599 }; 5600 var finishLazyStructWriting = (lazyWriter) => { 5601 flushLazyStructWriter(lazyWriter); 5602 const restEncoder = lazyWriter.encoder.restEncoder; 5603 writeVarUint(restEncoder, lazyWriter.clientStructs.length); 5604 for (let i = 0; i < lazyWriter.clientStructs.length; i++) { 5605 const partStructs = lazyWriter.clientStructs[i]; 5606 writeVarUint(restEncoder, partStructs.written); 5607 writeUint8Array(restEncoder, partStructs.restEncoder); 5608 } 5609 }; 5610 var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { 5611 const updateDecoder = new YDecoder(createDecoder(update)); 5612 const lazyDecoder = new LazyStructReader(updateDecoder, false); 5613 const updateEncoder = new YEncoder(); 5614 const lazyWriter = new LazyStructWriter(updateEncoder); 5615 for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { 5616 writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); 5617 } 5618 finishLazyStructWriting(lazyWriter); 5619 const ds = readDeleteSet(updateDecoder); 5620 writeDeleteSet(updateEncoder, ds); 5621 return updateEncoder.toUint8Array(); 5622 }; 5623 var createObfuscator = ({ formatting = true, subdocs = true, yxml = true } = {}) => { 5624 let i = 0; 5625 const mapKeyCache = create(); 5626 const nodeNameCache = create(); 5627 const formattingKeyCache = create(); 5628 const formattingValueCache = create(); 5629 formattingValueCache.set(null, null); 5630 return (block) => { 5631 switch (block.constructor) { 5632 case GC: 5633 case Skip: 5634 return block; 5635 case Item: { 5636 const item = ( 5637 /** @type {Item} */ 5638 block 5639 ); 5640 const content = item.content; 5641 switch (content.constructor) { 5642 case ContentDeleted: 5643 break; 5644 case ContentType: { 5645 if (yxml) { 5646 const type = ( 5647 /** @type {ContentType} */ 5648 content.type 5649 ); 5650 if (type instanceof YXmlElement) { 5651 type.nodeName = setIfUndefined(nodeNameCache, type.nodeName, () => "node-" + i); 5652 } 5653 if (type instanceof YXmlHook) { 5654 type.hookName = setIfUndefined(nodeNameCache, type.hookName, () => "hook-" + i); 5655 } 5656 } 5657 break; 5658 } 5659 case ContentAny: { 5660 const c = ( 5661 /** @type {ContentAny} */ 5662 content 5663 ); 5664 c.arr = c.arr.map(() => i); 5665 break; 5666 } 5667 case ContentBinary: { 5668 const c = ( 5669 /** @type {ContentBinary} */ 5670 content 5671 ); 5672 c.content = new Uint8Array([i]); 5673 break; 5674 } 5675 case ContentDoc: { 5676 const c = ( 5677 /** @type {ContentDoc} */ 5678 content 5679 ); 5680 if (subdocs) { 5681 c.opts = {}; 5682 c.doc.guid = i + ""; 5683 } 5684 break; 5685 } 5686 case ContentEmbed: { 5687 const c = ( 5688 /** @type {ContentEmbed} */ 5689 content 5690 ); 5691 c.embed = {}; 5692 break; 5693 } 5694 case ContentFormat: { 5695 const c = ( 5696 /** @type {ContentFormat} */ 5697 content 5698 ); 5699 if (formatting) { 5700 c.key = setIfUndefined(formattingKeyCache, c.key, () => i + ""); 5701 c.value = setIfUndefined(formattingValueCache, c.value, () => ({ i })); 5702 } 5703 break; 5704 } 5705 case ContentJSON: { 5706 const c = ( 5707 /** @type {ContentJSON} */ 5708 content 5709 ); 5710 c.arr = c.arr.map(() => i); 5711 break; 5712 } 5713 case ContentString: { 5714 const c = ( 5715 /** @type {ContentString} */ 5716 content 5717 ); 5718 c.str = repeat(i % 10 + "", c.str.length); 5719 break; 5720 } 5721 default: 5722 unexpectedCase(); 5723 } 5724 if (item.parentSub) { 5725 item.parentSub = setIfUndefined(mapKeyCache, item.parentSub, () => i + ""); 5726 } 5727 i++; 5728 return block; 5729 } 5730 default: 5731 unexpectedCase(); 5732 } 5733 }; 5734 }; 5735 var obfuscateUpdate = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV1, UpdateEncoderV1); 5736 var obfuscateUpdateV2 = (update, opts) => convertUpdateFormat(update, createObfuscator(opts), UpdateDecoderV2, UpdateEncoderV2); 5737 var convertUpdateFormatV1ToV2 = (update) => convertUpdateFormat(update, id, UpdateDecoderV1, UpdateEncoderV2); 5738 var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); 5739 var errorComputeChanges = "You must not compute changes after the event-handler fired."; 5740 var YEvent = class { 5741 /** 5742 * @param {T} target The changed type. 5743 * @param {Transaction} transaction 5744 */ 5745 constructor(target, transaction) { 5746 this.target = target; 5747 this.currentTarget = target; 5748 this.transaction = transaction; 5749 this._changes = null; 5750 this._keys = null; 5751 this._delta = null; 5752 this._path = null; 5753 } 5754 /** 5755 * Computes the path from `y` to the changed type. 5756 * 5757 * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. 5758 * 5759 * The following property holds: 5760 * @example 5761 * let type = y 5762 * event.path.forEach(dir => { 5763 * type = type.get(dir) 5764 * }) 5765 * type === event.target // => true 5766 */ 5767 get path() { 5768 return this._path || (this._path = getPathTo(this.currentTarget, this.target)); 5769 } 5770 /** 5771 * Check if a struct is deleted by this event. 5772 * 5773 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5774 * 5775 * @param {AbstractStruct} struct 5776 * @return {boolean} 5777 */ 5778 deletes(struct) { 5779 return isDeleted(this.transaction.deleteSet, struct.id); 5780 } 5781 /** 5782 * @type {Map<string, { action: 'add' | 'update' | 'delete', oldValue: any }>} 5783 */ 5784 get keys() { 5785 if (this._keys === null) { 5786 if (this.transaction.doc._transactionCleanups.length === 0) { 5787 throw create3(errorComputeChanges); 5788 } 5789 const keys2 = /* @__PURE__ */ new Map(); 5790 const target = this.target; 5791 const changed = ( 5792 /** @type Set<string|null> */ 5793 this.transaction.changed.get(target) 5794 ); 5795 changed.forEach((key) => { 5796 if (key !== null) { 5797 const item = ( 5798 /** @type {Item} */ 5799 target._map.get(key) 5800 ); 5801 let action; 5802 let oldValue; 5803 if (this.adds(item)) { 5804 let prev = item.left; 5805 while (prev !== null && this.adds(prev)) { 5806 prev = prev.left; 5807 } 5808 if (this.deletes(item)) { 5809 if (prev !== null && this.deletes(prev)) { 5810 action = "delete"; 5811 oldValue = last(prev.content.getContent()); 5812 } else { 5813 return; 5814 } 5815 } else { 5816 if (prev !== null && this.deletes(prev)) { 5817 action = "update"; 5818 oldValue = last(prev.content.getContent()); 5819 } else { 5820 action = "add"; 5821 oldValue = void 0; 5822 } 5823 } 5824 } else { 5825 if (this.deletes(item)) { 5826 action = "delete"; 5827 oldValue = last( 5828 /** @type {Item} */ 5829 item.content.getContent() 5830 ); 5831 } else { 5832 return; 5833 } 5834 } 5835 keys2.set(key, { action, oldValue }); 5836 } 5837 }); 5838 this._keys = keys2; 5839 } 5840 return this._keys; 5841 } 5842 /** 5843 * This is a computed property. Note that this can only be safely computed during the 5844 * event call. Computing this property after other changes happened might result in 5845 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5846 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5847 * 5848 * @type {Array<{insert?: string | Array<any> | object | AbstractType<any>, retain?: number, delete?: number, attributes?: Object<string, any>}>} 5849 */ 5850 get delta() { 5851 return this.changes.delta; 5852 } 5853 /** 5854 * Check if a struct is added by this event. 5855 * 5856 * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. 5857 * 5858 * @param {AbstractStruct} struct 5859 * @return {boolean} 5860 */ 5861 adds(struct) { 5862 return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); 5863 } 5864 /** 5865 * This is a computed property. Note that this can only be safely computed during the 5866 * event call. Computing this property after other changes happened might result in 5867 * unexpected behavior (incorrect computation of deltas). A safe way to collect changes 5868 * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. 5869 * 5870 * @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}>}} 5871 */ 5872 get changes() { 5873 let changes = this._changes; 5874 if (changes === null) { 5875 if (this.transaction.doc._transactionCleanups.length === 0) { 5876 throw create3(errorComputeChanges); 5877 } 5878 const target = this.target; 5879 const added = create2(); 5880 const deleted = create2(); 5881 const delta = []; 5882 changes = { 5883 added, 5884 deleted, 5885 delta, 5886 keys: this.keys 5887 }; 5888 const changed = ( 5889 /** @type Set<string|null> */ 5890 this.transaction.changed.get(target) 5891 ); 5892 if (changed.has(null)) { 5893 let lastOp = null; 5894 const packOp = () => { 5895 if (lastOp) { 5896 delta.push(lastOp); 5897 } 5898 }; 5899 for (let item = target._start; item !== null; item = item.right) { 5900 if (item.deleted) { 5901 if (this.deletes(item) && !this.adds(item)) { 5902 if (lastOp === null || lastOp.delete === void 0) { 5903 packOp(); 5904 lastOp = { delete: 0 }; 5905 } 5906 lastOp.delete += item.length; 5907 deleted.add(item); 5908 } 5909 } else { 5910 if (this.adds(item)) { 5911 if (lastOp === null || lastOp.insert === void 0) { 5912 packOp(); 5913 lastOp = { insert: [] }; 5914 } 5915 lastOp.insert = lastOp.insert.concat(item.content.getContent()); 5916 added.add(item); 5917 } else { 5918 if (lastOp === null || lastOp.retain === void 0) { 5919 packOp(); 5920 lastOp = { retain: 0 }; 5921 } 5922 lastOp.retain += item.length; 5923 } 5924 } 5925 } 5926 if (lastOp !== null && lastOp.retain === void 0) { 5927 packOp(); 5928 } 5929 } 5930 this._changes = changes; 5931 } 5932 return ( 5933 /** @type {any} */ 5934 changes 5935 ); 5936 } 5937 }; 5938 var getPathTo = (parent, child) => { 5939 const path = []; 5940 while (child._item !== null && child !== parent) { 5941 if (child._item.parentSub !== null) { 5942 path.unshift(child._item.parentSub); 5943 } else { 5944 let i = 0; 5945 let c = ( 5946 /** @type {AbstractType<any>} */ 5947 child._item.parent._start 5948 ); 5949 while (c !== child._item && c !== null) { 5950 if (!c.deleted && c.countable) { 5951 i += c.length; 5952 } 5953 c = c.right; 5954 } 5955 path.unshift(i); 5956 } 5957 child = /** @type {AbstractType<any>} */ 5958 child._item.parent; 5959 } 5960 return path; 5961 }; 5962 var warnPrematureAccess = () => { 5963 warn("Invalid access: Add Yjs type to a document before reading data."); 5964 }; 5965 var maxSearchMarker = 80; 5966 var globalSearchMarkerTimestamp = 0; 5967 var ArraySearchMarker = class { 5968 /** 5969 * @param {Item} p 5970 * @param {number} index 5971 */ 5972 constructor(p, index) { 5973 p.marker = true; 5974 this.p = p; 5975 this.index = index; 5976 this.timestamp = globalSearchMarkerTimestamp++; 5977 } 5978 }; 5979 var refreshMarkerTimestamp = (marker) => { 5980 marker.timestamp = globalSearchMarkerTimestamp++; 5981 }; 5982 var overwriteMarker = (marker, p, index) => { 5983 marker.p.marker = false; 5984 marker.p = p; 5985 p.marker = true; 5986 marker.index = index; 5987 marker.timestamp = globalSearchMarkerTimestamp++; 5988 }; 5989 var markPosition = (searchMarker, p, index) => { 5990 if (searchMarker.length >= maxSearchMarker) { 5991 const marker = searchMarker.reduce((a, b) => a.timestamp < b.timestamp ? a : b); 5992 overwriteMarker(marker, p, index); 5993 return marker; 5994 } else { 5995 const pm = new ArraySearchMarker(p, index); 5996 searchMarker.push(pm); 5997 return pm; 5998 } 5999 }; 6000 var findMarker = (yarray, index) => { 6001 if (yarray._start === null || index === 0 || yarray._searchMarker === null) { 6002 return null; 6003 } 6004 const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b) => abs(index - a.index) < abs(index - b.index) ? a : b); 6005 let p = yarray._start; 6006 let pindex = 0; 6007 if (marker !== null) { 6008 p = marker.p; 6009 pindex = marker.index; 6010 refreshMarkerTimestamp(marker); 6011 } 6012 while (p.right !== null && pindex < index) { 6013 if (!p.deleted && p.countable) { 6014 if (index < pindex + p.length) { 6015 break; 6016 } 6017 pindex += p.length; 6018 } 6019 p = p.right; 6020 } 6021 while (p.left !== null && pindex > index) { 6022 p = p.left; 6023 if (!p.deleted && p.countable) { 6024 pindex -= p.length; 6025 } 6026 } 6027 while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { 6028 p = p.left; 6029 if (!p.deleted && p.countable) { 6030 pindex -= p.length; 6031 } 6032 } 6033 if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray<any>} */ 6034 p.parent.length / maxSearchMarker) { 6035 overwriteMarker(marker, p, pindex); 6036 return marker; 6037 } else { 6038 return markPosition(yarray._searchMarker, p, pindex); 6039 } 6040 }; 6041 var updateMarkerChanges = (searchMarker, index, len) => { 6042 for (let i = searchMarker.length - 1; i >= 0; i--) { 6043 const m = searchMarker[i]; 6044 if (len > 0) { 6045 let p = m.p; 6046 p.marker = false; 6047 while (p && (p.deleted || !p.countable)) { 6048 p = p.left; 6049 if (p && !p.deleted && p.countable) { 6050 m.index -= p.length; 6051 } 6052 } 6053 if (p === null || p.marker === true) { 6054 searchMarker.splice(i, 1); 6055 continue; 6056 } 6057 m.p = p; 6058 p.marker = true; 6059 } 6060 if (index < m.index || len > 0 && index === m.index) { 6061 m.index = max(index, m.index + len); 6062 } 6063 } 6064 }; 6065 var getTypeChildren = (t) => { 6066 t.doc ?? warnPrematureAccess(); 6067 let s = t._start; 6068 const arr = []; 6069 while (s) { 6070 arr.push(s); 6071 s = s.right; 6072 } 6073 return arr; 6074 }; 6075 var callTypeObservers = (type, transaction, event) => { 6076 const changedType = type; 6077 const changedParentTypes = transaction.changedParentTypes; 6078 while (true) { 6079 setIfUndefined(changedParentTypes, type, () => []).push(event); 6080 if (type._item === null) { 6081 break; 6082 } 6083 type = /** @type {AbstractType<any>} */ 6084 type._item.parent; 6085 } 6086 callEventHandlerListeners(changedType._eH, event, transaction); 6087 }; 6088 var AbstractType = class { 6089 constructor() { 6090 this._item = null; 6091 this._map = /* @__PURE__ */ new Map(); 6092 this._start = null; 6093 this.doc = null; 6094 this._length = 0; 6095 this._eH = createEventHandler(); 6096 this._dEH = createEventHandler(); 6097 this._searchMarker = null; 6098 } 6099 /** 6100 * @return {AbstractType<any>|null} 6101 */ 6102 get parent() { 6103 return this._item ? ( 6104 /** @type {AbstractType<any>} */ 6105 this._item.parent 6106 ) : null; 6107 } 6108 /** 6109 * Integrate this type into the Yjs instance. 6110 * 6111 * * Save this struct in the os 6112 * * This type is sent to other client 6113 * * Observer functions are fired 6114 * 6115 * @param {Doc} y The Yjs instance 6116 * @param {Item|null} item 6117 */ 6118 _integrate(y, item) { 6119 this.doc = y; 6120 this._item = item; 6121 } 6122 /** 6123 * @return {AbstractType<EventType>} 6124 */ 6125 _copy() { 6126 throw methodUnimplemented(); 6127 } 6128 /** 6129 * Makes a copy of this data type that can be included somewhere else. 6130 * 6131 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6132 * 6133 * @return {AbstractType<EventType>} 6134 */ 6135 clone() { 6136 throw methodUnimplemented(); 6137 } 6138 /** 6139 * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder 6140 */ 6141 _write(_encoder) { 6142 } 6143 /** 6144 * The first non-deleted item 6145 */ 6146 get _first() { 6147 let n = this._start; 6148 while (n !== null && n.deleted) { 6149 n = n.right; 6150 } 6151 return n; 6152 } 6153 /** 6154 * Creates YEvent and calls all type observers. 6155 * Must be implemented by each type. 6156 * 6157 * @param {Transaction} transaction 6158 * @param {Set<null|string>} _parentSubs Keys changed on this type. `null` if list was modified. 6159 */ 6160 _callObserver(transaction, _parentSubs) { 6161 if (!transaction.local && this._searchMarker) { 6162 this._searchMarker.length = 0; 6163 } 6164 } 6165 /** 6166 * Observe all events that are created on this type. 6167 * 6168 * @param {function(EventType, Transaction):void} f Observer function 6169 */ 6170 observe(f) { 6171 addEventHandlerListener(this._eH, f); 6172 } 6173 /** 6174 * Observe all events that are created by this type and its children. 6175 * 6176 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 6177 */ 6178 observeDeep(f) { 6179 addEventHandlerListener(this._dEH, f); 6180 } 6181 /** 6182 * Unregister an observer function. 6183 * 6184 * @param {function(EventType,Transaction):void} f Observer function 6185 */ 6186 unobserve(f) { 6187 removeEventHandlerListener(this._eH, f); 6188 } 6189 /** 6190 * Unregister an observer function. 6191 * 6192 * @param {function(Array<YEvent<any>>,Transaction):void} f Observer function 6193 */ 6194 unobserveDeep(f) { 6195 removeEventHandlerListener(this._dEH, f); 6196 } 6197 /** 6198 * @abstract 6199 * @return {any} 6200 */ 6201 toJSON() { 6202 } 6203 }; 6204 var typeListSlice = (type, start, end) => { 6205 type.doc ?? warnPrematureAccess(); 6206 if (start < 0) { 6207 start = type._length + start; 6208 } 6209 if (end < 0) { 6210 end = type._length + end; 6211 } 6212 let len = end - start; 6213 const cs = []; 6214 let n = type._start; 6215 while (n !== null && len > 0) { 6216 if (n.countable && !n.deleted) { 6217 const c = n.content.getContent(); 6218 if (c.length <= start) { 6219 start -= c.length; 6220 } else { 6221 for (let i = start; i < c.length && len > 0; i++) { 6222 cs.push(c[i]); 6223 len--; 6224 } 6225 start = 0; 6226 } 6227 } 6228 n = n.right; 6229 } 6230 return cs; 6231 }; 6232 var typeListToArray = (type) => { 6233 type.doc ?? warnPrematureAccess(); 6234 const cs = []; 6235 let n = type._start; 6236 while (n !== null) { 6237 if (n.countable && !n.deleted) { 6238 const c = n.content.getContent(); 6239 for (let i = 0; i < c.length; i++) { 6240 cs.push(c[i]); 6241 } 6242 } 6243 n = n.right; 6244 } 6245 return cs; 6246 }; 6247 var typeListToArraySnapshot = (type, snapshot2) => { 6248 const cs = []; 6249 let n = type._start; 6250 while (n !== null) { 6251 if (n.countable && isVisible(n, snapshot2)) { 6252 const c = n.content.getContent(); 6253 for (let i = 0; i < c.length; i++) { 6254 cs.push(c[i]); 6255 } 6256 } 6257 n = n.right; 6258 } 6259 return cs; 6260 }; 6261 var typeListForEach = (type, f) => { 6262 let index = 0; 6263 let n = type._start; 6264 type.doc ?? warnPrematureAccess(); 6265 while (n !== null) { 6266 if (n.countable && !n.deleted) { 6267 const c = n.content.getContent(); 6268 for (let i = 0; i < c.length; i++) { 6269 f(c[i], index++, type); 6270 } 6271 } 6272 n = n.right; 6273 } 6274 }; 6275 var typeListMap = (type, f) => { 6276 const result = []; 6277 typeListForEach(type, (c, i) => { 6278 result.push(f(c, i, type)); 6279 }); 6280 return result; 6281 }; 6282 var typeListCreateIterator = (type) => { 6283 let n = type._start; 6284 let currentContent = null; 6285 let currentContentIndex = 0; 6286 return { 6287 [Symbol.iterator]() { 6288 return this; 6289 }, 6290 next: () => { 6291 if (currentContent === null) { 6292 while (n !== null && n.deleted) { 6293 n = n.right; 6294 } 6295 if (n === null) { 6296 return { 6297 done: true, 6298 value: void 0 6299 }; 6300 } 6301 currentContent = n.content.getContent(); 6302 currentContentIndex = 0; 6303 n = n.right; 6304 } 6305 const value = currentContent[currentContentIndex++]; 6306 if (currentContent.length <= currentContentIndex) { 6307 currentContent = null; 6308 } 6309 return { 6310 done: false, 6311 value 6312 }; 6313 } 6314 }; 6315 }; 6316 var typeListGet = (type, index) => { 6317 type.doc ?? warnPrematureAccess(); 6318 const marker = findMarker(type, index); 6319 let n = type._start; 6320 if (marker !== null) { 6321 n = marker.p; 6322 index -= marker.index; 6323 } 6324 for (; n !== null; n = n.right) { 6325 if (!n.deleted && n.countable) { 6326 if (index < n.length) { 6327 return n.content.getContent()[index]; 6328 } 6329 index -= n.length; 6330 } 6331 } 6332 }; 6333 var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { 6334 let left = referenceItem; 6335 const doc2 = transaction.doc; 6336 const ownClientId = doc2.clientID; 6337 const store2 = doc2.store; 6338 const right = referenceItem === null ? parent._start : referenceItem.right; 6339 let jsonContent = []; 6340 const packJsonContent = () => { 6341 if (jsonContent.length > 0) { 6342 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); 6343 left.integrate(transaction, 0); 6344 jsonContent = []; 6345 } 6346 }; 6347 content.forEach((c) => { 6348 if (c === null) { 6349 jsonContent.push(c); 6350 } else { 6351 switch (c.constructor) { 6352 case Number: 6353 case Object: 6354 case Boolean: 6355 case Array: 6356 case String: 6357 jsonContent.push(c); 6358 break; 6359 default: 6360 packJsonContent(); 6361 switch (c.constructor) { 6362 case Uint8Array: 6363 case ArrayBuffer: 6364 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( 6365 /** @type {Uint8Array} */ 6366 c 6367 ))); 6368 left.integrate(transaction, 0); 6369 break; 6370 case Doc: 6371 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( 6372 /** @type {Doc} */ 6373 c 6374 )); 6375 left.integrate(transaction, 0); 6376 break; 6377 default: 6378 if (c instanceof AbstractType) { 6379 left = new Item(createID(ownClientId, getState(store2, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); 6380 left.integrate(transaction, 0); 6381 } else { 6382 throw new Error("Unexpected content type in insert operation"); 6383 } 6384 } 6385 } 6386 } 6387 }); 6388 packJsonContent(); 6389 }; 6390 var lengthExceeded = () => create3("Length exceeded!"); 6391 var typeListInsertGenerics = (transaction, parent, index, content) => { 6392 if (index > parent._length) { 6393 throw lengthExceeded(); 6394 } 6395 if (index === 0) { 6396 if (parent._searchMarker) { 6397 updateMarkerChanges(parent._searchMarker, index, content.length); 6398 } 6399 return typeListInsertGenericsAfter(transaction, parent, null, content); 6400 } 6401 const startIndex = index; 6402 const marker = findMarker(parent, index); 6403 let n = parent._start; 6404 if (marker !== null) { 6405 n = marker.p; 6406 index -= marker.index; 6407 if (index === 0) { 6408 n = n.prev; 6409 index += n && n.countable && !n.deleted ? n.length : 0; 6410 } 6411 } 6412 for (; n !== null; n = n.right) { 6413 if (!n.deleted && n.countable) { 6414 if (index <= n.length) { 6415 if (index < n.length) { 6416 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 6417 } 6418 break; 6419 } 6420 index -= n.length; 6421 } 6422 } 6423 if (parent._searchMarker) { 6424 updateMarkerChanges(parent._searchMarker, startIndex, content.length); 6425 } 6426 return typeListInsertGenericsAfter(transaction, parent, n, content); 6427 }; 6428 var typeListPushGenerics = (transaction, parent, content) => { 6429 const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); 6430 let n = marker.p; 6431 if (n) { 6432 while (n.right) { 6433 n = n.right; 6434 } 6435 } 6436 return typeListInsertGenericsAfter(transaction, parent, n, content); 6437 }; 6438 var typeListDelete = (transaction, parent, index, length2) => { 6439 if (length2 === 0) { 6440 return; 6441 } 6442 const startIndex = index; 6443 const startLength = length2; 6444 const marker = findMarker(parent, index); 6445 let n = parent._start; 6446 if (marker !== null) { 6447 n = marker.p; 6448 index -= marker.index; 6449 } 6450 for (; n !== null && index > 0; n = n.right) { 6451 if (!n.deleted && n.countable) { 6452 if (index < n.length) { 6453 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); 6454 } 6455 index -= n.length; 6456 } 6457 } 6458 while (length2 > 0 && n !== null) { 6459 if (!n.deleted) { 6460 if (length2 < n.length) { 6461 getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length2)); 6462 } 6463 n.delete(transaction); 6464 length2 -= n.length; 6465 } 6466 n = n.right; 6467 } 6468 if (length2 > 0) { 6469 throw lengthExceeded(); 6470 } 6471 if (parent._searchMarker) { 6472 updateMarkerChanges( 6473 parent._searchMarker, 6474 startIndex, 6475 -startLength + length2 6476 /* in case we remove the above exception */ 6477 ); 6478 } 6479 }; 6480 var typeMapDelete = (transaction, parent, key) => { 6481 const c = parent._map.get(key); 6482 if (c !== void 0) { 6483 c.delete(transaction); 6484 } 6485 }; 6486 var typeMapSet = (transaction, parent, key, value) => { 6487 const left = parent._map.get(key) || null; 6488 const doc2 = transaction.doc; 6489 const ownClientId = doc2.clientID; 6490 let content; 6491 if (value == null) { 6492 content = new ContentAny([value]); 6493 } else { 6494 switch (value.constructor) { 6495 case Number: 6496 case Object: 6497 case Boolean: 6498 case Array: 6499 case String: 6500 case Date: 6501 case BigInt: 6502 content = new ContentAny([value]); 6503 break; 6504 case Uint8Array: 6505 content = new ContentBinary( 6506 /** @type {Uint8Array} */ 6507 value 6508 ); 6509 break; 6510 case Doc: 6511 content = new ContentDoc( 6512 /** @type {Doc} */ 6513 value 6514 ); 6515 break; 6516 default: 6517 if (value instanceof AbstractType) { 6518 content = new ContentType(value); 6519 } else { 6520 throw new Error("Unexpected content type"); 6521 } 6522 } 6523 } 6524 new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); 6525 }; 6526 var typeMapGet = (parent, key) => { 6527 parent.doc ?? warnPrematureAccess(); 6528 const val = parent._map.get(key); 6529 return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; 6530 }; 6531 var typeMapGetAll = (parent) => { 6532 const res = {}; 6533 parent.doc ?? warnPrematureAccess(); 6534 parent._map.forEach((value, key) => { 6535 if (!value.deleted) { 6536 res[key] = value.content.getContent()[value.length - 1]; 6537 } 6538 }); 6539 return res; 6540 }; 6541 var typeMapHas = (parent, key) => { 6542 parent.doc ?? warnPrematureAccess(); 6543 const val = parent._map.get(key); 6544 return val !== void 0 && !val.deleted; 6545 }; 6546 var typeMapGetSnapshot = (parent, key, snapshot2) => { 6547 let v = parent._map.get(key) || null; 6548 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 6549 v = v.left; 6550 } 6551 return v !== null && isVisible(v, snapshot2) ? v.content.getContent()[v.length - 1] : void 0; 6552 }; 6553 var typeMapGetAllSnapshot = (parent, snapshot2) => { 6554 const res = {}; 6555 parent._map.forEach((value, key) => { 6556 let v = value; 6557 while (v !== null && (!snapshot2.sv.has(v.id.client) || v.id.clock >= (snapshot2.sv.get(v.id.client) || 0))) { 6558 v = v.left; 6559 } 6560 if (v !== null && isVisible(v, snapshot2)) { 6561 res[key] = v.content.getContent()[v.length - 1]; 6562 } 6563 }); 6564 return res; 6565 }; 6566 var createMapIterator = (type) => { 6567 type.doc ?? warnPrematureAccess(); 6568 return iteratorFilter( 6569 type._map.entries(), 6570 /** @param {any} entry */ 6571 (entry) => !entry[1].deleted 6572 ); 6573 }; 6574 var YArrayEvent = class extends YEvent { 6575 }; 6576 var YArray = class _YArray extends AbstractType { 6577 constructor() { 6578 super(); 6579 this._prelimContent = []; 6580 this._searchMarker = []; 6581 } 6582 /** 6583 * Construct a new YArray containing the specified items. 6584 * @template {Object<string,any>|Array<any>|number|null|string|Uint8Array} T 6585 * @param {Array<T>} items 6586 * @return {YArray<T>} 6587 */ 6588 static from(items2) { 6589 const a = new _YArray(); 6590 a.push(items2); 6591 return a; 6592 } 6593 /** 6594 * Integrate this type into the Yjs instance. 6595 * 6596 * * Save this struct in the os 6597 * * This type is sent to other client 6598 * * Observer functions are fired 6599 * 6600 * @param {Doc} y The Yjs instance 6601 * @param {Item} item 6602 */ 6603 _integrate(y, item) { 6604 super._integrate(y, item); 6605 this.insert( 6606 0, 6607 /** @type {Array<any>} */ 6608 this._prelimContent 6609 ); 6610 this._prelimContent = null; 6611 } 6612 /** 6613 * @return {YArray<T>} 6614 */ 6615 _copy() { 6616 return new _YArray(); 6617 } 6618 /** 6619 * Makes a copy of this data type that can be included somewhere else. 6620 * 6621 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6622 * 6623 * @return {YArray<T>} 6624 */ 6625 clone() { 6626 const arr = new _YArray(); 6627 arr.insert(0, this.toArray().map( 6628 (el) => el instanceof AbstractType ? ( 6629 /** @type {typeof el} */ 6630 el.clone() 6631 ) : el 6632 )); 6633 return arr; 6634 } 6635 get length() { 6636 this.doc ?? warnPrematureAccess(); 6637 return this._length; 6638 } 6639 /** 6640 * Creates YArrayEvent and calls observers. 6641 * 6642 * @param {Transaction} transaction 6643 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6644 */ 6645 _callObserver(transaction, parentSubs) { 6646 super._callObserver(transaction, parentSubs); 6647 callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); 6648 } 6649 /** 6650 * Inserts new content at an index. 6651 * 6652 * Important: This function expects an array of content. Not just a content 6653 * object. The reason for this "weirdness" is that inserting several elements 6654 * is very efficient when it is done as a single operation. 6655 * 6656 * @example 6657 * // Insert character 'a' at position 0 6658 * yarray.insert(0, ['a']) 6659 * // Insert numbers 1, 2 at position 1 6660 * yarray.insert(1, [1, 2]) 6661 * 6662 * @param {number} index The index to insert content at. 6663 * @param {Array<T>} content The array of content 6664 */ 6665 insert(index, content) { 6666 if (this.doc !== null) { 6667 transact(this.doc, (transaction) => { 6668 typeListInsertGenerics( 6669 transaction, 6670 this, 6671 index, 6672 /** @type {any} */ 6673 content 6674 ); 6675 }); 6676 } else { 6677 this._prelimContent.splice(index, 0, ...content); 6678 } 6679 } 6680 /** 6681 * Appends content to this YArray. 6682 * 6683 * @param {Array<T>} content Array of content to append. 6684 * 6685 * @todo Use the following implementation in all types. 6686 */ 6687 push(content) { 6688 if (this.doc !== null) { 6689 transact(this.doc, (transaction) => { 6690 typeListPushGenerics( 6691 transaction, 6692 this, 6693 /** @type {any} */ 6694 content 6695 ); 6696 }); 6697 } else { 6698 this._prelimContent.push(...content); 6699 } 6700 } 6701 /** 6702 * Prepends content to this YArray. 6703 * 6704 * @param {Array<T>} content Array of content to prepend. 6705 */ 6706 unshift(content) { 6707 this.insert(0, content); 6708 } 6709 /** 6710 * Deletes elements starting from an index. 6711 * 6712 * @param {number} index Index at which to start deleting elements 6713 * @param {number} length The number of elements to remove. Defaults to 1. 6714 */ 6715 delete(index, length2 = 1) { 6716 if (this.doc !== null) { 6717 transact(this.doc, (transaction) => { 6718 typeListDelete(transaction, this, index, length2); 6719 }); 6720 } else { 6721 this._prelimContent.splice(index, length2); 6722 } 6723 } 6724 /** 6725 * Returns the i-th element from a YArray. 6726 * 6727 * @param {number} index The index of the element to return from the YArray 6728 * @return {T} 6729 */ 6730 get(index) { 6731 return typeListGet(this, index); 6732 } 6733 /** 6734 * Transforms this YArray to a JavaScript Array. 6735 * 6736 * @return {Array<T>} 6737 */ 6738 toArray() { 6739 return typeListToArray(this); 6740 } 6741 /** 6742 * Returns a portion of this YArray into a JavaScript Array selected 6743 * from start to end (end not included). 6744 * 6745 * @param {number} [start] 6746 * @param {number} [end] 6747 * @return {Array<T>} 6748 */ 6749 slice(start = 0, end = this.length) { 6750 return typeListSlice(this, start, end); 6751 } 6752 /** 6753 * Transforms this Shared Type to a JSON object. 6754 * 6755 * @return {Array<any>} 6756 */ 6757 toJSON() { 6758 return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); 6759 } 6760 /** 6761 * Returns an Array with the result of calling a provided function on every 6762 * element of this YArray. 6763 * 6764 * @template M 6765 * @param {function(T,number,YArray<T>):M} f Function that produces an element of the new Array 6766 * @return {Array<M>} A new array with each element being the result of the 6767 * callback function 6768 */ 6769 map(f) { 6770 return typeListMap( 6771 this, 6772 /** @type {any} */ 6773 f 6774 ); 6775 } 6776 /** 6777 * Executes a provided function once on every element of this YArray. 6778 * 6779 * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray. 6780 */ 6781 forEach(f) { 6782 typeListForEach(this, f); 6783 } 6784 /** 6785 * @return {IterableIterator<T>} 6786 */ 6787 [Symbol.iterator]() { 6788 return typeListCreateIterator(this); 6789 } 6790 /** 6791 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 6792 */ 6793 _write(encoder) { 6794 encoder.writeTypeRef(YArrayRefID); 6795 } 6796 }; 6797 var readYArray = (_decoder) => new YArray(); 6798 var YMapEvent = class extends YEvent { 6799 /** 6800 * @param {YMap<T>} ymap The YArray that changed. 6801 * @param {Transaction} transaction 6802 * @param {Set<any>} subs The keys that changed. 6803 */ 6804 constructor(ymap, transaction, subs) { 6805 super(ymap, transaction); 6806 this.keysChanged = subs; 6807 } 6808 }; 6809 var YMap = class _YMap extends AbstractType { 6810 /** 6811 * 6812 * @param {Iterable<readonly [string, any]>=} entries - an optional iterable to initialize the YMap 6813 */ 6814 constructor(entries) { 6815 super(); 6816 this._prelimContent = null; 6817 if (entries === void 0) { 6818 this._prelimContent = /* @__PURE__ */ new Map(); 6819 } else { 6820 this._prelimContent = new Map(entries); 6821 } 6822 } 6823 /** 6824 * Integrate this type into the Yjs instance. 6825 * 6826 * * Save this struct in the os 6827 * * This type is sent to other client 6828 * * Observer functions are fired 6829 * 6830 * @param {Doc} y The Yjs instance 6831 * @param {Item} item 6832 */ 6833 _integrate(y, item) { 6834 super._integrate(y, item); 6835 this._prelimContent.forEach((value, key) => { 6836 this.set(key, value); 6837 }); 6838 this._prelimContent = null; 6839 } 6840 /** 6841 * @return {YMap<MapType>} 6842 */ 6843 _copy() { 6844 return new _YMap(); 6845 } 6846 /** 6847 * Makes a copy of this data type that can be included somewhere else. 6848 * 6849 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 6850 * 6851 * @return {YMap<MapType>} 6852 */ 6853 clone() { 6854 const map2 = new _YMap(); 6855 this.forEach((value, key) => { 6856 map2.set(key, value instanceof AbstractType ? ( 6857 /** @type {typeof value} */ 6858 value.clone() 6859 ) : value); 6860 }); 6861 return map2; 6862 } 6863 /** 6864 * Creates YMapEvent and calls observers. 6865 * 6866 * @param {Transaction} transaction 6867 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 6868 */ 6869 _callObserver(transaction, parentSubs) { 6870 callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); 6871 } 6872 /** 6873 * Transforms this Shared Type to a JSON object. 6874 * 6875 * @return {Object<string,any>} 6876 */ 6877 toJSON() { 6878 this.doc ?? warnPrematureAccess(); 6879 const map2 = {}; 6880 this._map.forEach((item, key) => { 6881 if (!item.deleted) { 6882 const v = item.content.getContent()[item.length - 1]; 6883 map2[key] = v instanceof AbstractType ? v.toJSON() : v; 6884 } 6885 }); 6886 return map2; 6887 } 6888 /** 6889 * Returns the size of the YMap (count of key/value pairs) 6890 * 6891 * @return {number} 6892 */ 6893 get size() { 6894 return [...createMapIterator(this)].length; 6895 } 6896 /** 6897 * Returns the keys for each element in the YMap Type. 6898 * 6899 * @return {IterableIterator<string>} 6900 */ 6901 keys() { 6902 return iteratorMap( 6903 createMapIterator(this), 6904 /** @param {any} v */ 6905 (v) => v[0] 6906 ); 6907 } 6908 /** 6909 * Returns the values for each element in the YMap Type. 6910 * 6911 * @return {IterableIterator<MapType>} 6912 */ 6913 values() { 6914 return iteratorMap( 6915 createMapIterator(this), 6916 /** @param {any} v */ 6917 (v) => v[1].content.getContent()[v[1].length - 1] 6918 ); 6919 } 6920 /** 6921 * Returns an Iterator of [key, value] pairs 6922 * 6923 * @return {IterableIterator<[string, MapType]>} 6924 */ 6925 entries() { 6926 return iteratorMap( 6927 createMapIterator(this), 6928 /** @param {any} v */ 6929 (v) => ( 6930 /** @type {any} */ 6931 [v[0], v[1].content.getContent()[v[1].length - 1]] 6932 ) 6933 ); 6934 } 6935 /** 6936 * Executes a provided function on once on every key-value pair. 6937 * 6938 * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray. 6939 */ 6940 forEach(f) { 6941 this.doc ?? warnPrematureAccess(); 6942 this._map.forEach((item, key) => { 6943 if (!item.deleted) { 6944 f(item.content.getContent()[item.length - 1], key, this); 6945 } 6946 }); 6947 } 6948 /** 6949 * Returns an Iterator of [key, value] pairs 6950 * 6951 * @return {IterableIterator<[string, MapType]>} 6952 */ 6953 [Symbol.iterator]() { 6954 return this.entries(); 6955 } 6956 /** 6957 * Remove a specified element from this YMap. 6958 * 6959 * @param {string} key The key of the element to remove. 6960 */ 6961 delete(key) { 6962 if (this.doc !== null) { 6963 transact(this.doc, (transaction) => { 6964 typeMapDelete(transaction, this, key); 6965 }); 6966 } else { 6967 this._prelimContent.delete(key); 6968 } 6969 } 6970 /** 6971 * Adds or updates an element with a specified key and value. 6972 * @template {MapType} VAL 6973 * 6974 * @param {string} key The key of the element to add to this YMap 6975 * @param {VAL} value The value of the element to add 6976 * @return {VAL} 6977 */ 6978 set(key, value) { 6979 if (this.doc !== null) { 6980 transact(this.doc, (transaction) => { 6981 typeMapSet( 6982 transaction, 6983 this, 6984 key, 6985 /** @type {any} */ 6986 value 6987 ); 6988 }); 6989 } else { 6990 this._prelimContent.set(key, value); 6991 } 6992 return value; 6993 } 6994 /** 6995 * Returns a specified element from this YMap. 6996 * 6997 * @param {string} key 6998 * @return {MapType|undefined} 6999 */ 7000 get(key) { 7001 return ( 7002 /** @type {any} */ 7003 typeMapGet(this, key) 7004 ); 7005 } 7006 /** 7007 * Returns a boolean indicating whether the specified key exists or not. 7008 * 7009 * @param {string} key The key to test. 7010 * @return {boolean} 7011 */ 7012 has(key) { 7013 return typeMapHas(this, key); 7014 } 7015 /** 7016 * Removes all elements from this YMap. 7017 */ 7018 clear() { 7019 if (this.doc !== null) { 7020 transact(this.doc, (transaction) => { 7021 this.forEach(function(_value, key, map2) { 7022 typeMapDelete(transaction, map2, key); 7023 }); 7024 }); 7025 } else { 7026 this._prelimContent.clear(); 7027 } 7028 } 7029 /** 7030 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 7031 */ 7032 _write(encoder) { 7033 encoder.writeTypeRef(YMapRefID); 7034 } 7035 }; 7036 var readYMap = (_decoder) => new YMap(); 7037 var equalAttrs = (a, b) => a === b || typeof a === "object" && typeof b === "object" && a && b && equalFlat(a, b); 7038 var ItemTextListPosition = class { 7039 /** 7040 * @param {Item|null} left 7041 * @param {Item|null} right 7042 * @param {number} index 7043 * @param {Map<string,any>} currentAttributes 7044 */ 7045 constructor(left, right, index, currentAttributes) { 7046 this.left = left; 7047 this.right = right; 7048 this.index = index; 7049 this.currentAttributes = currentAttributes; 7050 } 7051 /** 7052 * Only call this if you know that this.right is defined 7053 */ 7054 forward() { 7055 if (this.right === null) { 7056 unexpectedCase(); 7057 } 7058 switch (this.right.content.constructor) { 7059 case ContentFormat: 7060 if (!this.right.deleted) { 7061 updateCurrentAttributes( 7062 this.currentAttributes, 7063 /** @type {ContentFormat} */ 7064 this.right.content 7065 ); 7066 } 7067 break; 7068 default: 7069 if (!this.right.deleted) { 7070 this.index += this.right.length; 7071 } 7072 break; 7073 } 7074 this.left = this.right; 7075 this.right = this.right.right; 7076 } 7077 }; 7078 var findNextPosition = (transaction, pos, count) => { 7079 while (pos.right !== null && count > 0) { 7080 switch (pos.right.content.constructor) { 7081 case ContentFormat: 7082 if (!pos.right.deleted) { 7083 updateCurrentAttributes( 7084 pos.currentAttributes, 7085 /** @type {ContentFormat} */ 7086 pos.right.content 7087 ); 7088 } 7089 break; 7090 default: 7091 if (!pos.right.deleted) { 7092 if (count < pos.right.length) { 7093 getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); 7094 } 7095 pos.index += pos.right.length; 7096 count -= pos.right.length; 7097 } 7098 break; 7099 } 7100 pos.left = pos.right; 7101 pos.right = pos.right.right; 7102 } 7103 return pos; 7104 }; 7105 var findPosition = (transaction, parent, index, useSearchMarker) => { 7106 const currentAttributes = /* @__PURE__ */ new Map(); 7107 const marker = useSearchMarker ? findMarker(parent, index) : null; 7108 if (marker) { 7109 const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); 7110 return findNextPosition(transaction, pos, index - marker.index); 7111 } else { 7112 const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); 7113 return findNextPosition(transaction, pos, index); 7114 } 7115 }; 7116 var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { 7117 while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( 7118 negatedAttributes.get( 7119 /** @type {ContentFormat} */ 7120 currPos.right.content.key 7121 ), 7122 /** @type {ContentFormat} */ 7123 currPos.right.content.value 7124 ))) { 7125 if (!currPos.right.deleted) { 7126 negatedAttributes.delete( 7127 /** @type {ContentFormat} */ 7128 currPos.right.content.key 7129 ); 7130 } 7131 currPos.forward(); 7132 } 7133 const doc2 = transaction.doc; 7134 const ownClientId = doc2.clientID; 7135 negatedAttributes.forEach((val, key) => { 7136 const left = currPos.left; 7137 const right = currPos.right; 7138 const nextFormat = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 7139 nextFormat.integrate(transaction, 0); 7140 currPos.right = nextFormat; 7141 currPos.forward(); 7142 }); 7143 }; 7144 var updateCurrentAttributes = (currentAttributes, format) => { 7145 const { key, value } = format; 7146 if (value === null) { 7147 currentAttributes.delete(key); 7148 } else { 7149 currentAttributes.set(key, value); 7150 } 7151 }; 7152 var minimizeAttributeChanges = (currPos, attributes) => { 7153 while (true) { 7154 if (currPos.right === null) { 7155 break; 7156 } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( 7157 attributes[ 7158 /** @type {ContentFormat} */ 7159 currPos.right.content.key 7160 ] ?? null, 7161 /** @type {ContentFormat} */ 7162 currPos.right.content.value 7163 )) ; 7164 else { 7165 break; 7166 } 7167 currPos.forward(); 7168 } 7169 }; 7170 var insertAttributes = (transaction, parent, currPos, attributes) => { 7171 const doc2 = transaction.doc; 7172 const ownClientId = doc2.clientID; 7173 const negatedAttributes = /* @__PURE__ */ new Map(); 7174 for (const key in attributes) { 7175 const val = attributes[key]; 7176 const currentVal = currPos.currentAttributes.get(key) ?? null; 7177 if (!equalAttrs(currentVal, val)) { 7178 negatedAttributes.set(key, currentVal); 7179 const { left, right } = currPos; 7180 currPos.right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); 7181 currPos.right.integrate(transaction, 0); 7182 currPos.forward(); 7183 } 7184 } 7185 return negatedAttributes; 7186 }; 7187 var insertText = (transaction, parent, currPos, text2, attributes) => { 7188 currPos.currentAttributes.forEach((_val, key) => { 7189 if (attributes[key] === void 0) { 7190 attributes[key] = null; 7191 } 7192 }); 7193 const doc2 = transaction.doc; 7194 const ownClientId = doc2.clientID; 7195 minimizeAttributeChanges(currPos, attributes); 7196 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 7197 const content = text2.constructor === String ? new ContentString( 7198 /** @type {string} */ 7199 text2 7200 ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); 7201 let { left, right, index } = currPos; 7202 if (parent._searchMarker) { 7203 updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); 7204 } 7205 right = new Item(createID(ownClientId, getState(doc2.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); 7206 right.integrate(transaction, 0); 7207 currPos.right = right; 7208 currPos.index = index; 7209 currPos.forward(); 7210 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 7211 }; 7212 var formatText = (transaction, parent, currPos, length2, attributes) => { 7213 const doc2 = transaction.doc; 7214 const ownClientId = doc2.clientID; 7215 minimizeAttributeChanges(currPos, attributes); 7216 const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); 7217 iterationLoop: while (currPos.right !== null && (length2 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { 7218 if (!currPos.right.deleted) { 7219 switch (currPos.right.content.constructor) { 7220 case ContentFormat: { 7221 const { key, value } = ( 7222 /** @type {ContentFormat} */ 7223 currPos.right.content 7224 ); 7225 const attr = attributes[key]; 7226 if (attr !== void 0) { 7227 if (equalAttrs(attr, value)) { 7228 negatedAttributes.delete(key); 7229 } else { 7230 if (length2 === 0) { 7231 break iterationLoop; 7232 } 7233 negatedAttributes.set(key, value); 7234 } 7235 currPos.right.delete(transaction); 7236 } else { 7237 currPos.currentAttributes.set(key, value); 7238 } 7239 break; 7240 } 7241 default: 7242 if (length2 < currPos.right.length) { 7243 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); 7244 } 7245 length2 -= currPos.right.length; 7246 break; 7247 } 7248 } 7249 currPos.forward(); 7250 } 7251 if (length2 > 0) { 7252 let newlines = ""; 7253 for (; length2 > 0; length2--) { 7254 newlines += "\n"; 7255 } 7256 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)); 7257 currPos.right.integrate(transaction, 0); 7258 currPos.forward(); 7259 } 7260 insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); 7261 }; 7262 var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { 7263 let end = start; 7264 const endFormats = create(); 7265 while (end && (!end.countable || end.deleted)) { 7266 if (!end.deleted && end.content.constructor === ContentFormat) { 7267 const cf = ( 7268 /** @type {ContentFormat} */ 7269 end.content 7270 ); 7271 endFormats.set(cf.key, cf); 7272 } 7273 end = end.right; 7274 } 7275 let cleanups = 0; 7276 let reachedCurr = false; 7277 while (start !== end) { 7278 if (curr === start) { 7279 reachedCurr = true; 7280 } 7281 if (!start.deleted) { 7282 const content = start.content; 7283 switch (content.constructor) { 7284 case ContentFormat: { 7285 const { key, value } = ( 7286 /** @type {ContentFormat} */ 7287 content 7288 ); 7289 const startAttrValue = startAttributes.get(key) ?? null; 7290 if (endFormats.get(key) !== content || startAttrValue === value) { 7291 start.delete(transaction); 7292 cleanups++; 7293 if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { 7294 if (startAttrValue === null) { 7295 currAttributes.delete(key); 7296 } else { 7297 currAttributes.set(key, startAttrValue); 7298 } 7299 } 7300 } 7301 if (!reachedCurr && !start.deleted) { 7302 updateCurrentAttributes( 7303 currAttributes, 7304 /** @type {ContentFormat} */ 7305 content 7306 ); 7307 } 7308 break; 7309 } 7310 } 7311 } 7312 start = /** @type {Item} */ 7313 start.right; 7314 } 7315 return cleanups; 7316 }; 7317 var cleanupContextlessFormattingGap = (transaction, item) => { 7318 while (item && item.right && (item.right.deleted || !item.right.countable)) { 7319 item = item.right; 7320 } 7321 const attrs = /* @__PURE__ */ new Set(); 7322 while (item && (item.deleted || !item.countable)) { 7323 if (!item.deleted && item.content.constructor === ContentFormat) { 7324 const key = ( 7325 /** @type {ContentFormat} */ 7326 item.content.key 7327 ); 7328 if (attrs.has(key)) { 7329 item.delete(transaction); 7330 } else { 7331 attrs.add(key); 7332 } 7333 } 7334 item = item.left; 7335 } 7336 }; 7337 var cleanupYTextFormatting = (type) => { 7338 let res = 0; 7339 transact( 7340 /** @type {Doc} */ 7341 type.doc, 7342 (transaction) => { 7343 let start = ( 7344 /** @type {Item} */ 7345 type._start 7346 ); 7347 let end = type._start; 7348 let startAttributes = create(); 7349 const currentAttributes = copy(startAttributes); 7350 while (end) { 7351 if (end.deleted === false) { 7352 switch (end.content.constructor) { 7353 case ContentFormat: 7354 updateCurrentAttributes( 7355 currentAttributes, 7356 /** @type {ContentFormat} */ 7357 end.content 7358 ); 7359 break; 7360 default: 7361 res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); 7362 startAttributes = copy(currentAttributes); 7363 start = end; 7364 break; 7365 } 7366 } 7367 end = end.right; 7368 } 7369 } 7370 ); 7371 return res; 7372 }; 7373 var cleanupYTextAfterTransaction = (transaction) => { 7374 const needFullCleanup = /* @__PURE__ */ new Set(); 7375 const doc2 = transaction.doc; 7376 for (const [client, afterClock] of transaction.afterState.entries()) { 7377 const clock = transaction.beforeState.get(client) || 0; 7378 if (afterClock === clock) { 7379 continue; 7380 } 7381 iterateStructs( 7382 transaction, 7383 /** @type {Array<Item|GC>} */ 7384 doc2.store.clients.get(client), 7385 clock, 7386 afterClock, 7387 (item) => { 7388 if (!item.deleted && /** @type {Item} */ 7389 item.content.constructor === ContentFormat && item.constructor !== GC) { 7390 needFullCleanup.add( 7391 /** @type {any} */ 7392 item.parent 7393 ); 7394 } 7395 } 7396 ); 7397 } 7398 transact(doc2, (t) => { 7399 iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { 7400 if (item instanceof GC || !/** @type {YText} */ 7401 item.parent._hasFormatting || needFullCleanup.has( 7402 /** @type {YText} */ 7403 item.parent 7404 )) { 7405 return; 7406 } 7407 const parent = ( 7408 /** @type {YText} */ 7409 item.parent 7410 ); 7411 if (item.content.constructor === ContentFormat) { 7412 needFullCleanup.add(parent); 7413 } else { 7414 cleanupContextlessFormattingGap(t, item); 7415 } 7416 }); 7417 for (const yText of needFullCleanup) { 7418 cleanupYTextFormatting(yText); 7419 } 7420 }); 7421 }; 7422 var deleteText = (transaction, currPos, length2) => { 7423 const startLength = length2; 7424 const startAttrs = copy(currPos.currentAttributes); 7425 const start = currPos.right; 7426 while (length2 > 0 && currPos.right !== null) { 7427 if (currPos.right.deleted === false) { 7428 switch (currPos.right.content.constructor) { 7429 case ContentType: 7430 case ContentEmbed: 7431 case ContentString: 7432 if (length2 < currPos.right.length) { 7433 getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); 7434 } 7435 length2 -= currPos.right.length; 7436 currPos.right.delete(transaction); 7437 break; 7438 } 7439 } 7440 currPos.forward(); 7441 } 7442 if (start) { 7443 cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); 7444 } 7445 const parent = ( 7446 /** @type {AbstractType<any>} */ 7447 /** @type {Item} */ 7448 (currPos.left || currPos.right).parent 7449 ); 7450 if (parent._searchMarker) { 7451 updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length2); 7452 } 7453 return currPos; 7454 }; 7455 var YTextEvent = class extends YEvent { 7456 /** 7457 * @param {YText} ytext 7458 * @param {Transaction} transaction 7459 * @param {Set<any>} subs The keys that changed 7460 */ 7461 constructor(ytext, transaction, subs) { 7462 super(ytext, transaction); 7463 this.childListChanged = false; 7464 this.keysChanged = /* @__PURE__ */ new Set(); 7465 subs.forEach((sub) => { 7466 if (sub === null) { 7467 this.childListChanged = true; 7468 } else { 7469 this.keysChanged.add(sub); 7470 } 7471 }); 7472 } 7473 /** 7474 * @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}>}} 7475 */ 7476 get changes() { 7477 if (this._changes === null) { 7478 const changes = { 7479 keys: this.keys, 7480 delta: this.delta, 7481 added: /* @__PURE__ */ new Set(), 7482 deleted: /* @__PURE__ */ new Set() 7483 }; 7484 this._changes = changes; 7485 } 7486 return ( 7487 /** @type {any} */ 7488 this._changes 7489 ); 7490 } 7491 /** 7492 * Compute the changes in the delta format. 7493 * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. 7494 * 7495 * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>} 7496 * 7497 * @public 7498 */ 7499 get delta() { 7500 if (this._delta === null) { 7501 const y = ( 7502 /** @type {Doc} */ 7503 this.target.doc 7504 ); 7505 const delta = []; 7506 transact(y, (transaction) => { 7507 const currentAttributes = /* @__PURE__ */ new Map(); 7508 const oldAttributes = /* @__PURE__ */ new Map(); 7509 let item = this.target._start; 7510 let action = null; 7511 const attributes = {}; 7512 let insert2 = ""; 7513 let retain = 0; 7514 let deleteLen = 0; 7515 const addOp = () => { 7516 if (action !== null) { 7517 let op = null; 7518 switch (action) { 7519 case "delete": 7520 if (deleteLen > 0) { 7521 op = { delete: deleteLen }; 7522 } 7523 deleteLen = 0; 7524 break; 7525 case "insert": 7526 if (typeof insert2 === "object" || insert2.length > 0) { 7527 op = { insert: insert2 }; 7528 if (currentAttributes.size > 0) { 7529 op.attributes = {}; 7530 currentAttributes.forEach((value, key) => { 7531 if (value !== null) { 7532 op.attributes[key] = value; 7533 } 7534 }); 7535 } 7536 } 7537 insert2 = ""; 7538 break; 7539 case "retain": 7540 if (retain > 0) { 7541 op = { retain }; 7542 if (!isEmpty(attributes)) { 7543 op.attributes = assign({}, attributes); 7544 } 7545 } 7546 retain = 0; 7547 break; 7548 } 7549 if (op) delta.push(op); 7550 action = null; 7551 } 7552 }; 7553 while (item !== null) { 7554 switch (item.content.constructor) { 7555 case ContentType: 7556 case ContentEmbed: 7557 if (this.adds(item)) { 7558 if (!this.deletes(item)) { 7559 addOp(); 7560 action = "insert"; 7561 insert2 = item.content.getContent()[0]; 7562 addOp(); 7563 } 7564 } else if (this.deletes(item)) { 7565 if (action !== "delete") { 7566 addOp(); 7567 action = "delete"; 7568 } 7569 deleteLen += 1; 7570 } else if (!item.deleted) { 7571 if (action !== "retain") { 7572 addOp(); 7573 action = "retain"; 7574 } 7575 retain += 1; 7576 } 7577 break; 7578 case ContentString: 7579 if (this.adds(item)) { 7580 if (!this.deletes(item)) { 7581 if (action !== "insert") { 7582 addOp(); 7583 action = "insert"; 7584 } 7585 insert2 += /** @type {ContentString} */ 7586 item.content.str; 7587 } 7588 } else if (this.deletes(item)) { 7589 if (action !== "delete") { 7590 addOp(); 7591 action = "delete"; 7592 } 7593 deleteLen += item.length; 7594 } else if (!item.deleted) { 7595 if (action !== "retain") { 7596 addOp(); 7597 action = "retain"; 7598 } 7599 retain += item.length; 7600 } 7601 break; 7602 case ContentFormat: { 7603 const { key, value } = ( 7604 /** @type {ContentFormat} */ 7605 item.content 7606 ); 7607 if (this.adds(item)) { 7608 if (!this.deletes(item)) { 7609 const curVal = currentAttributes.get(key) ?? null; 7610 if (!equalAttrs(curVal, value)) { 7611 if (action === "retain") { 7612 addOp(); 7613 } 7614 if (equalAttrs(value, oldAttributes.get(key) ?? null)) { 7615 delete attributes[key]; 7616 } else { 7617 attributes[key] = value; 7618 } 7619 } else if (value !== null) { 7620 item.delete(transaction); 7621 } 7622 } 7623 } else if (this.deletes(item)) { 7624 oldAttributes.set(key, value); 7625 const curVal = currentAttributes.get(key) ?? null; 7626 if (!equalAttrs(curVal, value)) { 7627 if (action === "retain") { 7628 addOp(); 7629 } 7630 attributes[key] = curVal; 7631 } 7632 } else if (!item.deleted) { 7633 oldAttributes.set(key, value); 7634 const attr = attributes[key]; 7635 if (attr !== void 0) { 7636 if (!equalAttrs(attr, value)) { 7637 if (action === "retain") { 7638 addOp(); 7639 } 7640 if (value === null) { 7641 delete attributes[key]; 7642 } else { 7643 attributes[key] = value; 7644 } 7645 } else if (attr !== null) { 7646 item.delete(transaction); 7647 } 7648 } 7649 } 7650 if (!item.deleted) { 7651 if (action === "insert") { 7652 addOp(); 7653 } 7654 updateCurrentAttributes( 7655 currentAttributes, 7656 /** @type {ContentFormat} */ 7657 item.content 7658 ); 7659 } 7660 break; 7661 } 7662 } 7663 item = item.right; 7664 } 7665 addOp(); 7666 while (delta.length > 0) { 7667 const lastOp = delta[delta.length - 1]; 7668 if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { 7669 delta.pop(); 7670 } else { 7671 break; 7672 } 7673 } 7674 }); 7675 this._delta = delta; 7676 } 7677 return ( 7678 /** @type {any} */ 7679 this._delta 7680 ); 7681 } 7682 }; 7683 var YText = class _YText extends AbstractType { 7684 /** 7685 * @param {String} [string] The initial value of the YText. 7686 */ 7687 constructor(string) { 7688 super(); 7689 this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; 7690 this._searchMarker = []; 7691 this._hasFormatting = false; 7692 } 7693 /** 7694 * Number of characters of this text type. 7695 * 7696 * @type {number} 7697 */ 7698 get length() { 7699 this.doc ?? warnPrematureAccess(); 7700 return this._length; 7701 } 7702 /** 7703 * @param {Doc} y 7704 * @param {Item} item 7705 */ 7706 _integrate(y, item) { 7707 super._integrate(y, item); 7708 try { 7709 this._pending.forEach((f) => f()); 7710 } catch (e) { 7711 console.error(e); 7712 } 7713 this._pending = null; 7714 } 7715 _copy() { 7716 return new _YText(); 7717 } 7718 /** 7719 * Makes a copy of this data type that can be included somewhere else. 7720 * 7721 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 7722 * 7723 * @return {YText} 7724 */ 7725 clone() { 7726 const text2 = new _YText(); 7727 text2.applyDelta(this.toDelta()); 7728 return text2; 7729 } 7730 /** 7731 * Creates YTextEvent and calls observers. 7732 * 7733 * @param {Transaction} transaction 7734 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 7735 */ 7736 _callObserver(transaction, parentSubs) { 7737 super._callObserver(transaction, parentSubs); 7738 const event = new YTextEvent(this, transaction, parentSubs); 7739 callTypeObservers(this, transaction, event); 7740 if (!transaction.local && this._hasFormatting) { 7741 transaction._needFormattingCleanup = true; 7742 } 7743 } 7744 /** 7745 * Returns the unformatted string representation of this YText type. 7746 * 7747 * @public 7748 */ 7749 toString() { 7750 this.doc ?? warnPrematureAccess(); 7751 let str = ""; 7752 let n = this._start; 7753 while (n !== null) { 7754 if (!n.deleted && n.countable && n.content.constructor === ContentString) { 7755 str += /** @type {ContentString} */ 7756 n.content.str; 7757 } 7758 n = n.right; 7759 } 7760 return str; 7761 } 7762 /** 7763 * Returns the unformatted string representation of this YText type. 7764 * 7765 * @return {string} 7766 * @public 7767 */ 7768 toJSON() { 7769 return this.toString(); 7770 } 7771 /** 7772 * Apply a {@link Delta} on this shared YText type. 7773 * 7774 * @param {Array<any>} delta The changes to apply on this element. 7775 * @param {object} opts 7776 * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. 7777 * 7778 * 7779 * @public 7780 */ 7781 applyDelta(delta, { sanitize = true } = {}) { 7782 if (this.doc !== null) { 7783 transact(this.doc, (transaction) => { 7784 const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); 7785 for (let i = 0; i < delta.length; i++) { 7786 const op = delta[i]; 7787 if (op.insert !== void 0) { 7788 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; 7789 if (typeof ins !== "string" || ins.length > 0) { 7790 insertText(transaction, this, currPos, ins, op.attributes || {}); 7791 } 7792 } else if (op.retain !== void 0) { 7793 formatText(transaction, this, currPos, op.retain, op.attributes || {}); 7794 } else if (op.delete !== void 0) { 7795 deleteText(transaction, currPos, op.delete); 7796 } 7797 } 7798 }); 7799 } else { 7800 this._pending.push(() => this.applyDelta(delta)); 7801 } 7802 } 7803 /** 7804 * Returns the Delta representation of this YText type. 7805 * 7806 * @param {Snapshot} [snapshot] 7807 * @param {Snapshot} [prevSnapshot] 7808 * @param {function('removed' | 'added', ID):any} [computeYChange] 7809 * @return {any} The Delta representation of this type. 7810 * 7811 * @public 7812 */ 7813 toDelta(snapshot2, prevSnapshot, computeYChange) { 7814 this.doc ?? warnPrematureAccess(); 7815 const ops = []; 7816 const currentAttributes = /* @__PURE__ */ new Map(); 7817 const doc2 = ( 7818 /** @type {Doc} */ 7819 this.doc 7820 ); 7821 let str = ""; 7822 let n = this._start; 7823 function packStr() { 7824 if (str.length > 0) { 7825 const attributes = {}; 7826 let addAttributes = false; 7827 currentAttributes.forEach((value, key) => { 7828 addAttributes = true; 7829 attributes[key] = value; 7830 }); 7831 const op = { insert: str }; 7832 if (addAttributes) { 7833 op.attributes = attributes; 7834 } 7835 ops.push(op); 7836 str = ""; 7837 } 7838 } 7839 const computeDelta = () => { 7840 while (n !== null) { 7841 if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { 7842 switch (n.content.constructor) { 7843 case ContentString: { 7844 const cur = currentAttributes.get("ychange"); 7845 if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { 7846 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { 7847 packStr(); 7848 currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); 7849 } 7850 } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { 7851 if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { 7852 packStr(); 7853 currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); 7854 } 7855 } else if (cur !== void 0) { 7856 packStr(); 7857 currentAttributes.delete("ychange"); 7858 } 7859 str += /** @type {ContentString} */ 7860 n.content.str; 7861 break; 7862 } 7863 case ContentType: 7864 case ContentEmbed: { 7865 packStr(); 7866 const op = { 7867 insert: n.content.getContent()[0] 7868 }; 7869 if (currentAttributes.size > 0) { 7870 const attrs = ( 7871 /** @type {Object<string,any>} */ 7872 {} 7873 ); 7874 op.attributes = attrs; 7875 currentAttributes.forEach((value, key) => { 7876 attrs[key] = value; 7877 }); 7878 } 7879 ops.push(op); 7880 break; 7881 } 7882 case ContentFormat: 7883 if (isVisible(n, snapshot2)) { 7884 packStr(); 7885 updateCurrentAttributes( 7886 currentAttributes, 7887 /** @type {ContentFormat} */ 7888 n.content 7889 ); 7890 } 7891 break; 7892 } 7893 } 7894 n = n.right; 7895 } 7896 packStr(); 7897 }; 7898 if (snapshot2 || prevSnapshot) { 7899 transact(doc2, (transaction) => { 7900 if (snapshot2) { 7901 splitSnapshotAffectedStructs(transaction, snapshot2); 7902 } 7903 if (prevSnapshot) { 7904 splitSnapshotAffectedStructs(transaction, prevSnapshot); 7905 } 7906 computeDelta(); 7907 }, "cleanup"); 7908 } else { 7909 computeDelta(); 7910 } 7911 return ops; 7912 } 7913 /** 7914 * Insert text at a given index. 7915 * 7916 * @param {number} index The index at which to start inserting. 7917 * @param {String} text The text to insert at the specified position. 7918 * @param {TextAttributes} [attributes] Optionally define some formatting 7919 * information to apply on the inserted 7920 * Text. 7921 * @public 7922 */ 7923 insert(index, text2, attributes) { 7924 if (text2.length <= 0) { 7925 return; 7926 } 7927 const y = this.doc; 7928 if (y !== null) { 7929 transact(y, (transaction) => { 7930 const pos = findPosition(transaction, this, index, !attributes); 7931 if (!attributes) { 7932 attributes = {}; 7933 pos.currentAttributes.forEach((v, k) => { 7934 attributes[k] = v; 7935 }); 7936 } 7937 insertText(transaction, this, pos, text2, attributes); 7938 }); 7939 } else { 7940 this._pending.push(() => this.insert(index, text2, attributes)); 7941 } 7942 } 7943 /** 7944 * Inserts an embed at a index. 7945 * 7946 * @param {number} index The index to insert the embed at. 7947 * @param {Object | AbstractType<any>} embed The Object that represents the embed. 7948 * @param {TextAttributes} [attributes] Attribute information to apply on the 7949 * embed 7950 * 7951 * @public 7952 */ 7953 insertEmbed(index, embed, attributes) { 7954 const y = this.doc; 7955 if (y !== null) { 7956 transact(y, (transaction) => { 7957 const pos = findPosition(transaction, this, index, !attributes); 7958 insertText(transaction, this, pos, embed, attributes || {}); 7959 }); 7960 } else { 7961 this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); 7962 } 7963 } 7964 /** 7965 * Deletes text starting from an index. 7966 * 7967 * @param {number} index Index at which to start deleting. 7968 * @param {number} length The number of characters to remove. Defaults to 1. 7969 * 7970 * @public 7971 */ 7972 delete(index, length2) { 7973 if (length2 === 0) { 7974 return; 7975 } 7976 const y = this.doc; 7977 if (y !== null) { 7978 transact(y, (transaction) => { 7979 deleteText(transaction, findPosition(transaction, this, index, true), length2); 7980 }); 7981 } else { 7982 this._pending.push(() => this.delete(index, length2)); 7983 } 7984 } 7985 /** 7986 * Assigns properties to a range of text. 7987 * 7988 * @param {number} index The position where to start formatting. 7989 * @param {number} length The amount of characters to assign properties to. 7990 * @param {TextAttributes} attributes Attribute information to apply on the 7991 * text. 7992 * 7993 * @public 7994 */ 7995 format(index, length2, attributes) { 7996 if (length2 === 0) { 7997 return; 7998 } 7999 const y = this.doc; 8000 if (y !== null) { 8001 transact(y, (transaction) => { 8002 const pos = findPosition(transaction, this, index, false); 8003 if (pos.right === null) { 8004 return; 8005 } 8006 formatText(transaction, this, pos, length2, attributes); 8007 }); 8008 } else { 8009 this._pending.push(() => this.format(index, length2, attributes)); 8010 } 8011 } 8012 /** 8013 * Removes an attribute. 8014 * 8015 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 8016 * 8017 * @param {String} attributeName The attribute name that is to be removed. 8018 * 8019 * @public 8020 */ 8021 removeAttribute(attributeName) { 8022 if (this.doc !== null) { 8023 transact(this.doc, (transaction) => { 8024 typeMapDelete(transaction, this, attributeName); 8025 }); 8026 } else { 8027 this._pending.push(() => this.removeAttribute(attributeName)); 8028 } 8029 } 8030 /** 8031 * Sets or updates an attribute. 8032 * 8033 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 8034 * 8035 * @param {String} attributeName The attribute name that is to be set. 8036 * @param {any} attributeValue The attribute value that is to be set. 8037 * 8038 * @public 8039 */ 8040 setAttribute(attributeName, attributeValue) { 8041 if (this.doc !== null) { 8042 transact(this.doc, (transaction) => { 8043 typeMapSet(transaction, this, attributeName, attributeValue); 8044 }); 8045 } else { 8046 this._pending.push(() => this.setAttribute(attributeName, attributeValue)); 8047 } 8048 } 8049 /** 8050 * Returns an attribute value that belongs to the attribute name. 8051 * 8052 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 8053 * 8054 * @param {String} attributeName The attribute name that identifies the 8055 * queried value. 8056 * @return {any} The queried attribute value. 8057 * 8058 * @public 8059 */ 8060 getAttribute(attributeName) { 8061 return ( 8062 /** @type {any} */ 8063 typeMapGet(this, attributeName) 8064 ); 8065 } 8066 /** 8067 * Returns all attribute name/value pairs in a JSON Object. 8068 * 8069 * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. 8070 * 8071 * @return {Object<string, any>} A JSON Object that describes the attributes. 8072 * 8073 * @public 8074 */ 8075 getAttributes() { 8076 return typeMapGetAll(this); 8077 } 8078 /** 8079 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8080 */ 8081 _write(encoder) { 8082 encoder.writeTypeRef(YTextRefID); 8083 } 8084 }; 8085 var readYText = (_decoder) => new YText(); 8086 var YXmlTreeWalker = class { 8087 /** 8088 * @param {YXmlFragment | YXmlElement} root 8089 * @param {function(AbstractType<any>):boolean} [f] 8090 */ 8091 constructor(root, f = () => true) { 8092 this._filter = f; 8093 this._root = root; 8094 this._currentNode = /** @type {Item} */ 8095 root._start; 8096 this._firstCall = true; 8097 root.doc ?? warnPrematureAccess(); 8098 } 8099 [Symbol.iterator]() { 8100 return this; 8101 } 8102 /** 8103 * Get the next node. 8104 * 8105 * @return {IteratorResult<YXmlElement|YXmlText|YXmlHook>} The next node. 8106 * 8107 * @public 8108 */ 8109 next() { 8110 let n = this._currentNode; 8111 let type = n && n.content && /** @type {any} */ 8112 n.content.type; 8113 if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { 8114 do { 8115 type = /** @type {any} */ 8116 n.content.type; 8117 if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { 8118 n = type._start; 8119 } else { 8120 while (n !== null) { 8121 const nxt = n.next; 8122 if (nxt !== null) { 8123 n = nxt; 8124 break; 8125 } else if (n.parent === this._root) { 8126 n = null; 8127 } else { 8128 n = /** @type {AbstractType<any>} */ 8129 n.parent._item; 8130 } 8131 } 8132 } 8133 } while (n !== null && (n.deleted || !this._filter( 8134 /** @type {ContentType} */ 8135 n.content.type 8136 ))); 8137 } 8138 this._firstCall = false; 8139 if (n === null) { 8140 return { value: void 0, done: true }; 8141 } 8142 this._currentNode = n; 8143 return { value: ( 8144 /** @type {any} */ 8145 n.content.type 8146 ), done: false }; 8147 } 8148 }; 8149 var YXmlFragment = class _YXmlFragment extends AbstractType { 8150 constructor() { 8151 super(); 8152 this._prelimContent = []; 8153 } 8154 /** 8155 * @type {YXmlElement|YXmlText|null} 8156 */ 8157 get firstChild() { 8158 const first = this._first; 8159 return first ? first.content.getContent()[0] : null; 8160 } 8161 /** 8162 * Integrate this type into the Yjs instance. 8163 * 8164 * * Save this struct in the os 8165 * * This type is sent to other client 8166 * * Observer functions are fired 8167 * 8168 * @param {Doc} y The Yjs instance 8169 * @param {Item} item 8170 */ 8171 _integrate(y, item) { 8172 super._integrate(y, item); 8173 this.insert( 8174 0, 8175 /** @type {Array<any>} */ 8176 this._prelimContent 8177 ); 8178 this._prelimContent = null; 8179 } 8180 _copy() { 8181 return new _YXmlFragment(); 8182 } 8183 /** 8184 * Makes a copy of this data type that can be included somewhere else. 8185 * 8186 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8187 * 8188 * @return {YXmlFragment} 8189 */ 8190 clone() { 8191 const el = new _YXmlFragment(); 8192 el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); 8193 return el; 8194 } 8195 get length() { 8196 this.doc ?? warnPrematureAccess(); 8197 return this._prelimContent === null ? this._length : this._prelimContent.length; 8198 } 8199 /** 8200 * Create a subtree of childNodes. 8201 * 8202 * @example 8203 * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') 8204 * for (let node in walker) { 8205 * // `node` is a div node 8206 * nop(node) 8207 * } 8208 * 8209 * @param {function(AbstractType<any>):boolean} filter Function that is called on each child element and 8210 * returns a Boolean indicating whether the child 8211 * is to be included in the subtree. 8212 * @return {YXmlTreeWalker} A subtree and a position within it. 8213 * 8214 * @public 8215 */ 8216 createTreeWalker(filter) { 8217 return new YXmlTreeWalker(this, filter); 8218 } 8219 /** 8220 * Returns the first YXmlElement that matches the query. 8221 * Similar to DOM's {@link querySelector}. 8222 * 8223 * Query support: 8224 * - tagname 8225 * TODO: 8226 * - id 8227 * - attribute 8228 * 8229 * @param {CSS_Selector} query The query on the children. 8230 * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. 8231 * 8232 * @public 8233 */ 8234 querySelector(query) { 8235 query = query.toUpperCase(); 8236 const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); 8237 const next = iterator.next(); 8238 if (next.done) { 8239 return null; 8240 } else { 8241 return next.value; 8242 } 8243 } 8244 /** 8245 * Returns all YXmlElements that match the query. 8246 * Similar to Dom's {@link querySelectorAll}. 8247 * 8248 * @todo Does not yet support all queries. Currently only query by tagName. 8249 * 8250 * @param {CSS_Selector} query The query on the children 8251 * @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query. 8252 * 8253 * @public 8254 */ 8255 querySelectorAll(query) { 8256 query = query.toUpperCase(); 8257 return from(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); 8258 } 8259 /** 8260 * Creates YXmlEvent and calls observers. 8261 * 8262 * @param {Transaction} transaction 8263 * @param {Set<null|string>} parentSubs Keys changed on this type. `null` if list was modified. 8264 */ 8265 _callObserver(transaction, parentSubs) { 8266 callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); 8267 } 8268 /** 8269 * Get the string representation of all the children of this YXmlFragment. 8270 * 8271 * @return {string} The string representation of all children. 8272 */ 8273 toString() { 8274 return typeListMap(this, (xml) => xml.toString()).join(""); 8275 } 8276 /** 8277 * @return {string} 8278 */ 8279 toJSON() { 8280 return this.toString(); 8281 } 8282 /** 8283 * Creates a Dom Element that mirrors this YXmlElement. 8284 * 8285 * @param {Document} [_document=document] The document object (you must define 8286 * this when calling this method in 8287 * nodejs) 8288 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 8289 * are presented in the DOM 8290 * @param {any} [binding] You should not set this property. This is 8291 * used if DomBinding wants to create a 8292 * association to the created DOM type. 8293 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8294 * 8295 * @public 8296 */ 8297 toDOM(_document = document, hooks = {}, binding) { 8298 const fragment = _document.createDocumentFragment(); 8299 if (binding !== void 0) { 8300 binding._createAssociation(fragment, this); 8301 } 8302 typeListForEach(this, (xmlType) => { 8303 fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); 8304 }); 8305 return fragment; 8306 } 8307 /** 8308 * Inserts new content at an index. 8309 * 8310 * @example 8311 * // Insert character 'a' at position 0 8312 * xml.insert(0, [new Y.XmlText('text')]) 8313 * 8314 * @param {number} index The index to insert content at 8315 * @param {Array<YXmlElement|YXmlText>} content The array of content 8316 */ 8317 insert(index, content) { 8318 if (this.doc !== null) { 8319 transact(this.doc, (transaction) => { 8320 typeListInsertGenerics(transaction, this, index, content); 8321 }); 8322 } else { 8323 this._prelimContent.splice(index, 0, ...content); 8324 } 8325 } 8326 /** 8327 * Inserts new content at an index. 8328 * 8329 * @example 8330 * // Insert character 'a' at position 0 8331 * xml.insert(0, [new Y.XmlText('text')]) 8332 * 8333 * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at 8334 * @param {Array<YXmlElement|YXmlText>} content The array of content 8335 */ 8336 insertAfter(ref, content) { 8337 if (this.doc !== null) { 8338 transact(this.doc, (transaction) => { 8339 const refItem = ref && ref instanceof AbstractType ? ref._item : ref; 8340 typeListInsertGenericsAfter(transaction, this, refItem, content); 8341 }); 8342 } else { 8343 const pc = ( 8344 /** @type {Array<any>} */ 8345 this._prelimContent 8346 ); 8347 const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; 8348 if (index === 0 && ref !== null) { 8349 throw create3("Reference item not found"); 8350 } 8351 pc.splice(index, 0, ...content); 8352 } 8353 } 8354 /** 8355 * Deletes elements starting from an index. 8356 * 8357 * @param {number} index Index at which to start deleting elements 8358 * @param {number} [length=1] The number of elements to remove. Defaults to 1. 8359 */ 8360 delete(index, length2 = 1) { 8361 if (this.doc !== null) { 8362 transact(this.doc, (transaction) => { 8363 typeListDelete(transaction, this, index, length2); 8364 }); 8365 } else { 8366 this._prelimContent.splice(index, length2); 8367 } 8368 } 8369 /** 8370 * Transforms this YArray to a JavaScript Array. 8371 * 8372 * @return {Array<YXmlElement|YXmlText|YXmlHook>} 8373 */ 8374 toArray() { 8375 return typeListToArray(this); 8376 } 8377 /** 8378 * Appends content to this YArray. 8379 * 8380 * @param {Array<YXmlElement|YXmlText>} content Array of content to append. 8381 */ 8382 push(content) { 8383 this.insert(this.length, content); 8384 } 8385 /** 8386 * Prepends content to this YArray. 8387 * 8388 * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend. 8389 */ 8390 unshift(content) { 8391 this.insert(0, content); 8392 } 8393 /** 8394 * Returns the i-th element from a YArray. 8395 * 8396 * @param {number} index The index of the element to return from the YArray 8397 * @return {YXmlElement|YXmlText} 8398 */ 8399 get(index) { 8400 return typeListGet(this, index); 8401 } 8402 /** 8403 * Returns a portion of this YXmlFragment into a JavaScript Array selected 8404 * from start to end (end not included). 8405 * 8406 * @param {number} [start] 8407 * @param {number} [end] 8408 * @return {Array<YXmlElement|YXmlText>} 8409 */ 8410 slice(start = 0, end = this.length) { 8411 return typeListSlice(this, start, end); 8412 } 8413 /** 8414 * Executes a provided function on once on every child element. 8415 * 8416 * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. 8417 */ 8418 forEach(f) { 8419 typeListForEach(this, f); 8420 } 8421 /** 8422 * Transform the properties of this type to binary and write it to an 8423 * BinaryEncoder. 8424 * 8425 * This is called when this Item is sent to a remote peer. 8426 * 8427 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8428 */ 8429 _write(encoder) { 8430 encoder.writeTypeRef(YXmlFragmentRefID); 8431 } 8432 }; 8433 var readYXmlFragment = (_decoder) => new YXmlFragment(); 8434 var YXmlElement = class _YXmlElement extends YXmlFragment { 8435 constructor(nodeName = "UNDEFINED") { 8436 super(); 8437 this.nodeName = nodeName; 8438 this._prelimAttrs = /* @__PURE__ */ new Map(); 8439 } 8440 /** 8441 * @type {YXmlElement|YXmlText|null} 8442 */ 8443 get nextSibling() { 8444 const n = this._item ? this._item.next : null; 8445 return n ? ( 8446 /** @type {YXmlElement|YXmlText} */ 8447 /** @type {ContentType} */ 8448 n.content.type 8449 ) : null; 8450 } 8451 /** 8452 * @type {YXmlElement|YXmlText|null} 8453 */ 8454 get prevSibling() { 8455 const n = this._item ? this._item.prev : null; 8456 return n ? ( 8457 /** @type {YXmlElement|YXmlText} */ 8458 /** @type {ContentType} */ 8459 n.content.type 8460 ) : null; 8461 } 8462 /** 8463 * Integrate this type into the Yjs instance. 8464 * 8465 * * Save this struct in the os 8466 * * This type is sent to other client 8467 * * Observer functions are fired 8468 * 8469 * @param {Doc} y The Yjs instance 8470 * @param {Item} item 8471 */ 8472 _integrate(y, item) { 8473 super._integrate(y, item); 8474 /** @type {Map<string, any>} */ 8475 this._prelimAttrs.forEach((value, key) => { 8476 this.setAttribute(key, value); 8477 }); 8478 this._prelimAttrs = null; 8479 } 8480 /** 8481 * Creates an Item with the same effect as this Item (without position effect) 8482 * 8483 * @return {YXmlElement} 8484 */ 8485 _copy() { 8486 return new _YXmlElement(this.nodeName); 8487 } 8488 /** 8489 * Makes a copy of this data type that can be included somewhere else. 8490 * 8491 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8492 * 8493 * @return {YXmlElement<KV>} 8494 */ 8495 clone() { 8496 const el = new _YXmlElement(this.nodeName); 8497 const attrs = this.getAttributes(); 8498 forEach(attrs, (value, key) => { 8499 el.setAttribute( 8500 key, 8501 /** @type {any} */ 8502 value 8503 ); 8504 }); 8505 el.insert(0, this.toArray().map((v) => v instanceof AbstractType ? v.clone() : v)); 8506 return el; 8507 } 8508 /** 8509 * Returns the XML serialization of this YXmlElement. 8510 * The attributes are ordered by attribute-name, so you can easily use this 8511 * method to compare YXmlElements 8512 * 8513 * @return {string} The string representation of this type. 8514 * 8515 * @public 8516 */ 8517 toString() { 8518 const attrs = this.getAttributes(); 8519 const stringBuilder = []; 8520 const keys2 = []; 8521 for (const key in attrs) { 8522 keys2.push(key); 8523 } 8524 keys2.sort(); 8525 const keysLen = keys2.length; 8526 for (let i = 0; i < keysLen; i++) { 8527 const key = keys2[i]; 8528 stringBuilder.push(key + '="' + attrs[key] + '"'); 8529 } 8530 const nodeName = this.nodeName.toLocaleLowerCase(); 8531 const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; 8532 return `<$nodeName}$attrsString}>$super.toString()}</$nodeName}>`; 8533 } 8534 /** 8535 * Removes an attribute from this YXmlElement. 8536 * 8537 * @param {string} attributeName The attribute name that is to be removed. 8538 * 8539 * @public 8540 */ 8541 removeAttribute(attributeName) { 8542 if (this.doc !== null) { 8543 transact(this.doc, (transaction) => { 8544 typeMapDelete(transaction, this, attributeName); 8545 }); 8546 } else { 8547 this._prelimAttrs.delete(attributeName); 8548 } 8549 } 8550 /** 8551 * Sets or updates an attribute. 8552 * 8553 * @template {keyof KV & string} KEY 8554 * 8555 * @param {KEY} attributeName The attribute name that is to be set. 8556 * @param {KV[KEY]} attributeValue The attribute value that is to be set. 8557 * 8558 * @public 8559 */ 8560 setAttribute(attributeName, attributeValue) { 8561 if (this.doc !== null) { 8562 transact(this.doc, (transaction) => { 8563 typeMapSet(transaction, this, attributeName, attributeValue); 8564 }); 8565 } else { 8566 this._prelimAttrs.set(attributeName, attributeValue); 8567 } 8568 } 8569 /** 8570 * Returns an attribute value that belongs to the attribute name. 8571 * 8572 * @template {keyof KV & string} KEY 8573 * 8574 * @param {KEY} attributeName The attribute name that identifies the 8575 * queried value. 8576 * @return {KV[KEY]|undefined} The queried attribute value. 8577 * 8578 * @public 8579 */ 8580 getAttribute(attributeName) { 8581 return ( 8582 /** @type {any} */ 8583 typeMapGet(this, attributeName) 8584 ); 8585 } 8586 /** 8587 * Returns whether an attribute exists 8588 * 8589 * @param {string} attributeName The attribute name to check for existence. 8590 * @return {boolean} whether the attribute exists. 8591 * 8592 * @public 8593 */ 8594 hasAttribute(attributeName) { 8595 return ( 8596 /** @type {any} */ 8597 typeMapHas(this, attributeName) 8598 ); 8599 } 8600 /** 8601 * Returns all attribute name/value pairs in a JSON Object. 8602 * 8603 * @param {Snapshot} [snapshot] 8604 * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes. 8605 * 8606 * @public 8607 */ 8608 getAttributes(snapshot2) { 8609 return ( 8610 /** @type {any} */ 8611 snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) 8612 ); 8613 } 8614 /** 8615 * Creates a Dom Element that mirrors this YXmlElement. 8616 * 8617 * @param {Document} [_document=document] The document object (you must define 8618 * this when calling this method in 8619 * nodejs) 8620 * @param {Object<string, any>} [hooks={}] Optional property to customize how hooks 8621 * are presented in the DOM 8622 * @param {any} [binding] You should not set this property. This is 8623 * used if DomBinding wants to create a 8624 * association to the created DOM type. 8625 * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8626 * 8627 * @public 8628 */ 8629 toDOM(_document = document, hooks = {}, binding) { 8630 const dom = _document.createElement(this.nodeName); 8631 const attrs = this.getAttributes(); 8632 for (const key in attrs) { 8633 const value = attrs[key]; 8634 if (typeof value === "string") { 8635 dom.setAttribute(key, value); 8636 } 8637 } 8638 typeListForEach(this, (yxml) => { 8639 dom.appendChild(yxml.toDOM(_document, hooks, binding)); 8640 }); 8641 if (binding !== void 0) { 8642 binding._createAssociation(dom, this); 8643 } 8644 return dom; 8645 } 8646 /** 8647 * Transform the properties of this type to binary and write it to an 8648 * BinaryEncoder. 8649 * 8650 * This is called when this Item is sent to a remote peer. 8651 * 8652 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8653 */ 8654 _write(encoder) { 8655 encoder.writeTypeRef(YXmlElementRefID); 8656 encoder.writeKey(this.nodeName); 8657 } 8658 }; 8659 var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); 8660 var YXmlEvent = class extends YEvent { 8661 /** 8662 * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. 8663 * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the 8664 * child list changed. 8665 * @param {Transaction} transaction The transaction instance with which the 8666 * change was created. 8667 */ 8668 constructor(target, subs, transaction) { 8669 super(target, transaction); 8670 this.childListChanged = false; 8671 this.attributesChanged = /* @__PURE__ */ new Set(); 8672 subs.forEach((sub) => { 8673 if (sub === null) { 8674 this.childListChanged = true; 8675 } else { 8676 this.attributesChanged.add(sub); 8677 } 8678 }); 8679 } 8680 }; 8681 var YXmlHook = class _YXmlHook extends YMap { 8682 /** 8683 * @param {string} hookName nodeName of the Dom Node. 8684 */ 8685 constructor(hookName) { 8686 super(); 8687 this.hookName = hookName; 8688 } 8689 /** 8690 * Creates an Item with the same effect as this Item (without position effect) 8691 */ 8692 _copy() { 8693 return new _YXmlHook(this.hookName); 8694 } 8695 /** 8696 * Makes a copy of this data type that can be included somewhere else. 8697 * 8698 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8699 * 8700 * @return {YXmlHook} 8701 */ 8702 clone() { 8703 const el = new _YXmlHook(this.hookName); 8704 this.forEach((value, key) => { 8705 el.set(key, value); 8706 }); 8707 return el; 8708 } 8709 /** 8710 * Creates a Dom Element that mirrors this YXmlElement. 8711 * 8712 * @param {Document} [_document=document] The document object (you must define 8713 * this when calling this method in 8714 * nodejs) 8715 * @param {Object.<string, any>} [hooks] Optional property to customize how hooks 8716 * are presented in the DOM 8717 * @param {any} [binding] You should not set this property. This is 8718 * used if DomBinding wants to create a 8719 * association to the created DOM type 8720 * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8721 * 8722 * @public 8723 */ 8724 toDOM(_document = document, hooks = {}, binding) { 8725 const hook = hooks[this.hookName]; 8726 let dom; 8727 if (hook !== void 0) { 8728 dom = hook.createDom(this); 8729 } else { 8730 dom = document.createElement(this.hookName); 8731 } 8732 dom.setAttribute("data-yjs-hook", this.hookName); 8733 if (binding !== void 0) { 8734 binding._createAssociation(dom, this); 8735 } 8736 return dom; 8737 } 8738 /** 8739 * Transform the properties of this type to binary and write it to an 8740 * BinaryEncoder. 8741 * 8742 * This is called when this Item is sent to a remote peer. 8743 * 8744 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8745 */ 8746 _write(encoder) { 8747 encoder.writeTypeRef(YXmlHookRefID); 8748 encoder.writeKey(this.hookName); 8749 } 8750 }; 8751 var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); 8752 var YXmlText = class _YXmlText extends YText { 8753 /** 8754 * @type {YXmlElement|YXmlText|null} 8755 */ 8756 get nextSibling() { 8757 const n = this._item ? this._item.next : null; 8758 return n ? ( 8759 /** @type {YXmlElement|YXmlText} */ 8760 /** @type {ContentType} */ 8761 n.content.type 8762 ) : null; 8763 } 8764 /** 8765 * @type {YXmlElement|YXmlText|null} 8766 */ 8767 get prevSibling() { 8768 const n = this._item ? this._item.prev : null; 8769 return n ? ( 8770 /** @type {YXmlElement|YXmlText} */ 8771 /** @type {ContentType} */ 8772 n.content.type 8773 ) : null; 8774 } 8775 _copy() { 8776 return new _YXmlText(); 8777 } 8778 /** 8779 * Makes a copy of this data type that can be included somewhere else. 8780 * 8781 * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. 8782 * 8783 * @return {YXmlText} 8784 */ 8785 clone() { 8786 const text2 = new _YXmlText(); 8787 text2.applyDelta(this.toDelta()); 8788 return text2; 8789 } 8790 /** 8791 * Creates a Dom Element that mirrors this YXmlText. 8792 * 8793 * @param {Document} [_document=document] The document object (you must define 8794 * this when calling this method in 8795 * nodejs) 8796 * @param {Object<string, any>} [hooks] Optional property to customize how hooks 8797 * are presented in the DOM 8798 * @param {any} [binding] You should not set this property. This is 8799 * used if DomBinding wants to create a 8800 * association to the created DOM type. 8801 * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} 8802 * 8803 * @public 8804 */ 8805 toDOM(_document = document, hooks, binding) { 8806 const dom = _document.createTextNode(this.toString()); 8807 if (binding !== void 0) { 8808 binding._createAssociation(dom, this); 8809 } 8810 return dom; 8811 } 8812 toString() { 8813 return this.toDelta().map((delta) => { 8814 const nestedNodes = []; 8815 for (const nodeName in delta.attributes) { 8816 const attrs = []; 8817 for (const key in delta.attributes[nodeName]) { 8818 attrs.push({ key, value: delta.attributes[nodeName][key] }); 8819 } 8820 attrs.sort((a, b) => a.key < b.key ? -1 : 1); 8821 nestedNodes.push({ nodeName, attrs }); 8822 } 8823 nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1); 8824 let str = ""; 8825 for (let i = 0; i < nestedNodes.length; i++) { 8826 const node = nestedNodes[i]; 8827 str += `<$node.nodeName}`; 8828 for (let j = 0; j < node.attrs.length; j++) { 8829 const attr = node.attrs[j]; 8830 str += ` $attr.key}="$attr.value}"`; 8831 } 8832 str += ">"; 8833 } 8834 str += delta.insert; 8835 for (let i = nestedNodes.length - 1; i >= 0; i--) { 8836 str += `</$nestedNodes[i].nodeName}>`; 8837 } 8838 return str; 8839 }).join(""); 8840 } 8841 /** 8842 * @return {string} 8843 */ 8844 toJSON() { 8845 return this.toString(); 8846 } 8847 /** 8848 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8849 */ 8850 _write(encoder) { 8851 encoder.writeTypeRef(YXmlTextRefID); 8852 } 8853 }; 8854 var readYXmlText = (decoder) => new YXmlText(); 8855 var AbstractStruct = class { 8856 /** 8857 * @param {ID} id 8858 * @param {number} length 8859 */ 8860 constructor(id2, length2) { 8861 this.id = id2; 8862 this.length = length2; 8863 } 8864 /** 8865 * @type {boolean} 8866 */ 8867 get deleted() { 8868 throw methodUnimplemented(); 8869 } 8870 /** 8871 * Merge this struct with the item to the right. 8872 * This method is already assuming that `this.id.clock + this.length === this.id.clock`. 8873 * Also this method does *not* remove right from StructStore! 8874 * @param {AbstractStruct} right 8875 * @return {boolean} whether this merged with right 8876 */ 8877 mergeWith(right) { 8878 return false; 8879 } 8880 /** 8881 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 8882 * @param {number} offset 8883 * @param {number} encodingRef 8884 */ 8885 write(encoder, offset, encodingRef) { 8886 throw methodUnimplemented(); 8887 } 8888 /** 8889 * @param {Transaction} transaction 8890 * @param {number} offset 8891 */ 8892 integrate(transaction, offset) { 8893 throw methodUnimplemented(); 8894 } 8895 }; 8896 var structGCRefNumber = 0; 8897 var GC = class extends AbstractStruct { 8898 get deleted() { 8899 return true; 8900 } 8901 delete() { 8902 } 8903 /** 8904 * @param {GC} right 8905 * @return {boolean} 8906 */ 8907 mergeWith(right) { 8908 if (this.constructor !== right.constructor) { 8909 return false; 8910 } 8911 this.length += right.length; 8912 return true; 8913 } 8914 /** 8915 * @param {Transaction} transaction 8916 * @param {number} offset 8917 */ 8918 integrate(transaction, offset) { 8919 if (offset > 0) { 8920 this.id.clock += offset; 8921 this.length -= offset; 8922 } 8923 addStruct(transaction.doc.store, this); 8924 } 8925 /** 8926 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 8927 * @param {number} offset 8928 */ 8929 write(encoder, offset) { 8930 encoder.writeInfo(structGCRefNumber); 8931 encoder.writeLen(this.length - offset); 8932 } 8933 /** 8934 * @param {Transaction} transaction 8935 * @param {StructStore} store 8936 * @return {null | number} 8937 */ 8938 getMissing(transaction, store2) { 8939 return null; 8940 } 8941 }; 8942 var ContentBinary = class _ContentBinary { 8943 /** 8944 * @param {Uint8Array} content 8945 */ 8946 constructor(content) { 8947 this.content = content; 8948 } 8949 /** 8950 * @return {number} 8951 */ 8952 getLength() { 8953 return 1; 8954 } 8955 /** 8956 * @return {Array<any>} 8957 */ 8958 getContent() { 8959 return [this.content]; 8960 } 8961 /** 8962 * @return {boolean} 8963 */ 8964 isCountable() { 8965 return true; 8966 } 8967 /** 8968 * @return {ContentBinary} 8969 */ 8970 copy() { 8971 return new _ContentBinary(this.content); 8972 } 8973 /** 8974 * @param {number} offset 8975 * @return {ContentBinary} 8976 */ 8977 splice(offset) { 8978 throw methodUnimplemented(); 8979 } 8980 /** 8981 * @param {ContentBinary} right 8982 * @return {boolean} 8983 */ 8984 mergeWith(right) { 8985 return false; 8986 } 8987 /** 8988 * @param {Transaction} transaction 8989 * @param {Item} item 8990 */ 8991 integrate(transaction, item) { 8992 } 8993 /** 8994 * @param {Transaction} transaction 8995 */ 8996 delete(transaction) { 8997 } 8998 /** 8999 * @param {StructStore} store 9000 */ 9001 gc(store2) { 9002 } 9003 /** 9004 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9005 * @param {number} offset 9006 */ 9007 write(encoder, offset) { 9008 encoder.writeBuf(this.content); 9009 } 9010 /** 9011 * @return {number} 9012 */ 9013 getRef() { 9014 return 3; 9015 } 9016 }; 9017 var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); 9018 var ContentDeleted = class _ContentDeleted { 9019 /** 9020 * @param {number} len 9021 */ 9022 constructor(len) { 9023 this.len = len; 9024 } 9025 /** 9026 * @return {number} 9027 */ 9028 getLength() { 9029 return this.len; 9030 } 9031 /** 9032 * @return {Array<any>} 9033 */ 9034 getContent() { 9035 return []; 9036 } 9037 /** 9038 * @return {boolean} 9039 */ 9040 isCountable() { 9041 return false; 9042 } 9043 /** 9044 * @return {ContentDeleted} 9045 */ 9046 copy() { 9047 return new _ContentDeleted(this.len); 9048 } 9049 /** 9050 * @param {number} offset 9051 * @return {ContentDeleted} 9052 */ 9053 splice(offset) { 9054 const right = new _ContentDeleted(this.len - offset); 9055 this.len = offset; 9056 return right; 9057 } 9058 /** 9059 * @param {ContentDeleted} right 9060 * @return {boolean} 9061 */ 9062 mergeWith(right) { 9063 this.len += right.len; 9064 return true; 9065 } 9066 /** 9067 * @param {Transaction} transaction 9068 * @param {Item} item 9069 */ 9070 integrate(transaction, item) { 9071 addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); 9072 item.markDeleted(); 9073 } 9074 /** 9075 * @param {Transaction} transaction 9076 */ 9077 delete(transaction) { 9078 } 9079 /** 9080 * @param {StructStore} store 9081 */ 9082 gc(store2) { 9083 } 9084 /** 9085 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9086 * @param {number} offset 9087 */ 9088 write(encoder, offset) { 9089 encoder.writeLen(this.len - offset); 9090 } 9091 /** 9092 * @return {number} 9093 */ 9094 getRef() { 9095 return 1; 9096 } 9097 }; 9098 var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); 9099 var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); 9100 var ContentDoc = class _ContentDoc { 9101 /** 9102 * @param {Doc} doc 9103 */ 9104 constructor(doc2) { 9105 if (doc2._item) { 9106 console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); 9107 } 9108 this.doc = doc2; 9109 const opts = {}; 9110 this.opts = opts; 9111 if (!doc2.gc) { 9112 opts.gc = false; 9113 } 9114 if (doc2.autoLoad) { 9115 opts.autoLoad = true; 9116 } 9117 if (doc2.meta !== null) { 9118 opts.meta = doc2.meta; 9119 } 9120 } 9121 /** 9122 * @return {number} 9123 */ 9124 getLength() { 9125 return 1; 9126 } 9127 /** 9128 * @return {Array<any>} 9129 */ 9130 getContent() { 9131 return [this.doc]; 9132 } 9133 /** 9134 * @return {boolean} 9135 */ 9136 isCountable() { 9137 return true; 9138 } 9139 /** 9140 * @return {ContentDoc} 9141 */ 9142 copy() { 9143 return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); 9144 } 9145 /** 9146 * @param {number} offset 9147 * @return {ContentDoc} 9148 */ 9149 splice(offset) { 9150 throw methodUnimplemented(); 9151 } 9152 /** 9153 * @param {ContentDoc} right 9154 * @return {boolean} 9155 */ 9156 mergeWith(right) { 9157 return false; 9158 } 9159 /** 9160 * @param {Transaction} transaction 9161 * @param {Item} item 9162 */ 9163 integrate(transaction, item) { 9164 this.doc._item = item; 9165 transaction.subdocsAdded.add(this.doc); 9166 if (this.doc.shouldLoad) { 9167 transaction.subdocsLoaded.add(this.doc); 9168 } 9169 } 9170 /** 9171 * @param {Transaction} transaction 9172 */ 9173 delete(transaction) { 9174 if (transaction.subdocsAdded.has(this.doc)) { 9175 transaction.subdocsAdded.delete(this.doc); 9176 } else { 9177 transaction.subdocsRemoved.add(this.doc); 9178 } 9179 } 9180 /** 9181 * @param {StructStore} store 9182 */ 9183 gc(store2) { 9184 } 9185 /** 9186 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9187 * @param {number} offset 9188 */ 9189 write(encoder, offset) { 9190 encoder.writeString(this.doc.guid); 9191 encoder.writeAny(this.opts); 9192 } 9193 /** 9194 * @return {number} 9195 */ 9196 getRef() { 9197 return 9; 9198 } 9199 }; 9200 var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); 9201 var ContentEmbed = class _ContentEmbed { 9202 /** 9203 * @param {Object} embed 9204 */ 9205 constructor(embed) { 9206 this.embed = embed; 9207 } 9208 /** 9209 * @return {number} 9210 */ 9211 getLength() { 9212 return 1; 9213 } 9214 /** 9215 * @return {Array<any>} 9216 */ 9217 getContent() { 9218 return [this.embed]; 9219 } 9220 /** 9221 * @return {boolean} 9222 */ 9223 isCountable() { 9224 return true; 9225 } 9226 /** 9227 * @return {ContentEmbed} 9228 */ 9229 copy() { 9230 return new _ContentEmbed(this.embed); 9231 } 9232 /** 9233 * @param {number} offset 9234 * @return {ContentEmbed} 9235 */ 9236 splice(offset) { 9237 throw methodUnimplemented(); 9238 } 9239 /** 9240 * @param {ContentEmbed} right 9241 * @return {boolean} 9242 */ 9243 mergeWith(right) { 9244 return false; 9245 } 9246 /** 9247 * @param {Transaction} transaction 9248 * @param {Item} item 9249 */ 9250 integrate(transaction, item) { 9251 } 9252 /** 9253 * @param {Transaction} transaction 9254 */ 9255 delete(transaction) { 9256 } 9257 /** 9258 * @param {StructStore} store 9259 */ 9260 gc(store2) { 9261 } 9262 /** 9263 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9264 * @param {number} offset 9265 */ 9266 write(encoder, offset) { 9267 encoder.writeJSON(this.embed); 9268 } 9269 /** 9270 * @return {number} 9271 */ 9272 getRef() { 9273 return 5; 9274 } 9275 }; 9276 var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); 9277 var ContentFormat = class _ContentFormat { 9278 /** 9279 * @param {string} key 9280 * @param {Object} value 9281 */ 9282 constructor(key, value) { 9283 this.key = key; 9284 this.value = value; 9285 } 9286 /** 9287 * @return {number} 9288 */ 9289 getLength() { 9290 return 1; 9291 } 9292 /** 9293 * @return {Array<any>} 9294 */ 9295 getContent() { 9296 return []; 9297 } 9298 /** 9299 * @return {boolean} 9300 */ 9301 isCountable() { 9302 return false; 9303 } 9304 /** 9305 * @return {ContentFormat} 9306 */ 9307 copy() { 9308 return new _ContentFormat(this.key, this.value); 9309 } 9310 /** 9311 * @param {number} _offset 9312 * @return {ContentFormat} 9313 */ 9314 splice(_offset) { 9315 throw methodUnimplemented(); 9316 } 9317 /** 9318 * @param {ContentFormat} _right 9319 * @return {boolean} 9320 */ 9321 mergeWith(_right) { 9322 return false; 9323 } 9324 /** 9325 * @param {Transaction} _transaction 9326 * @param {Item} item 9327 */ 9328 integrate(_transaction, item) { 9329 const p = ( 9330 /** @type {YText} */ 9331 item.parent 9332 ); 9333 p._searchMarker = null; 9334 p._hasFormatting = true; 9335 } 9336 /** 9337 * @param {Transaction} transaction 9338 */ 9339 delete(transaction) { 9340 } 9341 /** 9342 * @param {StructStore} store 9343 */ 9344 gc(store2) { 9345 } 9346 /** 9347 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9348 * @param {number} offset 9349 */ 9350 write(encoder, offset) { 9351 encoder.writeKey(this.key); 9352 encoder.writeJSON(this.value); 9353 } 9354 /** 9355 * @return {number} 9356 */ 9357 getRef() { 9358 return 6; 9359 } 9360 }; 9361 var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); 9362 var ContentJSON = class _ContentJSON { 9363 /** 9364 * @param {Array<any>} arr 9365 */ 9366 constructor(arr) { 9367 this.arr = arr; 9368 } 9369 /** 9370 * @return {number} 9371 */ 9372 getLength() { 9373 return this.arr.length; 9374 } 9375 /** 9376 * @return {Array<any>} 9377 */ 9378 getContent() { 9379 return this.arr; 9380 } 9381 /** 9382 * @return {boolean} 9383 */ 9384 isCountable() { 9385 return true; 9386 } 9387 /** 9388 * @return {ContentJSON} 9389 */ 9390 copy() { 9391 return new _ContentJSON(this.arr); 9392 } 9393 /** 9394 * @param {number} offset 9395 * @return {ContentJSON} 9396 */ 9397 splice(offset) { 9398 const right = new _ContentJSON(this.arr.slice(offset)); 9399 this.arr = this.arr.slice(0, offset); 9400 return right; 9401 } 9402 /** 9403 * @param {ContentJSON} right 9404 * @return {boolean} 9405 */ 9406 mergeWith(right) { 9407 this.arr = this.arr.concat(right.arr); 9408 return true; 9409 } 9410 /** 9411 * @param {Transaction} transaction 9412 * @param {Item} item 9413 */ 9414 integrate(transaction, item) { 9415 } 9416 /** 9417 * @param {Transaction} transaction 9418 */ 9419 delete(transaction) { 9420 } 9421 /** 9422 * @param {StructStore} store 9423 */ 9424 gc(store2) { 9425 } 9426 /** 9427 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9428 * @param {number} offset 9429 */ 9430 write(encoder, offset) { 9431 const len = this.arr.length; 9432 encoder.writeLen(len - offset); 9433 for (let i = offset; i < len; i++) { 9434 const c = this.arr[i]; 9435 encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); 9436 } 9437 } 9438 /** 9439 * @return {number} 9440 */ 9441 getRef() { 9442 return 2; 9443 } 9444 }; 9445 var readContentJSON = (decoder) => { 9446 const len = decoder.readLen(); 9447 const cs = []; 9448 for (let i = 0; i < len; i++) { 9449 const c = decoder.readString(); 9450 if (c === "undefined") { 9451 cs.push(void 0); 9452 } else { 9453 cs.push(JSON.parse(c)); 9454 } 9455 } 9456 return new ContentJSON(cs); 9457 }; 9458 var isDevMode = getVariable("node_env") === "development"; 9459 var ContentAny = class _ContentAny { 9460 /** 9461 * @param {Array<any>} arr 9462 */ 9463 constructor(arr) { 9464 this.arr = arr; 9465 isDevMode && deepFreeze(arr); 9466 } 9467 /** 9468 * @return {number} 9469 */ 9470 getLength() { 9471 return this.arr.length; 9472 } 9473 /** 9474 * @return {Array<any>} 9475 */ 9476 getContent() { 9477 return this.arr; 9478 } 9479 /** 9480 * @return {boolean} 9481 */ 9482 isCountable() { 9483 return true; 9484 } 9485 /** 9486 * @return {ContentAny} 9487 */ 9488 copy() { 9489 return new _ContentAny(this.arr); 9490 } 9491 /** 9492 * @param {number} offset 9493 * @return {ContentAny} 9494 */ 9495 splice(offset) { 9496 const right = new _ContentAny(this.arr.slice(offset)); 9497 this.arr = this.arr.slice(0, offset); 9498 return right; 9499 } 9500 /** 9501 * @param {ContentAny} right 9502 * @return {boolean} 9503 */ 9504 mergeWith(right) { 9505 this.arr = this.arr.concat(right.arr); 9506 return true; 9507 } 9508 /** 9509 * @param {Transaction} transaction 9510 * @param {Item} item 9511 */ 9512 integrate(transaction, item) { 9513 } 9514 /** 9515 * @param {Transaction} transaction 9516 */ 9517 delete(transaction) { 9518 } 9519 /** 9520 * @param {StructStore} store 9521 */ 9522 gc(store2) { 9523 } 9524 /** 9525 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9526 * @param {number} offset 9527 */ 9528 write(encoder, offset) { 9529 const len = this.arr.length; 9530 encoder.writeLen(len - offset); 9531 for (let i = offset; i < len; i++) { 9532 const c = this.arr[i]; 9533 encoder.writeAny(c); 9534 } 9535 } 9536 /** 9537 * @return {number} 9538 */ 9539 getRef() { 9540 return 8; 9541 } 9542 }; 9543 var readContentAny = (decoder) => { 9544 const len = decoder.readLen(); 9545 const cs = []; 9546 for (let i = 0; i < len; i++) { 9547 cs.push(decoder.readAny()); 9548 } 9549 return new ContentAny(cs); 9550 }; 9551 var ContentString = class _ContentString { 9552 /** 9553 * @param {string} str 9554 */ 9555 constructor(str) { 9556 this.str = str; 9557 } 9558 /** 9559 * @return {number} 9560 */ 9561 getLength() { 9562 return this.str.length; 9563 } 9564 /** 9565 * @return {Array<any>} 9566 */ 9567 getContent() { 9568 return this.str.split(""); 9569 } 9570 /** 9571 * @return {boolean} 9572 */ 9573 isCountable() { 9574 return true; 9575 } 9576 /** 9577 * @return {ContentString} 9578 */ 9579 copy() { 9580 return new _ContentString(this.str); 9581 } 9582 /** 9583 * @param {number} offset 9584 * @return {ContentString} 9585 */ 9586 splice(offset) { 9587 const right = new _ContentString(this.str.slice(offset)); 9588 this.str = this.str.slice(0, offset); 9589 const firstCharCode = this.str.charCodeAt(offset - 1); 9590 if (firstCharCode >= 55296 && firstCharCode <= 56319) { 9591 this.str = this.str.slice(0, offset - 1) + "\uFFFD"; 9592 right.str = "\uFFFD" + right.str.slice(1); 9593 } 9594 return right; 9595 } 9596 /** 9597 * @param {ContentString} right 9598 * @return {boolean} 9599 */ 9600 mergeWith(right) { 9601 this.str += right.str; 9602 return true; 9603 } 9604 /** 9605 * @param {Transaction} transaction 9606 * @param {Item} item 9607 */ 9608 integrate(transaction, item) { 9609 } 9610 /** 9611 * @param {Transaction} transaction 9612 */ 9613 delete(transaction) { 9614 } 9615 /** 9616 * @param {StructStore} store 9617 */ 9618 gc(store2) { 9619 } 9620 /** 9621 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9622 * @param {number} offset 9623 */ 9624 write(encoder, offset) { 9625 encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); 9626 } 9627 /** 9628 * @return {number} 9629 */ 9630 getRef() { 9631 return 4; 9632 } 9633 }; 9634 var readContentString = (decoder) => new ContentString(decoder.readString()); 9635 var typeRefs = [ 9636 readYArray, 9637 readYMap, 9638 readYText, 9639 readYXmlElement, 9640 readYXmlFragment, 9641 readYXmlHook, 9642 readYXmlText 9643 ]; 9644 var YArrayRefID = 0; 9645 var YMapRefID = 1; 9646 var YTextRefID = 2; 9647 var YXmlElementRefID = 3; 9648 var YXmlFragmentRefID = 4; 9649 var YXmlHookRefID = 5; 9650 var YXmlTextRefID = 6; 9651 var ContentType = class _ContentType { 9652 /** 9653 * @param {AbstractType<any>} type 9654 */ 9655 constructor(type) { 9656 this.type = type; 9657 } 9658 /** 9659 * @return {number} 9660 */ 9661 getLength() { 9662 return 1; 9663 } 9664 /** 9665 * @return {Array<any>} 9666 */ 9667 getContent() { 9668 return [this.type]; 9669 } 9670 /** 9671 * @return {boolean} 9672 */ 9673 isCountable() { 9674 return true; 9675 } 9676 /** 9677 * @return {ContentType} 9678 */ 9679 copy() { 9680 return new _ContentType(this.type._copy()); 9681 } 9682 /** 9683 * @param {number} offset 9684 * @return {ContentType} 9685 */ 9686 splice(offset) { 9687 throw methodUnimplemented(); 9688 } 9689 /** 9690 * @param {ContentType} right 9691 * @return {boolean} 9692 */ 9693 mergeWith(right) { 9694 return false; 9695 } 9696 /** 9697 * @param {Transaction} transaction 9698 * @param {Item} item 9699 */ 9700 integrate(transaction, item) { 9701 this.type._integrate(transaction.doc, item); 9702 } 9703 /** 9704 * @param {Transaction} transaction 9705 */ 9706 delete(transaction) { 9707 let item = this.type._start; 9708 while (item !== null) { 9709 if (!item.deleted) { 9710 item.delete(transaction); 9711 } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { 9712 transaction._mergeStructs.push(item); 9713 } 9714 item = item.right; 9715 } 9716 this.type._map.forEach((item2) => { 9717 if (!item2.deleted) { 9718 item2.delete(transaction); 9719 } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { 9720 transaction._mergeStructs.push(item2); 9721 } 9722 }); 9723 transaction.changed.delete(this.type); 9724 } 9725 /** 9726 * @param {StructStore} store 9727 */ 9728 gc(store2) { 9729 let item = this.type._start; 9730 while (item !== null) { 9731 item.gc(store2, true); 9732 item = item.right; 9733 } 9734 this.type._start = null; 9735 this.type._map.forEach( 9736 /** @param {Item | null} item */ 9737 (item2) => { 9738 while (item2 !== null) { 9739 item2.gc(store2, true); 9740 item2 = item2.left; 9741 } 9742 } 9743 ); 9744 this.type._map = /* @__PURE__ */ new Map(); 9745 } 9746 /** 9747 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 9748 * @param {number} offset 9749 */ 9750 write(encoder, offset) { 9751 this.type._write(encoder); 9752 } 9753 /** 9754 * @return {number} 9755 */ 9756 getRef() { 9757 return 7; 9758 } 9759 }; 9760 var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); 9761 var followRedone = (store2, id2) => { 9762 let nextID = id2; 9763 let diff = 0; 9764 let item; 9765 do { 9766 if (diff > 0) { 9767 nextID = createID(nextID.client, nextID.clock + diff); 9768 } 9769 item = getItem(store2, nextID); 9770 diff = nextID.clock - item.id.clock; 9771 nextID = item.redone; 9772 } while (nextID !== null && item instanceof Item); 9773 return { 9774 item, 9775 diff 9776 }; 9777 }; 9778 var keepItem = (item, keep) => { 9779 while (item !== null && item.keep !== keep) { 9780 item.keep = keep; 9781 item = /** @type {AbstractType<any>} */ 9782 item.parent._item; 9783 } 9784 }; 9785 var splitItem = (transaction, leftItem, diff) => { 9786 const { client, clock } = leftItem.id; 9787 const rightItem = new Item( 9788 createID(client, clock + diff), 9789 leftItem, 9790 createID(client, clock + diff - 1), 9791 leftItem.right, 9792 leftItem.rightOrigin, 9793 leftItem.parent, 9794 leftItem.parentSub, 9795 leftItem.content.splice(diff) 9796 ); 9797 if (leftItem.deleted) { 9798 rightItem.markDeleted(); 9799 } 9800 if (leftItem.keep) { 9801 rightItem.keep = true; 9802 } 9803 if (leftItem.redone !== null) { 9804 rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); 9805 } 9806 leftItem.right = rightItem; 9807 if (rightItem.right !== null) { 9808 rightItem.right.left = rightItem; 9809 } 9810 transaction._mergeStructs.push(rightItem); 9811 if (rightItem.parentSub !== null && rightItem.right === null) { 9812 rightItem.parent._map.set(rightItem.parentSub, rightItem); 9813 } 9814 leftItem.length = diff; 9815 return rightItem; 9816 }; 9817 var isDeletedByUndoStack = (stack, id2) => some( 9818 stack, 9819 /** @param {StackItem} s */ 9820 (s) => isDeleted(s.deletions, id2) 9821 ); 9822 var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { 9823 const doc2 = transaction.doc; 9824 const store2 = doc2.store; 9825 const ownClientID = doc2.clientID; 9826 const redone = item.redone; 9827 if (redone !== null) { 9828 return getItemCleanStart(transaction, redone); 9829 } 9830 let parentItem = ( 9831 /** @type {AbstractType<any>} */ 9832 item.parent._item 9833 ); 9834 let left = null; 9835 let right; 9836 if (parentItem !== null && parentItem.deleted === true) { 9837 if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { 9838 return null; 9839 } 9840 while (parentItem.redone !== null) { 9841 parentItem = getItemCleanStart(transaction, parentItem.redone); 9842 } 9843 } 9844 const parentType = parentItem === null ? ( 9845 /** @type {AbstractType<any>} */ 9846 item.parent 9847 ) : ( 9848 /** @type {ContentType} */ 9849 parentItem.content.type 9850 ); 9851 if (item.parentSub === null) { 9852 left = item.left; 9853 right = item; 9854 while (left !== null) { 9855 let leftTrace = left; 9856 while (leftTrace !== null && /** @type {AbstractType<any>} */ 9857 leftTrace.parent._item !== parentItem) { 9858 leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); 9859 } 9860 if (leftTrace !== null && /** @type {AbstractType<any>} */ 9861 leftTrace.parent._item === parentItem) { 9862 left = leftTrace; 9863 break; 9864 } 9865 left = left.left; 9866 } 9867 while (right !== null) { 9868 let rightTrace = right; 9869 while (rightTrace !== null && /** @type {AbstractType<any>} */ 9870 rightTrace.parent._item !== parentItem) { 9871 rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); 9872 } 9873 if (rightTrace !== null && /** @type {AbstractType<any>} */ 9874 rightTrace.parent._item === parentItem) { 9875 right = rightTrace; 9876 break; 9877 } 9878 right = right.right; 9879 } 9880 } else { 9881 right = null; 9882 if (item.right && !ignoreRemoteMapChanges) { 9883 left = item; 9884 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))) { 9885 left = left.right; 9886 while (left.redone) left = getItemCleanStart(transaction, left.redone); 9887 } 9888 if (left && left.right !== null) { 9889 return null; 9890 } 9891 } else { 9892 left = parentType._map.get(item.parentSub) || null; 9893 } 9894 } 9895 const nextClock = getState(store2, ownClientID); 9896 const nextId = createID(ownClientID, nextClock); 9897 const redoneItem = new Item( 9898 nextId, 9899 left, 9900 left && left.lastId, 9901 right, 9902 right && right.id, 9903 parentType, 9904 item.parentSub, 9905 item.content.copy() 9906 ); 9907 item.redone = nextId; 9908 keepItem(redoneItem, true); 9909 redoneItem.integrate(transaction, 0); 9910 return redoneItem; 9911 }; 9912 var Item = class _Item extends AbstractStruct { 9913 /** 9914 * @param {ID} id 9915 * @param {Item | null} left 9916 * @param {ID | null} origin 9917 * @param {Item | null} right 9918 * @param {ID | null} rightOrigin 9919 * @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. 9920 * @param {string | null} parentSub 9921 * @param {AbstractContent} content 9922 */ 9923 constructor(id2, left, origin2, right, rightOrigin, parent, parentSub, content) { 9924 super(id2, content.getLength()); 9925 this.origin = origin2; 9926 this.left = left; 9927 this.right = right; 9928 this.rightOrigin = rightOrigin; 9929 this.parent = parent; 9930 this.parentSub = parentSub; 9931 this.redone = null; 9932 this.content = content; 9933 this.info = this.content.isCountable() ? BIT2 : 0; 9934 } 9935 /** 9936 * This is used to mark the item as an indexed fast-search marker 9937 * 9938 * @type {boolean} 9939 */ 9940 set marker(isMarked) { 9941 if ((this.info & BIT4) > 0 !== isMarked) { 9942 this.info ^= BIT4; 9943 } 9944 } 9945 get marker() { 9946 return (this.info & BIT4) > 0; 9947 } 9948 /** 9949 * If true, do not garbage collect this Item. 9950 */ 9951 get keep() { 9952 return (this.info & BIT1) > 0; 9953 } 9954 set keep(doKeep) { 9955 if (this.keep !== doKeep) { 9956 this.info ^= BIT1; 9957 } 9958 } 9959 get countable() { 9960 return (this.info & BIT2) > 0; 9961 } 9962 /** 9963 * Whether this item was deleted or not. 9964 * @type {Boolean} 9965 */ 9966 get deleted() { 9967 return (this.info & BIT3) > 0; 9968 } 9969 set deleted(doDelete) { 9970 if (this.deleted !== doDelete) { 9971 this.info ^= BIT3; 9972 } 9973 } 9974 markDeleted() { 9975 this.info |= BIT3; 9976 } 9977 /** 9978 * Return the creator clientID of the missing op or define missing items and return null. 9979 * 9980 * @param {Transaction} transaction 9981 * @param {StructStore} store 9982 * @return {null | number} 9983 */ 9984 getMissing(transaction, store2) { 9985 if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store2, this.origin.client)) { 9986 return this.origin.client; 9987 } 9988 if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store2, this.rightOrigin.client)) { 9989 return this.rightOrigin.client; 9990 } 9991 if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store2, this.parent.client)) { 9992 return this.parent.client; 9993 } 9994 if (this.origin) { 9995 this.left = getItemCleanEnd(transaction, store2, this.origin); 9996 this.origin = this.left.lastId; 9997 } 9998 if (this.rightOrigin) { 9999 this.right = getItemCleanStart(transaction, this.rightOrigin); 10000 this.rightOrigin = this.right.id; 10001 } 10002 if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { 10003 this.parent = null; 10004 } else if (!this.parent) { 10005 if (this.left && this.left.constructor === _Item) { 10006 this.parent = this.left.parent; 10007 this.parentSub = this.left.parentSub; 10008 } else if (this.right && this.right.constructor === _Item) { 10009 this.parent = this.right.parent; 10010 this.parentSub = this.right.parentSub; 10011 } 10012 } else if (this.parent.constructor === ID) { 10013 const parentItem = getItem(store2, this.parent); 10014 if (parentItem.constructor === GC) { 10015 this.parent = null; 10016 } else { 10017 this.parent = /** @type {ContentType} */ 10018 parentItem.content.type; 10019 } 10020 } 10021 return null; 10022 } 10023 /** 10024 * @param {Transaction} transaction 10025 * @param {number} offset 10026 */ 10027 integrate(transaction, offset) { 10028 if (offset > 0) { 10029 this.id.clock += offset; 10030 this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); 10031 this.origin = this.left.lastId; 10032 this.content = this.content.splice(offset); 10033 this.length -= offset; 10034 } 10035 if (this.parent) { 10036 if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { 10037 let left = this.left; 10038 let o; 10039 if (left !== null) { 10040 o = left.right; 10041 } else if (this.parentSub !== null) { 10042 o = /** @type {AbstractType<any>} */ 10043 this.parent._map.get(this.parentSub) || null; 10044 while (o !== null && o.left !== null) { 10045 o = o.left; 10046 } 10047 } else { 10048 o = /** @type {AbstractType<any>} */ 10049 this.parent._start; 10050 } 10051 const conflictingItems = /* @__PURE__ */ new Set(); 10052 const itemsBeforeOrigin = /* @__PURE__ */ new Set(); 10053 while (o !== null && o !== this.right) { 10054 itemsBeforeOrigin.add(o); 10055 conflictingItems.add(o); 10056 if (compareIDs(this.origin, o.origin)) { 10057 if (o.id.client < this.id.client) { 10058 left = o; 10059 conflictingItems.clear(); 10060 } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { 10061 break; 10062 } 10063 } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { 10064 if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { 10065 left = o; 10066 conflictingItems.clear(); 10067 } 10068 } else { 10069 break; 10070 } 10071 o = o.right; 10072 } 10073 this.left = left; 10074 } 10075 if (this.left !== null) { 10076 const right = this.left.right; 10077 this.right = right; 10078 this.left.right = this; 10079 } else { 10080 let r2; 10081 if (this.parentSub !== null) { 10082 r2 = /** @type {AbstractType<any>} */ 10083 this.parent._map.get(this.parentSub) || null; 10084 while (r2 !== null && r2.left !== null) { 10085 r2 = r2.left; 10086 } 10087 } else { 10088 r2 = /** @type {AbstractType<any>} */ 10089 this.parent._start; 10090 this.parent._start = this; 10091 } 10092 this.right = r2; 10093 } 10094 if (this.right !== null) { 10095 this.right.left = this; 10096 } else if (this.parentSub !== null) { 10097 this.parent._map.set(this.parentSub, this); 10098 if (this.left !== null) { 10099 this.left.delete(transaction); 10100 } 10101 } 10102 if (this.parentSub === null && this.countable && !this.deleted) { 10103 this.parent._length += this.length; 10104 } 10105 addStruct(transaction.doc.store, this); 10106 this.content.integrate(transaction, this); 10107 addChangedTypeToTransaction( 10108 transaction, 10109 /** @type {AbstractType<any>} */ 10110 this.parent, 10111 this.parentSub 10112 ); 10113 if ( 10114 /** @type {AbstractType<any>} */ 10115 this.parent._item !== null && /** @type {AbstractType<any>} */ 10116 this.parent._item.deleted || this.parentSub !== null && this.right !== null 10117 ) { 10118 this.delete(transaction); 10119 } 10120 } else { 10121 new GC(this.id, this.length).integrate(transaction, 0); 10122 } 10123 } 10124 /** 10125 * Returns the next non-deleted item 10126 */ 10127 get next() { 10128 let n = this.right; 10129 while (n !== null && n.deleted) { 10130 n = n.right; 10131 } 10132 return n; 10133 } 10134 /** 10135 * Returns the previous non-deleted item 10136 */ 10137 get prev() { 10138 let n = this.left; 10139 while (n !== null && n.deleted) { 10140 n = n.left; 10141 } 10142 return n; 10143 } 10144 /** 10145 * Computes the last content address of this Item. 10146 */ 10147 get lastId() { 10148 return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); 10149 } 10150 /** 10151 * Try to merge two items 10152 * 10153 * @param {Item} right 10154 * @return {boolean} 10155 */ 10156 mergeWith(right) { 10157 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)) { 10158 const searchMarker = ( 10159 /** @type {AbstractType<any>} */ 10160 this.parent._searchMarker 10161 ); 10162 if (searchMarker) { 10163 searchMarker.forEach((marker) => { 10164 if (marker.p === right) { 10165 marker.p = this; 10166 if (!this.deleted && this.countable) { 10167 marker.index -= this.length; 10168 } 10169 } 10170 }); 10171 } 10172 if (right.keep) { 10173 this.keep = true; 10174 } 10175 this.right = right.right; 10176 if (this.right !== null) { 10177 this.right.left = this; 10178 } 10179 this.length += right.length; 10180 return true; 10181 } 10182 return false; 10183 } 10184 /** 10185 * Mark this Item as deleted. 10186 * 10187 * @param {Transaction} transaction 10188 */ 10189 delete(transaction) { 10190 if (!this.deleted) { 10191 const parent = ( 10192 /** @type {AbstractType<any>} */ 10193 this.parent 10194 ); 10195 if (this.countable && this.parentSub === null) { 10196 parent._length -= this.length; 10197 } 10198 this.markDeleted(); 10199 addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); 10200 addChangedTypeToTransaction(transaction, parent, this.parentSub); 10201 this.content.delete(transaction); 10202 } 10203 } 10204 /** 10205 * @param {StructStore} store 10206 * @param {boolean} parentGCd 10207 */ 10208 gc(store2, parentGCd) { 10209 if (!this.deleted) { 10210 throw unexpectedCase(); 10211 } 10212 this.content.gc(store2); 10213 if (parentGCd) { 10214 replaceStruct(store2, this, new GC(this.id, this.length)); 10215 } else { 10216 this.content = new ContentDeleted(this.length); 10217 } 10218 } 10219 /** 10220 * Transform the properties of this type to binary and write it to an 10221 * BinaryEncoder. 10222 * 10223 * This is called when this Item is sent to a remote peer. 10224 * 10225 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. 10226 * @param {number} offset 10227 */ 10228 write(encoder, offset) { 10229 const origin2 = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; 10230 const rightOrigin = this.rightOrigin; 10231 const parentSub = this.parentSub; 10232 const info = this.content.getRef() & BITS5 | (origin2 === null ? 0 : BIT8) | // origin is defined 10233 (rightOrigin === null ? 0 : BIT7) | // right origin is defined 10234 (parentSub === null ? 0 : BIT6); 10235 encoder.writeInfo(info); 10236 if (origin2 !== null) { 10237 encoder.writeLeftID(origin2); 10238 } 10239 if (rightOrigin !== null) { 10240 encoder.writeRightID(rightOrigin); 10241 } 10242 if (origin2 === null && rightOrigin === null) { 10243 const parent = ( 10244 /** @type {AbstractType<any>} */ 10245 this.parent 10246 ); 10247 if (parent._item !== void 0) { 10248 const parentItem = parent._item; 10249 if (parentItem === null) { 10250 const ykey = findRootTypeKey(parent); 10251 encoder.writeParentInfo(true); 10252 encoder.writeString(ykey); 10253 } else { 10254 encoder.writeParentInfo(false); 10255 encoder.writeLeftID(parentItem.id); 10256 } 10257 } else if (parent.constructor === String) { 10258 encoder.writeParentInfo(true); 10259 encoder.writeString(parent); 10260 } else if (parent.constructor === ID) { 10261 encoder.writeParentInfo(false); 10262 encoder.writeLeftID(parent); 10263 } else { 10264 unexpectedCase(); 10265 } 10266 if (parentSub !== null) { 10267 encoder.writeString(parentSub); 10268 } 10269 } 10270 this.content.write(encoder, offset); 10271 } 10272 }; 10273 var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); 10274 var contentRefs = [ 10275 () => { 10276 unexpectedCase(); 10277 }, 10278 // GC is not ItemContent 10279 readContentDeleted, 10280 // 1 10281 readContentJSON, 10282 // 2 10283 readContentBinary, 10284 // 3 10285 readContentString, 10286 // 4 10287 readContentEmbed, 10288 // 5 10289 readContentFormat, 10290 // 6 10291 readContentType, 10292 // 7 10293 readContentAny, 10294 // 8 10295 readContentDoc, 10296 // 9 10297 () => { 10298 unexpectedCase(); 10299 } 10300 // 10 - Skip is not ItemContent 10301 ]; 10302 var structSkipRefNumber = 10; 10303 var Skip = class extends AbstractStruct { 10304 get deleted() { 10305 return true; 10306 } 10307 delete() { 10308 } 10309 /** 10310 * @param {Skip} right 10311 * @return {boolean} 10312 */ 10313 mergeWith(right) { 10314 if (this.constructor !== right.constructor) { 10315 return false; 10316 } 10317 this.length += right.length; 10318 return true; 10319 } 10320 /** 10321 * @param {Transaction} transaction 10322 * @param {number} offset 10323 */ 10324 integrate(transaction, offset) { 10325 unexpectedCase(); 10326 } 10327 /** 10328 * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder 10329 * @param {number} offset 10330 */ 10331 write(encoder, offset) { 10332 encoder.writeInfo(structSkipRefNumber); 10333 writeVarUint(encoder.restEncoder, this.length - offset); 10334 } 10335 /** 10336 * @param {Transaction} transaction 10337 * @param {StructStore} store 10338 * @return {null | number} 10339 */ 10340 getMissing(transaction, store2) { 10341 return null; 10342 } 10343 }; 10344 var glo = ( 10345 /** @type {any} */ 10346 typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} 10347 ); 10348 var importIdentifier = "__ $YJS$ __"; 10349 if (glo[importIdentifier] === true) { 10350 console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); 10351 } 10352 glo[importIdentifier] = true; 10353 10354 // node_modules/.store/y-protocols@1.0.7-LCrc4ked9I2BIv1vBZfNXw/node_modules/y-protocols/awareness.js 10355 var outdatedTimeout = 3e4; 10356 var Awareness = class extends Observable { 10357 /** 10358 * @param {Y.Doc} doc 10359 */ 10360 constructor(doc2) { 10361 super(); 10362 this.doc = doc2; 10363 this.clientID = doc2.clientID; 10364 this.states = /* @__PURE__ */ new Map(); 10365 this.meta = /* @__PURE__ */ new Map(); 10366 this._checkInterval = /** @type {any} */ 10367 setInterval(() => { 10368 const now = getUnixTime(); 10369 if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ 10370 this.meta.get(this.clientID).lastUpdated) { 10371 this.setLocalState(this.getLocalState()); 10372 } 10373 const remove = []; 10374 this.meta.forEach((meta, clientid) => { 10375 if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { 10376 remove.push(clientid); 10377 } 10378 }); 10379 if (remove.length > 0) { 10380 removeAwarenessStates(this, remove, "timeout"); 10381 } 10382 }, floor(outdatedTimeout / 10)); 10383 doc2.on("destroy", () => { 10384 this.destroy(); 10385 }); 10386 this.setLocalState({}); 10387 } 10388 destroy() { 10389 this.emit("destroy", [this]); 10390 this.setLocalState(null); 10391 super.destroy(); 10392 clearInterval(this._checkInterval); 10393 } 10394 /** 10395 * @return {Object<string,any>|null} 10396 */ 10397 getLocalState() { 10398 return this.states.get(this.clientID) || null; 10399 } 10400 /** 10401 * @param {Object<string,any>|null} state 10402 */ 10403 setLocalState(state) { 10404 const clientID = this.clientID; 10405 const currLocalMeta = this.meta.get(clientID); 10406 const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; 10407 const prevState = this.states.get(clientID); 10408 if (state === null) { 10409 this.states.delete(clientID); 10410 } else { 10411 this.states.set(clientID, state); 10412 } 10413 this.meta.set(clientID, { 10414 clock, 10415 lastUpdated: getUnixTime() 10416 }); 10417 const added = []; 10418 const updated = []; 10419 const filteredUpdated = []; 10420 const removed = []; 10421 if (state === null) { 10422 removed.push(clientID); 10423 } else if (prevState == null) { 10424 if (state != null) { 10425 added.push(clientID); 10426 } 10427 } else { 10428 updated.push(clientID); 10429 if (!equalityDeep(prevState, state)) { 10430 filteredUpdated.push(clientID); 10431 } 10432 } 10433 if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { 10434 this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); 10435 } 10436 this.emit("update", [{ added, updated, removed }, "local"]); 10437 } 10438 /** 10439 * @param {string} field 10440 * @param {any} value 10441 */ 10442 setLocalStateField(field, value) { 10443 const state = this.getLocalState(); 10444 if (state !== null) { 10445 this.setLocalState({ 10446 ...state, 10447 [field]: value 10448 }); 10449 } 10450 } 10451 /** 10452 * @return {Map<number,Object<string,any>>} 10453 */ 10454 getStates() { 10455 return this.states; 10456 } 10457 }; 10458 var removeAwarenessStates = (awareness, clients, origin2) => { 10459 const removed = []; 10460 for (let i = 0; i < clients.length; i++) { 10461 const clientID = clients[i]; 10462 if (awareness.states.has(clientID)) { 10463 awareness.states.delete(clientID); 10464 if (clientID === awareness.clientID) { 10465 const curMeta = ( 10466 /** @type {MetaClientState} */ 10467 awareness.meta.get(clientID) 10468 ); 10469 awareness.meta.set(clientID, { 10470 clock: curMeta.clock + 1, 10471 lastUpdated: getUnixTime() 10472 }); 10473 } 10474 removed.push(clientID); 10475 } 10476 } 10477 if (removed.length > 0) { 10478 awareness.emit("change", [{ added: [], updated: [], removed }, origin2]); 10479 awareness.emit("update", [{ added: [], updated: [], removed }, origin2]); 10480 } 10481 }; 10482 10483 // packages/sync/build-module/config.mjs 10484 var CRDT_DOC_VERSION = 1; 10485 var CRDT_DOC_META_PERSISTENCE_KEY = "fromPersistence"; 10486 var CRDT_RECORD_MAP_KEY = "document"; 10487 var CRDT_STATE_MAP_KEY = "state"; 10488 var CRDT_STATE_MAP_SAVED_AT_KEY = "savedAt"; 10489 var CRDT_STATE_MAP_SAVED_BY_KEY = "savedBy"; 10490 var CRDT_STATE_MAP_VERSION_KEY = "version"; 10491 var LOCAL_EDITOR_ORIGIN = "gutenberg"; 10492 var LOCAL_SYNC_MANAGER_ORIGIN = "syncManager"; 10493 var LOCAL_UNDO_IGNORED_ORIGIN = "gutenberg-undo-ignored"; 10494 10495 // packages/sync/build-module/errors.mjs 10496 var ConnectionErrorCode = /* @__PURE__ */ ((ConnectionErrorCode2) => { 10497 ConnectionErrorCode2["AUTHENTICATION_FAILED"] = "authentication-failed"; 10498 ConnectionErrorCode2["CONNECTION_EXPIRED"] = "connection-expired"; 10499 ConnectionErrorCode2["CONNECTION_LIMIT_EXCEEDED"] = "connection-limit-exceeded"; 10500 ConnectionErrorCode2["DOCUMENT_SIZE_LIMIT_EXCEEDED"] = "document-size-limit-exceeded"; 10501 ConnectionErrorCode2["PROTOCOL_MISMATCH"] = "protocol-mismatch"; 10502 ConnectionErrorCode2["UNKNOWN_ERROR"] = "unknown-error"; 10503 return ConnectionErrorCode2; 10504 })(ConnectionErrorCode || {}); 10505 var ConnectionError = class extends Error { 10506 constructor(code = "unknown-error", message) { 10507 super(message); 10508 this.code = code; 10509 this.name = "ConnectionError"; 10510 } 10511 }; 10512 10513 // packages/sync/build-module/performance.mjs 10514 function logPerformanceTiming(fn) { 10515 return function(...args2) { 10516 const start = performance.now(); 10517 const result = fn.apply(this, args2); 10518 const end = performance.now(); 10519 console.log( 10520 `[SyncManager][performance]: $fn.name} took ${(end - start).toFixed(2)} ms` 10521 ); 10522 return result; 10523 }; 10524 } 10525 function passThru(fn) { 10526 return ((...args2) => fn(...args2)); 10527 } 10528 10529 // packages/sync/build-module/providers/index.mjs 10530 var import_hooks3 = __toESM(require_hooks(), 1); 10531 10532 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 10533 var import_hooks2 = __toESM(require_hooks(), 1); 10534 10535 // node_modules/.store/y-protocols@1.0.7-LCrc4ked9I2BIv1vBZfNXw/node_modules/y-protocols/sync.js 10536 var messageYjsSyncStep1 = 0; 10537 var messageYjsSyncStep2 = 1; 10538 var messageYjsUpdate = 2; 10539 var writeSyncStep1 = (encoder, doc2) => { 10540 writeVarUint(encoder, messageYjsSyncStep1); 10541 const sv = encodeStateVector(doc2); 10542 writeVarUint8Array(encoder, sv); 10543 }; 10544 var writeSyncStep2 = (encoder, doc2, encodedStateVector) => { 10545 writeVarUint(encoder, messageYjsSyncStep2); 10546 writeVarUint8Array(encoder, encodeStateAsUpdate(doc2, encodedStateVector)); 10547 }; 10548 var readSyncStep1 = (decoder, encoder, doc2) => writeSyncStep2(encoder, doc2, readVarUint8Array(decoder)); 10549 var readSyncStep2 = (decoder, doc2, transactionOrigin, errorHandler) => { 10550 try { 10551 applyUpdate(doc2, readVarUint8Array(decoder), transactionOrigin); 10552 } catch (error) { 10553 if (errorHandler != null) errorHandler( 10554 /** @type {Error} */ 10555 error 10556 ); 10557 console.error("Caught error while handling a Yjs update", error); 10558 } 10559 }; 10560 var readUpdate2 = readSyncStep2; 10561 var readSyncMessage = (decoder, encoder, doc2, transactionOrigin, errorHandler) => { 10562 const messageType = readVarUint(decoder); 10563 switch (messageType) { 10564 case messageYjsSyncStep1: 10565 readSyncStep1(decoder, encoder, doc2); 10566 break; 10567 case messageYjsSyncStep2: 10568 readSyncStep2(decoder, doc2, transactionOrigin, errorHandler); 10569 break; 10570 case messageYjsUpdate: 10571 readUpdate2(decoder, doc2, transactionOrigin, errorHandler); 10572 break; 10573 default: 10574 throw new Error("Unknown message type"); 10575 } 10576 return messageType; 10577 }; 10578 10579 // packages/sync/build-module/providers/http-polling/config.mjs 10580 var import_hooks = __toESM(require_hooks(), 1); 10581 var DEFAULT_CLIENT_LIMIT_PER_ROOM = 3; 10582 var ERROR_RETRY_DELAYS_SOLO_MS = [ 10583 2e3, 10584 4e3, 10585 8e3, 10586 12e3 10587 // Solo: 26s total retry time solo before dialog 10588 ]; 10589 var ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS = [ 10590 1e3, 10591 2e3, 10592 4e3, 10593 8e3 10594 // With collaborators: 15s total retry time before dialog 10595 ]; 10596 var DISCONNECT_DIALOG_RETRY_MS = 3e4; 10597 var MANUAL_RETRY_INTERVAL_MS = 15e3; 10598 var MAX_ENCODED_UPDATE_SIZE_IN_BYTES = 1 * 1024 * 1024; 10599 var MAX_UPDATE_SIZE_IN_BYTES = Math.floor(MAX_ENCODED_UPDATE_SIZE_IN_BYTES / 4) * 3; 10600 var MAX_ROOMS_PER_REQUEST = 50; 10601 var MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES = 15 * 1024 * 1024; 10602 var MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES = 2 * 1024 * 1024; 10603 var DEFAULT_POLLING_INTERVAL_IN_MS = 4e3; 10604 var DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = 1e3; 10605 function getFilteredPollingInterval(hookName, defaultInterval) { 10606 const filteredInterval = (0, import_hooks.applyFilters)(hookName, defaultInterval); 10607 if (typeof filteredInterval !== "number" || !Number.isFinite(filteredInterval) || filteredInterval <= 0) { 10608 return defaultInterval; 10609 } 10610 return Math.min(filteredInterval, defaultInterval); 10611 } 10612 var POLLING_INTERVAL_IN_MS = getFilteredPollingInterval( 10613 "sync.pollingManager.pollingInterval", 10614 DEFAULT_POLLING_INTERVAL_IN_MS 10615 ); 10616 var POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS = getFilteredPollingInterval( 10617 "sync.pollingManager.pollingIntervalWithCollaborators", 10618 DEFAULT_POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS 10619 ); 10620 var POLLING_INTERVAL_BACKGROUND_TAB_IN_MS = 25 * 1e3; 10621 10622 // packages/sync/build-module/providers/http-polling/types.mjs 10623 var SyncUpdateType = /* @__PURE__ */ ((SyncUpdateType2) => { 10624 SyncUpdateType2["COMPACTION"] = "compaction"; 10625 SyncUpdateType2["SYNC_STEP_1"] = "sync_step1"; 10626 SyncUpdateType2["SYNC_STEP_2"] = "sync_step2"; 10627 SyncUpdateType2["UPDATE"] = "update"; 10628 return SyncUpdateType2; 10629 })(SyncUpdateType || {}); 10630 10631 // packages/sync/build-module/providers/http-polling/utils.mjs 10632 var import_api_fetch = __toESM(require_api_fetch(), 1); 10633 var SYNC_API_PATH = "/wp-sync/v1/updates"; 10634 function uint8ArrayToBase64(data) { 10635 let binary = ""; 10636 const len = data.byteLength; 10637 for (let i = 0; i < len; i++) { 10638 binary += String.fromCharCode(data[i]); 10639 } 10640 return globalThis.btoa(binary); 10641 } 10642 function base64ToUint8Array(base64) { 10643 const binaryString = globalThis.atob(base64); 10644 const len = binaryString.length; 10645 const bytes = new Uint8Array(len); 10646 for (let i = 0; i < len; i++) { 10647 bytes[i] = binaryString.charCodeAt(i); 10648 } 10649 return bytes; 10650 } 10651 function createSyncUpdate(data, type) { 10652 return { 10653 data: uint8ArrayToBase64(data), 10654 type 10655 }; 10656 } 10657 function createUpdateQueue(initial = [], paused = true) { 10658 let isPaused = paused; 10659 const updates = [...initial]; 10660 return { 10661 add(update) { 10662 updates.push(update); 10663 }, 10664 addBulk(bulkUpdates) { 10665 if (0 === bulkUpdates.length) { 10666 return; 10667 } 10668 updates.push(...bulkUpdates); 10669 }, 10670 clear() { 10671 updates.splice(0, updates.length); 10672 }, 10673 get() { 10674 if (isPaused) { 10675 return []; 10676 } 10677 return updates.splice(0, updates.length); 10678 }, 10679 pause() { 10680 isPaused = true; 10681 }, 10682 peek() { 10683 if (isPaused) { 10684 return []; 10685 } 10686 return [...updates]; 10687 }, 10688 restore(restoredUpdates) { 10689 const filtered = restoredUpdates.filter( 10690 (u) => u.type !== SyncUpdateType.COMPACTION 10691 ); 10692 if (0 === filtered.length) { 10693 return; 10694 } 10695 updates.unshift(...filtered); 10696 }, 10697 restoreExact(restoredUpdates) { 10698 if (0 === restoredUpdates.length) { 10699 return; 10700 } 10701 updates.unshift(...restoredUpdates); 10702 }, 10703 resume() { 10704 isPaused = false; 10705 }, 10706 size() { 10707 return updates.length; 10708 }, 10709 take(count) { 10710 if (isPaused || count <= 0) { 10711 return []; 10712 } 10713 return updates.splice(0, count); 10714 } 10715 }; 10716 } 10717 function postSyncUpdate(payload) { 10718 return (0, import_api_fetch.default)({ 10719 method: "POST", 10720 path: SYNC_API_PATH, 10721 data: payload 10722 }); 10723 } 10724 function postSyncUpdateNonBlocking(payload) { 10725 if (payload.rooms.length === 0) { 10726 return; 10727 } 10728 (0, import_api_fetch.default)({ 10729 method: "POST", 10730 path: SYNC_API_PATH, 10731 data: payload, 10732 keepalive: true 10733 }).catch(() => { 10734 }); 10735 } 10736 function intValueOrDefault(value, defaultValue) { 10737 const intValue = parseInt(String(value), 10); 10738 return isNaN(intValue) ? defaultValue : intValue; 10739 } 10740 function rotateWindow(items2, offset, size2) { 10741 if (items2.length === 0) { 10742 return { window: [], nextOffset: 0 }; 10743 } 10744 const start = (offset % items2.length + items2.length) % items2.length; 10745 const wrapped = [...items2.slice(start), ...items2.slice(0, start)]; 10746 return { 10747 window: wrapped.slice(0, Math.max(0, size2)), 10748 nextOffset: (start + Math.max(0, size2)) % items2.length 10749 }; 10750 } 10751 10752 // packages/sync/build-module/providers/http-polling/polling-manager.mjs 10753 var POLLING_MANAGER_ORIGIN = "polling-manager"; 10754 function isForbiddenError(error) { 10755 return error?.data?.status === 403; 10756 } 10757 function isRequestBodyTooLargeError(error) { 10758 return error?.data?.status === 413 && error?.code === "rest_sync_body_too_large"; 10759 } 10760 function isProtocolMismatchError(error) { 10761 return error?.code === "rest_sync_protocol_mismatch"; 10762 } 10763 function handleForbiddenError(error, requestedRooms) { 10764 const requestedRoomNames = new Set( 10765 requestedRooms.map((room) => room.room) 10766 ); 10767 const forbiddenRooms = Array.isArray(error.data.rooms) ? error.data.rooms.filter((room) => requestedRoomNames.has(room)) : []; 10768 if (forbiddenRooms.length > 0) { 10769 for (const room of forbiddenRooms) { 10770 const state = roomStates.get(room); 10771 if (state) { 10772 state.log( 10773 "Permission denied, unregistering room", 10774 { error }, 10775 "error", 10776 true 10777 // force 10778 ); 10779 unregisterRoom(room, { sendDisconnectSignal: false }); 10780 } 10781 } 10782 for (const room of requestedRooms) { 10783 if (forbiddenRooms.includes(room.room)) { 10784 continue; 10785 } 10786 if (!roomStates.has(room.room)) { 10787 continue; 10788 } 10789 const remainingState = roomStates.get(room.room); 10790 if (room.updates.length > 0) { 10791 remainingState.updateQueue.restore(room.updates); 10792 } 10793 } 10794 } else { 10795 const rooms = [...roomStates.keys()]; 10796 for (const room of rooms) { 10797 const state = roomStates.get(room); 10798 if (state) { 10799 state.log( 10800 "Permission denied, unregistering room", 10801 { error }, 10802 "error", 10803 true 10804 // force 10805 ); 10806 unregisterRoom(room, { sendDisconnectSignal: false }); 10807 } 10808 } 10809 } 10810 } 10811 var roomStates = /* @__PURE__ */ new Map(); 10812 function createDeprecatedCompactionUpdate(updates) { 10813 const mergeable = updates.filter( 10814 (u) => [SyncUpdateType.COMPACTION, SyncUpdateType.UPDATE].includes( 10815 u.type 10816 ) 10817 ).map((u) => base64ToUint8Array(u.data)); 10818 return createSyncUpdate( 10819 mergeUpdatesV2(mergeable), 10820 SyncUpdateType.COMPACTION 10821 ); 10822 } 10823 function createSyncStep1Update(doc2) { 10824 const encoder = createEncoder(); 10825 writeSyncStep1(encoder, doc2); 10826 return createSyncUpdate( 10827 toUint8Array(encoder), 10828 SyncUpdateType.SYNC_STEP_1 10829 ); 10830 } 10831 function createSyncStep2Update(doc2, step1) { 10832 const decoder = createDecoder(step1); 10833 const encoder = createEncoder(); 10834 readSyncMessage( 10835 decoder, 10836 encoder, 10837 doc2, 10838 POLLING_MANAGER_ORIGIN 10839 ); 10840 return createSyncUpdate( 10841 toUint8Array(encoder), 10842 SyncUpdateType.SYNC_STEP_2 10843 ); 10844 } 10845 function processAwarenessUpdate(state, awareness) { 10846 const currentStates = awareness.getStates(); 10847 const added = /* @__PURE__ */ new Set(); 10848 const updated = /* @__PURE__ */ new Set(); 10849 const removed = new Set( 10850 Array.from(currentStates.keys()).filter( 10851 (clientId) => !state[clientId] 10852 ) 10853 ); 10854 Object.entries(state).forEach(([clientIdString, awarenessState]) => { 10855 const clientId = Number(clientIdString); 10856 if (clientId === awareness.clientID) { 10857 return; 10858 } 10859 if (null === awarenessState) { 10860 currentStates.delete(clientId); 10861 removed.add(clientId); 10862 return; 10863 } 10864 if (!currentStates.has(clientId)) { 10865 currentStates.set(clientId, awarenessState); 10866 added.add(clientId); 10867 return; 10868 } 10869 const currentState = currentStates.get(clientId); 10870 if (JSON.stringify(currentState) !== JSON.stringify(awarenessState)) { 10871 currentStates.set(clientId, awarenessState); 10872 updated.add(clientId); 10873 } 10874 }); 10875 if (added.size + updated.size > 0) { 10876 awareness.emit("change", [ 10877 { 10878 added: Array.from(added), 10879 updated: Array.from(updated), 10880 // Left blank on purpose, as the removal of clients is handled in the if condition below. 10881 removed: [] 10882 } 10883 ]); 10884 } 10885 if (removed.size > 0) { 10886 removeAwarenessStates( 10887 awareness, 10888 Array.from(removed), 10889 POLLING_MANAGER_ORIGIN 10890 ); 10891 } 10892 } 10893 function processDocUpdate(update, doc2) { 10894 const data = base64ToUint8Array(update.data); 10895 switch (update.type) { 10896 case SyncUpdateType.SYNC_STEP_1: { 10897 return createSyncStep2Update(doc2, data); 10898 } 10899 case SyncUpdateType.SYNC_STEP_2: { 10900 const decoder = createDecoder(data); 10901 const encoder = createEncoder(); 10902 readSyncMessage( 10903 decoder, 10904 encoder, 10905 doc2, 10906 POLLING_MANAGER_ORIGIN 10907 ); 10908 return; 10909 } 10910 case SyncUpdateType.COMPACTION: 10911 case SyncUpdateType.UPDATE: { 10912 applyUpdateV2(doc2, data, POLLING_MANAGER_ORIGIN); 10913 } 10914 } 10915 } 10916 function checkConnectionLimit(awareness, roomState) { 10917 if (!roomState.isPrimaryRoom || hasCheckedConnectionLimit) { 10918 return false; 10919 } 10920 hasCheckedConnectionLimit = true; 10921 const maxClientsPerRoom = (0, import_hooks2.applyFilters)( 10922 "sync.pollingProvider.maxClientsPerRoom", 10923 DEFAULT_CLIENT_LIMIT_PER_ROOM, 10924 roomState.room 10925 ); 10926 const clientCount = Object.keys(awareness).length; 10927 const validatedLimit = intValueOrDefault( 10928 maxClientsPerRoom, 10929 DEFAULT_CLIENT_LIMIT_PER_ROOM 10930 ); 10931 if (clientCount > validatedLimit) { 10932 roomState.log("Connection limit exceeded", { 10933 clientCount, 10934 maxClientsPerRoom: validatedLimit, 10935 room: roomState.room 10936 }); 10937 return true; 10938 } 10939 return false; 10940 } 10941 var areListenersRegistered = false; 10942 var consecutiveFailures = 0; 10943 var hasCheckedConnectionLimit = false; 10944 var isManualRetry = false; 10945 var hasCollaborators = false; 10946 var isActiveBrowser = "visible" === document.visibilityState; 10947 var isPolling = false; 10948 var isUnloadPending = false; 10949 var pollInterval = POLLING_INTERVAL_IN_MS; 10950 var pollingTimeoutId = null; 10951 var syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 10952 var roomOverflowOffset = 0; 10953 function handleBeforeUnload() { 10954 isUnloadPending = true; 10955 } 10956 function handlePageHide() { 10957 const rooms = Array.from(roomStates.entries()).map( 10958 ([room, state]) => ({ 10959 after: 0, 10960 awareness: null, 10961 client_id: state.clientId, 10962 room, 10963 updates: [] 10964 }) 10965 ); 10966 for (let i = 0; i < rooms.length; i += MAX_ROOMS_PER_REQUEST) { 10967 postSyncUpdateNonBlocking({ 10968 rooms: rooms.slice(i, i + MAX_ROOMS_PER_REQUEST) 10969 }); 10970 } 10971 } 10972 function handleVisibilityChange() { 10973 const wasActive = isActiveBrowser; 10974 isActiveBrowser = document.visibilityState === "visible"; 10975 if (isActiveBrowser && !wasActive) { 10976 if (pollingTimeoutId) { 10977 clearTimeout(pollingTimeoutId); 10978 pollingTimeoutId = null; 10979 poll(); 10980 } 10981 } 10982 } 10983 function selectRoomsForRequest() { 10984 const allRooms = Array.from(roomStates.values()); 10985 if (allRooms.length <= MAX_ROOMS_PER_REQUEST) { 10986 return allRooms; 10987 } 10988 const primaryRoom = allRooms.find((state) => state.isPrimaryRoom); 10989 const overflowRooms = allRooms.filter((state) => state !== primaryRoom); 10990 const overflowSlotsPerRequest = MAX_ROOMS_PER_REQUEST - (primaryRoom ? 1 : 0); 10991 const { window: overflowSlice, nextOffset } = rotateWindow( 10992 overflowRooms, 10993 roomOverflowOffset, 10994 overflowSlotsPerRequest 10995 ); 10996 roomOverflowOffset = nextOffset; 10997 if (primaryRoom) { 10998 return [primaryRoom, ...overflowSlice]; 10999 } 11000 return overflowSlice; 11001 } 11002 var textEncoder = new TextEncoder(); 11003 function getJsonByteLength(value) { 11004 return textEncoder.encode(JSON.stringify(value)).byteLength; 11005 } 11006 function createPayloadRoom(state, updates = []) { 11007 return { 11008 after: state.endCursor ?? 0, 11009 awareness: state.localAwarenessState, 11010 client_id: state.clientId, 11011 room: state.room, 11012 updates 11013 }; 11014 } 11015 function getUpdatePayloadSizeDelta(existingUpdateCount, update) { 11016 const commaSize = existingUpdateCount === 0 ? 0 : 1; 11017 return commaSize + getJsonByteLength(update); 11018 } 11019 function buildPayloadForRequest(selectedRoomStates) { 11020 const payload = { rooms: [] }; 11021 const roomsInRequest = []; 11022 for (const state of selectedRoomStates) { 11023 const room = createPayloadRoom(state); 11024 const candidate = { rooms: [...payload.rooms, room] }; 11025 if (payload.rooms.length > 0 && getJsonByteLength(candidate) > syncRequestBodySizeLimit) { 11026 break; 11027 } 11028 payload.rooms.push(room); 11029 roomsInRequest.push(state); 11030 } 11031 const pendingUpdates = roomsInRequest.map( 11032 (state) => state.updateQueue.peek() 11033 ); 11034 const sentUpdateCounts = roomsInRequest.map(() => 0); 11035 let payloadSize = getJsonByteLength(payload); 11036 let addedUpdate = true; 11037 while (addedUpdate) { 11038 addedUpdate = false; 11039 for (let i = 0; i < roomsInRequest.length; i++) { 11040 const update = pendingUpdates[i][sentUpdateCounts[i]]; 11041 if (!update) { 11042 continue; 11043 } 11044 const sizeDelta = getUpdatePayloadSizeDelta( 11045 sentUpdateCounts[i], 11046 update 11047 ); 11048 if (payloadSize + sizeDelta > syncRequestBodySizeLimit) { 11049 continue; 11050 } 11051 sentUpdateCounts[i]++; 11052 payloadSize += sizeDelta; 11053 addedUpdate = true; 11054 } 11055 } 11056 for (let i = 0; i < roomsInRequest.length; i++) { 11057 payload.rooms[i].updates = roomsInRequest[i].updateQueue.take( 11058 sentUpdateCounts[i] 11059 ); 11060 } 11061 return { payload, roomsInRequest }; 11062 } 11063 function restoreExactUpdates(payload) { 11064 for (const room of payload.rooms) { 11065 if (!roomStates.has(room.room) || room.updates.length === 0) { 11066 continue; 11067 } 11068 roomStates.get(room.room).updateQueue.restoreExact(room.updates); 11069 } 11070 } 11071 function poll() { 11072 isPolling = true; 11073 pollingTimeoutId = null; 11074 async function start() { 11075 if (0 === roomStates.size) { 11076 isPolling = false; 11077 return; 11078 } 11079 isUnloadPending = false; 11080 const { payload, roomsInRequest } = buildPayloadForRequest( 11081 selectRoomsForRequest() 11082 ); 11083 roomsInRequest.forEach((state) => { 11084 state.onStatusChange({ status: "connecting" }); 11085 }); 11086 try { 11087 const { rooms } = await postSyncUpdate(payload); 11088 consecutiveFailures = 0; 11089 isManualRetry = false; 11090 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 11091 roomsInRequest.forEach((state) => { 11092 if (roomStates.get(state.room) !== state) { 11093 return; 11094 } 11095 state.onStatusChange({ status: "connected" }); 11096 }); 11097 hasCollaborators = false; 11098 rooms.forEach((room) => { 11099 if (!roomStates.has(room.room)) { 11100 return; 11101 } 11102 const roomState = roomStates.get(room.room); 11103 roomState.endCursor = room.end_cursor; 11104 if (checkConnectionLimit(room.awareness, roomState)) { 11105 roomState.onStatusChange({ 11106 status: "disconnected", 11107 error: new ConnectionError( 11108 ConnectionErrorCode.CONNECTION_LIMIT_EXCEEDED, 11109 "Connection limit exceeded" 11110 ) 11111 }); 11112 unregisterRoom(room.room); 11113 return; 11114 } 11115 roomState.processAwarenessUpdate(room.awareness); 11116 if (roomState.isPrimaryRoom && Object.keys(room.awareness).length > 1) { 11117 hasCollaborators = true; 11118 roomStates.forEach((state) => { 11119 state.updateQueue.resume(); 11120 }); 11121 } 11122 const responseUpdates = []; 11123 for (const update of room.updates) { 11124 try { 11125 const response = roomState.processDocUpdate(update); 11126 if (response) { 11127 responseUpdates.push(response); 11128 } 11129 } catch (error) { 11130 roomState.log( 11131 "Failed to apply sync update", 11132 { error, update }, 11133 "error", 11134 true 11135 // force 11136 ); 11137 } 11138 } 11139 roomState.updateQueue.addBulk(responseUpdates); 11140 if (room.should_compact) { 11141 roomState.log("Server requested compaction update"); 11142 roomState.updateQueue.clear(); 11143 roomState.updateQueue.add( 11144 roomState.createCompactionUpdate() 11145 ); 11146 } else if (room.compaction_request) { 11147 roomState.log("Server requested (old) compaction update"); 11148 roomState.updateQueue.add( 11149 createDeprecatedCompactionUpdate( 11150 room.compaction_request 11151 ) 11152 ); 11153 } 11154 }); 11155 if (isActiveBrowser && hasCollaborators) { 11156 pollInterval = POLLING_INTERVAL_WITH_COLLABORATORS_IN_MS; 11157 } else if (isActiveBrowser) { 11158 pollInterval = POLLING_INTERVAL_IN_MS; 11159 } else { 11160 pollInterval = POLLING_INTERVAL_BACKGROUND_TAB_IN_MS; 11161 } 11162 } catch (error) { 11163 if (isForbiddenError(error)) { 11164 handleForbiddenError(error, payload.rooms); 11165 if (roomStates.size === 0) { 11166 isPolling = false; 11167 return; 11168 } 11169 } else if (isRequestBodyTooLargeError(error)) { 11170 syncRequestBodySizeLimit = Math.max( 11171 MIN_SYNC_REQUEST_BODY_SIZE_LIMIT_IN_BYTES, 11172 Math.floor(syncRequestBodySizeLimit / 2) 11173 ); 11174 pollInterval = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS[0] : ERROR_RETRY_DELAYS_SOLO_MS[0]; 11175 restoreExactUpdates(payload); 11176 for (const room of payload.rooms) { 11177 if (!roomStates.has(room.room)) { 11178 continue; 11179 } 11180 roomStates.get(room.room).log( 11181 "Sync request body too large, retrying with smaller batches", 11182 { 11183 error, 11184 nextPoll: pollInterval, 11185 syncRequestBodySizeLimit 11186 }, 11187 "error", 11188 true 11189 // force 11190 ); 11191 } 11192 } else if (isProtocolMismatchError(error)) { 11193 const affectedRooms = [...roomStates.entries()]; 11194 for (const [, state] of affectedRooms) { 11195 state.onStatusChange({ 11196 status: "disconnected", 11197 error: new ConnectionError( 11198 ConnectionErrorCode.PROTOCOL_MISMATCH, 11199 "Protocol mismatch between client and server" 11200 ) 11201 }); 11202 } 11203 for (const [room] of affectedRooms) { 11204 unregisterRoom(room, { sendDisconnectSignal: false }); 11205 } 11206 isPolling = false; 11207 return; 11208 } else { 11209 consecutiveFailures++; 11210 const retrySchedule = hasCollaborators ? ERROR_RETRY_DELAYS_WITH_COLLABORATORS_MS : ERROR_RETRY_DELAYS_SOLO_MS; 11211 if (consecutiveFailures <= retrySchedule.length) { 11212 pollInterval = retrySchedule[consecutiveFailures - 1]; 11213 } else { 11214 pollInterval = DISCONNECT_DIALOG_RETRY_MS; 11215 } 11216 if (isManualRetry) { 11217 pollInterval = MANUAL_RETRY_INTERVAL_MS; 11218 isManualRetry = false; 11219 } 11220 for (const room of payload.rooms) { 11221 if (!roomStates.has(room.room)) { 11222 continue; 11223 } 11224 const state = roomStates.get(room.room); 11225 if (room.updates.length > 0 && state.endCursor > 0) { 11226 state.updateQueue.clear(); 11227 state.updateQueue.add(state.createCompactionUpdate()); 11228 } else if (room.updates.length > 0) { 11229 state.updateQueue.restore(room.updates); 11230 } 11231 state.log( 11232 "Error posting sync update, will retry with backoff", 11233 { error, nextPoll: pollInterval }, 11234 "error", 11235 true 11236 // force 11237 ); 11238 } 11239 if (!isUnloadPending) { 11240 const backgroundRetriesFailed = consecutiveFailures > retrySchedule.length; 11241 roomsInRequest.forEach((state) => { 11242 if (roomStates.get(state.room) !== state) { 11243 return; 11244 } 11245 state.onStatusChange({ 11246 status: "disconnected", 11247 canManuallyRetry: true, 11248 consecutiveFailures, 11249 backgroundRetriesFailed, 11250 willAutoRetryInMs: pollInterval 11251 }); 11252 }); 11253 } 11254 } 11255 } 11256 pollingTimeoutId = setTimeout(poll, pollInterval); 11257 } 11258 void start(); 11259 } 11260 function registerRoom({ 11261 room, 11262 doc: doc2, 11263 awareness, 11264 log, 11265 onStatusChange 11266 }) { 11267 if (roomStates.has(room)) { 11268 return; 11269 } 11270 const updateQueue = createUpdateQueue([createSyncStep1Update(doc2)]); 11271 const isPrimaryRoom = 0 === roomStates.size; 11272 function onAwarenessUpdate() { 11273 roomState.localAwarenessState = awareness.getLocalState() ?? {}; 11274 } 11275 function onDocUpdate(update, origin2) { 11276 if (POLLING_MANAGER_ORIGIN === origin2) { 11277 return; 11278 } 11279 if (update.byteLength > MAX_UPDATE_SIZE_IN_BYTES) { 11280 const state = roomStates.get(room); 11281 if (!state) { 11282 return; 11283 } 11284 state.log("Document size limit exceeded", { 11285 maxUpdateSizeInBytes: MAX_UPDATE_SIZE_IN_BYTES, 11286 updateSizeInBytes: update.byteLength 11287 }); 11288 state.onStatusChange({ 11289 status: "disconnected", 11290 error: new ConnectionError( 11291 ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED, 11292 "Document size limit exceeded" 11293 ) 11294 }); 11295 unregisterRoom(room); 11296 return; 11297 } 11298 updateQueue.add(createSyncUpdate(update, SyncUpdateType.UPDATE)); 11299 } 11300 function unregister() { 11301 doc2.off("updateV2", onDocUpdate); 11302 awareness.off("change", onAwarenessUpdate); 11303 updateQueue.clear(); 11304 } 11305 const roomState = { 11306 clientId: doc2.clientID, 11307 createCompactionUpdate: () => createSyncUpdate( 11308 encodeStateAsUpdateV2(doc2), 11309 SyncUpdateType.COMPACTION 11310 ), 11311 endCursor: 0, 11312 isPrimaryRoom, 11313 localAwarenessState: awareness.getLocalState() ?? {}, 11314 log, 11315 onStatusChange, 11316 processAwarenessUpdate: (state) => processAwarenessUpdate(state, awareness), 11317 processDocUpdate: (update) => processDocUpdate(update, doc2), 11318 room, 11319 unregister, 11320 updateQueue 11321 }; 11322 doc2.on("updateV2", onDocUpdate); 11323 awareness.on("change", onAwarenessUpdate); 11324 roomStates.set(room, roomState); 11325 if (!areListenersRegistered) { 11326 window.addEventListener("beforeunload", handleBeforeUnload); 11327 window.addEventListener("pagehide", handlePageHide); 11328 document.addEventListener("visibilitychange", handleVisibilityChange); 11329 areListenersRegistered = true; 11330 } 11331 if (!isPolling) { 11332 poll(); 11333 } 11334 } 11335 function unregisterRoom(room, { sendDisconnectSignal = true } = {}) { 11336 const state = roomStates.get(room); 11337 if (state) { 11338 if (sendDisconnectSignal) { 11339 const rooms = [ 11340 { 11341 after: 0, 11342 awareness: null, 11343 client_id: state.clientId, 11344 room, 11345 updates: [] 11346 } 11347 ]; 11348 postSyncUpdateNonBlocking({ rooms }); 11349 } 11350 state.unregister(); 11351 roomStates.delete(room); 11352 } 11353 if (0 === roomStates.size && areListenersRegistered) { 11354 window.removeEventListener("beforeunload", handleBeforeUnload); 11355 window.removeEventListener("pagehide", handlePageHide); 11356 document.removeEventListener( 11357 "visibilitychange", 11358 handleVisibilityChange 11359 ); 11360 areListenersRegistered = false; 11361 hasCheckedConnectionLimit = false; 11362 consecutiveFailures = 0; 11363 roomOverflowOffset = 0; 11364 syncRequestBodySizeLimit = MAX_SYNC_REQUEST_BODY_SIZE_IN_BYTES; 11365 } 11366 } 11367 function retryNow() { 11368 isManualRetry = true; 11369 if (pollingTimeoutId) { 11370 clearTimeout(pollingTimeoutId); 11371 pollingTimeoutId = null; 11372 poll(); 11373 } 11374 } 11375 function retrySyncConnection() { 11376 pollingManager.retryNow(); 11377 } 11378 var pollingManager = { 11379 registerRoom, 11380 retryNow, 11381 unregisterRoom 11382 }; 11383 11384 // packages/sync/build-module/providers/http-polling/http-polling-provider.mjs 11385 var HttpPollingProvider = class extends ObservableV2 { 11386 constructor(options) { 11387 super(); 11388 this.options = options; 11389 this.log("Initializing", { room: options.room }); 11390 this.awareness = options.awareness ?? new Awareness(options.ydoc); 11391 this.connect(); 11392 } 11393 awareness; 11394 status = "disconnected"; 11395 /** 11396 * Connect to the endpoint and initialize sync. 11397 */ 11398 connect() { 11399 this.log("Connecting"); 11400 pollingManager.registerRoom({ 11401 room: this.options.room, 11402 doc: this.options.ydoc, 11403 awareness: this.awareness, 11404 log: this.log, 11405 onStatusChange: this.emitStatus 11406 }); 11407 } 11408 /** 11409 * Destroy the provider and cleanup resources. 11410 */ 11411 destroy() { 11412 this.disconnect(); 11413 super.destroy(); 11414 } 11415 /** 11416 * Disconnect the provider and allow reconnection later. 11417 */ 11418 disconnect() { 11419 this.log("Disconnecting"); 11420 pollingManager.unregisterRoom(this.options.room); 11421 this.emitStatus({ status: "disconnected" }); 11422 } 11423 /** 11424 * Emit connection status, passing the full object through so that 11425 * additional fields (e.g. `willAutoRetryInMs`) are preserved for consumers. 11426 * 11427 * @param connectionStatus The connection status object 11428 */ 11429 emitStatus = (connectionStatus) => { 11430 const { status } = connectionStatus; 11431 const error = status === "disconnected" ? connectionStatus.error : void 0; 11432 if (this.status === status && !error) { 11433 return; 11434 } 11435 if (status === "connecting" && this.status !== "disconnected") { 11436 return; 11437 } 11438 this.log("Status change", { status, error }); 11439 this.status = status; 11440 this.emit("status", [connectionStatus]); 11441 }; 11442 /** 11443 * Log debug messages if debugging is enabled. 11444 * 11445 * @param message The debug message 11446 * @param debug Additional debug information 11447 * @param errorLevel The console method to use for logging 11448 * @param force Whether to force logging regardless of debug setting 11449 */ 11450 log = (message, debug = {}, errorLevel = "log", force = false) => { 11451 if (!this.options.debug && !force) { 11452 return; 11453 } 11454 const logFn = console[errorLevel] || console.log; 11455 logFn(`[$this.constructor.name}]: $message}`, { 11456 room: this.options.room, 11457 ...debug 11458 }); 11459 }; 11460 }; 11461 function createHttpPollingProvider() { 11462 return async ({ 11463 awareness, 11464 objectType, 11465 objectId, 11466 ydoc 11467 }) => { 11468 const room = objectId ? `$objectType}:$objectId}` : objectType; 11469 const provider = new HttpPollingProvider({ 11470 awareness, 11471 // debug: true, 11472 room, 11473 ydoc 11474 }); 11475 return { 11476 destroy: () => provider.destroy(), 11477 // Adapter: ObservableV2.on is compatible with ProviderOn 11478 // The callback receives data as the first parameter 11479 on: (event, callback) => { 11480 provider.on(event, callback); 11481 } 11482 }; 11483 }; 11484 } 11485 11486 // packages/sync/build-module/providers/index.mjs 11487 var providerCreators = null; 11488 function getDefaultProviderCreators() { 11489 return window.__experimentalEnableRealTimeCollaboration ? [createHttpPollingProvider()] : []; 11490 } 11491 function isProviderCreator(creator) { 11492 return "function" === typeof creator; 11493 } 11494 function getProviderCreators() { 11495 if (providerCreators) { 11496 return providerCreators; 11497 } 11498 if (!window.__experimentalEnableRealTimeCollaboration) { 11499 return []; 11500 } 11501 const filteredProviderCreators = (0, import_hooks3.applyFilters)( 11502 "sync.providers", 11503 getDefaultProviderCreators() 11504 ); 11505 if (!Array.isArray(filteredProviderCreators)) { 11506 providerCreators = []; 11507 return providerCreators; 11508 } 11509 providerCreators = filteredProviderCreators.filter(isProviderCreator); 11510 return providerCreators; 11511 } 11512 11513 // packages/sync/build-module/undo-manager.mjs 11514 function createEntityUndoManager(ydoc, ymap, handlers) { 11515 let isApplyingHistory = false; 11516 const yUndoManager = new UndoManager(ymap, { 11517 // Throttle undo/redo captures after 500ms of inactivity. 11518 // 500 was selected from subjective local UX testing, shorter timeouts 11519 // may cause mid-word undo stack items. 11520 captureTimeout: 500, 11521 // Ensure that we only scope the undo/redo to the current editor. 11522 trackedOrigins: /* @__PURE__ */ new Set([LOCAL_EDITOR_ORIGIN]) 11523 }); 11524 yUndoManager.on("stack-item-added", (event) => { 11525 handlers.addUndoMeta(ydoc, event.stackItem.meta); 11526 if ("undo" === event.type && !isApplyingHistory) { 11527 handlers.onUndoLevelOpened?.(); 11528 } 11529 }); 11530 yUndoManager.on("stack-item-popped", (event) => { 11531 handlers.restoreUndoMeta(ydoc, event.stackItem.meta); 11532 }); 11533 const applyHistory = (type) => { 11534 isApplyingHistory = true; 11535 try { 11536 const stackItem = "undo" === type ? yUndoManager.undo() : yUndoManager.redo(); 11537 return null !== stackItem; 11538 } finally { 11539 isApplyingHistory = false; 11540 } 11541 }; 11542 return { 11543 clearRedo: () => yUndoManager.clear(false, true), 11544 hasRedo: () => yUndoManager.canRedo(), 11545 hasUndo: () => yUndoManager.canUndo(), 11546 redo: () => applyHistory("redo"), 11547 stopCapturing: () => yUndoManager.stopCapturing(), 11548 undo: () => applyHistory("undo") 11549 }; 11550 } 11551 11552 // packages/sync/build-module/crdt-snapshot.mjs 11553 function encodeDocSnapshot(ydoc) { 11554 return toBase64(encodeSnapshotV2(snapshot(ydoc))); 11555 } 11556 function docContainsSnapshot(ydoc, encodedSnapshot) { 11557 let snapshot2; 11558 try { 11559 snapshot2 = decodeSnapshotV2(fromBase64(encodedSnapshot)); 11560 } catch { 11561 return false; 11562 } 11563 const localSnapshot = snapshot(ydoc); 11564 for (const [client, clock] of snapshot2.sv) { 11565 if ((localSnapshot.sv.get(client) ?? 0) < clock) { 11566 return false; 11567 } 11568 } 11569 const copiedDeleteSet = snapshot(ydoc).ds; 11570 const mergedDeleteSet = mergeDeleteSets([ 11571 copiedDeleteSet, 11572 snapshot2.ds 11573 ]); 11574 return equalDeleteSets(localSnapshot.ds, mergedDeleteSet); 11575 } 11576 11577 // packages/sync/build-module/utils.mjs 11578 function createYjsDoc(documentMeta = {}) { 11579 const metaMap = new Map( 11580 Object.entries(documentMeta) 11581 ); 11582 return new Doc({ meta: metaMap }); 11583 } 11584 function initializeYjsDoc(ydoc) { 11585 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11586 stateMap.set(CRDT_STATE_MAP_VERSION_KEY, CRDT_DOC_VERSION); 11587 } 11588 function markEntityAsSaved(ydoc) { 11589 const recordMeta = ydoc.getMap(CRDT_STATE_MAP_KEY); 11590 recordMeta.set(CRDT_STATE_MAP_SAVED_AT_KEY, Date.now()); 11591 recordMeta.set(CRDT_STATE_MAP_SAVED_BY_KEY, ydoc.clientID); 11592 } 11593 function pseudoRandomID() { 11594 return Math.floor(Math.random() * 1e9); 11595 } 11596 function serializeCrdtDoc(crdtDoc) { 11597 const tempDoc = createYjsDoc(); 11598 applyUpdateV2(tempDoc, encodeStateAsUpdateV2(crdtDoc)); 11599 const compactedUpdate = encodeStateAsUpdateV2(tempDoc); 11600 tempDoc.destroy(); 11601 return JSON.stringify({ 11602 document: toBase64(compactedUpdate), 11603 updateId: pseudoRandomID() 11604 // helps with debugging 11605 }); 11606 } 11607 function deserializeCrdtDoc(serializedCrdtDoc) { 11608 try { 11609 const { document: document2 } = JSON.parse(serializedCrdtDoc); 11610 const docMeta = { 11611 [CRDT_DOC_META_PERSISTENCE_KEY]: true 11612 }; 11613 const ydoc = createYjsDoc(docMeta); 11614 const yupdate = fromBase64(document2); 11615 applyUpdateV2(ydoc, yupdate); 11616 ydoc.clientID = pseudoRandomID(); 11617 return ydoc; 11618 } catch { 11619 return null; 11620 } 11621 } 11622 11623 // packages/sync/build-module/manager.mjs 11624 function getEntityId(objectType, objectId) { 11625 return `$objectType}_$objectId}`; 11626 } 11627 function createSyncManager(debug = false) { 11628 const debugWrap = debug ? logPerformanceTiming : passThru; 11629 const collectionStates = /* @__PURE__ */ new Map(); 11630 const entityStates = /* @__PURE__ */ new Map(); 11631 const undoManager2 = { 11632 undo(objectType, objectId) { 11633 flushPendingCRDTDocUpdates(); 11634 const entityState = entityStates.get( 11635 getEntityId(objectType, objectId) 11636 ); 11637 return entityState?.undoManager.undo() ?? false; 11638 }, 11639 redo(objectType, objectId) { 11640 flushPendingCRDTDocUpdates(); 11641 const entityState = entityStates.get( 11642 getEntityId(objectType, objectId) 11643 ); 11644 return entityState?.undoManager.redo() ?? false; 11645 }, 11646 hasUndo() { 11647 return [...entityStates.values()].some( 11648 (entityState) => entityState.undoManager.hasUndo() 11649 ); 11650 }, 11651 hasRedo() { 11652 return [...entityStates.values()].some( 11653 (entityState) => entityState.undoManager.hasRedo() 11654 ); 11655 }, 11656 stopCapturing() { 11657 flushPendingCRDTDocUpdates(); 11658 entityStates.forEach( 11659 (entityState) => entityState.undoManager.stopCapturing() 11660 ); 11661 }, 11662 clearRedo() { 11663 flushPendingCRDTDocUpdates(); 11664 entityStates.forEach( 11665 (entityState) => entityState.undoManager.clearRedo() 11666 ); 11667 } 11668 }; 11669 function log(component, message, entityId, context = {}) { 11670 if (!debug) { 11671 return; 11672 } 11673 console.log(`[SyncManager][$component}]: $message}`, { 11674 ...context, 11675 entityId 11676 }); 11677 } 11678 async function loadEntity(syncConfig, objectType, objectId, record, handlers) { 11679 const providerCreators2 = getProviderCreators(); 11680 const entityId = getEntityId(objectType, objectId); 11681 if (0 === providerCreators2.length) { 11682 log("loadEntity", "no providers, skipping", entityId); 11683 return; 11684 } 11685 if (entityStates.has(entityId)) { 11686 log("loadEntity", "already loaded", entityId); 11687 return; 11688 } 11689 if (false === syncConfig.shouldSync?.(objectType, objectId)) { 11690 log("loadEntity", "shouldSync false, skipping", entityId); 11691 return; 11692 } 11693 log("loadEntity", "loading", entityId); 11694 handlers = { 11695 addUndoMeta: debugWrap(handlers.addUndoMeta), 11696 editRecord: debugWrap(handlers.editRecord), 11697 getEditedRecord: debugWrap(handlers.getEditedRecord), 11698 onStatusChange: debugWrap(handlers.onStatusChange), 11699 persistCRDTDoc: debugWrap(handlers.persistCRDTDoc), 11700 refetchRecord: debugWrap(handlers.refetchRecord), 11701 restoreUndoMeta: debugWrap(handlers.restoreUndoMeta), 11702 onUndoLevelOpened: handlers.onUndoLevelOpened ? debugWrap(handlers.onUndoLevelOpened) : void 0 11703 }; 11704 const ydoc = createYjsDoc({ objectType }); 11705 const recordMap = ydoc.getMap(CRDT_RECORD_MAP_KEY); 11706 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11707 const now = Date.now(); 11708 let hasObserversAttached = false; 11709 let isEntityUnloaded = false; 11710 const unload = () => { 11711 log("loadEntity", "unloading", entityId); 11712 isEntityUnloaded = true; 11713 providerResults?.forEach((result) => result.destroy()); 11714 handlers.onStatusChange(null); 11715 if (hasObserversAttached) { 11716 recordMap.unobserveDeep(onRecordUpdate); 11717 stateMap.unobserve(onStateMapUpdate); 11718 } 11719 ydoc.destroy(); 11720 entityStates.delete(entityId); 11721 }; 11722 const awareness = syncConfig.createAwareness?.(ydoc, objectId); 11723 const onRecordUpdate = (_events, transaction) => { 11724 if (transaction.local && !(transaction.origin instanceof UndoManager)) { 11725 return; 11726 } 11727 void internal.updateEntityRecord(objectType, objectId); 11728 }; 11729 const onStateMapUpdate = (event, transaction) => { 11730 if (transaction.local) { 11731 return; 11732 } 11733 event.keysChanged.forEach((key) => { 11734 switch (key) { 11735 case CRDT_STATE_MAP_SAVED_AT_KEY: 11736 const savedAt = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11737 if ("number" === typeof savedAt && savedAt > now) { 11738 log("loadEntity", "refetching record", entityId); 11739 void handlers.refetchRecord().catch(() => { 11740 }); 11741 } 11742 break; 11743 } 11744 }); 11745 }; 11746 const { addUndoMeta, onUndoLevelOpened, restoreUndoMeta } = handlers; 11747 const entityUndoManager = createEntityUndoManager(ydoc, recordMap, { 11748 addUndoMeta, 11749 restoreUndoMeta, 11750 onUndoLevelOpened: () => { 11751 entityStates.forEach((other) => { 11752 if (other.undoManager !== entityUndoManager) { 11753 other.undoManager.stopCapturing(); 11754 other.undoManager.clearRedo(); 11755 } 11756 }); 11757 onUndoLevelOpened?.(); 11758 } 11759 }); 11760 let providerResults; 11761 const entityState = { 11762 awareness, 11763 handlers, 11764 objectId, 11765 objectType, 11766 syncConfig, 11767 undoManager: entityUndoManager, 11768 unload, 11769 ydoc 11770 }; 11771 entityStates.set(entityId, entityState); 11772 log("loadEntity", "connecting", entityId); 11773 providerResults = await Promise.all( 11774 providerCreators2.map(async (create9) => { 11775 const provider = await create9({ 11776 objectType, 11777 objectId, 11778 ydoc, 11779 awareness, 11780 Y: yjs_exports 11781 }); 11782 provider.on("status", handlers.onStatusChange); 11783 return provider; 11784 }) 11785 ); 11786 if (isEntityUnloaded) { 11787 log("loadEntity", "unloaded during connect, aborting", entityId); 11788 providerResults.forEach((result) => result.destroy()); 11789 return; 11790 } 11791 initializeYjsDoc(ydoc); 11792 internal.applyPersistedCrdtDoc(objectType, objectId, record); 11793 recordMap.observeDeep(onRecordUpdate); 11794 stateMap.observe(onStateMapUpdate); 11795 hasObserversAttached = true; 11796 } 11797 async function loadCollection(syncConfig, objectType, handlers) { 11798 const providerCreators2 = getProviderCreators(); 11799 const entityId = getEntityId(objectType, null); 11800 if (0 === providerCreators2.length) { 11801 log("loadCollection", "no providers, skipping", entityId); 11802 return; 11803 } 11804 if (collectionStates.has(objectType)) { 11805 log("loadCollection", "already loaded", entityId); 11806 return; 11807 } 11808 if (false === syncConfig.shouldSync?.(objectType, null)) { 11809 log("loadCollection", "shouldSync false, skipping", entityId); 11810 return; 11811 } 11812 log("loadCollection", "loading", entityId); 11813 const ydoc = createYjsDoc({ collection: true, objectType }); 11814 const stateMap = ydoc.getMap(CRDT_STATE_MAP_KEY); 11815 const now = Date.now(); 11816 let hasObserversAttached = false; 11817 let isCollectionUnloaded = false; 11818 const unload = () => { 11819 log("loadCollection", "unloading", entityId); 11820 isCollectionUnloaded = true; 11821 providerResults?.forEach((result) => result.destroy()); 11822 handlers.onStatusChange(null); 11823 if (hasObserversAttached) { 11824 stateMap.unobserve(onStateMapUpdate); 11825 } 11826 ydoc.destroy(); 11827 collectionStates.delete(objectType); 11828 }; 11829 const onStateMapUpdate = (event, transaction) => { 11830 if (transaction.local) { 11831 return; 11832 } 11833 event.keysChanged.forEach((key) => { 11834 switch (key) { 11835 case CRDT_STATE_MAP_SAVED_AT_KEY: 11836 const newValue = stateMap.get(CRDT_STATE_MAP_SAVED_AT_KEY); 11837 if ("number" === typeof newValue && newValue > now) { 11838 void handlers.refetchRecords().catch(() => { 11839 }); 11840 } 11841 break; 11842 } 11843 }); 11844 }; 11845 const awareness = syncConfig.createAwareness?.(ydoc); 11846 let providerResults; 11847 const collectionState = { 11848 awareness, 11849 handlers, 11850 syncConfig, 11851 unload, 11852 ydoc 11853 }; 11854 collectionStates.set(objectType, collectionState); 11855 log("loadCollection", "connecting", entityId); 11856 providerResults = await Promise.all( 11857 providerCreators2.map(async (create9) => { 11858 const provider = await create9({ 11859 awareness, 11860 objectType, 11861 objectId: null, 11862 ydoc, 11863 Y: yjs_exports 11864 }); 11865 provider.on("status", handlers.onStatusChange); 11866 return provider; 11867 }) 11868 ); 11869 if (isCollectionUnloaded) { 11870 log( 11871 "loadCollection", 11872 "unloaded during connect, aborting", 11873 entityId 11874 ); 11875 providerResults.forEach((result) => result.destroy()); 11876 return; 11877 } 11878 stateMap.observe(onStateMapUpdate); 11879 hasObserversAttached = true; 11880 initializeYjsDoc(ydoc); 11881 } 11882 function isLoaded(objectType, objectId) { 11883 return entityStates.has(getEntityId(objectType, objectId)); 11884 } 11885 function unloadEntity(objectType, objectId) { 11886 const entityId = getEntityId(objectType, objectId); 11887 log("unloadEntity", "unloading", entityId); 11888 entityStates.get(entityId)?.unload(); 11889 updateCRDTDoc(objectType, null, {}, origin, { 11890 isSave: true 11891 }); 11892 } 11893 function unloadAll() { 11894 log("unloadAll", "unloading all entities", "all"); 11895 for (const [, entityState] of [...entityStates]) { 11896 entityState.unload(); 11897 } 11898 entityStates.clear(); 11899 for (const [, collectionState] of [...collectionStates]) { 11900 collectionState.unload(); 11901 } 11902 collectionStates.clear(); 11903 } 11904 function getAwareness(objectType, objectId) { 11905 const entityId = getEntityId(objectType, objectId); 11906 const entityState = entityStates.get(entityId); 11907 if (!entityState || !entityState.awareness) { 11908 return void 0; 11909 } 11910 return entityState.awareness; 11911 } 11912 function _applyPersistedCrdtDoc(objectType, objectId, record) { 11913 const entityId = getEntityId(objectType, objectId); 11914 const entityState = entityStates.get(entityId); 11915 if (!entityState) { 11916 log("applyPersistedCrdtDoc", "no entity state", entityId); 11917 return; 11918 } 11919 const { 11920 handlers, 11921 syncConfig: { 11922 applyChangesToCRDTDoc, 11923 getChangesFromCRDTDoc, 11924 getPersistedCRDTDoc 11925 }, 11926 ydoc: targetDoc 11927 } = entityState; 11928 const serialized = getPersistedCRDTDoc?.(record); 11929 const tempDoc = serialized ? deserializeCrdtDoc(serialized) : null; 11930 if (!tempDoc) { 11931 log("applyPersistedCrdtDoc", "no persisted doc", entityId); 11932 targetDoc.transact(() => { 11933 applyChangesToCRDTDoc(targetDoc, record); 11934 handlers.persistCRDTDoc(); 11935 }, LOCAL_SYNC_MANAGER_ORIGIN); 11936 return; 11937 } 11938 const update = encodeStateAsUpdateV2(tempDoc); 11939 applyUpdateV2(targetDoc, update); 11940 const invalidations = getChangesFromCRDTDoc(tempDoc, record); 11941 const invalidatedKeys = Object.keys(invalidations); 11942 tempDoc.destroy(); 11943 if (0 === invalidatedKeys.length) { 11944 log("applyPersistedCrdtDoc", "valid persisted doc", entityId); 11945 return; 11946 } 11947 log("applyPersistedCrdtDoc", "invalidated keys", entityId, { 11948 invalidatedKeys 11949 }); 11950 const changes = invalidatedKeys.reduce( 11951 (acc, key) => Object.assign(acc, { 11952 [key]: record[key] 11953 }), 11954 {} 11955 ); 11956 targetDoc.transact(() => { 11957 applyChangesToCRDTDoc(targetDoc, changes); 11958 handlers.persistCRDTDoc(); 11959 }, LOCAL_SYNC_MANAGER_ORIGIN); 11960 } 11961 function updateCRDTDoc(objectType, objectId, changes, origin2, options = {}) { 11962 const { isSave = false, isNewUndoLevel: isNewUndoLevel2 = false } = options; 11963 const entityId = getEntityId(objectType, objectId); 11964 const entityState = entityStates.get(entityId); 11965 const collectionState = collectionStates.get(objectType); 11966 if (entityState) { 11967 const { syncConfig, ydoc } = entityState; 11968 if (isNewUndoLevel2) { 11969 undoManager2.stopCapturing(); 11970 } 11971 ydoc.transact(() => { 11972 log("updateCRDTDoc", "applying changes", entityId, { 11973 changedKeys: Object.keys(changes) 11974 }); 11975 syncConfig.applyChangesToCRDTDoc(ydoc, changes); 11976 if (isSave) { 11977 markEntityAsSaved(ydoc); 11978 } 11979 }, origin2); 11980 } 11981 if (collectionState && isSave) { 11982 collectionState.ydoc.transact(() => { 11983 markEntityAsSaved(collectionState.ydoc); 11984 }, origin2); 11985 } 11986 } 11987 const pendingCRDTDocUpdates = []; 11988 let isFlushingCRDTDocUpdates = false; 11989 function flushPendingCRDTDocUpdates() { 11990 if (isFlushingCRDTDocUpdates) { 11991 return; 11992 } 11993 isFlushingCRDTDocUpdates = true; 11994 try { 11995 while (pendingCRDTDocUpdates.length > 0) { 11996 const args2 = pendingCRDTDocUpdates.shift(); 11997 if (args2) { 11998 updateCRDTDoc(...args2); 11999 } 12000 } 12001 } finally { 12002 isFlushingCRDTDocUpdates = false; 12003 } 12004 } 12005 function deferUpdateCRDTDoc(...args2) { 12006 pendingCRDTDocUpdates.push(args2); 12007 setTimeout(flushPendingCRDTDocUpdates, 0); 12008 } 12009 function updateOrDefer(objectType, objectId, changes, origin2, options = {}) { 12010 const hasRemotePeers = (getAwareness(objectType, objectId)?.getStates().size ?? 0) > 1; 12011 if (hasRemotePeers) { 12012 flushPendingCRDTDocUpdates(); 12013 updateCRDTDoc(objectType, objectId, changes, origin2, options); 12014 return; 12015 } 12016 deferUpdateCRDTDoc(objectType, objectId, changes, origin2, options); 12017 } 12018 function getEntitySnapshot2(objectType, objectId) { 12019 const entityId = getEntityId(objectType, objectId); 12020 const entityState = entityStates.get(entityId); 12021 if (!entityState) { 12022 log("getEntitySnapshot", "no entity state", entityId); 12023 return void 0; 12024 } 12025 flushPendingCRDTDocUpdates(); 12026 return encodeDocSnapshot(entityState.ydoc); 12027 } 12028 function entityContainsSnapshot2(objectType, objectId, encodedSnapshot) { 12029 const entityId = getEntityId(objectType, objectId); 12030 const entityState = entityStates.get(entityId); 12031 if (!entityState) { 12032 return false; 12033 } 12034 flushPendingCRDTDocUpdates(); 12035 return docContainsSnapshot(entityState.ydoc, encodedSnapshot); 12036 } 12037 async function _updateEntityRecord(objectType, objectId) { 12038 const entityId = getEntityId(objectType, objectId); 12039 const entityState = entityStates.get(entityId); 12040 if (!entityState) { 12041 log("updateEntityRecord", "no entity state", entityId); 12042 return; 12043 } 12044 const { handlers, syncConfig, ydoc } = entityState; 12045 const changes = syncConfig.getChangesFromCRDTDoc( 12046 ydoc, 12047 await handlers.getEditedRecord() 12048 ); 12049 const changedKeys = Object.keys(changes); 12050 if (0 === changedKeys.length) { 12051 return; 12052 } 12053 log("updateEntityRecord", "changes", entityId, { 12054 changedKeys 12055 }); 12056 handlers.editRecord(changes); 12057 } 12058 async function createPersistedCRDTDoc(objectType, objectId) { 12059 const entityId = getEntityId(objectType, objectId); 12060 const entityState = entityStates.get(entityId); 12061 if (!entityState?.ydoc) { 12062 return null; 12063 } 12064 flushPendingCRDTDocUpdates(); 12065 return serializeCrdtDoc(entityState.ydoc); 12066 } 12067 const internal = { 12068 applyPersistedCrdtDoc: debugWrap(_applyPersistedCrdtDoc), 12069 updateEntityRecord: debugWrap(_updateEntityRecord) 12070 }; 12071 return { 12072 createPersistedCRDTDoc: debugWrap(createPersistedCRDTDoc), 12073 entityContainsSnapshot: debugWrap(entityContainsSnapshot2), 12074 getAwareness, 12075 getEntitySnapshot: debugWrap(getEntitySnapshot2), 12076 isLoaded, 12077 load: debugWrap(loadEntity), 12078 loadCollection: debugWrap(loadCollection), 12079 undoManager: undoManager2, 12080 unload: debugWrap(unloadEntity), 12081 unloadAll: debugWrap(unloadAll), 12082 update: debugWrap(updateOrDefer) 12083 }; 12084 } 12085 12086 // node_modules/.store/diff@8.0.4-eS1ZVYhaFC9fHfWvV2-kIQ/node_modules/diff/libesm/diff/base.js 12087 var Diff = class { 12088 diff(oldStr, newStr, options = {}) { 12089 let callback; 12090 if (typeof options === "function") { 12091 callback = options; 12092 options = {}; 12093 } else if ("callback" in options) { 12094 callback = options.callback; 12095 } 12096 const oldString = this.castInput(oldStr, options); 12097 const newString = this.castInput(newStr, options); 12098 const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); 12099 const newTokens = this.removeEmpty(this.tokenize(newString, options)); 12100 return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); 12101 } 12102 diffWithOptionsObj(oldTokens, newTokens, options, callback) { 12103 var _a; 12104 const done = (value) => { 12105 value = this.postProcess(value, options); 12106 if (callback) { 12107 setTimeout(function() { 12108 callback(value); 12109 }, 0); 12110 return void 0; 12111 } else { 12112 return value; 12113 } 12114 }; 12115 const newLen = newTokens.length, oldLen = oldTokens.length; 12116 let editLength = 1; 12117 let maxEditLength = newLen + oldLen; 12118 if (options.maxEditLength != null) { 12119 maxEditLength = Math.min(maxEditLength, options.maxEditLength); 12120 } 12121 const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; 12122 const abortAfterTimestamp = Date.now() + maxExecutionTime; 12123 const bestPath = [{ oldPos: -1, lastComponent: void 0 }]; 12124 let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); 12125 if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 12126 return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); 12127 } 12128 let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; 12129 const execEditLength = () => { 12130 for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { 12131 let basePath; 12132 const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; 12133 if (removePath) { 12134 bestPath[diagonalPath - 1] = void 0; 12135 } 12136 let canAdd = false; 12137 if (addPath) { 12138 const addPathNewPos = addPath.oldPos - diagonalPath; 12139 canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; 12140 } 12141 const canRemove = removePath && removePath.oldPos + 1 < oldLen; 12142 if (!canAdd && !canRemove) { 12143 bestPath[diagonalPath] = void 0; 12144 continue; 12145 } 12146 if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) { 12147 basePath = this.addToPath(addPath, true, false, 0, options); 12148 } else { 12149 basePath = this.addToPath(removePath, false, true, 1, options); 12150 } 12151 newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); 12152 if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { 12153 return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; 12154 } else { 12155 bestPath[diagonalPath] = basePath; 12156 if (basePath.oldPos + 1 >= oldLen) { 12157 maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); 12158 } 12159 if (newPos + 1 >= newLen) { 12160 minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); 12161 } 12162 } 12163 } 12164 editLength++; 12165 }; 12166 if (callback) { 12167 (function exec() { 12168 setTimeout(function() { 12169 if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { 12170 return callback(void 0); 12171 } 12172 if (!execEditLength()) { 12173 exec(); 12174 } 12175 }, 0); 12176 })(); 12177 } else { 12178 while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { 12179 const ret = execEditLength(); 12180 if (ret) { 12181 return ret; 12182 } 12183 } 12184 } 12185 } 12186 addToPath(path, added, removed, oldPosInc, options) { 12187 const last2 = path.lastComponent; 12188 if (last2 && !options.oneChangePerToken && last2.added === added && last2.removed === removed) { 12189 return { 12190 oldPos: path.oldPos + oldPosInc, 12191 lastComponent: { count: last2.count + 1, added, removed, previousComponent: last2.previousComponent } 12192 }; 12193 } else { 12194 return { 12195 oldPos: path.oldPos + oldPosInc, 12196 lastComponent: { count: 1, added, removed, previousComponent: last2 } 12197 }; 12198 } 12199 } 12200 extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { 12201 const newLen = newTokens.length, oldLen = oldTokens.length; 12202 let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; 12203 while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { 12204 newPos++; 12205 oldPos++; 12206 commonCount++; 12207 if (options.oneChangePerToken) { 12208 basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; 12209 } 12210 } 12211 if (commonCount && !options.oneChangePerToken) { 12212 basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; 12213 } 12214 basePath.oldPos = oldPos; 12215 return newPos; 12216 } 12217 equals(left, right, options) { 12218 if (options.comparator) { 12219 return options.comparator(left, right); 12220 } else { 12221 return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase(); 12222 } 12223 } 12224 removeEmpty(array) { 12225 const ret = []; 12226 for (let i = 0; i < array.length; i++) { 12227 if (array[i]) { 12228 ret.push(array[i]); 12229 } 12230 } 12231 return ret; 12232 } 12233 // eslint-disable-next-line @typescript-eslint/no-unused-vars 12234 castInput(value, options) { 12235 return value; 12236 } 12237 // eslint-disable-next-line @typescript-eslint/no-unused-vars 12238 tokenize(value, options) { 12239 return Array.from(value); 12240 } 12241 join(chars) { 12242 return chars.join(""); 12243 } 12244 postProcess(changeObjects, options) { 12245 return changeObjects; 12246 } 12247 get useLongestToken() { 12248 return false; 12249 } 12250 buildValues(lastComponent, newTokens, oldTokens) { 12251 const components = []; 12252 let nextComponent; 12253 while (lastComponent) { 12254 components.push(lastComponent); 12255 nextComponent = lastComponent.previousComponent; 12256 delete lastComponent.previousComponent; 12257 lastComponent = nextComponent; 12258 } 12259 components.reverse(); 12260 const componentLen = components.length; 12261 let componentPos = 0, newPos = 0, oldPos = 0; 12262 for (; componentPos < componentLen; componentPos++) { 12263 const component = components[componentPos]; 12264 if (!component.removed) { 12265 if (!component.added && this.useLongestToken) { 12266 let value = newTokens.slice(newPos, newPos + component.count); 12267 value = value.map(function(value2, i) { 12268 const oldValue = oldTokens[oldPos + i]; 12269 return oldValue.length > value2.length ? oldValue : value2; 12270 }); 12271 component.value = this.join(value); 12272 } else { 12273 component.value = this.join(newTokens.slice(newPos, newPos + component.count)); 12274 } 12275 newPos += component.count; 12276 if (!component.added) { 12277 oldPos += component.count; 12278 } 12279 } else { 12280 component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); 12281 oldPos += component.count; 12282 } 12283 } 12284 return components; 12285 } 12286 }; 12287 12288 // node_modules/.store/diff@8.0.4-eS1ZVYhaFC9fHfWvV2-kIQ/node_modules/diff/libesm/diff/character.js 12289 var CharacterDiff = class extends Diff { 12290 }; 12291 var characterDiff = new CharacterDiff(); 12292 function diffChars(oldStr, newStr, options) { 12293 return characterDiff.diff(oldStr, newStr, options); 12294 } 12295 12296 // node_modules/.store/diff@8.0.4-eS1ZVYhaFC9fHfWvV2-kIQ/node_modules/diff/libesm/diff/line.js 12297 var LineDiff = class extends Diff { 12298 constructor() { 12299 super(...arguments); 12300 this.tokenize = tokenize; 12301 } 12302 equals(left, right, options) { 12303 if (options.ignoreWhitespace) { 12304 if (!options.newlineIsToken || !left.includes("\n")) { 12305 left = left.trim(); 12306 } 12307 if (!options.newlineIsToken || !right.includes("\n")) { 12308 right = right.trim(); 12309 } 12310 } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { 12311 if (left.endsWith("\n")) { 12312 left = left.slice(0, -1); 12313 } 12314 if (right.endsWith("\n")) { 12315 right = right.slice(0, -1); 12316 } 12317 } 12318 return super.equals(left, right, options); 12319 } 12320 }; 12321 var lineDiff = new LineDiff(); 12322 function diffLines(oldStr, newStr, options) { 12323 return lineDiff.diff(oldStr, newStr, options); 12324 } 12325 function tokenize(value, options) { 12326 if (options.stripTrailingCr) { 12327 value = value.replace(/\r\n/g, "\n"); 12328 } 12329 const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); 12330 if (!linesAndNewlines[linesAndNewlines.length - 1]) { 12331 linesAndNewlines.pop(); 12332 } 12333 for (let i = 0; i < linesAndNewlines.length; i++) { 12334 const line = linesAndNewlines[i]; 12335 if (i % 2 && !options.newlineIsToken) { 12336 retLines[retLines.length - 1] += line; 12337 } else { 12338 retLines.push(line); 12339 } 12340 } 12341 return retLines; 12342 } 12343 12344 // packages/sync/build-module/quill-delta/Delta.mjs 12345 var import_es64 = __toESM(require_es6(), 1); 12346 12347 // packages/sync/build-module/quill-delta/AttributeMap.mjs 12348 var import_es63 = __toESM(require_es6(), 1); 12349 function cloneDeep(value) { 12350 return JSON.parse(JSON.stringify(value)); 12351 } 12352 var AttributeMap; 12353 ((AttributeMap2) => { 12354 function compose3(a = {}, b = {}, keepNull = false) { 12355 if (typeof a !== "object") { 12356 a = {}; 12357 } 12358 if (typeof b !== "object") { 12359 b = {}; 12360 } 12361 let attributes = cloneDeep(b); 12362 if (!keepNull) { 12363 attributes = Object.keys(attributes).reduce( 12364 (copy2, key) => { 12365 if (attributes[key] !== null || attributes[key] !== void 0) { 12366 copy2[key] = attributes[key]; 12367 } 12368 return copy2; 12369 }, 12370 {} 12371 ); 12372 } 12373 for (const key in a) { 12374 if (a[key] !== void 0 && b[key] === void 0) { 12375 attributes[key] = a[key]; 12376 } 12377 } 12378 return Object.keys(attributes).length > 0 ? attributes : void 0; 12379 } 12380 AttributeMap2.compose = compose3; 12381 function diff(a = {}, b = {}) { 12382 if (typeof a !== "object") { 12383 a = {}; 12384 } 12385 if (typeof b !== "object") { 12386 b = {}; 12387 } 12388 const attributes = Object.keys(a).concat(Object.keys(b)).reduce((attrs, key) => { 12389 if (!(0, import_es63.default)(a[key], b[key])) { 12390 attrs[key] = b[key] === void 0 ? null : b[key]; 12391 } 12392 return attrs; 12393 }, {}); 12394 return Object.keys(attributes).length > 0 ? attributes : void 0; 12395 } 12396 AttributeMap2.diff = diff; 12397 function invert(attr = {}, base = {}) { 12398 attr = attr || {}; 12399 const baseInverted = Object.keys(base).reduce( 12400 (memo, key) => { 12401 if (base[key] !== attr[key] && attr[key] !== void 0) { 12402 memo[key] = base[key]; 12403 } 12404 return memo; 12405 }, 12406 {} 12407 ); 12408 return Object.keys(attr).reduce((memo, key) => { 12409 if (attr[key] !== base[key] && base[key] === void 0) { 12410 memo[key] = null; 12411 } 12412 return memo; 12413 }, baseInverted); 12414 } 12415 AttributeMap2.invert = invert; 12416 function transform(a, b, priority = false) { 12417 if (typeof a !== "object") { 12418 return b; 12419 } 12420 if (typeof b !== "object") { 12421 return void 0; 12422 } 12423 if (!priority) { 12424 return b; 12425 } 12426 const attributes = Object.keys(b).reduce( 12427 (attrs, key) => { 12428 if (a[key] === void 0) { 12429 attrs[key] = b[key]; 12430 } 12431 return attrs; 12432 }, 12433 {} 12434 ); 12435 return Object.keys(attributes).length > 0 ? attributes : void 0; 12436 } 12437 AttributeMap2.transform = transform; 12438 })(AttributeMap || (AttributeMap = {})); 12439 var AttributeMap_default = AttributeMap; 12440 12441 // packages/sync/build-module/quill-delta/Op.mjs 12442 var Op; 12443 ((Op2) => { 12444 function length2(op) { 12445 if (typeof op.delete === "number") { 12446 return op.delete; 12447 } else if (typeof op.retain === "number") { 12448 return op.retain; 12449 } else if (typeof op.retain === "object" && op.retain !== null) { 12450 return 1; 12451 } 12452 return typeof op.insert === "string" ? op.insert.length : 1; 12453 } 12454 Op2.length = length2; 12455 })(Op || (Op = {})); 12456 var Op_default = Op; 12457 12458 // packages/sync/build-module/quill-delta/OpIterator.mjs 12459 var Iterator2 = class { 12460 ops; 12461 index; 12462 offset; 12463 constructor(ops) { 12464 this.ops = ops; 12465 this.index = 0; 12466 this.offset = 0; 12467 } 12468 hasNext() { 12469 return this.peekLength() < Infinity; 12470 } 12471 next(length2) { 12472 if (!length2) { 12473 length2 = Infinity; 12474 } 12475 const nextOp = this.ops[this.index]; 12476 if (nextOp) { 12477 const offset = this.offset; 12478 const opLength = Op_default.length(nextOp); 12479 if (length2 >= opLength - offset) { 12480 length2 = opLength - offset; 12481 this.index += 1; 12482 this.offset = 0; 12483 } else { 12484 this.offset += length2; 12485 } 12486 if (typeof nextOp.delete === "number") { 12487 return { delete: length2 }; 12488 } 12489 const retOp = {}; 12490 if (nextOp.attributes) { 12491 retOp.attributes = nextOp.attributes; 12492 } 12493 if (typeof nextOp.retain === "number") { 12494 retOp.retain = length2; 12495 } else if (typeof nextOp.retain === "object" && nextOp.retain !== null) { 12496 retOp.retain = nextOp.retain; 12497 } else if (typeof nextOp.insert === "string") { 12498 retOp.insert = nextOp.insert.substr(offset, length2); 12499 } else { 12500 retOp.insert = nextOp.insert; 12501 } 12502 return retOp; 12503 } 12504 return { retain: Infinity }; 12505 } 12506 peek() { 12507 return this.ops[this.index]; 12508 } 12509 peekLength() { 12510 if (this.ops[this.index]) { 12511 return Op_default.length(this.ops[this.index]) - this.offset; 12512 } 12513 return Infinity; 12514 } 12515 peekType() { 12516 const op = this.ops[this.index]; 12517 if (op) { 12518 if (typeof op.delete === "number") { 12519 return "delete"; 12520 } else if (typeof op.retain === "number" || typeof op.retain === "object" && op.retain !== null) { 12521 return "retain"; 12522 } 12523 return "insert"; 12524 } 12525 return "retain"; 12526 } 12527 rest() { 12528 if (!this.hasNext()) { 12529 return []; 12530 } else if (this.offset === 0) { 12531 return this.ops.slice(this.index); 12532 } 12533 const offset = this.offset; 12534 const index = this.index; 12535 const next = this.next(); 12536 const rest = this.ops.slice(this.index); 12537 this.offset = offset; 12538 this.index = index; 12539 return [next].concat(rest); 12540 } 12541 }; 12542 12543 // packages/sync/build-module/quill-delta/Delta.mjs 12544 function cloneDeep2(value) { 12545 return JSON.parse(JSON.stringify(value)); 12546 } 12547 var NULL_CHARACTER = String.fromCharCode(0); 12548 var STRING_TOO_LARGE_THRESHOLD = 1e4; 12549 function normalizeChangeCounts(changes) { 12550 return changes.map((change) => ({ 12551 ...change, 12552 count: change.value.length 12553 })); 12554 } 12555 var getEmbedTypeAndData = (a, b) => { 12556 if (typeof a !== "object" || a === null) { 12557 throw new Error(`cannot retain a $typeof a}`); 12558 } 12559 if (typeof b !== "object" || b === null) { 12560 throw new Error(`cannot retain a $typeof b}`); 12561 } 12562 const embedType = Object.keys(a)[0]; 12563 if (!embedType || embedType !== Object.keys(b)[0]) { 12564 throw new Error( 12565 `embed types not matched: $embedType} != $Object.keys(b)[0]}` 12566 ); 12567 } 12568 return [embedType, a[embedType], b[embedType]]; 12569 }; 12570 var Delta = class _Delta { 12571 static Op = Op_default; 12572 static OpIterator = Iterator2; 12573 static AttributeMap = AttributeMap_default; 12574 static handlers = {}; 12575 static registerEmbed(embedType, handler) { 12576 this.handlers[embedType] = handler; 12577 } 12578 static unregisterEmbed(embedType) { 12579 delete this.handlers[embedType]; 12580 } 12581 static getHandler(embedType) { 12582 const handler = this.handlers[embedType]; 12583 if (!handler) { 12584 throw new Error(`no handlers for embed type "$embedType}"`); 12585 } 12586 return handler; 12587 } 12588 ops; 12589 constructor(ops) { 12590 if (Array.isArray(ops)) { 12591 this.ops = ops; 12592 } else if (ops !== null && ops !== void 0 && Array.isArray(ops.ops)) { 12593 this.ops = ops.ops; 12594 } else { 12595 this.ops = []; 12596 } 12597 } 12598 insert(arg, attributes) { 12599 const newOp = {}; 12600 if (typeof arg === "string" && arg.length === 0) { 12601 return this; 12602 } 12603 newOp.insert = arg; 12604 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12605 newOp.attributes = attributes; 12606 } 12607 return this.push(newOp); 12608 } 12609 delete(length2) { 12610 if (length2 <= 0) { 12611 return this; 12612 } 12613 return this.push({ delete: length2 }); 12614 } 12615 retain(length2, attributes) { 12616 if (typeof length2 === "number" && length2 <= 0) { 12617 return this; 12618 } 12619 const newOp = { retain: length2 }; 12620 if (attributes !== null && attributes !== void 0 && typeof attributes === "object" && Object.keys(attributes).length > 0) { 12621 newOp.attributes = attributes; 12622 } 12623 return this.push(newOp); 12624 } 12625 push(newOp) { 12626 let index = this.ops.length; 12627 let lastOp = this.ops[index - 1]; 12628 newOp = cloneDeep2(newOp); 12629 if (typeof lastOp === "object") { 12630 if (typeof newOp.delete === "number" && typeof lastOp.delete === "number") { 12631 this.ops[index - 1] = { 12632 delete: lastOp.delete + newOp.delete 12633 }; 12634 return this; 12635 } 12636 if (typeof lastOp.delete === "number" && newOp.insert !== null && newOp.insert !== void 0) { 12637 index -= 1; 12638 lastOp = this.ops[index - 1]; 12639 if (typeof lastOp !== "object") { 12640 this.ops.unshift(newOp); 12641 return this; 12642 } 12643 } 12644 if ((0, import_es64.default)(newOp.attributes, lastOp.attributes)) { 12645 if (typeof newOp.insert === "string" && typeof lastOp.insert === "string") { 12646 this.ops[index - 1] = { 12647 insert: lastOp.insert + newOp.insert 12648 }; 12649 if (typeof newOp.attributes === "object") { 12650 this.ops[index - 1].attributes = newOp.attributes; 12651 } 12652 return this; 12653 } else if (typeof newOp.retain === "number" && typeof lastOp.retain === "number") { 12654 this.ops[index - 1] = { 12655 retain: lastOp.retain + newOp.retain 12656 }; 12657 if (typeof newOp.attributes === "object") { 12658 this.ops[index - 1].attributes = newOp.attributes; 12659 } 12660 return this; 12661 } 12662 } 12663 } 12664 if (index === this.ops.length) { 12665 this.ops.push(newOp); 12666 } else { 12667 this.ops.splice(index, 0, newOp); 12668 } 12669 return this; 12670 } 12671 chop() { 12672 const lastOp = this.ops[this.ops.length - 1]; 12673 if (lastOp && typeof lastOp.retain === "number" && !lastOp.attributes) { 12674 this.ops.pop(); 12675 } 12676 return this; 12677 } 12678 filter(predicate) { 12679 return this.ops.filter(predicate); 12680 } 12681 forEach(predicate) { 12682 this.ops.forEach(predicate); 12683 } 12684 map(predicate) { 12685 return this.ops.map(predicate); 12686 } 12687 partition(predicate) { 12688 const passed = []; 12689 const failed = []; 12690 this.forEach((op) => { 12691 const target = predicate(op) ? passed : failed; 12692 target.push(op); 12693 }); 12694 return [passed, failed]; 12695 } 12696 reduce(predicate, initialValue) { 12697 return this.ops.reduce(predicate, initialValue); 12698 } 12699 changeLength() { 12700 return this.reduce((length2, elem) => { 12701 if (elem.insert) { 12702 return length2 + Op_default.length(elem); 12703 } else if (elem.delete) { 12704 return length2 - elem.delete; 12705 } 12706 return length2; 12707 }, 0); 12708 } 12709 length() { 12710 return this.reduce((length2, elem) => { 12711 return length2 + Op_default.length(elem); 12712 }, 0); 12713 } 12714 slice(start = 0, end = Infinity) { 12715 const ops = []; 12716 const iter = new Iterator2(this.ops); 12717 let index = 0; 12718 while (index < end && iter.hasNext()) { 12719 let nextOp; 12720 if (index < start) { 12721 nextOp = iter.next(start - index); 12722 } else { 12723 nextOp = iter.next(end - index); 12724 ops.push(nextOp); 12725 } 12726 index += Op_default.length(nextOp); 12727 } 12728 return new _Delta(ops); 12729 } 12730 compose(other) { 12731 const thisIter = new Iterator2(this.ops); 12732 const otherIter = new Iterator2(other.ops); 12733 const ops = []; 12734 const firstOther = otherIter.peek(); 12735 if (firstOther !== null && firstOther !== void 0 && typeof firstOther.retain === "number" && (firstOther.attributes === null || firstOther.attributes === void 0)) { 12736 let firstLeft = firstOther.retain; 12737 while (thisIter.peekType() === "insert" && thisIter.peekLength() <= firstLeft) { 12738 firstLeft -= thisIter.peekLength(); 12739 ops.push(thisIter.next()); 12740 } 12741 if (firstOther.retain - firstLeft > 0) { 12742 otherIter.next(firstOther.retain - firstLeft); 12743 } 12744 } 12745 const delta = new _Delta(ops); 12746 while (thisIter.hasNext() || otherIter.hasNext()) { 12747 if (otherIter.peekType() === "insert") { 12748 delta.push(otherIter.next()); 12749 } else if (thisIter.peekType() === "delete") { 12750 delta.push(thisIter.next()); 12751 } else { 12752 const length2 = Math.min( 12753 thisIter.peekLength(), 12754 otherIter.peekLength() 12755 ); 12756 const thisOp = thisIter.next(length2); 12757 const otherOp = otherIter.next(length2); 12758 if (otherOp.retain) { 12759 const newOp = {}; 12760 if (typeof thisOp.retain === "number") { 12761 newOp.retain = typeof otherOp.retain === "number" ? length2 : otherOp.retain; 12762 } else if (typeof otherOp.retain === "number") { 12763 if (thisOp.retain === null || thisOp.retain === void 0) { 12764 newOp.insert = thisOp.insert; 12765 } else { 12766 newOp.retain = thisOp.retain; 12767 } 12768 } else { 12769 const action = thisOp.retain === null || thisOp.retain === void 0 ? "insert" : "retain"; 12770 const [embedType, thisData, otherData] = getEmbedTypeAndData( 12771 thisOp[action], 12772 otherOp.retain 12773 ); 12774 const handler = _Delta.getHandler(embedType); 12775 newOp[action] = { 12776 [embedType]: handler.compose( 12777 thisData, 12778 otherData, 12779 action === "retain" 12780 ) 12781 }; 12782 } 12783 const attributes = AttributeMap_default.compose( 12784 thisOp.attributes, 12785 otherOp.attributes, 12786 typeof thisOp.retain === "number" 12787 ); 12788 if (attributes) { 12789 newOp.attributes = attributes; 12790 } 12791 delta.push(newOp); 12792 if (!otherIter.hasNext() && (0, import_es64.default)(delta.ops[delta.ops.length - 1], newOp)) { 12793 const rest = new _Delta(thisIter.rest()); 12794 return delta.concat(rest).chop(); 12795 } 12796 } else if (typeof otherOp.delete === "number" && (typeof thisOp.retain === "number" || typeof thisOp.retain === "object" && thisOp.retain !== null)) { 12797 delta.push(otherOp); 12798 } 12799 } 12800 } 12801 return delta.chop(); 12802 } 12803 concat(other) { 12804 const delta = new _Delta(this.ops.slice()); 12805 if (other.ops.length > 0) { 12806 delta.push(other.ops[0]); 12807 delta.ops = delta.ops.concat(other.ops.slice(1)); 12808 } 12809 return delta; 12810 } 12811 diff(other) { 12812 if (this.ops === other.ops) { 12813 return new _Delta(); 12814 } 12815 const strings = this.deltasToStrings(other); 12816 const diffResult = normalizeChangeCounts( 12817 diffChars(strings[0], strings[1]) 12818 ); 12819 const thisIter = new Iterator2(this.ops); 12820 const otherIter = new Iterator2(other.ops); 12821 const retDelta = this.convertChangesToDelta( 12822 diffResult, 12823 thisIter, 12824 otherIter 12825 ); 12826 return retDelta.chop(); 12827 } 12828 eachLine(predicate, newline = "\n") { 12829 const iter = new Iterator2(this.ops); 12830 let line = new _Delta(); 12831 let i = 0; 12832 while (iter.hasNext()) { 12833 if (iter.peekType() !== "insert") { 12834 return; 12835 } 12836 const thisOp = iter.peek(); 12837 const start = Op_default.length(thisOp) - iter.peekLength(); 12838 const index = typeof thisOp.insert === "string" ? thisOp.insert.indexOf(newline, start) - start : -1; 12839 if (index < 0) { 12840 line.push(iter.next()); 12841 } else if (index > 0) { 12842 line.push(iter.next(index)); 12843 } else { 12844 if (predicate(line, iter.next(1).attributes || {}, i) === false) { 12845 return; 12846 } 12847 i += 1; 12848 line = new _Delta(); 12849 } 12850 } 12851 if (line.length() > 0) { 12852 predicate(line, {}, i); 12853 } 12854 } 12855 invert(base) { 12856 const inverted = new _Delta(); 12857 this.reduce((baseIndex, op) => { 12858 if (op.insert) { 12859 inverted.delete(Op_default.length(op)); 12860 } else if (typeof op.retain === "number" && (op.attributes === null || op.attributes === void 0)) { 12861 inverted.retain(op.retain); 12862 return baseIndex + op.retain; 12863 } else if (op.delete || typeof op.retain === "number") { 12864 const length2 = op.delete || op.retain; 12865 const slice = base.slice(baseIndex, baseIndex + length2); 12866 slice.forEach((baseOp) => { 12867 if (op.delete) { 12868 inverted.push(baseOp); 12869 } else if (op.retain && op.attributes) { 12870 inverted.retain( 12871 Op_default.length(baseOp), 12872 AttributeMap_default.invert( 12873 op.attributes, 12874 baseOp.attributes 12875 ) 12876 ); 12877 } 12878 }); 12879 return baseIndex + length2; 12880 } else if (typeof op.retain === "object" && op.retain !== null) { 12881 const slice = base.slice(baseIndex, baseIndex + 1); 12882 const baseOp = new Iterator2(slice.ops).next(); 12883 const [embedType, opData, baseOpData] = getEmbedTypeAndData( 12884 op.retain, 12885 baseOp.insert 12886 ); 12887 const handler = _Delta.getHandler(embedType); 12888 inverted.retain( 12889 { [embedType]: handler.invert(opData, baseOpData) }, 12890 AttributeMap_default.invert(op.attributes, baseOp.attributes) 12891 ); 12892 return baseIndex + 1; 12893 } 12894 return baseIndex; 12895 }, 0); 12896 return inverted.chop(); 12897 } 12898 transform(arg, priority = false) { 12899 priority = !!priority; 12900 if (typeof arg === "number") { 12901 return this.transformPosition(arg, priority); 12902 } 12903 const other = arg; 12904 const thisIter = new Iterator2(this.ops); 12905 const otherIter = new Iterator2(other.ops); 12906 const delta = new _Delta(); 12907 while (thisIter.hasNext() || otherIter.hasNext()) { 12908 if (thisIter.peekType() === "insert" && (priority || otherIter.peekType() !== "insert")) { 12909 delta.retain(Op_default.length(thisIter.next())); 12910 } else if (otherIter.peekType() === "insert") { 12911 delta.push(otherIter.next()); 12912 } else { 12913 const length2 = Math.min( 12914 thisIter.peekLength(), 12915 otherIter.peekLength() 12916 ); 12917 const thisOp = thisIter.next(length2); 12918 const otherOp = otherIter.next(length2); 12919 if (thisOp.delete) { 12920 continue; 12921 } else if (otherOp.delete) { 12922 delta.push(otherOp); 12923 } else { 12924 const thisData = thisOp.retain; 12925 const otherData = otherOp.retain; 12926 let transformedData = typeof otherData === "object" && otherData !== null ? otherData : length2; 12927 if (typeof thisData === "object" && thisData !== null && typeof otherData === "object" && otherData !== null) { 12928 const embedType = Object.keys(thisData)[0]; 12929 if (embedType === Object.keys(otherData)[0]) { 12930 const handler = _Delta.getHandler(embedType); 12931 if (handler) { 12932 transformedData = { 12933 [embedType]: handler.transform( 12934 thisData[embedType], 12935 otherData[embedType], 12936 priority 12937 ) 12938 }; 12939 } 12940 } 12941 } 12942 delta.retain( 12943 transformedData, 12944 AttributeMap_default.transform( 12945 thisOp.attributes, 12946 otherOp.attributes, 12947 priority 12948 ) 12949 ); 12950 } 12951 } 12952 } 12953 return delta.chop(); 12954 } 12955 transformPosition(index, priority = false) { 12956 priority = !!priority; 12957 const thisIter = new Iterator2(this.ops); 12958 let offset = 0; 12959 while (thisIter.hasNext() && offset <= index) { 12960 const length2 = thisIter.peekLength(); 12961 const nextType = thisIter.peekType(); 12962 thisIter.next(); 12963 if (nextType === "delete") { 12964 index -= Math.min(length2, index - offset); 12965 continue; 12966 } else if (nextType === "insert" && (offset < index || !priority)) { 12967 index += length2; 12968 } 12969 offset += length2; 12970 } 12971 return index; 12972 } 12973 /** 12974 * Given a Delta and a cursor position, do a diff and attempt to adjust 12975 * the diff to place insertions or deletions at the cursor position. 12976 * 12977 * @todo There are at least a few known cases where this produces a corrupted 12978 * diff. When this is fixed, it should not be necessary to verify that the 12979 * transformed diff applies cleanly. 12980 * 12981 * @see import("@wordpress/core-data/src/utils/crdt-blocks").mergeRichTextUpdate() 12982 * 12983 * @param other - The other Delta to diff against. 12984 * @param cursorAfterChange - The cursor position index after the change. 12985 * @return A Delta that attempts to place insertions or deletions at the cursor position. 12986 */ 12987 diffWithCursor(other, cursorAfterChange) { 12988 if (this.ops === other.ops) { 12989 return new _Delta(); 12990 } 12991 const strings = this.deltasToStrings(other); 12992 const maxStringLength = Math.max( 12993 ...strings.map((str) => str.length) 12994 ); 12995 if (maxStringLength > STRING_TOO_LARGE_THRESHOLD) { 12996 const diffResult = normalizeChangeCounts( 12997 diffLines(strings[0], strings[1]) 12998 ); 12999 const thisIterLarge = new Iterator2(this.ops); 13000 const otherIterLarge = new Iterator2(other.ops); 13001 return this.convertChangesToDelta( 13002 diffResult, 13003 thisIterLarge, 13004 otherIterLarge 13005 ).chop(); 13006 } else if (cursorAfterChange === null) { 13007 return this.diff(other); 13008 } 13009 let diffs = normalizeChangeCounts( 13010 diffChars(strings[0], strings[1]) 13011 ); 13012 let lastDiffPosition = 0; 13013 const adjustedDiffs = []; 13014 for (let i = 0; i < diffs.length; i++) { 13015 const diff = diffs[i]; 13016 const segmentStart = lastDiffPosition; 13017 const segmentEnd = lastDiffPosition + (diff.count ?? 0); 13018 const isCursorInSegment = cursorAfterChange > segmentStart && cursorAfterChange <= segmentEnd; 13019 const isUnchangedSegment = !diff.added && !diff.removed; 13020 const isRemovalSegment = diff.removed && !diff.added; 13021 const nextDiff = diffs[i + 1]; 13022 const isNextDiffAnInsert = nextDiff && nextDiff.added && !nextDiff.removed; 13023 if (isUnchangedSegment && isCursorInSegment && isNextDiffAnInsert) { 13024 const movedSegments = this.tryMoveInsertionToCursor( 13025 diff, 13026 nextDiff, 13027 cursorAfterChange, 13028 segmentStart 13029 ); 13030 if (movedSegments) { 13031 adjustedDiffs.push(...movedSegments); 13032 i++; 13033 lastDiffPosition = segmentEnd; 13034 continue; 13035 } 13036 } 13037 if (isRemovalSegment) { 13038 const movedSegments = this.tryMoveDeletionToCursor( 13039 diff, 13040 adjustedDiffs, 13041 cursorAfterChange, 13042 lastDiffPosition 13043 ); 13044 if (movedSegments) { 13045 adjustedDiffs.pop(); 13046 adjustedDiffs.push(...movedSegments); 13047 lastDiffPosition += diff.count ?? 0; 13048 continue; 13049 } 13050 } 13051 adjustedDiffs.push(diff); 13052 if (!diff.added) { 13053 lastDiffPosition += diff.count ?? 0; 13054 } 13055 } 13056 diffs = adjustedDiffs; 13057 const thisIter = new Iterator2(this.ops); 13058 const otherIter = new Iterator2(other.ops); 13059 const retDelta = this.convertChangesToDelta( 13060 diffs, 13061 thisIter, 13062 otherIter 13063 ); 13064 return retDelta.chop(); 13065 } 13066 /** 13067 * Try to move an insertion operation from after an unchanged segment to the cursor position within it. 13068 * This is a "look-ahead" strategy. 13069 * 13070 * @param diff - The current unchanged diff segment. 13071 * @param nextDiff - The next diff segment (expected to be an insertion). 13072 * @param cursorAfterChange - The cursor position after the change. 13073 * @param segmentStart - The start position of the current segment. 13074 * @return An array of adjusted diff segments if the insertion was successfully moved, null otherwise. 13075 */ 13076 tryMoveInsertionToCursor(diff, nextDiff, cursorAfterChange, segmentStart) { 13077 const nextDiffInsert = nextDiff.value; 13078 const insertLength = nextDiffInsert.length; 13079 const insertOffset = cursorAfterChange - segmentStart - insertLength; 13080 const textAtCursor = diff.value.substring( 13081 insertOffset, 13082 insertOffset + nextDiffInsert.length 13083 ); 13084 const isInsertMoveable = textAtCursor === nextDiffInsert; 13085 if (!isInsertMoveable) { 13086 return null; 13087 } 13088 const beforeCursor = diff.value.substring(0, insertOffset); 13089 const afterCursor = diff.value.substring(insertOffset); 13090 const result = []; 13091 if (beforeCursor.length > 0) { 13092 result.push({ 13093 value: beforeCursor, 13094 count: beforeCursor.length, 13095 added: false, 13096 removed: false 13097 }); 13098 } 13099 result.push(nextDiff); 13100 if (afterCursor.length > 0) { 13101 result.push({ 13102 value: afterCursor, 13103 count: afterCursor.length, 13104 added: false, 13105 removed: false 13106 }); 13107 } 13108 return result; 13109 } 13110 /** 13111 * Try to move a deletion operation to the cursor position by looking back at the previous unchanged segment. 13112 * This is a "look-back" strategy. 13113 * 13114 * @param diff - The current deletion diff segment. 13115 * @param adjustedDiffs - The array of previously processed diff segments. 13116 * @param cursorAfterChange - The cursor position after the change. 13117 * @param lastDiffPosition - The position in the document up to (but not including) the current diff. 13118 * @return An array of adjusted diff segments if the deletion was successfully moved, null otherwise. 13119 */ 13120 tryMoveDeletionToCursor(diff, adjustedDiffs, cursorAfterChange, lastDiffPosition) { 13121 const prevDiff = adjustedDiffs[adjustedDiffs.length - 1]; 13122 if (!prevDiff || prevDiff.added || prevDiff.removed) { 13123 return null; 13124 } 13125 const prevSegmentStart = lastDiffPosition - (prevDiff.count ?? 0); 13126 const prevSegmentEnd = lastDiffPosition; 13127 if (cursorAfterChange < prevSegmentStart || cursorAfterChange >= prevSegmentEnd) { 13128 return null; 13129 } 13130 const deletedChars = diff.value; 13131 const deleteOffset = cursorAfterChange - prevSegmentStart; 13132 const textAtCursor = prevDiff.value.substring( 13133 deleteOffset, 13134 deleteOffset + deletedChars.length 13135 ); 13136 const canBePlacedHere = textAtCursor === deletedChars; 13137 if (!canBePlacedHere) { 13138 return null; 13139 } 13140 const beforeCursor = prevDiff.value.substring(0, deleteOffset); 13141 const atAndAfterCursor = prevDiff.value.substring(deleteOffset); 13142 const deletionLength = diff.count ?? 0; 13143 const afterDeletion = atAndAfterCursor.substring(deletionLength); 13144 const result = []; 13145 if (beforeCursor.length > 0) { 13146 result.push({ 13147 value: beforeCursor, 13148 count: beforeCursor.length, 13149 added: false, 13150 removed: false 13151 }); 13152 } 13153 result.push(diff); 13154 if (afterDeletion.length > 0) { 13155 result.push({ 13156 value: afterDeletion, 13157 count: afterDeletion.length, 13158 added: false, 13159 removed: false 13160 }); 13161 } 13162 return result; 13163 } 13164 /** 13165 * Convert two Deltas to string representations for diffing. 13166 * 13167 * @param other - The other Delta to convert. 13168 * @return A tuple of [thisString, otherString]. 13169 */ 13170 deltasToStrings(other) { 13171 return [this, other].map((delta) => { 13172 return delta.map((op) => { 13173 if (op.insert !== null || op.insert !== void 0) { 13174 return typeof op.insert === "string" ? op.insert : NULL_CHARACTER; 13175 } 13176 const prep = delta === other ? "on" : "with"; 13177 throw new Error( 13178 "diff() called " + prep + " non-document" 13179 ); 13180 }).join(""); 13181 }); 13182 } 13183 /** 13184 * Process diff changes and convert them to Delta operations. 13185 * 13186 * @param changes - The array of changes from the diff algorithm. 13187 * @param thisIter - Iterator for this Delta's operations. 13188 * @param otherIter - Iterator for the other Delta's operations. 13189 * @return A Delta containing the processed diff operations. 13190 */ 13191 convertChangesToDelta(changes, thisIter, otherIter) { 13192 const retDelta = new _Delta(); 13193 changes.forEach((component) => { 13194 let length2 = component.count ?? 0; 13195 while (length2 > 0) { 13196 let opLength = 0; 13197 if (component.added) { 13198 opLength = Math.min(otherIter.peekLength(), length2); 13199 retDelta.push(otherIter.next(opLength)); 13200 } else if (component.removed) { 13201 opLength = Math.min(length2, thisIter.peekLength()); 13202 thisIter.next(opLength); 13203 retDelta.delete(opLength); 13204 } else { 13205 opLength = Math.min( 13206 thisIter.peekLength(), 13207 otherIter.peekLength(), 13208 length2 13209 ); 13210 const thisOp = thisIter.next(opLength); 13211 const otherOp = otherIter.next(opLength); 13212 if ((0, import_es64.default)(thisOp.insert, otherOp.insert)) { 13213 retDelta.retain( 13214 opLength, 13215 AttributeMap_default.diff( 13216 thisOp.attributes, 13217 otherOp.attributes 13218 ) 13219 ); 13220 } else { 13221 retDelta.push(otherOp).delete(opLength); 13222 } 13223 } 13224 length2 -= opLength; 13225 } 13226 }); 13227 return retDelta; 13228 } 13229 }; 13230 var Delta_default = Delta; 13231 13232 // packages/core-data/build-module/entity-sync.mjs 13233 var import_warning = __toESM(require_warning(), 1); 13234 var registeredManager; 13235 function registerEntitySyncManager(manager) { 13236 if (registeredManager && registeredManager !== manager) { 13237 (0, import_warning.default)( 13238 "registerEntitySyncManager: an entity sync manager is already registered. The new manager was ignored." 13239 ); 13240 return () => { 13241 }; 13242 } 13243 registeredManager = manager; 13244 return () => { 13245 if (registeredManager === manager) { 13246 registeredManager = void 0; 13247 } 13248 }; 13249 } 13250 function getEntitySyncManager() { 13251 return registeredManager; 13252 } 13253 13254 // node_modules/.store/tslib@2.8.1-LT-dxu1EkVy7OUDyVf5glQ/node_modules/tslib/tslib.es6.mjs 13255 var __assign = function() { 13256 __assign = Object.assign || function __assign2(t) { 13257 for (var s, i = 1, n = arguments.length; i < n; i++) { 13258 s = arguments[i]; 13259 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 13260 } 13261 return t; 13262 }; 13263 return __assign.apply(this, arguments); 13264 }; 13265 13266 // node_modules/.store/lower-case@2.0.2-5YZP5nczP5_f_8Vt5KBPjA/node_modules/lower-case/dist.es2015/index.js 13267 function lowerCase(str) { 13268 return str.toLowerCase(); 13269 } 13270 13271 // node_modules/.store/no-case@3.0.4-R4Hzt6qn-erEsTak7ojDpg/node_modules/no-case/dist.es2015/index.js 13272 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 13273 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 13274 function noCase(input, options) { 13275 if (options === void 0) { 13276 options = {}; 13277 } 13278 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; 13279 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 13280 var start = 0; 13281 var end = result.length; 13282 while (result.charAt(start) === "\0") 13283 start++; 13284 while (result.charAt(end - 1) === "\0") 13285 end--; 13286 return result.slice(start, end).split("\0").map(transform).join(delimiter); 13287 } 13288 function replace(input, re, value) { 13289 if (re instanceof RegExp) 13290 return input.replace(re, value); 13291 return re.reduce(function(input2, re2) { 13292 return input2.replace(re2, value); 13293 }, input); 13294 } 13295 13296 // node_modules/.store/pascal-case@3.1.2-khtSA9hpCTEVLYfMgyRdoA/node_modules/pascal-case/dist.es2015/index.js 13297 function pascalCaseTransform(input, index) { 13298 var firstChar = input.charAt(0); 13299 var lowerChars = input.substr(1).toLowerCase(); 13300 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 13301 return "_" + firstChar + lowerChars; 13302 } 13303 return "" + firstChar.toUpperCase() + lowerChars; 13304 } 13305 function pascalCase(input, options) { 13306 if (options === void 0) { 13307 options = {}; 13308 } 13309 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 13310 } 13311 13312 // node_modules/.store/camel-case@4.1.2-5Gz5buNb7xjdcDcS4uJ7xw/node_modules/camel-case/dist.es2015/index.js 13313 function camelCaseTransform(input, index) { 13314 if (index === 0) 13315 return input.toLowerCase(); 13316 return pascalCaseTransform(input, index); 13317 } 13318 function camelCase(input, options) { 13319 if (options === void 0) { 13320 options = {}; 13321 } 13322 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 13323 } 13324 13325 // node_modules/.store/upper-case-first@2.0.2-gj8G2jcL821LJ7crhULHjQ/node_modules/upper-case-first/dist.es2015/index.js 13326 function upperCaseFirst(input) { 13327 return input.charAt(0).toUpperCase() + input.substr(1); 13328 } 13329 13330 // node_modules/.store/capital-case@1.0.4-EVMMP2kRcoYmFbV1LUR_-w/node_modules/capital-case/dist.es2015/index.js 13331 function capitalCaseTransform(input) { 13332 return upperCaseFirst(input.toLowerCase()); 13333 } 13334 function capitalCase(input, options) { 13335 if (options === void 0) { 13336 options = {}; 13337 } 13338 return noCase(input, __assign({ delimiter: " ", transform: capitalCaseTransform }, options)); 13339 } 13340 13341 // packages/core-data/build-module/entities.mjs 13342 var import_api_fetch2 = __toESM(require_api_fetch(), 1); 13343 var import_blocks4 = __toESM(require_blocks(), 1); 13344 var import_i18n = __toESM(require_i18n(), 1); 13345 13346 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 13347 var import_data4 = __toESM(require_data(), 1); 13348 var import_block_editor3 = __toESM(require_block_editor(), 1); 13349 13350 // packages/core-data/build-module/awareness/base-awareness.mjs 13351 var import_data = __toESM(require_data(), 1); 13352 13353 // packages/core-data/build-module/awareness/config.mjs 13354 var AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS = 100; 13355 var LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS = 5; 13356 var REMOVAL_DELAY_IN_MS = 5e3; 13357 13358 // packages/core-data/build-module/awareness/utils.mjs 13359 function getBrowserName() { 13360 const userAgent = window.navigator.userAgent; 13361 let browserName = "Unknown"; 13362 if (userAgent.includes("Firefox")) { 13363 browserName = "Firefox"; 13364 } else if (userAgent.includes("Edg")) { 13365 browserName = "Microsoft Edge"; 13366 } else if (userAgent.includes("Chrome") && !userAgent.includes("Edg")) { 13367 browserName = "Chrome"; 13368 } else if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) { 13369 browserName = "Safari"; 13370 } else if (userAgent.includes("MSIE") || userAgent.includes("Trident")) { 13371 browserName = "Internet Explorer"; 13372 } else if (userAgent.includes("Opera") || userAgent.includes("OPR")) { 13373 browserName = "Opera"; 13374 } 13375 return browserName; 13376 } 13377 function areMapsEqual(map1, map2, comparatorFn) { 13378 if (map1.size !== map2.size) { 13379 return false; 13380 } 13381 for (const [key, value1] of map1.entries()) { 13382 if (!map2.has(key)) { 13383 return false; 13384 } 13385 if (!comparatorFn(value1, map2.get(key))) { 13386 return false; 13387 } 13388 } 13389 return true; 13390 } 13391 function areCollaboratorInfosEqual(collaboratorInfo1, collaboratorInfo2) { 13392 if (!collaboratorInfo1 || !collaboratorInfo2) { 13393 return collaboratorInfo1 === collaboratorInfo2; 13394 } 13395 if (Object.keys(collaboratorInfo1).length !== Object.keys(collaboratorInfo2).length) { 13396 return false; 13397 } 13398 return Object.entries(collaboratorInfo1).every(([key, value]) => { 13399 return value === collaboratorInfo2[key]; 13400 }); 13401 } 13402 function hasValidAvatarUrls(value) { 13403 if ("object" !== typeof value || null === value || Array.isArray(value)) { 13404 return false; 13405 } 13406 return ["24", "48", "96"].every( 13407 (size2) => !(size2 in value) || "string" === typeof value[size2] 13408 ); 13409 } 13410 function isCollaboratorInfo(value) { 13411 if ("object" !== typeof value || null === value) { 13412 return false; 13413 } 13414 return "id" in value && "name" in value && "slug" in value && "browserType" in value && "enteredAt" in value && (null === value.id || "number" === typeof value.id && Number.isInteger(value.id) && value.id > 0) && "string" === typeof value.name && "" !== value.name.trim() && "string" === typeof value.slug && (!("avatar_urls" in value) || hasValidAvatarUrls(value.avatar_urls)) && "string" === typeof value.browserType && "number" === typeof value.enteredAt && Number.isFinite(value.enteredAt); 13415 } 13416 function generateCollaboratorInfo(currentCollaborator, clientId) { 13417 const presentationInfo = { 13418 browserType: getBrowserName(), 13419 enteredAt: Date.now() 13420 }; 13421 if ("object" === typeof currentCollaborator && currentCollaborator) { 13422 const user = currentCollaborator; 13423 if ("id" in user && "name" in user) { 13424 const collaboratorInfo = { 13425 ...presentationInfo, 13426 ..."avatar_urls" in user && hasValidAvatarUrls(user.avatar_urls) ? { avatar_urls: user.avatar_urls } : {}, 13427 id: user.id, 13428 name: user.name, 13429 slug: "slug" in user && "string" === typeof user.slug ? user.slug : "" 13430 }; 13431 if (isCollaboratorInfo(collaboratorInfo) && null !== collaboratorInfo.id) { 13432 return collaboratorInfo; 13433 } 13434 } 13435 } 13436 return { 13437 ...presentationInfo, 13438 id: null, 13439 // Keep shared awareness data language-neutral. The editor localizes this 13440 // fallback name for the viewer when it is displayed. 13441 name: "Anonymous User", 13442 slug: `anonymous-$clientId}` 13443 }; 13444 } 13445 function getRecordValue(obj, key) { 13446 if ("object" === typeof obj && null !== obj && key in obj) { 13447 return obj[key]; 13448 } 13449 return null; 13450 } 13451 function getTypedKeys(obj) { 13452 return Object.keys(obj); 13453 } 13454 13455 // packages/core-data/build-module/awareness/typed-awareness.mjs 13456 var TypedAwareness = class extends Awareness { 13457 /** 13458 * Get the states from an awareness document. 13459 */ 13460 getStates() { 13461 return super.getStates(); 13462 } 13463 /** 13464 * Get a local state field from an awareness document. 13465 * @param field 13466 */ 13467 getLocalStateField(field) { 13468 const state = this.getLocalState(); 13469 return getRecordValue(state, field); 13470 } 13471 /** 13472 * Set a local state field on an awareness document. 13473 * @param field 13474 * @param value 13475 */ 13476 setLocalStateField(field, value) { 13477 super.setLocalStateField(field, value); 13478 } 13479 }; 13480 13481 // packages/core-data/build-module/awareness/awareness-state.mjs 13482 var AwarenessWithEqualityChecks = class extends TypedAwareness { 13483 /** OVERRIDDEN METHODS */ 13484 /** 13485 * Set a local state field on an awareness document. Calling this method may 13486 * trigger rerenders of any subscribed components. 13487 * 13488 * Equality checks are provided by the abstract `equalityFieldChecks` property. 13489 * @param field - The field to set. 13490 * @param value - The value to set. 13491 */ 13492 setLocalStateField(field, value) { 13493 if (this.isFieldEqual( 13494 field, 13495 value, 13496 this.getLocalStateField(field) ?? void 0 13497 )) { 13498 return; 13499 } 13500 super.setLocalStateField(field, value); 13501 } 13502 /** CUSTOM METHODS */ 13503 /** 13504 * Determine if a field value has changed using the provided equality checks. 13505 * @param field - The field to check. 13506 * @param value1 - The first value to compare. 13507 * @param value2 - The second value to compare. 13508 */ 13509 isFieldEqual(field, value1, value2) { 13510 if (["clientId", "isConnected", "isMe"].includes(field)) { 13511 return value1 === value2; 13512 } 13513 if (field in this.equalityFieldChecks) { 13514 const fn = this.equalityFieldChecks[field]; 13515 return fn(value1, value2); 13516 } 13517 throw new Error( 13518 `No equality check implemented for awareness state field "$field.toString()}".` 13519 ); 13520 } 13521 /** 13522 * Determine if two states are equal by comparing each field using the 13523 * provided equality checks. 13524 * @param state1 - The first state to compare. 13525 * @param state2 - The second state to compare. 13526 */ 13527 isStateEqual(state1, state2) { 13528 return [ 13529 .../* @__PURE__ */ new Set([ 13530 ...getTypedKeys(state1), 13531 ...getTypedKeys(state2) 13532 ]) 13533 ].every((field) => { 13534 const value1 = state1[field]; 13535 const value2 = state2[field]; 13536 return this.isFieldEqual(field, value1, value2); 13537 }); 13538 } 13539 }; 13540 var AwarenessState = class extends AwarenessWithEqualityChecks { 13541 /** CUSTOM PROPERTIES */ 13542 /** 13543 * Whether the setUp method has been called, to avoid running it multiple 13544 * times. 13545 */ 13546 hasSetupRun = false; 13547 /** 13548 * We keep track of all seen states during the current session for two reasons: 13549 * 13550 * 1. So that we can represent recently disconnected collaborators in our UI, even 13551 * after they have been removed from the awareness document. 13552 * 2. So that we can provide debug information about all collaborators seen during 13553 * the session. 13554 */ 13555 disconnectedCollaborators = /* @__PURE__ */ new Set(); 13556 seenStates = /* @__PURE__ */ new Map(); 13557 /** 13558 * Hold a snapshot of the previous awareness state allows us to compare the 13559 * state values and avoid unnecessary updates to subscribers. 13560 */ 13561 previousSnapshot = /* @__PURE__ */ new Map(); 13562 stateSubscriptions = []; 13563 /** 13564 * In some cases, we may want to throttle setting local state fields to avoid 13565 * overwhelming the awareness document with rapid updates. At the same time, we 13566 * want to ensure that when we read our own state locally, we get the latest 13567 * value -- even if it hasn't yet been set on the awareness instance. 13568 */ 13569 myThrottledState = {}; 13570 throttleTimeouts = /* @__PURE__ */ new Map(); 13571 /** CUSTOM METHODS */ 13572 /** 13573 * Set up the awareness state. This method is idempotent and will only run 13574 * once. Subclasses should override `onSetUp()` instead of this method to 13575 * add their own setup logic. 13576 * 13577 * This is defined as a readonly arrow function property to prevent 13578 * subclasses from overriding it. 13579 */ 13580 setUp = () => { 13581 if (this.hasSetupRun) { 13582 return; 13583 } 13584 this.hasSetupRun = true; 13585 this.onSetUp(); 13586 this.on( 13587 "change", 13588 ({ added, removed, updated }) => { 13589 [...added, ...updated].forEach((id2) => { 13590 this.disconnectedCollaborators.delete(id2); 13591 }); 13592 removed.forEach((id2) => { 13593 this.disconnectedCollaborators.add(id2); 13594 setTimeout(() => { 13595 this.disconnectedCollaborators.delete(id2); 13596 this.updateSubscribers( 13597 true 13598 /* force update */ 13599 ); 13600 }, REMOVAL_DELAY_IN_MS); 13601 }); 13602 this.updateSubscribers(); 13603 } 13604 ); 13605 }; 13606 /** 13607 * Get the most recent state from the last processed change event. 13608 * 13609 * @return An array of EnhancedState< State >. 13610 */ 13611 getCurrentState() { 13612 return Array.from(this.previousSnapshot.values()); 13613 } 13614 /** 13615 * Get all seen states in this session to enable debug reporting. 13616 */ 13617 getSeenStates() { 13618 return this.seenStates; 13619 } 13620 /** 13621 * Allow external code to subscribe to awareness state changes. 13622 * @param callback - The callback to subscribe to. 13623 */ 13624 onStateChange(callback) { 13625 this.stateSubscriptions.push(callback); 13626 return () => { 13627 this.stateSubscriptions = this.stateSubscriptions.filter( 13628 (cb) => cb !== callback 13629 ); 13630 }; 13631 } 13632 /** 13633 * Set a local state field on an awareness document with throttle. See caveats 13634 * of this.setLocalStateField. 13635 * @param field - The field to set. 13636 * @param value - The value to set. 13637 * @param wait - The wait time in milliseconds. 13638 */ 13639 setThrottledLocalStateField(field, value, wait) { 13640 this.setLocalStateField(field, value); 13641 this.throttleTimeouts.set( 13642 field, 13643 setTimeout(() => { 13644 this.throttleTimeouts.delete(field); 13645 if (this.myThrottledState[field]) { 13646 this.setLocalStateField( 13647 field, 13648 this.myThrottledState[field] 13649 ); 13650 delete this.myThrottledState[field]; 13651 } 13652 }, wait) 13653 ); 13654 } 13655 /** 13656 * Set the current collaborator's connection status as awareness state. 13657 * @param isConnected - The connection status. 13658 */ 13659 setConnectionStatus(isConnected) { 13660 if (isConnected) { 13661 this.disconnectedCollaborators.delete(this.clientID); 13662 } else { 13663 this.disconnectedCollaborators.add(this.clientID); 13664 } 13665 this.updateSubscribers( 13666 true 13667 /* force update */ 13668 ); 13669 } 13670 /** 13671 * Update all subscribed listeners with the latest awareness state. 13672 * @param forceUpdate - Whether to force an update. 13673 */ 13674 updateSubscribers(forceUpdate = false) { 13675 if (!this.stateSubscriptions.length) { 13676 return; 13677 } 13678 const states = this.getStates(); 13679 this.seenStates = new Map([ 13680 ...this.seenStates.entries(), 13681 ...states.entries() 13682 ]); 13683 const updatedStates = new Map( 13684 [...this.disconnectedCollaborators, ...states.keys()].filter((clientId) => { 13685 return Object.keys(this.seenStates.get(clientId) ?? {}).length > 0; 13686 }).map((clientId) => { 13687 const rawState = this.seenStates.get(clientId); 13688 const isConnected = !this.disconnectedCollaborators.has(clientId); 13689 const isMe = clientId === this.clientID; 13690 const myState = isMe ? this.myThrottledState : {}; 13691 const state = { 13692 ...rawState, 13693 ...myState, 13694 clientId, 13695 isConnected, 13696 isMe 13697 }; 13698 return [clientId, state]; 13699 }) 13700 ); 13701 if (!forceUpdate) { 13702 if (areMapsEqual( 13703 this.previousSnapshot, 13704 updatedStates, 13705 this.isStateEqual.bind(this) 13706 )) { 13707 return; 13708 } 13709 } 13710 this.previousSnapshot = updatedStates; 13711 this.stateSubscriptions.forEach((callback) => { 13712 callback(Array.from(updatedStates.values())); 13713 }); 13714 } 13715 }; 13716 13717 // packages/core-data/build-module/name.mjs 13718 var STORE_NAME = "core"; 13719 13720 // packages/core-data/build-module/awareness/base-awareness.mjs 13721 var BaseAwarenessState = class extends AwarenessState { 13722 onSetUp() { 13723 void this.setCurrentCollaboratorInfo(); 13724 } 13725 /** 13726 * Set the current collaborator info in the local state. 13727 */ 13728 async setCurrentCollaboratorInfo() { 13729 let currentUser2; 13730 try { 13731 currentUser2 = await (0, import_data.resolveSelect)(STORE_NAME).getCurrentUser(); 13732 } catch { 13733 } 13734 this.setLocalStateField( 13735 "collaboratorInfo", 13736 generateCollaboratorInfo(currentUser2, this.clientID) 13737 ); 13738 } 13739 }; 13740 var baseEqualityFieldChecks = { 13741 collaboratorInfo: areCollaboratorInfosEqual 13742 }; 13743 var BaseAwareness = class extends BaseAwarenessState { 13744 equalityFieldChecks = baseEqualityFieldChecks; 13745 }; 13746 13747 // packages/core-data/build-module/awareness/block-lookup.mjs 13748 var import_data2 = __toESM(require_data(), 1); 13749 var import_block_editor = __toESM(require_block_editor(), 1); 13750 13751 // packages/core-data/build-module/lock-unlock.mjs 13752 var import_private_apis = __toESM(require_private_apis(), 1); 13753 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)( 13754 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.", 13755 "@wordpress/core-data" 13756 ); 13757 13758 // packages/core-data/build-module/awareness/block-lookup.mjs 13759 function getContainingBlockYMap(yType) { 13760 let current = yType; 13761 while (current) { 13762 const parent = current.parent; 13763 if (parent instanceof yjs_exports.Map && parent.parent instanceof yjs_exports.Array && parent.get("clientId") !== void 0 && parent.get("innerBlocks") instanceof yjs_exports.Array) { 13764 return parent; 13765 } 13766 current = parent instanceof yjs_exports.AbstractType ? parent : null; 13767 } 13768 return null; 13769 } 13770 function getBlockPathInYdoc(yType) { 13771 const path = []; 13772 let current = yType; 13773 while (current) { 13774 const parentArray = current.parent; 13775 if (!parentArray || !(parentArray instanceof yjs_exports.Array)) { 13776 return null; 13777 } 13778 let index = -1; 13779 for (let i = 0; i < parentArray.length; i++) { 13780 if (parentArray.get(i) === current) { 13781 index = i; 13782 break; 13783 } 13784 } 13785 if (index === -1) { 13786 return null; 13787 } 13788 path.unshift(index); 13789 const grandparent = parentArray.parent; 13790 if (grandparent instanceof yjs_exports.Map && grandparent.get("clientId") !== void 0) { 13791 current = grandparent; 13792 } else { 13793 break; 13794 } 13795 } 13796 return path; 13797 } 13798 function resolveBlockClientIdByPath(path, blocks) { 13799 if (path.length === 0) { 13800 return null; 13801 } 13802 for (let i = 0; i < path.length; i++) { 13803 const block = blocks[path[i]]; 13804 if (!block) { 13805 return null; 13806 } 13807 if (i === path.length - 1) { 13808 return block.clientId; 13809 } 13810 blocks = block.innerBlocks; 13811 } 13812 return null; 13813 } 13814 function usePostContentBlocks() { 13815 return (0, import_data2.useSelect)((select6) => { 13816 const { getBlocksByName, getClientIdsTree } = unlock( 13817 select6(import_block_editor.store) 13818 ); 13819 const [postContentClientId] = getBlocksByName("core/post-content"); 13820 return getClientIdsTree(postContentClientId ?? ""); 13821 }, []); 13822 } 13823 13824 // packages/core-data/build-module/utils/crdt-utils.mjs 13825 var import_rich_text = __toESM(require_rich_text(), 1); 13826 function getRootMap(doc2, key) { 13827 return doc2.getMap(key); 13828 } 13829 function createYMap(partial = {}) { 13830 return new yjs_exports.Map(Object.entries(partial)); 13831 } 13832 function isYMap(value) { 13833 return value instanceof yjs_exports.Map; 13834 } 13835 function asRichTextOffset(offset) { 13836 return offset; 13837 } 13838 function asHtmlStringIndex(index) { 13839 return index; 13840 } 13841 function getYTextByAttributeKey(attributes, attributeKey) { 13842 const directValue = attributes.get(attributeKey); 13843 if (directValue instanceof yjs_exports.Text) { 13844 return directValue; 13845 } 13846 let value = attributes; 13847 for (const pathPart of attributeKey.split(".")) { 13848 if (value instanceof yjs_exports.Map) { 13849 value = value.get(pathPart); 13850 } else if (value instanceof yjs_exports.Array) { 13851 const index = Number.parseInt(pathPart, 10); 13852 if (!Number.isSafeInteger(index) || index < 0 || index.toString() !== pathPart) { 13853 return null; 13854 } 13855 value = value.get(index); 13856 } else { 13857 return null; 13858 } 13859 } 13860 return value instanceof yjs_exports.Text ? value : null; 13861 } 13862 function findBlockByClientIdInDoc(blockId, ydoc) { 13863 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 13864 const blocks = ymap.get("blocks"); 13865 if (!(blocks instanceof yjs_exports.Array)) { 13866 return null; 13867 } 13868 return findBlockByClientIdInBlocks(blockId, blocks); 13869 } 13870 var MARKER_START = 57344; 13871 function pickMarker(text2) { 13872 const tryCount = 16; 13873 for (let code = MARKER_START; code < MARKER_START + tryCount; code++) { 13874 const candidate = String.fromCharCode(code); 13875 if (!text2.includes(candidate)) { 13876 return candidate; 13877 } 13878 } 13879 return null; 13880 } 13881 function htmlIndexToRichTextOffset(html, htmlIndex) { 13882 if (!html.includes("<") && !html.includes("&")) { 13883 return asRichTextOffset(htmlIndex); 13884 } 13885 const marker = pickMarker(html); 13886 if (!marker) { 13887 return asRichTextOffset(htmlIndex); 13888 } 13889 const withMarker = html.slice(0, htmlIndex) + marker + html.slice(htmlIndex); 13890 const value = (0, import_rich_text.create)({ html: withMarker }); 13891 const markerPos = value.text.indexOf(marker); 13892 return asRichTextOffset(markerPos === -1 ? htmlIndex : markerPos); 13893 } 13894 function richTextOffsetToHtmlIndex(html, richTextOffset) { 13895 if (!html.includes("<") && !html.includes("&")) { 13896 return asHtmlStringIndex(richTextOffset); 13897 } 13898 const marker = pickMarker(html); 13899 if (!marker) { 13900 return asHtmlStringIndex(richTextOffset); 13901 } 13902 const value = (0, import_rich_text.create)({ html }); 13903 const markerValue = (0, import_rich_text.create)({ text: marker }); 13904 if (value.formats[richTextOffset]) { 13905 markerValue.formats[0] = value.formats[richTextOffset]; 13906 } 13907 const withMarker = (0, import_rich_text.insert)( 13908 value, 13909 markerValue, 13910 richTextOffset, 13911 richTextOffset 13912 ); 13913 const htmlWithMarker = (0, import_rich_text.toHTMLString)({ value: withMarker }); 13914 const markerIndex = htmlWithMarker.indexOf(marker); 13915 return asHtmlStringIndex( 13916 markerIndex === -1 ? richTextOffset : markerIndex 13917 ); 13918 } 13919 function findBlockByClientIdInBlocks(blockId, blocks) { 13920 for (const block of blocks) { 13921 if (block.get("clientId") === blockId) { 13922 return block; 13923 } 13924 const innerBlocks = block.get("innerBlocks"); 13925 if (innerBlocks && innerBlocks.length > 0) { 13926 const innerBlock = findBlockByClientIdInBlocks( 13927 blockId, 13928 innerBlocks 13929 ); 13930 if (innerBlock) { 13931 return innerBlock; 13932 } 13933 } 13934 } 13935 return null; 13936 } 13937 13938 // packages/core-data/build-module/utils/crdt-user-selections.mjs 13939 var import_data3 = __toESM(require_data(), 1); 13940 var import_block_editor2 = __toESM(require_block_editor(), 1); 13941 var SelectionType = /* @__PURE__ */ ((SelectionType2) => { 13942 SelectionType2["None"] = "none"; 13943 SelectionType2["Cursor"] = "cursor"; 13944 SelectionType2["SelectionInOneBlock"] = "selection-in-one-block"; 13945 SelectionType2["SelectionInMultipleBlocks"] = "selection-in-multiple-blocks"; 13946 SelectionType2["WholeBlock"] = "whole-block"; 13947 return SelectionType2; 13948 })(SelectionType || {}); 13949 var SelectionDirection = /* @__PURE__ */ ((SelectionDirection2) => { 13950 SelectionDirection2["Forward"] = "f"; 13951 SelectionDirection2["Backward"] = "b"; 13952 return SelectionDirection2; 13953 })(SelectionDirection || {}); 13954 function getSelectionState(selectionStart, selectionEnd, yDoc, options) { 13955 const { selectionDirection } = options ?? {}; 13956 const ymap = getRootMap(yDoc, CRDT_RECORD_MAP_KEY); 13957 const yBlocks = ymap.get("blocks"); 13958 const isSelectionEmpty = Object.keys(selectionStart).length === 0; 13959 const noSelection = { 13960 type: "none" 13961 /* None */ 13962 }; 13963 if (isSelectionEmpty || !yBlocks) { 13964 return noSelection; 13965 } 13966 const isSelectionInOneBlock = selectionStart.clientId === selectionEnd.clientId; 13967 const isCursorOnly = isSelectionInOneBlock && selectionStart.offset === selectionEnd.offset; 13968 const isSelectionAWholeBlock = isSelectionInOneBlock && selectionStart.offset === void 0 && selectionEnd.offset === void 0; 13969 if (isSelectionAWholeBlock) { 13970 const path = getBlockPathForLocalClientId(selectionStart.clientId); 13971 const blockPosition = path ? createRelativePositionForBlockPath(path, yBlocks) : null; 13972 if (!blockPosition) { 13973 return noSelection; 13974 } 13975 return { 13976 type: "whole-block", 13977 blockPosition 13978 }; 13979 } else if (isCursorOnly) { 13980 const cursorPosition = getCursorPosition(selectionStart, yBlocks); 13981 if (!cursorPosition) { 13982 return noSelection; 13983 } 13984 return { 13985 type: "cursor", 13986 cursorPosition 13987 }; 13988 } else if (isSelectionInOneBlock) { 13989 const cursorStartPosition = getCursorPosition( 13990 selectionStart, 13991 yBlocks 13992 ); 13993 const cursorEndPosition = getCursorPosition(selectionEnd, yBlocks); 13994 if (!cursorStartPosition || !cursorEndPosition) { 13995 return noSelection; 13996 } 13997 return { 13998 type: "selection-in-one-block", 13999 cursorStartPosition, 14000 cursorEndPosition, 14001 selectionDirection 14002 }; 14003 } 14004 const startEndpoint = getSelectionEndpoint(selectionStart, yBlocks); 14005 const endEndpoint = getSelectionEndpoint(selectionEnd, yBlocks); 14006 if (!startEndpoint || !endEndpoint) { 14007 return noSelection; 14008 } 14009 return { 14010 type: "selection-in-multiple-blocks", 14011 startEndpoint, 14012 endEndpoint, 14013 selectionDirection 14014 }; 14015 } 14016 function getCursorPosition(selection, blocks) { 14017 const path = getBlockPathForLocalClientId(selection.clientId); 14018 const block = path ? findBlockByPath(path, blocks) : null; 14019 if (!block || !selection.attributeKey || void 0 === selection.offset) { 14020 return null; 14021 } 14022 const attributes = block.get("attributes"); 14023 const currentYText = attributes ? getYTextByAttributeKey(attributes, selection.attributeKey) : null; 14024 if (!(currentYText instanceof yjs_exports.Text)) { 14025 return null; 14026 } 14027 const relativePosition = yjs_exports.createRelativePositionFromTypeIndex( 14028 currentYText, 14029 richTextOffsetToHtmlIndex( 14030 currentYText.toString(), 14031 asRichTextOffset(selection.offset) 14032 ) 14033 ); 14034 return { 14035 relativePosition, 14036 absoluteOffset: selection.offset, 14037 attributeKey: selection.attributeKey 14038 }; 14039 } 14040 function getSelectionEndpoint(selection, blocks) { 14041 const cursorPosition = getCursorPosition(selection, blocks); 14042 if (cursorPosition) { 14043 return { type: "cursor", cursorPosition }; 14044 } 14045 const path = getBlockPathForLocalClientId(selection.clientId); 14046 const blockPosition = path ? createRelativePositionForBlockPath(path, blocks) : null; 14047 if (blockPosition) { 14048 return { type: "whole-block", blockPosition }; 14049 } 14050 return null; 14051 } 14052 function getBlockPathForLocalClientId(clientId) { 14053 const { getBlockIndex, getBlockRootClientId, getBlockName } = (0, import_data3.select)(import_block_editor2.store); 14054 const path = []; 14055 let current = clientId; 14056 while (current) { 14057 const index = getBlockIndex(current); 14058 if (index === -1) { 14059 return null; 14060 } 14061 path.unshift(index); 14062 const parent = getBlockRootClientId(current); 14063 if (!parent) { 14064 break; 14065 } 14066 const parentName = getBlockName(parent); 14067 if (parentName === "core/post-content") { 14068 break; 14069 } 14070 current = parent; 14071 } 14072 return path.length > 0 ? path : null; 14073 } 14074 function findBlockByPath(path, blocks) { 14075 let currentBlocks = blocks; 14076 for (let i = 0; i < path.length; i++) { 14077 if (path[i] >= currentBlocks.length) { 14078 return null; 14079 } 14080 const block = currentBlocks.get(path[i]); 14081 if (!block) { 14082 return null; 14083 } 14084 if (i === path.length - 1) { 14085 return block; 14086 } 14087 currentBlocks = block.get("innerBlocks") ?? new yjs_exports.Array(); 14088 } 14089 return null; 14090 } 14091 function createRelativePositionForBlockPath(path, blocks) { 14092 let currentBlocks = blocks; 14093 for (let i = 0; i < path.length; i++) { 14094 if (path[i] >= currentBlocks.length) { 14095 return null; 14096 } 14097 if (i === path.length - 1) { 14098 return yjs_exports.createRelativePositionFromTypeIndex( 14099 currentBlocks, 14100 path[i] 14101 ); 14102 } 14103 const block = currentBlocks.get(path[i]); 14104 currentBlocks = block?.get("innerBlocks") ?? new yjs_exports.Array(); 14105 } 14106 return null; 14107 } 14108 function areSelectionsStatesEqual(selection1, selection2) { 14109 if (selection1.type !== selection2.type) { 14110 return false; 14111 } 14112 switch (selection1.type) { 14113 case "none": 14114 return true; 14115 case "cursor": 14116 return areCursorPositionsEqual( 14117 selection1.cursorPosition, 14118 selection2.cursorPosition 14119 ); 14120 case "selection-in-one-block": 14121 return areCursorPositionsEqual( 14122 selection1.cursorStartPosition, 14123 selection2.cursorStartPosition 14124 ) && areCursorPositionsEqual( 14125 selection1.cursorEndPosition, 14126 selection2.cursorEndPosition 14127 ) && selection1.selectionDirection === selection2.selectionDirection; 14128 case "selection-in-multiple-blocks": 14129 return areEndpointsEqual( 14130 selection1.startEndpoint, 14131 selection2.startEndpoint 14132 ) && areEndpointsEqual( 14133 selection1.endEndpoint, 14134 selection2.endEndpoint 14135 ) && selection1.selectionDirection === selection2.selectionDirection; 14136 case "whole-block": 14137 return yjs_exports.compareRelativePositions( 14138 selection1.blockPosition, 14139 selection2.blockPosition 14140 ); 14141 default: 14142 return false; 14143 } 14144 } 14145 function areEndpointsEqual(ep1, ep2) { 14146 if (ep1.type !== ep2.type) { 14147 return false; 14148 } 14149 if (ep1.type === "cursor" && ep2.type === "cursor") { 14150 return areCursorPositionsEqual( 14151 ep1.cursorPosition, 14152 ep2.cursorPosition 14153 ); 14154 } 14155 return yjs_exports.compareRelativePositions( 14156 ep1.blockPosition, 14157 ep2.blockPosition 14158 ); 14159 } 14160 function areCursorPositionsEqual(cursorPosition1, cursorPosition2) { 14161 const isRelativePositionEqual = yjs_exports.compareRelativePositions( 14162 cursorPosition1.relativePosition, 14163 cursorPosition2.relativePosition 14164 ); 14165 const isAbsoluteOffsetEqual = cursorPosition1.absoluteOffset === cursorPosition2.absoluteOffset; 14166 return isRelativePositionEqual && isAbsoluteOffsetEqual; 14167 } 14168 14169 // packages/core-data/build-module/awareness/post-editor-awareness.mjs 14170 var PostEditorAwareness = class extends BaseAwarenessState { 14171 constructor(doc2, kind, name, postId) { 14172 super(doc2); 14173 this.kind = kind; 14174 this.name = name; 14175 this.postId = postId; 14176 } 14177 equalityFieldChecks = { 14178 ...baseEqualityFieldChecks, 14179 editorState: this.areEditorStatesEqual 14180 }; 14181 onSetUp() { 14182 super.onSetUp(); 14183 this.subscribeToCollaboratorSelectionChanges(); 14184 } 14185 /** 14186 * Subscribe to collaborator selection changes and update the selection state. 14187 */ 14188 subscribeToCollaboratorSelectionChanges() { 14189 const { 14190 getSelectionStart, 14191 getSelectionEnd, 14192 getSelectedBlocksInitialCaretPosition 14193 } = (0, import_data4.select)(import_block_editor3.store); 14194 let selectionStart = getSelectionStart(); 14195 let selectionEnd = getSelectionEnd(); 14196 let localCursorTimeout = null; 14197 let selectionBeforeDebounce = null; 14198 (0, import_data4.subscribe)(() => { 14199 const newSelectionStart = getSelectionStart(); 14200 const newSelectionEnd = getSelectionEnd(); 14201 if (newSelectionStart === selectionStart && newSelectionEnd === selectionEnd) { 14202 return; 14203 } 14204 if (!selectionBeforeDebounce) { 14205 selectionBeforeDebounce = { 14206 start: selectionStart, 14207 end: selectionEnd 14208 }; 14209 } 14210 selectionStart = newSelectionStart; 14211 selectionEnd = newSelectionEnd; 14212 const initialPosition = getSelectedBlocksInitialCaretPosition(); 14213 void this.updateSelectionInEntityRecord( 14214 selectionStart, 14215 selectionEnd, 14216 initialPosition 14217 ); 14218 if (localCursorTimeout) { 14219 clearTimeout(localCursorTimeout); 14220 } 14221 localCursorTimeout = setTimeout(() => { 14222 const selectionStateOptions = {}; 14223 if (selectionBeforeDebounce) { 14224 selectionStateOptions.selectionDirection = detectSelectionDirection( 14225 selectionBeforeDebounce.start, 14226 selectionBeforeDebounce.end, 14227 selectionStart, 14228 selectionEnd 14229 ); 14230 selectionBeforeDebounce = null; 14231 } 14232 const selectionState = getSelectionState( 14233 selectionStart, 14234 selectionEnd, 14235 this.doc, 14236 selectionStateOptions 14237 ); 14238 this.setThrottledLocalStateField( 14239 "editorState", 14240 { selection: selectionState }, 14241 AWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS 14242 ); 14243 }, LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS); 14244 }); 14245 } 14246 /** 14247 * Update the entity record with the current collaborator's selection. 14248 * 14249 * @param selectionStart - The start position of the selection. 14250 * @param selectionEnd - The end position of the selection. 14251 * @param initialPosition - The initial position of the selection. 14252 */ 14253 async updateSelectionInEntityRecord(selectionStart, selectionEnd, initialPosition) { 14254 const edits = { 14255 selection: { selectionStart, selectionEnd, initialPosition } 14256 }; 14257 const options = { 14258 undoIgnore: true 14259 }; 14260 (0, import_data4.dispatch)(STORE_NAME).editEntityRecord( 14261 this.kind, 14262 this.name, 14263 this.postId, 14264 edits, 14265 options 14266 ); 14267 } 14268 /** 14269 * Check if two editor states are equal. 14270 * 14271 * @param state1 - The first editor state. 14272 * @param state2 - The second editor state. 14273 * @return True if the editor states are equal, false otherwise. 14274 */ 14275 areEditorStatesEqual(state1, state2) { 14276 if (!state1 || !state2) { 14277 return state1 === state2; 14278 } 14279 if (!state1.selection || !state2.selection) { 14280 return state1.selection === state2.selection; 14281 } 14282 return areSelectionsStatesEqual(state1.selection, state2.selection); 14283 } 14284 /** 14285 * Resolve a selection state to a text index and block client ID. 14286 * 14287 * For text-based selections, navigates up from the resolved Y.Text via 14288 * AbstractType.parent to find the containing block, then resolves the 14289 * local clientId via the block's tree path. 14290 * For WholeBlock selections, resolves the block's relative position and 14291 * then finds the local clientId via tree path. 14292 * 14293 * Tree-path resolution is used instead of reading the clientId directly 14294 * from the Yjs block because the local block-editor store may use different 14295 * clientIds (e.g. in "Show Template" mode where blocks are cloned). 14296 * 14297 * @param selection - The selection state. 14298 * @param blocks - The tree of block-editor store post content blocks. 14299 * @return The rich-text offset and block client ID, or nulls if not resolvable. 14300 */ 14301 convertSelectionStateToAbsolute(selection, blocks) { 14302 if (selection.type === SelectionType.None) { 14303 return { 14304 richTextOffset: null, 14305 localClientId: null, 14306 attributeKey: null 14307 }; 14308 } 14309 if (selection.type === SelectionType.WholeBlock) { 14310 const absolutePos = yjs_exports.createAbsolutePositionFromRelativePosition( 14311 selection.blockPosition, 14312 this.doc 14313 ); 14314 let localClientId2 = null; 14315 if (absolutePos && absolutePos.type instanceof yjs_exports.Array) { 14316 const parentArray = absolutePos.type; 14317 const block = parentArray.get(absolutePos.index); 14318 if (block instanceof yjs_exports.Map) { 14319 const path2 = getBlockPathInYdoc(block); 14320 localClientId2 = path2 ? resolveBlockClientIdByPath(path2, blocks) : null; 14321 } 14322 } 14323 return { 14324 richTextOffset: null, 14325 localClientId: localClientId2, 14326 attributeKey: null 14327 }; 14328 } 14329 if (selection.type === SelectionType.SelectionInMultipleBlocks) { 14330 return { 14331 richTextOffset: null, 14332 localClientId: null, 14333 attributeKey: null 14334 }; 14335 } 14336 const cursorPos = "cursorPosition" in selection ? selection.cursorPosition : selection.cursorStartPosition; 14337 const absolutePosition = yjs_exports.createAbsolutePositionFromRelativePosition( 14338 cursorPos.relativePosition, 14339 this.doc 14340 ); 14341 if (!absolutePosition) { 14342 return { 14343 richTextOffset: null, 14344 localClientId: null, 14345 attributeKey: null 14346 }; 14347 } 14348 const yType = getContainingBlockYMap(absolutePosition.type); 14349 const path = yType ? getBlockPathInYdoc(yType) : null; 14350 const localClientId = path ? resolveBlockClientIdByPath(path, blocks) : null; 14351 return { 14352 richTextOffset: htmlIndexToRichTextOffset( 14353 absolutePosition.type.toString(), 14354 asHtmlStringIndex(absolutePosition.index) 14355 ), 14356 localClientId, 14357 attributeKey: cursorPos.attributeKey ?? null 14358 }; 14359 } 14360 /** 14361 * Type guard to check if a struct is a Y.Item (not Y.GC) 14362 * @param struct - The struct to check. 14363 * @return True if the struct is a Y.Item, false otherwise. 14364 */ 14365 isYItem(struct) { 14366 return "content" in struct; 14367 } 14368 /** 14369 * Get data for debugging, using the awareness state. 14370 * 14371 * @return {YDocDebugData} The debug data. 14372 */ 14373 getDebugData() { 14374 const ydoc = this.doc; 14375 const docData = Object.fromEntries( 14376 Array.from(ydoc.share, ([key, value]) => [ 14377 key, 14378 value.toJSON() 14379 ]) 14380 ); 14381 const collaboratorMapData = new Map( 14382 Array.from(this.getSeenStates().entries()).filter( 14383 ([, collaboratorState]) => isCollaboratorInfo(collaboratorState.collaboratorInfo) 14384 ).map(([clientId, collaboratorState]) => [ 14385 String(clientId), 14386 { 14387 name: collaboratorState.collaboratorInfo.name, 14388 wpUserId: collaboratorState.collaboratorInfo.id 14389 } 14390 ]) 14391 ); 14392 const serializableClientItems = {}; 14393 ydoc.store.clients.forEach((structs, clientId) => { 14394 const items2 = structs.filter(this.isYItem); 14395 serializableClientItems[clientId] = items2.map((item) => { 14396 const { left, right, ...rest } = item; 14397 return { 14398 ...rest, 14399 left: left ? { 14400 id: left.id, 14401 length: left.length, 14402 origin: left.origin, 14403 content: left.content 14404 } : null, 14405 right: right ? { 14406 id: right.id, 14407 length: right.length, 14408 origin: right.origin, 14409 content: right.content 14410 } : null 14411 }; 14412 }); 14413 }); 14414 return { 14415 doc: docData, 14416 clients: serializableClientItems, 14417 collaboratorMap: Object.fromEntries(collaboratorMapData) 14418 }; 14419 } 14420 }; 14421 function detectSelectionDirection(prevStart, prevEnd, newStart, newEnd) { 14422 const startMoved = !areBlockSelectionsEqual(prevStart, newStart); 14423 const endMoved = !areBlockSelectionsEqual(prevEnd, newEnd); 14424 if (startMoved && !endMoved) { 14425 return SelectionDirection.Backward; 14426 } 14427 return SelectionDirection.Forward; 14428 } 14429 function areBlockSelectionsEqual(a, b) { 14430 return a.clientId === b.clientId && a.attributeKey === b.attributeKey && a.offset === b.offset; 14431 } 14432 14433 // packages/core-data/build-module/utils/crdt.mjs 14434 var import_es66 = __toESM(require_es6(), 1); 14435 var import_blocks3 = __toESM(require_blocks(), 1); 14436 14437 // node_modules/.store/uuid@14.0.2-ALlTd6-Rf9bZs703d7TIjQ/node_modules/uuid/dist/stringify.js 14438 var byteToHex = []; 14439 for (let i = 0; i < 256; ++i) { 14440 byteToHex.push((i + 256).toString(16).slice(1)); 14441 } 14442 function unsafeStringify(arr, offset = 0) { 14443 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]]).toLowerCase(); 14444 } 14445 14446 // node_modules/.store/uuid@14.0.2-ALlTd6-Rf9bZs703d7TIjQ/node_modules/uuid/dist/rng.js 14447 var rnds8 = new Uint8Array(16); 14448 function rng() { 14449 return crypto.getRandomValues(rnds8); 14450 } 14451 14452 // node_modules/.store/uuid@14.0.2-ALlTd6-Rf9bZs703d7TIjQ/node_modules/uuid/dist/v4.js 14453 function v4(options, buf, offset) { 14454 if (!buf && !options && crypto.randomUUID) { 14455 return crypto.randomUUID(); 14456 } 14457 return _v4(options, buf, offset); 14458 } 14459 function _v4(options, buf, offset) { 14460 options = options || {}; 14461 const rnds = options.random ?? options.rng?.() ?? rng(); 14462 if (rnds.length < 16) { 14463 throw new Error("Random bytes length must be >= 16"); 14464 } 14465 rnds[6] = rnds[6] & 15 | 64; 14466 rnds[8] = rnds[8] & 63 | 128; 14467 if (buf) { 14468 offset = offset || 0; 14469 if (offset < 0 || offset + 16 > buf.length) { 14470 throw new RangeError(`UUID byte range $offset}:$offset + 15} is out of buffer bounds`); 14471 } 14472 for (let i = 0; i < 16; ++i) { 14473 buf[offset + i] = rnds[i]; 14474 } 14475 return buf; 14476 } 14477 return unsafeStringify(rnds); 14478 } 14479 var v4_default = v4; 14480 14481 // packages/core-data/build-module/utils/crdt-blocks.mjs 14482 var import_es65 = __toESM(require_es6(), 1); 14483 var import_blocks = __toESM(require_blocks(), 1); 14484 var import_rich_text3 = __toESM(require_rich_text(), 1); 14485 14486 // packages/core-data/build-module/utils/crdt-text.mjs 14487 var import_rich_text2 = __toESM(require_rich_text(), 1); 14488 var RICH_TEXT_CACHE_MAX_SIZE = 500; 14489 function createRichTextDataCache(maxSize) { 14490 const cache3 = /* @__PURE__ */ new Map(); 14491 return function(value) { 14492 const cached = cache3.get(value); 14493 if (cached) { 14494 return cached; 14495 } 14496 const result = import_rich_text2.RichTextData.fromHTMLString(value); 14497 if (cache3.size >= maxSize) { 14498 cache3.delete(cache3.keys().next().value); 14499 } 14500 cache3.set(value, result); 14501 return result; 14502 }; 14503 } 14504 var getCachedRichTextData = createRichTextDataCache( 14505 RICH_TEXT_CACHE_MAX_SIZE 14506 ); 14507 14508 // packages/core-data/build-module/utils/crdt-blocks.mjs 14509 var serializableBlocksCache = /* @__PURE__ */ new WeakMap(); 14510 function serializeAttributeValue(value) { 14511 if (value instanceof import_rich_text3.RichTextData) { 14512 return value.valueOf(); 14513 } 14514 if (Array.isArray(value)) { 14515 return value.map(serializeAttributeValue); 14516 } 14517 if (value && typeof value === "object") { 14518 const result = {}; 14519 for (const [k, v] of Object.entries(value)) { 14520 result[k] = serializeAttributeValue(v); 14521 } 14522 return result; 14523 } 14524 return value; 14525 } 14526 function makeBlockAttributesSerializable(blockName, attributes) { 14527 const newAttributes = { ...attributes }; 14528 for (const [key, value] of Object.entries(attributes)) { 14529 if (isLocalAttribute(blockName, key)) { 14530 delete newAttributes[key]; 14531 continue; 14532 } 14533 newAttributes[key] = serializeAttributeValue(value); 14534 } 14535 return newAttributes; 14536 } 14537 function makeBlocksSerializable(blocks) { 14538 return blocks.map((block) => { 14539 const { 14540 name, 14541 innerBlocks, 14542 attributes, 14543 /* 14544 * Any validation issues discovered when loading a block are appended 14545 * to the block node with a logging function, which cannot be serialized. 14546 * 14547 * @see import("@wordpress/blocks/src/api/parser").parseRawBlock() 14548 */ 14549 validationIssues, 14550 ...rest 14551 } = block; 14552 return { 14553 ...rest, 14554 name, 14555 attributes: makeBlockAttributesSerializable(name, attributes), 14556 innerBlocks: makeBlocksSerializable(innerBlocks) 14557 }; 14558 }); 14559 } 14560 function deserializeAttributeValue(schema, value) { 14561 if (schema?.type === "rich-text" && typeof value === "string") { 14562 return getCachedRichTextData(value); 14563 } 14564 if (Array.isArray(value)) { 14565 return value.map( 14566 (item) => deserializeAttributeValue(schema, item) 14567 ); 14568 } 14569 if (value && typeof value === "object") { 14570 const result = {}; 14571 for (const [key, innerValue] of Object.entries( 14572 value 14573 )) { 14574 result[key] = deserializeAttributeValue( 14575 schema?.query?.[key], 14576 innerValue 14577 ); 14578 } 14579 return result; 14580 } 14581 return value; 14582 } 14583 function deserializeBlockAttributes(blocks) { 14584 return blocks.map((block) => { 14585 const { name, innerBlocks, attributes, ...rest } = block; 14586 const newAttributes = { ...attributes }; 14587 for (const [key, value] of Object.entries(attributes)) { 14588 const schema = getBlockAttributeSchema(name, key); 14589 if (schema) { 14590 newAttributes[key] = deserializeAttributeValue( 14591 schema, 14592 value 14593 ); 14594 } 14595 } 14596 return { 14597 ...rest, 14598 name, 14599 attributes: newAttributes, 14600 innerBlocks: deserializeBlockAttributes(innerBlocks ?? []) 14601 }; 14602 }); 14603 } 14604 function areBlocksEqual(gblock, yblock) { 14605 const yblockAsJson = yblock.toJSON(); 14606 const overwrites = { 14607 innerBlocks: null, 14608 clientId: null 14609 }; 14610 const res = (0, import_es65.default)( 14611 Object.assign({}, gblock, overwrites), 14612 Object.assign({}, yblockAsJson, overwrites) 14613 ); 14614 const inners = gblock.innerBlocks || []; 14615 const yinners = yblock.get("innerBlocks"); 14616 return res && inners.length === yinners?.length && inners.every( 14617 (block, i) => areBlocksEqual(block, yinners.get(i)) 14618 ); 14619 } 14620 function createNewYAttributeMap(blockName, attributes) { 14621 return new yjs_exports.Map( 14622 Object.entries(attributes).map( 14623 ([attributeName, attributeValue]) => { 14624 return [ 14625 attributeName, 14626 createNewYAttributeValue( 14627 blockName, 14628 attributeName, 14629 attributeValue 14630 ) 14631 ]; 14632 } 14633 ) 14634 ); 14635 } 14636 function createNewYAttributeValue(blockName, attributeName, attributeValue) { 14637 const schema = getBlockAttributeSchema(blockName, attributeName); 14638 return createYValueFromSchema(schema, attributeValue); 14639 } 14640 function createYValueFromSchema(schema, value) { 14641 if (!schema) { 14642 return value; 14643 } 14644 if (schema.type === "rich-text") { 14645 return new yjs_exports.Text(value?.toString() ?? ""); 14646 } 14647 if (schema.type === "array" && schema.query && Array.isArray(value)) { 14648 const query = schema.query; 14649 const yArray = new yjs_exports.Array(); 14650 yArray.insert( 14651 0, 14652 value.map((item) => createYMapFromQuery(query, item)) 14653 ); 14654 return yArray; 14655 } 14656 if (schema.type === "object" && schema.query && isRecord(value)) { 14657 return createYMapFromQuery(schema.query, value); 14658 } 14659 return value; 14660 } 14661 function isRecord(value) { 14662 return !!value && typeof value === "object" && !Array.isArray(value); 14663 } 14664 function createYMapFromQuery(query, obj) { 14665 if (!isRecord(obj)) { 14666 return new yjs_exports.Map(); 14667 } 14668 const entries = Object.entries(obj).map( 14669 ([key, val]) => { 14670 const subSchema = query[key]; 14671 return [key, createYValueFromSchema(subSchema, val)]; 14672 } 14673 ); 14674 return new yjs_exports.Map(entries); 14675 } 14676 function createNewYBlock(block) { 14677 return createYMap( 14678 Object.fromEntries( 14679 Object.entries(block).map(([key, value]) => { 14680 switch (key) { 14681 case "attributes": { 14682 return [ 14683 key, 14684 createNewYAttributeMap(block.name, value) 14685 ]; 14686 } 14687 case "innerBlocks": { 14688 const innerBlocks = new yjs_exports.Array(); 14689 if (!Array.isArray(value)) { 14690 return [key, innerBlocks]; 14691 } 14692 innerBlocks.insert( 14693 0, 14694 value.map( 14695 (innerBlock) => createNewYBlock(innerBlock) 14696 ) 14697 ); 14698 return [key, innerBlocks]; 14699 } 14700 default: 14701 return [key, value]; 14702 } 14703 }) 14704 ) 14705 ); 14706 } 14707 function mergeCrdtBlocks(yblocks, incomingBlocks, attributeCursor, options = {}) { 14708 if (!serializableBlocksCache.has(incomingBlocks)) { 14709 serializableBlocksCache.set( 14710 incomingBlocks, 14711 makeBlocksSerializable(incomingBlocks) 14712 ); 14713 } 14714 const incomingBlocksToSync = serializableBlocksCache.get(incomingBlocks) ?? []; 14715 const numOfCommonEntries = Math.min( 14716 incomingBlocksToSync.length ?? 0, 14717 yblocks.length 14718 ); 14719 let left = 0; 14720 let right = 0; 14721 for (; left < numOfCommonEntries && areBlocksEqual(incomingBlocksToSync[left], yblocks.get(left)); left++) { 14722 } 14723 for (; right < numOfCommonEntries - left && areBlocksEqual( 14724 incomingBlocksToSync[incomingBlocksToSync.length - right - 1], 14725 yblocks.get(yblocks.length - right - 1) 14726 ); right++) { 14727 } 14728 const numOfUpdatesNeeded = numOfCommonEntries - left - right; 14729 const numOfInsertionsNeeded = Math.max( 14730 0, 14731 incomingBlocksToSync.length - yblocks.length 14732 ); 14733 const numOfDeletionsNeeded = Math.max( 14734 0, 14735 yblocks.length - incomingBlocksToSync.length 14736 ); 14737 for (let i = 0; i < numOfUpdatesNeeded; i++, left++) { 14738 const incomingYBlock = incomingBlocksToSync[left]; 14739 const localYBlock = yblocks.get(left); 14740 Object.entries(incomingYBlock).forEach( 14741 ([incomingBlockProperty, incomingBlockPropertyValue]) => { 14742 switch (incomingBlockProperty) { 14743 case "attributes": { 14744 const localAttributes = localYBlock.get( 14745 incomingBlockProperty 14746 ); 14747 const incomingAttributes = incomingBlockPropertyValue; 14748 if (!localAttributes) { 14749 localYBlock.set( 14750 incomingBlockProperty, 14751 createNewYAttributeMap( 14752 incomingYBlock.name, 14753 incomingAttributes 14754 ) 14755 ); 14756 break; 14757 } 14758 Object.entries(incomingAttributes).forEach( 14759 ([ 14760 incomingAttributeName, 14761 incomingAttributeValue 14762 ]) => { 14763 const currentAttribute = localAttributes?.get( 14764 incomingAttributeName 14765 ); 14766 const isExpectedType = isExpectedAttributeType( 14767 incomingYBlock.name, 14768 incomingAttributeName, 14769 currentAttribute 14770 ); 14771 const isYType = currentAttribute instanceof yjs_exports.AbstractType; 14772 const isAttributeChanged = !isExpectedType || isYType || !(0, import_es65.default)( 14773 currentAttribute, 14774 incomingAttributeValue 14775 ); 14776 if (isAttributeChanged) { 14777 updateYBlockAttribute( 14778 incomingYBlock.name, 14779 incomingYBlock.clientId, 14780 incomingAttributeName, 14781 incomingAttributeValue, 14782 localAttributes, 14783 attributeCursor 14784 ); 14785 } 14786 } 14787 ); 14788 localAttributes.forEach( 14789 (_attrValue, attrName) => { 14790 if (!incomingBlockPropertyValue.hasOwnProperty( 14791 attrName 14792 )) { 14793 localAttributes.delete(attrName); 14794 } 14795 } 14796 ); 14797 break; 14798 } 14799 case "innerBlocks": { 14800 let yInnerBlocks = localYBlock.get( 14801 incomingBlockProperty 14802 ); 14803 if (!(yInnerBlocks instanceof yjs_exports.Array)) { 14804 yInnerBlocks = new yjs_exports.Array(); 14805 localYBlock.set( 14806 incomingBlockProperty, 14807 yInnerBlocks 14808 ); 14809 } 14810 mergeCrdtBlocks( 14811 yInnerBlocks, 14812 incomingBlockPropertyValue ?? [], 14813 attributeCursor, 14814 options 14815 ); 14816 break; 14817 } 14818 case "clientId": { 14819 if (options.preserveClientIds) { 14820 break; 14821 } 14822 if (incomingBlockPropertyValue !== localYBlock.get(incomingBlockProperty)) { 14823 localYBlock.set( 14824 incomingBlockProperty, 14825 incomingBlockPropertyValue 14826 ); 14827 } 14828 break; 14829 } 14830 default: 14831 if (!(0, import_es65.default)( 14832 incomingYBlock[incomingBlockProperty], 14833 localYBlock.get(incomingBlockProperty) 14834 )) { 14835 localYBlock.set( 14836 incomingBlockProperty, 14837 incomingBlockPropertyValue 14838 ); 14839 } 14840 } 14841 } 14842 ); 14843 localYBlock.forEach((_v, k) => { 14844 if (!incomingYBlock.hasOwnProperty(k)) { 14845 localYBlock.delete(k); 14846 } 14847 }); 14848 } 14849 yblocks.delete(left, numOfDeletionsNeeded); 14850 for (let i = 0; i < numOfInsertionsNeeded; i++, left++) { 14851 const newBlock = [createNewYBlock(incomingBlocksToSync[left])]; 14852 yblocks.insert(left, newBlock); 14853 } 14854 const knownClientIds = /* @__PURE__ */ new Set(); 14855 for (let j = 0; j < yblocks.length; j++) { 14856 const yblock = yblocks.get(j); 14857 let clientId = yblock.get("clientId"); 14858 if (!clientId) { 14859 continue; 14860 } 14861 if (knownClientIds.has(clientId)) { 14862 clientId = v4_default(); 14863 yblock.set("clientId", clientId); 14864 } 14865 knownClientIds.add(clientId); 14866 } 14867 } 14868 function areArrayElementsEqual(newElement, yElement) { 14869 if (yElement instanceof yjs_exports.Map && isRecord(newElement)) { 14870 return (0, import_es65.default)(newElement, yElement.toJSON()); 14871 } 14872 return (0, import_es65.default)(newElement, yElement); 14873 } 14874 function mergeYArray(yArray, newValue, schema, cursorPosition, cursorScope) { 14875 if (!schema.query) { 14876 return; 14877 } 14878 const query = schema.query; 14879 const numOfCommonEntries = Math.min(newValue.length, yArray.length); 14880 let left = 0; 14881 let right = 0; 14882 for (; left < numOfCommonEntries && areArrayElementsEqual(newValue[left], yArray.get(left)); left++) { 14883 } 14884 for (; right < numOfCommonEntries - left && areArrayElementsEqual( 14885 newValue[newValue.length - right - 1], 14886 yArray.get(yArray.length - right - 1) 14887 ); right++) { 14888 } 14889 const numOfUpdatesNeeded = numOfCommonEntries - left - right; 14890 for (let i = 0; i < numOfUpdatesNeeded; i++) { 14891 const currentElement = yArray.get(left + i); 14892 const newElement = newValue[left + i]; 14893 if (currentElement instanceof yjs_exports.Map && isRecord(newElement)) { 14894 mergeYMapValues( 14895 currentElement, 14896 newElement, 14897 query, 14898 cursorPosition, 14899 cursorScope 14900 ); 14901 } else { 14902 yArray.delete(0, yArray.length); 14903 yArray.insert( 14904 0, 14905 newValue.map((item) => createYMapFromQuery(query, item)) 14906 ); 14907 return; 14908 } 14909 } 14910 const numOfDeletionsNeeded = Math.max(0, yArray.length - newValue.length); 14911 if (numOfDeletionsNeeded > 0) { 14912 yArray.delete(left + numOfUpdatesNeeded, numOfDeletionsNeeded); 14913 } 14914 const numOfInsertionsNeeded = Math.max( 14915 0, 14916 newValue.length - yArray.length 14917 ); 14918 if (numOfInsertionsNeeded > 0) { 14919 const insertAt = left + numOfUpdatesNeeded; 14920 const itemsToInsert = new Array( 14921 numOfInsertionsNeeded 14922 ); 14923 for (let i = 0; i < numOfInsertionsNeeded; i++) { 14924 itemsToInsert[i] = createYMapFromQuery( 14925 query, 14926 newValue[insertAt + i] 14927 ); 14928 } 14929 yArray.insert(insertAt, itemsToInsert); 14930 } 14931 } 14932 function mergeYValue(schema, newVal, yMap, key, cursorPosition, cursorScope) { 14933 const currentVal = yMap.get(key); 14934 if (schema?.type === "rich-text" && typeof newVal === "string" && currentVal instanceof yjs_exports.Text) { 14935 mergeRichTextUpdate( 14936 currentVal, 14937 newVal, 14938 resolveRichTextCursorPosition(cursorPosition, cursorScope, newVal) 14939 ); 14940 } else if (schema?.type === "array" && schema.query && Array.isArray(newVal) && currentVal instanceof yjs_exports.Array) { 14941 mergeYArray(currentVal, newVal, schema, cursorPosition, cursorScope); 14942 } else if (schema?.type === "object" && schema.query && isRecord(newVal) && currentVal instanceof yjs_exports.Map) { 14943 mergeYMapValues( 14944 currentVal, 14945 newVal, 14946 schema.query, 14947 cursorPosition, 14948 cursorScope 14949 ); 14950 } else { 14951 const newYValue = createYValueFromSchema(schema, newVal); 14952 if (newYValue !== newVal || !(0, import_es65.default)(currentVal, newVal)) { 14953 yMap.set(key, newYValue); 14954 } 14955 } 14956 } 14957 function mergeYMapValues(yMap, newObj, query, cursorPosition, cursorScope) { 14958 for (const [key, newVal] of Object.entries(newObj)) { 14959 mergeYValue( 14960 query[key], 14961 newVal, 14962 yMap, 14963 key, 14964 cursorPosition, 14965 cursorScope 14966 ); 14967 } 14968 for (const key of yMap.keys()) { 14969 if (!Object.hasOwn(newObj, key)) { 14970 yMap.delete(key); 14971 } 14972 } 14973 } 14974 function updateYBlockAttribute(blockName, clientId, attributeName, attributeValue, currentAttributes, newCursorPosition) { 14975 const schema = getBlockAttributeSchema(blockName, attributeName); 14976 mergeYValue( 14977 schema, 14978 attributeValue, 14979 currentAttributes, 14980 attributeName, 14981 newCursorPosition, 14982 { attributeKey: attributeName, clientId } 14983 ); 14984 } 14985 function resolveRichTextCursorPosition(cursorPosition, cursorScope, updatedValue) { 14986 return cursorPosition && cursorPosition.clientId === cursorScope.clientId && cursorPosition.attributeKey === cursorScope.attributeKey && "number" === typeof cursorPosition.offset && Number.isInteger(cursorPosition.offset) ? richTextOffsetToHtmlIndex( 14987 updatedValue, 14988 asRichTextOffset(cursorPosition.offset) 14989 ) : null; 14990 } 14991 var cachedBlockAttributeSchemas; 14992 function getBlockAttributeSchema(blockName, attributeName) { 14993 if (!cachedBlockAttributeSchemas) { 14994 cachedBlockAttributeSchemas = /* @__PURE__ */ new Map(); 14995 for (const blockType of (0, import_blocks.getBlockTypes)()) { 14996 cachedBlockAttributeSchemas.set( 14997 blockType.name, 14998 new Map( 14999 Object.entries(blockType.attributes ?? {}).map( 15000 ([name, definition]) => { 15001 const { role, type, query } = definition; 15002 return [name, { role, type, query }]; 15003 } 15004 ) 15005 ) 15006 ); 15007 } 15008 } 15009 return cachedBlockAttributeSchemas.get(blockName)?.get(attributeName); 15010 } 15011 function isExpectedAttributeType(blockName, attributeName, attributeValue) { 15012 const schema = getBlockAttributeSchema(blockName, attributeName); 15013 if (schema?.type === "rich-text") { 15014 return attributeValue instanceof yjs_exports.Text; 15015 } 15016 if (schema?.type === "string") { 15017 return typeof attributeValue === "string"; 15018 } 15019 if (schema?.type === "array" && schema.query) { 15020 return attributeValue instanceof yjs_exports.Array; 15021 } 15022 if (schema?.type === "object" && schema.query) { 15023 return attributeValue instanceof yjs_exports.Map; 15024 } 15025 return true; 15026 } 15027 function isLocalAttribute(blockName, attributeName) { 15028 return "local" === getBlockAttributeSchema(blockName, attributeName)?.role; 15029 } 15030 var localDoc; 15031 function mergeRichTextUpdate(blockYText, updatedValue, htmlCursorIndex = null) { 15032 const currentValueAsDelta = new Delta_default(blockYText.toDelta()); 15033 const updatedValueAsDelta = new Delta_default([{ insert: updatedValue }]); 15034 const deltaDiff = currentValueAsDelta.diffWithCursor( 15035 updatedValueAsDelta, 15036 htmlCursorIndex 15037 ); 15038 const safeDiff = htmlCursorIndex === null || isDeltaVerificationMatch(blockYText, deltaDiff, updatedValue) ? deltaDiff : currentValueAsDelta.diff(updatedValueAsDelta); 15039 blockYText.applyDelta(safeDiff.ops); 15040 } 15041 function isDeltaVerificationMatch(blockYText, delta, expectedValue) { 15042 if (!localDoc) { 15043 localDoc = new yjs_exports.Doc(); 15044 } 15045 const verificationYText = localDoc.getText("verification-text"); 15046 verificationYText.delete(0, verificationYText.length); 15047 verificationYText.insert(0, blockYText.toString()); 15048 verificationYText.applyDelta(delta.ops); 15049 return verificationYText.toString() === expectedValue; 15050 } 15051 15052 // packages/core-data/build-module/utils/crdt-selection.mjs 15053 var import_data5 = __toESM(require_data(), 1); 15054 var import_block_editor4 = __toESM(require_block_editor(), 1); 15055 var import_blocks2 = __toESM(require_blocks(), 1); 15056 15057 // packages/core-data/build-module/utils/block-selection-history.mjs 15058 var SELECTION_HISTORY_DEFAULT_SIZE = 5; 15059 var YSelectionType = /* @__PURE__ */ ((YSelectionType2) => { 15060 YSelectionType2["RelativeSelection"] = "RelativeSelection"; 15061 YSelectionType2["BlockSelection"] = "BlockSelection"; 15062 return YSelectionType2; 15063 })(YSelectionType || {}); 15064 function createBlockSelectionHistory(ydoc, historySize = SELECTION_HISTORY_DEFAULT_SIZE) { 15065 let history = []; 15066 const getSelectionHistory2 = () => { 15067 return history.slice(0); 15068 }; 15069 const updateSelection = (newSelection) => { 15070 if (!newSelection?.selectionStart?.clientId || !newSelection?.selectionEnd?.clientId) { 15071 return; 15072 } 15073 const { selectionStart, selectionEnd } = newSelection; 15074 const start = convertWPBlockSelectionToSelection( 15075 selectionStart, 15076 ydoc 15077 ); 15078 const end = convertWPBlockSelectionToSelection(selectionEnd, ydoc); 15079 addToHistory({ start, end }); 15080 }; 15081 const addToHistory = (yFullSelection) => { 15082 const startClientId = yFullSelection.start.clientId; 15083 const endClientId = yFullSelection.end.clientId; 15084 history = history.filter((entry) => { 15085 const isSameBlockCombination = entry.start.clientId === startClientId && entry.end.clientId === endClientId; 15086 return !isSameBlockCombination; 15087 }); 15088 history.unshift(yFullSelection); 15089 if (history.length > historySize + 1) { 15090 history = history.slice(0, historySize + 1); 15091 } 15092 }; 15093 return { 15094 getSelectionHistory: getSelectionHistory2, 15095 updateSelection 15096 }; 15097 } 15098 function convertWPBlockSelectionToSelection(selection, ydoc) { 15099 const clientId = selection.clientId; 15100 const block = findBlockByClientIdInDoc(clientId, ydoc); 15101 const attributes = block?.get("attributes"); 15102 const attributeKey = selection.attributeKey; 15103 let changedYText = null; 15104 if (attributeKey && attributes) { 15105 changedYText = getYTextByAttributeKey(attributes, attributeKey); 15106 } 15107 if (!(changedYText instanceof yjs_exports.Text) || !attributeKey || !clientId) { 15108 return { 15109 type: "BlockSelection", 15110 clientId 15111 }; 15112 } 15113 const offset = selection.offset ?? 0; 15114 const relativePosition = yjs_exports.createRelativePositionFromTypeIndex( 15115 changedYText, 15116 richTextOffsetToHtmlIndex( 15117 changedYText.toString(), 15118 asRichTextOffset(offset) 15119 ) 15120 ); 15121 return { 15122 type: "RelativeSelection", 15123 attributeKey, 15124 relativePosition, 15125 clientId, 15126 offset 15127 }; 15128 } 15129 15130 // packages/core-data/build-module/utils/crdt-selection.mjs 15131 var selectionHistoryMap = /* @__PURE__ */ new WeakMap(); 15132 function getBlockSelectionHistory(ydoc) { 15133 let history = selectionHistoryMap.get(ydoc); 15134 if (!history) { 15135 history = createBlockSelectionHistory(ydoc); 15136 selectionHistoryMap.set(ydoc, history); 15137 } 15138 return history; 15139 } 15140 function getSelectionHistory(ydoc) { 15141 return getBlockSelectionHistory(ydoc).getSelectionHistory(); 15142 } 15143 function updateSelectionHistory(ydoc, wpSelection) { 15144 return getBlockSelectionHistory(ydoc).updateSelection(wpSelection); 15145 } 15146 function convertYSelectionToBlockSelection(ySelection, ydoc) { 15147 if (ySelection.type === YSelectionType.RelativeSelection) { 15148 const { relativePosition, attributeKey, clientId } = ySelection; 15149 const absolutePosition = yjs_exports.createAbsolutePositionFromRelativePosition( 15150 relativePosition, 15151 ydoc 15152 ); 15153 if (absolutePosition) { 15154 return { 15155 clientId, 15156 attributeKey, 15157 offset: htmlIndexToRichTextOffset( 15158 absolutePosition.type.toString(), 15159 asHtmlStringIndex(absolutePosition.index) 15160 ) 15161 }; 15162 } 15163 } else if (ySelection.type === YSelectionType.BlockSelection) { 15164 return { 15165 clientId: ySelection.clientId, 15166 attributeKey: void 0, 15167 offset: void 0 15168 }; 15169 } 15170 return null; 15171 } 15172 function convertYFullSelectionToWPSelection(yFullSelection, ydoc) { 15173 const { start, end } = yFullSelection; 15174 const startBlock = findBlockByClientIdInDoc(start.clientId, ydoc); 15175 const endBlock = findBlockByClientIdInDoc(end.clientId, ydoc); 15176 if (!startBlock || !endBlock) { 15177 return null; 15178 } 15179 const startBlockSelection = convertYSelectionToBlockSelection( 15180 start, 15181 ydoc 15182 ); 15183 const endBlockSelection = convertYSelectionToBlockSelection(end, ydoc); 15184 if (startBlockSelection === null || endBlockSelection === null) { 15185 return null; 15186 } 15187 return { 15188 selectionStart: startBlockSelection, 15189 selectionEnd: endBlockSelection 15190 }; 15191 } 15192 function findSelectionFromHistory(ydoc, selectionHistory) { 15193 for (const positionToTry of selectionHistory) { 15194 const result = convertYFullSelectionToWPSelection( 15195 positionToTry, 15196 ydoc 15197 ); 15198 if (result !== null) { 15199 return result; 15200 } 15201 } 15202 return null; 15203 } 15204 function restoreSelection(selectionHistory, ydoc) { 15205 const selectionToRestore = findSelectionFromHistory( 15206 ydoc, 15207 selectionHistory 15208 ); 15209 if (selectionToRestore === null) { 15210 return; 15211 } 15212 const { getBlock } = (0, import_data5.select)(import_block_editor4.store); 15213 const { resetSelection } = (0, import_data5.dispatch)(import_block_editor4.store); 15214 const { selectionStart, selectionEnd } = selectionToRestore; 15215 const isSelectionInSameBlock = selectionStart.clientId === selectionEnd.clientId; 15216 if (isSelectionInSameBlock) { 15217 const block = getBlock(selectionStart.clientId); 15218 const isBlockEmpty = block && (0, import_blocks2.isUnmodifiedBlock)(block); 15219 const isBeginningOfEmptyBlock = 0 === selectionStart.offset && 0 === selectionEnd.offset && isBlockEmpty && !selectionStart.attributeKey && !selectionEnd.attributeKey; 15220 if (isBeginningOfEmptyBlock) { 15221 const selectionStartWithoutOffset = { 15222 clientId: selectionStart.clientId 15223 }; 15224 const selectionEndWithoutOffset = { 15225 clientId: selectionEnd.clientId 15226 }; 15227 resetSelection( 15228 selectionStartWithoutOffset, 15229 selectionEndWithoutOffset, 15230 0 15231 ); 15232 } else { 15233 resetSelection(selectionStart, selectionEnd, 0); 15234 } 15235 } else { 15236 resetSelection(selectionEnd, selectionEnd, 0); 15237 } 15238 } 15239 function getShiftedSelection(ydoc, selectionHistory) { 15240 if (selectionHistory.length === 0) { 15241 return null; 15242 } 15243 const { start, end } = selectionHistory[0]; 15244 if (start.type === YSelectionType.BlockSelection || end.type === YSelectionType.BlockSelection) { 15245 return null; 15246 } 15247 const selectionStart = convertYSelectionToBlockSelection(start, ydoc); 15248 const selectionEnd = convertYSelectionToBlockSelection(end, ydoc); 15249 if (!selectionStart || !selectionEnd) { 15250 return null; 15251 } 15252 const startShifted = selectionStart.offset !== start.offset; 15253 const endShifted = selectionEnd.offset !== end.offset; 15254 if (!startShifted && !endShifted) { 15255 return null; 15256 } 15257 return { selectionStart, selectionEnd }; 15258 } 15259 15260 // packages/core-data/build-module/utils/crdt.mjs 15261 var POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE = "_crdt_document"; 15262 var disallowedPostMetaKeys = /* @__PURE__ */ new Set([ 15263 POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE 15264 ]); 15265 var unsyncedTaxonomyProperties = /* @__PURE__ */ new Set([ 15266 "id", 15267 "count", 15268 "link", 15269 "taxonomy", 15270 "_links", 15271 "_embedded" 15272 ]); 15273 function applyTaxonomyChangesToCRDTDoc(ydoc, changes) { 15274 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 15275 Object.entries(changes).forEach(([key, newValue]) => { 15276 if (unsyncedTaxonomyProperties.has(key)) { 15277 return; 15278 } 15279 if ("function" === typeof newValue) { 15280 return; 15281 } 15282 const currentValue = ymap.get(key); 15283 updateMapValue(ymap, key, currentValue, newValue); 15284 }); 15285 } 15286 function applyPostChangesToCRDTDoc(ydoc, changes, syncedProperties) { 15287 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 15288 Object.keys(changes).forEach((key) => { 15289 if (!syncedProperties.has(key)) { 15290 return; 15291 } 15292 const newValue = changes[key]; 15293 if ("function" === typeof newValue) { 15294 return; 15295 } 15296 switch (key) { 15297 case "blocks": { 15298 const newCursorPosition = parseCursorSelection( 15299 changes.selection 15300 ); 15301 const rawContent = getRawValue(changes.content); 15302 if (!newValue && typeof rawContent === "string") { 15303 mergeContentWithoutBlocks( 15304 ymap, 15305 rawContent, 15306 newCursorPosition 15307 ); 15308 break; 15309 } else if (!newValue) { 15310 ymap.set(key, void 0); 15311 break; 15312 } 15313 let currentBlocks = ymap.get(key); 15314 if (!(currentBlocks instanceof yjs_exports.Array)) { 15315 currentBlocks = new yjs_exports.Array(); 15316 ymap.set(key, currentBlocks); 15317 } 15318 mergeCrdtBlocks(currentBlocks, newValue, newCursorPosition); 15319 break; 15320 } 15321 case "content": 15322 case "excerpt": 15323 case "title": { 15324 const currentValue = ymap.get(key); 15325 let rawValue = getRawValue(newValue); 15326 if (key === "title" && !currentValue?.toString() && "Auto Draft" === rawValue) { 15327 rawValue = ""; 15328 } 15329 if (currentValue instanceof yjs_exports.Text) { 15330 mergeRichTextUpdate(currentValue, rawValue ?? ""); 15331 } else { 15332 const newYText = new yjs_exports.Text(rawValue ?? ""); 15333 ymap.set(key, newYText); 15334 } 15335 break; 15336 } 15337 // "Meta" is overloaded term; here, it refers to post meta. 15338 case "meta": { 15339 let metaMap = ymap.get("meta"); 15340 if (!isYMap(metaMap)) { 15341 metaMap = createYMap(); 15342 ymap.set("meta", metaMap); 15343 } 15344 Object.entries(newValue ?? {}).forEach( 15345 ([metaKey, metaValue]) => { 15346 if (disallowedPostMetaKeys.has(metaKey)) { 15347 return; 15348 } 15349 updateMapValue( 15350 metaMap, 15351 metaKey, 15352 metaMap.get(metaKey), 15353 // current value in CRDT 15354 metaValue 15355 // new value from changes 15356 ); 15357 } 15358 ); 15359 break; 15360 } 15361 case "slug": { 15362 if (!newValue) { 15363 break; 15364 } 15365 const currentValue = ymap.get(key); 15366 updateMapValue(ymap, key, currentValue, newValue); 15367 break; 15368 } 15369 // Add support for additional properties here. 15370 default: { 15371 const currentValue = ymap.get(key); 15372 updateMapValue(ymap, key, currentValue, newValue); 15373 } 15374 } 15375 }); 15376 if (changes.selection) { 15377 const selection = changes.selection; 15378 setTimeout(() => { 15379 updateSelectionHistory(ydoc, selection); 15380 }, 0); 15381 } 15382 } 15383 function mergeContentWithoutBlocks(ymap, rawContent, cursorPosition) { 15384 let currentBlocks = ymap.get("blocks"); 15385 if (!(currentBlocks instanceof yjs_exports.Array)) { 15386 currentBlocks = new yjs_exports.Array(); 15387 ymap.set("blocks", currentBlocks); 15388 } 15389 mergeCrdtBlocks( 15390 currentBlocks, 15391 (0, import_blocks3.parse)(rawContent), 15392 cursorPosition, 15393 { preserveClientIds: true } 15394 ); 15395 } 15396 function parseCursorSelection(selection) { 15397 const selectionStart = selection?.selectionStart; 15398 return selectionStart?.clientId && selectionStart.attributeKey && "number" === typeof selectionStart.offset && Number.isInteger(selectionStart.offset) ? { 15399 attributeKey: selectionStart.attributeKey, 15400 clientId: selectionStart.clientId, 15401 offset: asRichTextOffset(selectionStart.offset) 15402 } : null; 15403 } 15404 function getTaxonomyChangesFromCRDTDoc(crdtDoc, editedRecord) { 15405 const docRecord = getRootMap(crdtDoc, CRDT_RECORD_MAP_KEY).toJSON(); 15406 return Object.fromEntries( 15407 Object.entries(docRecord).filter( 15408 ([key, newValue]) => !unsyncedTaxonomyProperties.has(key) && haveValuesChanged(editedRecord?.[key], newValue) 15409 ) 15410 ); 15411 } 15412 function getPostChangesFromCRDTDoc(ydoc, editedRecord, syncedProperties) { 15413 const ymap = getRootMap(ydoc, CRDT_RECORD_MAP_KEY); 15414 let allowedMetaChanges = {}; 15415 const changes = Object.fromEntries( 15416 Object.entries(ymap.toJSON()).filter(([key, newValue]) => { 15417 if (!syncedProperties.has(key)) { 15418 return false; 15419 } 15420 const currentValue = editedRecord[key]; 15421 switch (key) { 15422 case "blocks": { 15423 if (ydoc.meta?.get(CRDT_DOC_META_PERSISTENCE_KEY) && editedRecord.content) { 15424 const blocksJson = ymap.get("blocks")?.toJSON() ?? []; 15425 return (0, import_blocks3.__unstableSerializeAndClean)(blocksJson).trim() !== getRawValue(editedRecord.content); 15426 } 15427 return true; 15428 } 15429 case "date": { 15430 const currentDateIsFloating = null === currentValue || editedRecord.modified === currentValue; 15431 if (currentDateIsFloating) { 15432 return false; 15433 } 15434 return haveValuesChanged(currentValue, newValue); 15435 } 15436 case "meta": { 15437 const currentMeta = currentValue ?? {}; 15438 allowedMetaChanges = Object.fromEntries( 15439 Object.entries(newValue ?? {}).filter( 15440 ([metaKey]) => { 15441 if (disallowedPostMetaKeys.has(metaKey)) { 15442 return false; 15443 } 15444 return metaKey in currentMeta; 15445 } 15446 ) 15447 ); 15448 const mergedValue = { 15449 ...currentMeta, 15450 ...allowedMetaChanges 15451 }; 15452 return haveValuesChanged(currentValue, mergedValue); 15453 } 15454 case "status": { 15455 if ("auto-draft" === newValue) { 15456 return false; 15457 } 15458 return haveValuesChanged(currentValue, newValue); 15459 } 15460 case "content": 15461 case "excerpt": 15462 case "title": { 15463 return haveValuesChanged( 15464 getRawValue(currentValue), 15465 newValue 15466 ); 15467 } 15468 // Add support for additional data types here. 15469 default: { 15470 return haveValuesChanged(currentValue, newValue); 15471 } 15472 } 15473 }) 15474 ); 15475 if (changes.blocks) { 15476 changes.blocks = deserializeBlockAttributes( 15477 changes.blocks 15478 ); 15479 } 15480 if (changes.blocks && !changes.content) { 15481 const capturedBlocks = changes.blocks; 15482 changes.content = () => (0, import_blocks3.__unstableSerializeAndClean)(capturedBlocks); 15483 } 15484 if ("object" === typeof changes.meta) { 15485 changes.meta = { 15486 ...editedRecord.meta, 15487 ...allowedMetaChanges 15488 }; 15489 } 15490 const selectionHistory = getSelectionHistory(ydoc); 15491 const shiftedSelection = getShiftedSelection(ydoc, selectionHistory); 15492 if (shiftedSelection) { 15493 changes.selection = { 15494 ...shiftedSelection, 15495 initialPosition: 0 15496 }; 15497 } 15498 return changes; 15499 } 15500 var taxonomySyncConfig = { 15501 applyChangesToCRDTDoc: applyTaxonomyChangesToCRDTDoc, 15502 createAwareness: (ydoc) => new BaseAwareness(ydoc), 15503 getChangesFromCRDTDoc: getTaxonomyChangesFromCRDTDoc 15504 }; 15505 var defaultCollectionSyncConfig = { 15506 applyChangesToCRDTDoc: () => { 15507 }, 15508 getChangesFromCRDTDoc: () => ({}), 15509 shouldSync: (_, objectId) => null === objectId 15510 }; 15511 function getRawValue(value) { 15512 if ("string" === typeof value) { 15513 return value; 15514 } 15515 if (value && "object" === typeof value && "raw" in value && "string" === typeof value.raw) { 15516 return value.raw; 15517 } 15518 return void 0; 15519 } 15520 function haveValuesChanged(currentValue, newValue) { 15521 return !(0, import_es66.default)(currentValue, newValue); 15522 } 15523 function updateMapValue(map2, key, currentValue, newValue) { 15524 if (void 0 === newValue) { 15525 map2.delete(key); 15526 return; 15527 } 15528 if (haveValuesChanged(currentValue, newValue)) { 15529 map2.set(key, newValue); 15530 } 15531 } 15532 15533 // packages/core-data/build-module/entities.mjs 15534 var DEFAULT_ENTITY_KEY = "id"; 15535 var POST_RAW_ATTRIBUTES = ["title", "excerpt", "content"]; 15536 var blocksTransientEdits = { 15537 blocks: { 15538 read: (record) => (0, import_blocks4.parse)(record.content?.raw ?? ""), 15539 write: (record) => ({ 15540 content: (0, import_blocks4.__unstableSerializeAndClean)(record.blocks) 15541 }) 15542 } 15543 }; 15544 var rootEntitiesConfig = [ 15545 { 15546 label: (0, import_i18n.__)("Base"), 15547 kind: "root", 15548 key: false, 15549 name: "__unstableBase", 15550 baseURL: "/", 15551 baseURLParams: { 15552 // Please also change the preload path when changing this. 15553 // @see lib/compat/wordpress-7.2/preload.php 15554 _fields: [ 15555 "description", 15556 "generate_animated_image_subsizes", 15557 "gmt_offset", 15558 "home", 15559 "image_max_bit_depth", 15560 "image_sizes", 15561 "image_size_threshold", 15562 "image_strip_meta", 15563 "name", 15564 "site_icon", 15565 "site_icon_url", 15566 "site_logo", 15567 "timezone_string", 15568 "url", 15569 "page_for_posts", 15570 "page_on_front", 15571 "show_on_front" 15572 ].join(",") 15573 }, 15574 // The entity doesn't support selecting multiple records. 15575 // The property is maintained for backward compatibility. 15576 plural: "__unstableBases", 15577 supportsPagination: false 15578 }, 15579 { 15580 label: (0, import_i18n.__)("Post Type"), 15581 name: "postType", 15582 kind: "root", 15583 key: "slug", 15584 baseURL: "/wp/v2/types", 15585 baseURLParams: { context: "edit" }, 15586 plural: "postTypes", 15587 supportsPagination: false 15588 }, 15589 { 15590 name: "media", 15591 kind: "root", 15592 baseURL: "/wp/v2/media", 15593 baseURLParams: { context: "edit" }, 15594 plural: "mediaItems", 15595 label: (0, import_i18n.__)("Media"), 15596 rawAttributes: ["caption", "title", "description"], 15597 supportsPagination: true 15598 }, 15599 { 15600 name: "taxonomy", 15601 kind: "root", 15602 key: "slug", 15603 baseURL: "/wp/v2/taxonomies", 15604 baseURLParams: { context: "edit" }, 15605 plural: "taxonomies", 15606 label: (0, import_i18n.__)("Taxonomy"), 15607 supportsPagination: false 15608 }, 15609 { 15610 name: "sidebar", 15611 kind: "root", 15612 baseURL: "/wp/v2/sidebars", 15613 baseURLParams: { context: "edit" }, 15614 plural: "sidebars", 15615 transientEdits: { blocks: true }, 15616 label: (0, import_i18n.__)("Widget areas"), 15617 supportsPagination: false 15618 }, 15619 { 15620 name: "widget", 15621 kind: "root", 15622 baseURL: "/wp/v2/widgets", 15623 baseURLParams: { context: "edit" }, 15624 plural: "widgets", 15625 transientEdits: { blocks: true }, 15626 label: (0, import_i18n.__)("Widgets"), 15627 supportsPagination: false 15628 }, 15629 { 15630 name: "widgetType", 15631 kind: "root", 15632 baseURL: "/wp/v2/widget-types", 15633 baseURLParams: { context: "edit" }, 15634 plural: "widgetTypes", 15635 label: (0, import_i18n.__)("Widget types"), 15636 supportsPagination: false 15637 }, 15638 { 15639 label: (0, import_i18n.__)("User"), 15640 name: "user", 15641 kind: "root", 15642 baseURL: "/wp/v2/users", 15643 getTitle: (record) => record?.name || record?.slug, 15644 baseURLParams: { context: "edit" }, 15645 plural: "users", 15646 supportsPagination: true 15647 }, 15648 { 15649 name: "comment", 15650 kind: "root", 15651 baseURL: "/wp/v2/comments", 15652 baseURLParams: { context: "edit" }, 15653 plural: "comments", 15654 label: (0, import_i18n.__)("Comment"), 15655 supportsPagination: true, 15656 ...globalThis.window?.__experimentalEnableRealTimeCollaboration ? { syncConfig: defaultCollectionSyncConfig } : {} 15657 }, 15658 { 15659 name: "menu", 15660 kind: "root", 15661 baseURL: "/wp/v2/menus", 15662 baseURLParams: { context: "edit" }, 15663 plural: "menus", 15664 label: (0, import_i18n.__)("Menu"), 15665 supportsPagination: true 15666 }, 15667 { 15668 name: "menuItem", 15669 kind: "root", 15670 baseURL: "/wp/v2/menu-items", 15671 baseURLParams: { context: "edit" }, 15672 plural: "menuItems", 15673 label: (0, import_i18n.__)("Menu Item"), 15674 rawAttributes: ["title"], 15675 supportsPagination: true 15676 }, 15677 { 15678 name: "menuLocation", 15679 kind: "root", 15680 baseURL: "/wp/v2/menu-locations", 15681 baseURLParams: { context: "edit" }, 15682 plural: "menuLocations", 15683 label: (0, import_i18n.__)("Menu Location"), 15684 key: "name", 15685 supportsPagination: false 15686 }, 15687 { 15688 label: (0, import_i18n.__)("Global Styles"), 15689 name: "globalStyles", 15690 kind: "root", 15691 baseURL: "/wp/v2/global-styles", 15692 baseURLParams: { context: "edit" }, 15693 plural: "globalStylesVariations", 15694 // Should be different from name. 15695 getTitle: () => (0, import_i18n.__)("Custom Styles"), 15696 getRevisionsUrl: (parentId, revisionId) => `/wp/v2/global-styles/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 15697 supportsPagination: true 15698 }, 15699 { 15700 label: (0, import_i18n.__)("Themes"), 15701 name: "theme", 15702 kind: "root", 15703 baseURL: "/wp/v2/themes", 15704 baseURLParams: { context: "edit" }, 15705 plural: "themes", 15706 key: "stylesheet", 15707 supportsPagination: false 15708 }, 15709 { 15710 label: (0, import_i18n.__)("Plugins"), 15711 name: "plugin", 15712 kind: "root", 15713 baseURL: "/wp/v2/plugins", 15714 baseURLParams: { context: "edit" }, 15715 plural: "plugins", 15716 key: "plugin", 15717 supportsPagination: false 15718 }, 15719 { 15720 label: (0, import_i18n.__)("Status"), 15721 name: "status", 15722 kind: "root", 15723 baseURL: "/wp/v2/statuses", 15724 baseURLParams: { context: "edit" }, 15725 plural: "statuses", 15726 key: "slug", 15727 supportsPagination: false 15728 }, 15729 { 15730 label: (0, import_i18n.__)("Font Collections"), 15731 name: "fontCollection", 15732 kind: "root", 15733 baseURL: "/wp/v2/font-collections", 15734 baseURLParams: { context: "view" }, 15735 plural: "fontCollections", 15736 key: "slug", 15737 supportsPagination: true 15738 }, 15739 { 15740 label: (0, import_i18n.__)("Icons"), 15741 name: "icon", 15742 kind: "root", 15743 baseURL: "/wp/v2/icons", 15744 baseURLParams: { context: "view" }, 15745 plural: "icons", 15746 key: "name", 15747 supportsPagination: false 15748 }, 15749 { 15750 label: (0, import_i18n.__)("Icon Collections"), 15751 name: "iconCollection", 15752 kind: "root", 15753 baseURL: "/wp/v2/icon-collections", 15754 baseURLParams: { context: "view" }, 15755 plural: "iconCollections", 15756 key: "slug", 15757 supportsPagination: false 15758 } 15759 ]; 15760 var deprecatedEntities = { 15761 root: { 15762 media: { 15763 since: "6.9", 15764 alternative: { 15765 kind: "postType", 15766 name: "attachment" 15767 } 15768 } 15769 } 15770 }; 15771 var additionalEntityConfigLoaders = [ 15772 { kind: "postType", loadEntities: loadPostTypeEntities }, 15773 { kind: "taxonomy", loadEntities: loadTaxonomyEntities }, 15774 { 15775 kind: "root", 15776 name: "site", 15777 plural: "sites", 15778 loadEntities: loadSiteEntity 15779 } 15780 ]; 15781 var prePersistPostType = async (persistedRecord, edits, name, isTemplate) => { 15782 const newEdits = {}; 15783 if (!isTemplate && persistedRecord?.status === "auto-draft") { 15784 if (!edits.status && !newEdits.status) { 15785 newEdits.status = "draft"; 15786 } 15787 if ((!edits.title || edits.title === "Auto Draft") && !newEdits.title && (!persistedRecord?.title || persistedRecord?.title === "Auto Draft")) { 15788 newEdits.title = ""; 15789 } 15790 } 15791 return newEdits; 15792 }; 15793 async function loadPostTypeEntities() { 15794 const postTypesPromise = (0, import_api_fetch2.default)({ path: "/wp/v2/types?context=view" }); 15795 const taxonomiesPromise = window.__experimentalEnableRealTimeCollaboration ? (0, import_api_fetch2.default)({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({}); 15796 const [postTypes, taxonomies] = await Promise.all([ 15797 postTypesPromise, 15798 taxonomiesPromise 15799 ]); 15800 return Object.entries(postTypes ?? {}).map(([name, postType]) => { 15801 const isTemplate = ["wp_template", "wp_template_part"].includes( 15802 name 15803 ); 15804 const namespace = postType?.rest_namespace ?? "wp/v2"; 15805 const syncedProperties = /* @__PURE__ */ new Set([ 15806 "author", 15807 "blocks", 15808 "content", 15809 "comment_status", 15810 "date", 15811 "excerpt", 15812 "featured_media", 15813 "format", 15814 "meta", 15815 "ping_status", 15816 "slug", 15817 "status", 15818 "sticky", 15819 "template", 15820 "title", 15821 ...postType.taxonomies?.map((taxonomy) => taxonomies?.[taxonomy]?.rest_base)?.filter(Boolean) ?? [] 15822 ]); 15823 const entity2 = { 15824 kind: "postType", 15825 baseURL: `/$namespace}/$postType.rest_base}`, 15826 baseURLParams: { context: "edit" }, 15827 name, 15828 label: postType.name, 15829 transientEdits: { 15830 ...blocksTransientEdits, 15831 selection: true 15832 }, 15833 mergedEdits: { meta: true }, 15834 rawAttributes: POST_RAW_ATTRIBUTES, 15835 getTitle: (record) => record?.title?.rendered || record?.title || (isTemplate ? capitalCase(record.slug ?? "") : String(record.id)), 15836 __unstablePrePersist: (persistedRecord, edits) => prePersistPostType(persistedRecord, edits, name, isTemplate), 15837 __unstable_rest_base: postType.rest_base, 15838 // The templates controller returns the whole collection and never 15839 // paginates. 15840 supportsPagination: !isTemplate, 15841 getRevisionsUrl: (parentId, revisionId) => `/$namespace}/$postType.rest_base}/$parentId}/revisions$revisionId ? "/" + revisionId : ""}`, 15842 revisionKey: isTemplate ? "wp_id" : DEFAULT_ENTITY_KEY 15843 }; 15844 if (!window.__experimentalEnableRealTimeCollaboration) { 15845 return entity2; 15846 } 15847 entity2.syncConfig = { 15848 // Save a CRDT document with this entity 15849 supportsPersistence: true, 15850 /** 15851 * Apply changes from the local editor to the local CRDT document so 15852 * that those changes can be synced to other peers (via the provider). 15853 * 15854 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 15855 * @param {Partial< import('@wordpress/sync').ObjectData >} changes 15856 * @return {void} 15857 */ 15858 applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, syncedProperties), 15859 /** 15860 * Create the awareness instance for the entity's CRDT document. 15861 * 15862 * @param {import('@wordpress/sync').CRDTDoc} ydoc 15863 * @param {import('@wordpress/sync').ObjectID} objectId 15864 * @return {import('@wordpress/sync').Awareness} Awareness instance 15865 */ 15866 createAwareness: (ydoc, objectId) => { 15867 const kind = "postType"; 15868 const id2 = parseInt(objectId, 10); 15869 return new PostEditorAwareness(ydoc, kind, name, id2); 15870 }, 15871 /** 15872 * Extract changes from a CRDT document that can be used to update the 15873 * local editor state. 15874 * 15875 * @param {import('@wordpress/sync').CRDTDoc} crdtDoc 15876 * @param {import('@wordpress/sync').ObjectData} editedRecord 15877 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 15878 */ 15879 getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc( 15880 crdtDoc, 15881 editedRecord, 15882 syncedProperties 15883 ), 15884 /** 15885 * Extract changes from a CRDT document that can be used to update the 15886 * local editor state. 15887 * 15888 * @param {import('@wordpress/sync').ObjectData} record 15889 * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record 15890 */ 15891 getPersistedCRDTDoc: (record) => { 15892 return record?.meta?.[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null; 15893 }, 15894 shouldSync: () => !(Array.isArray(window._wpCollaborationDisabledPostTypes) && window._wpCollaborationDisabledPostTypes.includes(name)) 15895 }; 15896 return entity2; 15897 }); 15898 } 15899 async function loadTaxonomyEntities() { 15900 const taxonomies = await (0, import_api_fetch2.default)({ 15901 path: "/wp/v2/taxonomies?context=view" 15902 }); 15903 return Object.entries(taxonomies ?? {}).map(([name, taxonomy]) => { 15904 const namespace = taxonomy?.rest_namespace ?? "wp/v2"; 15905 const entity2 = { 15906 kind: "taxonomy", 15907 baseURL: `/$namespace}/$taxonomy.rest_base}`, 15908 baseURLParams: { context: "edit" }, 15909 name, 15910 label: taxonomy.name, 15911 getTitle: (record) => record?.name, 15912 supportsPagination: true 15913 }; 15914 if (window.__experimentalEnableRealTimeCollaboration) { 15915 entity2.syncConfig = taxonomySyncConfig; 15916 } 15917 return entity2; 15918 }); 15919 } 15920 async function loadSiteEntity() { 15921 const entity2 = { 15922 label: (0, import_i18n.__)("Site"), 15923 name: "site", 15924 kind: "root", 15925 key: false, 15926 baseURL: "/wp/v2/settings", 15927 supportsPagination: false, 15928 meta: {} 15929 }; 15930 const site = await (0, import_api_fetch2.default)({ 15931 path: entity2.baseURL, 15932 method: "OPTIONS" 15933 }); 15934 const labels = {}; 15935 Object.entries(site?.schema?.properties ?? {}).forEach( 15936 ([key, value]) => { 15937 if (typeof value === "object" && value.title) { 15938 labels[key] = value.title; 15939 } 15940 } 15941 ); 15942 return [{ ...entity2, meta: { labels } }]; 15943 } 15944 var getMethodName = (kind, name, prefix = "get") => { 15945 const kindPrefix = kind === "root" ? "" : pascalCase(kind); 15946 const suffix = pascalCase(name); 15947 return `$prefix}$kindPrefix}$suffix}`; 15948 }; 15949 15950 // packages/core-data/build-module/sync.mjs 15951 var CRDT_AUTOSAVE_SNAPSHOT_KEY = "crdt_snapshot"; 15952 var syncManager; 15953 function getSyncManager() { 15954 if (syncManager) { 15955 return syncManager; 15956 } 15957 if (!globalThis.window?.__experimentalEnableRealTimeCollaboration) { 15958 return void 0; 15959 } 15960 syncManager = createSyncManager(); 15961 return syncManager; 15962 } 15963 function hasSyncManager() { 15964 return Boolean(syncManager); 15965 } 15966 function getEntitySnapshot(kind, name, recordId) { 15967 if (!hasSyncManager()) { 15968 return void 0; 15969 } 15970 return getSyncManager()?.getEntitySnapshot( 15971 `$kind}/$name}`, 15972 `$recordId}` 15973 ); 15974 } 15975 function entityContainsSnapshot(kind, name, recordId, encodedSnapshot) { 15976 if (!hasSyncManager()) { 15977 return false; 15978 } 15979 return getSyncManager()?.entityContainsSnapshot( 15980 `$kind}/$name}`, 15981 `$recordId}`, 15982 encodedSnapshot 15983 ) ?? false; 15984 } 15985 function getServerMutatedMetaFields(updatedMeta, persistedMeta, syncedMeta) { 15986 const baseline = { ...persistedMeta, ...syncedMeta }; 15987 return Object.fromEntries( 15988 Object.entries(updatedMeta ?? {}).filter(([key, value]) => { 15989 if (key === POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE) { 15990 return false; 15991 } 15992 return !(0, import_es67.default)(value, baseline[key]); 15993 }) 15994 ); 15995 } 15996 function getServerMutatedFields(updatedRecord, persistedRecord, syncedChanges) { 15997 return Object.fromEntries( 15998 Object.entries(updatedRecord).flatMap(([key, value]) => { 15999 if (key === "meta") { 16000 const serverMutatedMeta = getServerMutatedMetaFields( 16001 value, 16002 persistedRecord.meta, 16003 syncedChanges.meta 16004 ); 16005 return Object.keys(serverMutatedMeta).length ? [[key, serverMutatedMeta]] : []; 16006 } 16007 const baseline = key in syncedChanges ? syncedChanges[key] : persistedRecord[key]; 16008 const wasServerMutated = !(0, import_es67.default)( 16009 getRawValue(value) ?? value, 16010 getRawValue(baseline) ?? baseline 16011 ); 16012 return wasServerMutated ? [[key, value]] : []; 16013 }) 16014 ); 16015 } 16016 var defaultDataAccess = { select: import_data6.select, dispatch: import_data6.dispatch, resolveSelect: import_data6.resolveSelect }; 16017 function toObjectId(recordId) { 16018 return recordId; 16019 } 16020 function createDefaultEntitySyncManager(data = defaultDataAccess) { 16021 const getSyncConfig = (kind, name) => data.select(STORE_NAME).getEntityConfig(kind, name)?.syncConfig; 16022 return { 16023 shouldSync(kind, name) { 16024 return Boolean(getSyncManager() && getSyncConfig(kind, name)); 16025 }, 16026 isLoaded(kind, name, recordId) { 16027 if (!hasSyncManager()) { 16028 return false; 16029 } 16030 return Boolean( 16031 getSyncManager()?.isLoaded( 16032 `$kind}/$name}`, 16033 toObjectId(recordId) 16034 ) 16035 ); 16036 }, 16037 load(kind, name, recordId, record, handlers) { 16038 const syncConfig = getSyncConfig(kind, name); 16039 const manager = getSyncManager(); 16040 if (!syncConfig || !manager) { 16041 return; 16042 } 16043 return manager.load( 16044 syncConfig, 16045 `$kind}/$name}`, 16046 toObjectId(recordId), 16047 record, 16048 createRecordHandlers( 16049 data, 16050 kind, 16051 name, 16052 recordId, 16053 syncConfig, 16054 handlers 16055 ) 16056 ); 16057 }, 16058 loadCollection(kind, name, handlers) { 16059 const syncConfig = getSyncConfig(kind, name); 16060 const manager = getSyncManager(); 16061 if (!syncConfig || !manager) { 16062 return; 16063 } 16064 return manager.loadCollection( 16065 syncConfig, 16066 `$kind}/$name}`, 16067 createCollectionHandlers(data, kind, name, handlers) 16068 ); 16069 }, 16070 update(kind, name, recordId, edits, options) { 16071 if (!getSyncConfig(kind, name)) { 16072 return; 16073 } 16074 getSyncManager()?.update( 16075 `$kind}/$name}`, 16076 toObjectId(recordId), 16077 edits, 16078 getEditOrigin(options), 16079 { isNewUndoLevel: isNewUndoLevel(options) } 16080 ); 16081 }, 16082 beforeSave(kind, name, recordId, edits, context) { 16083 if (!getSyncConfig(kind, name)) { 16084 return; 16085 } 16086 return beforeSave(kind, name, recordId, edits, context); 16087 }, 16088 afterSave(kind, name, recordId, context) { 16089 if (!getSyncConfig(kind, name)) { 16090 return; 16091 } 16092 const { savedRecord, persistedRecord, edits } = context; 16093 const syncChanges = persistedRecord ? getServerMutatedFields(savedRecord, persistedRecord, edits) : savedRecord; 16094 getSyncManager()?.update( 16095 `$kind}/$name}`, 16096 void 0 === recordId ? null : toObjectId(recordId), 16097 syncChanges, 16098 LOCAL_UNDO_IGNORED_ORIGIN, 16099 { isSave: true } 16100 ); 16101 }, 16102 unload(kind, name, recordId) { 16103 if (!getSyncConfig(kind, name)) { 16104 return; 16105 } 16106 getSyncManager()?.unload( 16107 `$kind}/$name}`, 16108 toObjectId(recordId) 16109 ); 16110 }, 16111 unloadAll() { 16112 if (hasSyncManager()) { 16113 getSyncManager()?.unloadAll(); 16114 } 16115 }, 16116 // A getter, so the value is read when core-data asks. There is no 16117 // history before a sync manager exists, and asking must not create 16118 // one. 16119 get undoHistory() { 16120 if (!hasSyncManager()) { 16121 return void 0; 16122 } 16123 const undoManager2 = getSyncManager()?.undoManager; 16124 if (!undoManager2) { 16125 return void 0; 16126 } 16127 return { 16128 undo: (kind, name, recordId) => undoManager2.undo( 16129 `$kind}/$name}`, 16130 toObjectId(recordId) 16131 ), 16132 redo: (kind, name, recordId) => undoManager2.redo( 16133 `$kind}/$name}`, 16134 toObjectId(recordId) 16135 ), 16136 stopCapturing: () => undoManager2.stopCapturing(), 16137 clearRedo: () => undoManager2.clearRedo() 16138 }; 16139 } 16140 }; 16141 } 16142 function getEditOrigin(options) { 16143 return options.undoIgnore ? LOCAL_UNDO_IGNORED_ORIGIN : LOCAL_EDITOR_ORIGIN; 16144 } 16145 function isNewUndoLevel(options) { 16146 return options.undoIgnore ? false : !options.isCached; 16147 } 16148 async function beforeSave(kind, name, recordId, edits, { persistedRecord, isAutosave }) { 16149 const manager = getSyncManager(); 16150 if (!manager) { 16151 return; 16152 } 16153 const objectType = `$kind}/$name}`; 16154 const objectId = toObjectId(recordId); 16155 if (persistedRecord) { 16156 manager.update( 16157 objectType, 16158 objectId, 16159 edits, 16160 LOCAL_UNDO_IGNORED_ORIGIN 16161 ); 16162 } 16163 if (isAutosave) { 16164 const snapshot2 = manager.getEntitySnapshot(objectType, objectId); 16165 return snapshot2 ? { [CRDT_AUTOSAVE_SNAPSHOT_KEY]: snapshot2 } : void 0; 16166 } 16167 if ("postType" !== kind || !persistedRecord) { 16168 return; 16169 } 16170 const serializedDoc = await manager.createPersistedCRDTDoc( 16171 objectType, 16172 toObjectId(persistedRecord.id) 16173 ); 16174 if (!serializedDoc) { 16175 return; 16176 } 16177 return { 16178 meta: { 16179 ...edits.meta, 16180 [POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE]: serializedDoc 16181 } 16182 }; 16183 } 16184 function createRecordHandlers(data, kind, name, recordId, syncConfig, handlers) { 16185 return { 16186 editRecord: handlers.editRecord, 16187 getEditedRecord: handlers.getEditedRecord, 16188 refetchRecord: handlers.refetchRecord, 16189 onUndoLevelOpened: handlers.onUndoLevelOpened, 16190 // Handle sync connection status changes. 16191 onStatusChange: (status) => { 16192 unlock(data.dispatch(STORE_NAME)).setSyncConnectionStatus( 16193 kind, 16194 name, 16195 recordId, 16196 status 16197 ); 16198 }, 16199 // Persist the CRDT document. 16200 // 16201 // TODO: Currently, persisted CRDT documents are stored in post meta. 16202 // This effectively means that only post entities support CRDT 16203 // persistence. As we add support for syncing additional entity, 16204 // we'll need to revisit where persisted CRDT documents are stored. 16205 persistCRDTDoc: () => { 16206 if (!syncConfig.supportsPersistence) { 16207 return; 16208 } 16209 return data.resolveSelect(STORE_NAME).getEditedEntityRecord(kind, name, recordId).then(async (editedRecord) => { 16210 const { meta, status } = editedRecord; 16211 if ("auto-draft" === status || !meta) { 16212 return; 16213 } 16214 const entityConfig = data.select(STORE_NAME).getEntityConfig(kind, name); 16215 const entityIdKey = entityConfig?.key || DEFAULT_ENTITY_KEY; 16216 const entityId = editedRecord[entityIdKey]; 16217 await saveCRDTDoc( 16218 `$kind}/$name}`, 16219 toObjectId(entityId) 16220 ); 16221 }); 16222 }, 16223 addUndoMeta: (ydoc, meta) => { 16224 const selectionHistory = getSelectionHistory(ydoc); 16225 if (selectionHistory) { 16226 meta.set("selectionHistory", selectionHistory); 16227 } 16228 }, 16229 restoreUndoMeta: (ydoc, meta) => { 16230 const selectionHistory = meta.get("selectionHistory"); 16231 if (selectionHistory) { 16232 setTimeout(() => { 16233 restoreSelection(selectionHistory, ydoc); 16234 }, 0); 16235 } 16236 } 16237 }; 16238 } 16239 function createCollectionHandlers(data, kind, name, handlers) { 16240 return { 16241 refetchRecords: handlers.refetchRecords, 16242 onStatusChange: (status) => { 16243 unlock(data.dispatch(STORE_NAME)).setSyncConnectionStatus( 16244 kind, 16245 name, 16246 null, 16247 status 16248 ); 16249 } 16250 }; 16251 } 16252 if (globalThis.window?.__experimentalEnableRealTimeCollaboration) { 16253 registerEntitySyncManager(createDefaultEntitySyncManager()); 16254 } 16255 16256 // packages/core-data/build-module/utils/save-crdt-doc.mjs 16257 var SYNC_SAVE_API_PATH = "/wp-sync/v1/save"; 16258 var saveCRDTDocQueues = /* @__PURE__ */ new Map(); 16259 async function serializeAndSaveCRDTDoc(objectType, objectId, room) { 16260 const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc( 16261 objectType, 16262 objectId 16263 ); 16264 if (!serializedDoc) { 16265 return; 16266 } 16267 await (0, import_api_fetch3.default)({ 16268 path: SYNC_SAVE_API_PATH, 16269 method: "POST", 16270 data: { 16271 room, 16272 doc: serializedDoc 16273 } 16274 }); 16275 } 16276 async function saveCRDTDoc(objectType, objectId) { 16277 const room = `$objectType}:$objectId}`; 16278 const previousSave = saveCRDTDocQueues.get(room) || Promise.resolve(); 16279 const currentSave = previousSave.catch(() => { 16280 }).then(() => serializeAndSaveCRDTDoc(objectType, objectId, room)); 16281 saveCRDTDocQueues.set(room, currentSave); 16282 try { 16283 await currentSave; 16284 } finally { 16285 if (saveCRDTDocQueues.get(room) === currentSave) { 16286 saveCRDTDocQueues.delete(room); 16287 } 16288 } 16289 } 16290 16291 // packages/core-data/build-module/utils/get-pagination-meta.mjs 16292 function getPaginationMeta(headers) { 16293 const totalItems = parseInt(headers.get("X-WP-Total") ?? ""); 16294 const totalPages = parseInt(headers.get("X-WP-TotalPages") ?? ""); 16295 return { 16296 totalItems: Number.isFinite(totalItems) ? totalItems : null, 16297 totalPages: Number.isFinite(totalPages) ? totalPages : null 16298 }; 16299 } 16300 16301 // packages/core-data/build-module/queried-data/actions.mjs 16302 function receiveItems(items2, edits, meta) { 16303 return { 16304 type: "RECEIVE_ITEMS", 16305 items: items2, 16306 persistedEdits: edits, 16307 meta 16308 }; 16309 } 16310 function removeItems(kind, name, records, invalidateCache = false) { 16311 return { 16312 type: "REMOVE_ITEMS", 16313 itemIds: Array.isArray(records) ? records : [records], 16314 kind, 16315 name, 16316 invalidateCache 16317 }; 16318 } 16319 function receiveQueriedItems(items2, query = {}, edits, meta) { 16320 return { 16321 ...receiveItems(items2, edits, meta), 16322 query 16323 }; 16324 } 16325 16326 // packages/core-data/build-module/queried-data/selectors.mjs 16327 var import_equivalent_key_map = __toESM(require_equivalent_key_map(), 1); 16328 16329 // packages/core-data/build-module/queried-data/get-query-parts.mjs 16330 var import_url = __toESM(require_url(), 1); 16331 function getQueryParts(query) { 16332 const parts = { 16333 stableKey: "", 16334 page: 1, 16335 perPage: 10, 16336 offset: null, 16337 fields: null, 16338 include: null, 16339 context: "default" 16340 }; 16341 const keys2 = Object.keys(query).sort(); 16342 for (let i = 0; i < keys2.length; i++) { 16343 const key = keys2[i]; 16344 let value = query[key]; 16345 switch (key) { 16346 case "page": 16347 parts[key] = Number(value); 16348 break; 16349 case "per_page": 16350 parts.perPage = Number(value); 16351 break; 16352 case "offset": { 16353 const numericOffset = Number(value); 16354 if (Number.isFinite(numericOffset)) { 16355 parts.offset = numericOffset; 16356 } 16357 break; 16358 } 16359 case "context": 16360 parts.context = value; 16361 break; 16362 default: 16363 if (key === "_fields") { 16364 parts.fields = get_normalized_comma_separable_default(value) ?? []; 16365 value = parts.fields.join(); 16366 } 16367 if (key === "include") { 16368 if (typeof value === "number") { 16369 value = value.toString(); 16370 } 16371 parts.include = (get_normalized_comma_separable_default(value) ?? []).map(Number); 16372 value = parts.include.join(); 16373 } 16374 parts.stableKey += (parts.stableKey ? "&" : "") + (0, import_url.addQueryArgs)("", { [key]: value }).slice(1); 16375 } 16376 } 16377 return parts; 16378 } 16379 var get_query_parts_default = with_weak_map_cache_default(getQueryParts); 16380 16381 // packages/core-data/build-module/queried-data/selectors.mjs 16382 var queriedItemsCacheByState = /* @__PURE__ */ new WeakMap(); 16383 function getQueriedItemsUncached(state, query, options = {}) { 16384 const { supportsPagination = true } = options; 16385 const { 16386 stableKey, 16387 page, 16388 perPage, 16389 offset: queryOffset, 16390 include, 16391 fields, 16392 context 16393 } = get_query_parts_default(query); 16394 const itemIds = state.queries?.[context]?.[stableKey]?.itemIds; 16395 if (!itemIds) { 16396 return null; 16397 } 16398 const isPaginated = supportsPagination && perPage !== -1; 16399 const startOffset = isPaginated ? queryOffset ?? (page - 1) * perPage : 0; 16400 const endOffset = isPaginated ? Math.min(startOffset + perPage, itemIds.length) : itemIds.length; 16401 if (isPaginated && itemIds.length < startOffset + perPage) { 16402 const totalItems = state.queries[context][stableKey].meta?.totalItems; 16403 if (Number.isFinite(totalItems) && itemIds.length < totalItems) { 16404 return null; 16405 } 16406 } 16407 const items2 = []; 16408 for (let i = startOffset; i < endOffset; i++) { 16409 const itemId = itemIds[i]; 16410 if (Array.isArray(include) && !include.includes(itemId)) { 16411 continue; 16412 } 16413 if (itemId === void 0) { 16414 continue; 16415 } 16416 if (!state.items[context]?.hasOwnProperty(itemId)) { 16417 return null; 16418 } 16419 const item = state.items[context][itemId]; 16420 let filteredItem; 16421 if (Array.isArray(fields)) { 16422 filteredItem = {}; 16423 for (let f = 0; f < fields.length; f++) { 16424 const field = fields[f].split("."); 16425 let value = item; 16426 field.forEach((fieldName) => { 16427 value = value?.[fieldName]; 16428 }); 16429 setNestedValue(filteredItem, field, value); 16430 } 16431 } else { 16432 if (!state.itemIsComplete[context]?.[itemId]) { 16433 return null; 16434 } 16435 filteredItem = item; 16436 } 16437 items2.push(filteredItem); 16438 } 16439 return items2; 16440 } 16441 function getQueriedItems(state, query = {}, options = {}) { 16442 let queriedItemsCache = queriedItemsCacheByState.get(state); 16443 if (queriedItemsCache) { 16444 const queriedItems = queriedItemsCache.get(query); 16445 if (queriedItems !== void 0) { 16446 return queriedItems; 16447 } 16448 } else { 16449 queriedItemsCache = new import_equivalent_key_map.default(); 16450 queriedItemsCacheByState.set(state, queriedItemsCache); 16451 } 16452 const items2 = getQueriedItemsUncached(state, query, options); 16453 queriedItemsCache.set(query, items2); 16454 return items2; 16455 } 16456 function getQueriedTotalItems(state, query = {}) { 16457 const { stableKey, context } = get_query_parts_default(query); 16458 return state.queries?.[context]?.[stableKey]?.meta?.totalItems ?? null; 16459 } 16460 function getQueriedTotalPages(state, query = {}) { 16461 const { stableKey, context } = get_query_parts_default(query); 16462 return state.queries?.[context]?.[stableKey]?.meta?.totalPages ?? null; 16463 } 16464 16465 // packages/core-data/build-module/queried-data/reducer.mjs 16466 var import_data7 = __toESM(require_data(), 1); 16467 var import_compose = __toESM(require_compose(), 1); 16468 function getContextFromAction(action) { 16469 const { query } = action; 16470 if (!query) { 16471 return "default"; 16472 } 16473 const queryParts = get_query_parts_default(query); 16474 return queryParts.context; 16475 } 16476 function getMergedItemIds(itemIds = [], nextItemIds, { page = 1, offset, perPage = 10 } = {}) { 16477 if (perPage === -1) { 16478 return nextItemIds; 16479 } 16480 const nextItemIdsStartIndex = offset ?? (page - 1) * perPage; 16481 const nextItemIdsRange = Math.max(perPage, nextItemIds.length); 16482 const size2 = Math.max( 16483 itemIds.length, 16484 nextItemIdsStartIndex + nextItemIds.length 16485 ); 16486 const mergedItemIds = new Array(size2); 16487 for (let i = 0; i < size2; i++) { 16488 const isInNextItemsRange = i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + nextItemIdsRange; 16489 if (isInNextItemsRange) { 16490 mergedItemIds[i] = nextItemIds[i - nextItemIdsStartIndex]; 16491 } else { 16492 mergedItemIds[i] = itemIds[i]; 16493 } 16494 } 16495 return mergedItemIds; 16496 } 16497 function removeEntitiesById(entities2, ids) { 16498 return Object.fromEntries( 16499 Object.entries(entities2).filter( 16500 ([id2]) => !ids.some((itemId) => { 16501 if (Number.isInteger(itemId)) { 16502 return itemId === +id2; 16503 } 16504 return itemId === id2; 16505 }) 16506 ) 16507 ); 16508 } 16509 function items(state = {}, action) { 16510 switch (action.type) { 16511 case "RECEIVE_ITEMS": { 16512 const context = getContextFromAction(action); 16513 const key = action.key || DEFAULT_ENTITY_KEY; 16514 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 16515 return { 16516 ...state, 16517 [context]: { 16518 ...state[context], 16519 ...Object.fromEntries( 16520 itemsList.map((item) => [ 16521 item?.[key], 16522 conservativeMapItem( 16523 state?.[context]?.[item?.[key]], 16524 item 16525 ) 16526 ]) 16527 ) 16528 } 16529 }; 16530 } 16531 case "REMOVE_ITEMS": 16532 return Object.fromEntries( 16533 Object.entries(state).map(([itemId, contextState]) => [ 16534 itemId, 16535 removeEntitiesById(contextState, action.itemIds) 16536 ]) 16537 ); 16538 } 16539 return state; 16540 } 16541 function itemIsComplete(state = {}, action) { 16542 switch (action.type) { 16543 case "RECEIVE_ITEMS": { 16544 const context = getContextFromAction(action); 16545 const { query, key = DEFAULT_ENTITY_KEY } = action; 16546 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 16547 const queryParts = query ? get_query_parts_default(query) : {}; 16548 const isCompleteQuery = !query || !Array.isArray(queryParts.fields); 16549 return { 16550 ...state, 16551 [context]: { 16552 ...state[context], 16553 ...itemsList.reduce((result, item) => { 16554 const itemId = item?.[key]; 16555 result[itemId] = state?.[context]?.[itemId] || isCompleteQuery; 16556 return result; 16557 }, {}) 16558 } 16559 }; 16560 } 16561 case "REMOVE_ITEMS": 16562 return Object.fromEntries( 16563 Object.entries(state).map(([itemId, contextState]) => [ 16564 itemId, 16565 removeEntitiesById(contextState, action.itemIds) 16566 ]) 16567 ); 16568 } 16569 return state; 16570 } 16571 var receiveQueries = (0, import_compose.compose)([ 16572 // Limit to matching action type so we don't attempt to replace action on 16573 // an unhandled action. 16574 if_matching_action_default((action) => "query" in action), 16575 // Inject query parts into action for use both in `keyedReducer` and reducer. 16576 replace_action_default((action) => { 16577 if (action.query) { 16578 return { 16579 ...action, 16580 ...get_query_parts_default(action.query) 16581 }; 16582 } 16583 return action; 16584 }), 16585 (0, import_data7.keyedReducer)("context"), 16586 // Queries shape is shared, but keyed by query `stableKey` part. Original 16587 // reducer tracks only a single query object. 16588 (0, import_data7.keyedReducer)("stableKey") 16589 ])((state = {}, action) => { 16590 if (action.type !== "RECEIVE_ITEMS") { 16591 return state; 16592 } 16593 if (!Array.isArray(action.items)) { 16594 return state; 16595 } 16596 const key = action.key ?? DEFAULT_ENTITY_KEY; 16597 return { 16598 itemIds: getMergedItemIds( 16599 state.itemIds, 16600 action.items.map((item) => item?.[key]).filter(Boolean), 16601 { 16602 page: action.page, 16603 offset: action.offset, 16604 perPage: action.perPage 16605 } 16606 ), 16607 meta: action.meta 16608 }; 16609 }); 16610 function removeQueryItems(queryItems, removedItems) { 16611 const itemIds = queryItems.itemIds.filter( 16612 (itemId) => !removedItems[itemId] 16613 ); 16614 const removedCount = queryItems.itemIds.length - itemIds.length; 16615 if (removedCount === 0) { 16616 return queryItems; 16617 } 16618 const nextQueryItems = { ...queryItems, itemIds }; 16619 if (Number.isFinite(queryItems.meta?.totalItems)) { 16620 nextQueryItems.meta = { 16621 ...queryItems.meta, 16622 totalItems: Math.max( 16623 0, 16624 queryItems.meta.totalItems - removedCount 16625 ), 16626 totalPages: null 16627 }; 16628 } 16629 return nextQueryItems; 16630 } 16631 var queries = (state = {}, action) => { 16632 switch (action.type) { 16633 case "RECEIVE_ITEMS": 16634 return receiveQueries(state, action); 16635 case "REMOVE_ITEMS": 16636 const removedItems = action.itemIds.reduce((result, itemId) => { 16637 result[itemId] = true; 16638 return result; 16639 }, {}); 16640 return Object.fromEntries( 16641 Object.entries(state).map( 16642 ([queryGroup, contextQueries]) => [ 16643 queryGroup, 16644 Object.fromEntries( 16645 Object.entries(contextQueries).map( 16646 ([query, queryItems]) => [ 16647 query, 16648 removeQueryItems( 16649 queryItems, 16650 removedItems 16651 ) 16652 ] 16653 ) 16654 ) 16655 ] 16656 ) 16657 ); 16658 default: 16659 return state; 16660 } 16661 }; 16662 var reducer_default = (0, import_data7.combineReducers)({ 16663 items, 16664 itemIsComplete, 16665 queries 16666 }); 16667 16668 // packages/core-data/build-module/reducer.mjs 16669 function users(state = { byId: {}, queries: {} }, action) { 16670 switch (action.type) { 16671 case "RECEIVE_USER_QUERY": 16672 return { 16673 byId: { 16674 ...state.byId, 16675 // Key users by their ID. 16676 ...action.users.reduce( 16677 (newUsers, user) => ({ 16678 ...newUsers, 16679 [user.id]: user 16680 }), 16681 {} 16682 ) 16683 }, 16684 queries: { 16685 ...state.queries, 16686 [action.queryID]: action.users.map((user) => user.id) 16687 } 16688 }; 16689 } 16690 return state; 16691 } 16692 function currentUser(state = {}, action) { 16693 switch (action.type) { 16694 case "RECEIVE_CURRENT_USER": 16695 return action.currentUser; 16696 } 16697 return state; 16698 } 16699 function currentTheme(state = void 0, action) { 16700 switch (action.type) { 16701 case "RECEIVE_CURRENT_THEME": 16702 return action.currentTheme.stylesheet; 16703 } 16704 return state; 16705 } 16706 function currentGlobalStylesId(state = void 0, action) { 16707 switch (action.type) { 16708 case "RECEIVE_CURRENT_GLOBAL_STYLES_ID": 16709 return action.id; 16710 } 16711 return state; 16712 } 16713 function themeBaseGlobalStyles(state = {}, action) { 16714 switch (action.type) { 16715 case "RECEIVE_THEME_GLOBAL_STYLES": 16716 return { 16717 ...state, 16718 [action.stylesheet]: action.globalStyles 16719 }; 16720 } 16721 return state; 16722 } 16723 function themeGlobalStyleVariations(state = {}, action) { 16724 switch (action.type) { 16725 case "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS": 16726 return { 16727 ...state, 16728 [action.stylesheet]: action.variations 16729 }; 16730 } 16731 return state; 16732 } 16733 var withMultiEntityRecordEdits = (reducer) => (state, action) => { 16734 if (action.type === "UNDO" || action.type === "REDO") { 16735 const { record } = action; 16736 let newState = state; 16737 record.forEach(({ id: { kind, name, recordId }, changes }) => { 16738 const persistedRecord = state?.queriedData?.items?.default?.[recordId]; 16739 const edits = Object.fromEntries( 16740 Object.entries(changes).map(([key, value]) => [ 16741 key, 16742 action.type === "UNDO" ? value.from : value.to 16743 ]) 16744 ); 16745 newState = reducer(newState, { 16746 type: "EDIT_ENTITY_RECORD", 16747 kind, 16748 name, 16749 recordId, 16750 // Clear edits matching the persisted record so the entity is 16751 // no longer dirty after undoing back to its saved state. 16752 edits: clearUnchangedEdits(edits, persistedRecord) 16753 }); 16754 }); 16755 return newState; 16756 } 16757 return reducer(state, action); 16758 }; 16759 function entity(entityConfig) { 16760 return (0, import_compose2.compose)([ 16761 withMultiEntityRecordEdits, 16762 // Limit to matching action type so we don't attempt to replace action on 16763 // an unhandled action. 16764 if_matching_action_default( 16765 (action) => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind 16766 ), 16767 // Inject the entity config into the action. 16768 replace_action_default((action) => { 16769 return { 16770 key: entityConfig.key || DEFAULT_ENTITY_KEY, 16771 ...action 16772 }; 16773 }) 16774 ])( 16775 (0, import_data8.combineReducers)({ 16776 queriedData: reducer_default, 16777 edits: (state = {}, action) => { 16778 switch (action.type) { 16779 case "RECEIVE_ITEMS": 16780 const context = action?.query?.context ?? "default"; 16781 if (context !== "default") { 16782 return state; 16783 } 16784 const nextState = { ...state }; 16785 const itemsList = Array.isArray(action.items) ? action.items : [action.items]; 16786 for (const record of itemsList) { 16787 const recordId = record?.[action.key]; 16788 const edits = nextState[recordId]; 16789 if (!edits) { 16790 continue; 16791 } 16792 const nextEdits2 = Object.keys(edits).reduce( 16793 (acc, key) => { 16794 if ( 16795 // Edits are the "raw" attribute values, but records may have 16796 // objects with more properties, so we use `get` here for the 16797 // comparison. 16798 !(0, import_es68.default)( 16799 edits[key], 16800 record[key]?.raw ?? record[key] 16801 ) && // Sometimes the server alters the sent value which means 16802 // we need to also remove the edits before the api request. 16803 (!action.persistedEdits || !(0, import_es68.default)( 16804 edits[key], 16805 action.persistedEdits[key] 16806 )) 16807 ) { 16808 acc[key] = edits[key]; 16809 } 16810 return acc; 16811 }, 16812 {} 16813 ); 16814 if (Object.keys(nextEdits2).length) { 16815 nextState[recordId] = nextEdits2; 16816 } else { 16817 delete nextState[recordId]; 16818 } 16819 } 16820 return nextState; 16821 case "EDIT_ENTITY_RECORD": 16822 const nextEdits = { 16823 ...state[action.recordId], 16824 ...action.edits 16825 }; 16826 Object.keys(nextEdits).forEach((key) => { 16827 if (nextEdits[key] === void 0) { 16828 delete nextEdits[key]; 16829 } 16830 }); 16831 return { 16832 ...state, 16833 [action.recordId]: nextEdits 16834 }; 16835 } 16836 return state; 16837 }, 16838 saving: (state = {}, action) => { 16839 switch (action.type) { 16840 case "SAVE_ENTITY_RECORD_START": 16841 case "SAVE_ENTITY_RECORD_FINISH": 16842 return { 16843 ...state, 16844 [action.recordId]: { 16845 pending: action.type === "SAVE_ENTITY_RECORD_START", 16846 error: action.error, 16847 isAutosave: action.isAutosave 16848 } 16849 }; 16850 } 16851 return state; 16852 }, 16853 deleting: (state = {}, action) => { 16854 switch (action.type) { 16855 case "DELETE_ENTITY_RECORD_START": 16856 case "DELETE_ENTITY_RECORD_FINISH": 16857 return { 16858 ...state, 16859 [action.recordId]: { 16860 pending: action.type === "DELETE_ENTITY_RECORD_START", 16861 error: action.error 16862 } 16863 }; 16864 } 16865 return state; 16866 }, 16867 revisions: (state = {}, action) => { 16868 if (action.type === "RECEIVE_ITEM_REVISIONS") { 16869 const recordKey = action.recordKey; 16870 delete action.recordKey; 16871 const newState = reducer_default(state[recordKey], { 16872 ...action, 16873 type: "RECEIVE_ITEMS" 16874 }); 16875 return { 16876 ...state, 16877 [recordKey]: newState 16878 }; 16879 } 16880 if (action.type === "REMOVE_ITEMS") { 16881 return Object.fromEntries( 16882 Object.entries(state).filter( 16883 ([id2]) => !action.itemIds.some((itemId) => { 16884 if (Number.isInteger(itemId)) { 16885 return itemId === +id2; 16886 } 16887 return itemId === id2; 16888 }) 16889 ) 16890 ); 16891 } 16892 return state; 16893 } 16894 }) 16895 ); 16896 } 16897 function entitiesConfig(state = rootEntitiesConfig, action) { 16898 switch (action.type) { 16899 case "ADD_ENTITIES": 16900 return [...state, ...action.entities]; 16901 } 16902 return state; 16903 } 16904 var entities = (state = {}, action) => { 16905 const newConfig = entitiesConfig(state.config, action); 16906 let entitiesDataReducer = state.reducer; 16907 if (!entitiesDataReducer || newConfig !== state.config) { 16908 const entitiesByKind = newConfig.reduce((acc, record) => { 16909 const { kind } = record; 16910 if (!acc[kind]) { 16911 acc[kind] = []; 16912 } 16913 acc[kind].push(record); 16914 return acc; 16915 }, {}); 16916 entitiesDataReducer = (0, import_data8.combineReducers)( 16917 Object.fromEntries( 16918 Object.entries(entitiesByKind).map( 16919 ([kind, subEntities]) => { 16920 const kindReducer = (0, import_data8.combineReducers)( 16921 Object.fromEntries( 16922 subEntities.map((entityConfig) => [ 16923 entityConfig.name, 16924 entity(entityConfig) 16925 ]) 16926 ) 16927 ); 16928 return [kind, kindReducer]; 16929 } 16930 ) 16931 ) 16932 ); 16933 } 16934 const newData = entitiesDataReducer(state.records, action); 16935 if (newData === state.records && newConfig === state.config && entitiesDataReducer === state.reducer) { 16936 return state; 16937 } 16938 return { 16939 reducer: entitiesDataReducer, 16940 records: newData, 16941 config: newConfig 16942 }; 16943 }; 16944 function undoManager(state = (0, import_undo_manager2.createUndoManager)()) { 16945 return state; 16946 } 16947 function undoManagerReference(state = {}, action) { 16948 switch (action.type) { 16949 case "RECORD_SYNC_UNDO_LEVEL": 16950 return {}; 16951 } 16952 return state; 16953 } 16954 function editsReference(state = {}, action) { 16955 switch (action.type) { 16956 case "EDIT_ENTITY_RECORD": 16957 case "UNDO": 16958 case "REDO": 16959 return {}; 16960 } 16961 return state; 16962 } 16963 function embedPreviews(state = {}, action) { 16964 switch (action.type) { 16965 case "RECEIVE_EMBED_PREVIEW": 16966 const { url, preview } = action; 16967 return { 16968 ...state, 16969 [url]: preview 16970 }; 16971 } 16972 return state; 16973 } 16974 function userPermissions(state = {}, action) { 16975 switch (action.type) { 16976 case "RECEIVE_USER_PERMISSION": 16977 return { 16978 ...state, 16979 [action.key]: action.isAllowed 16980 }; 16981 case "RECEIVE_USER_PERMISSIONS": 16982 return { 16983 ...state, 16984 ...action.permissions 16985 }; 16986 } 16987 return state; 16988 } 16989 function autosaves(state = {}, action) { 16990 switch (action.type) { 16991 case "RECEIVE_AUTOSAVES": 16992 const { postId, autosaves: autosavesData } = action; 16993 return { 16994 ...state, 16995 [postId]: autosavesData 16996 }; 16997 } 16998 return state; 16999 } 17000 function blockPatterns(state = [], action) { 17001 switch (action.type) { 17002 case "RECEIVE_BLOCK_PATTERNS": 17003 return action.patterns; 17004 } 17005 return state; 17006 } 17007 function blockPatternCategories(state = [], action) { 17008 switch (action.type) { 17009 case "RECEIVE_BLOCK_PATTERN_CATEGORIES": 17010 return action.categories; 17011 } 17012 return state; 17013 } 17014 function userPatternCategories(state = [], action) { 17015 switch (action.type) { 17016 case "RECEIVE_USER_PATTERN_CATEGORIES": 17017 return action.patternCategories; 17018 } 17019 return state; 17020 } 17021 function navigationFallbackId(state = null, action) { 17022 switch (action.type) { 17023 case "RECEIVE_NAVIGATION_FALLBACK_ID": 17024 return action.fallbackId; 17025 } 17026 return state; 17027 } 17028 function themeGlobalStyleRevisions(state = {}, action) { 17029 switch (action.type) { 17030 case "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS": 17031 return { 17032 ...state, 17033 [action.currentId]: action.revisions 17034 }; 17035 } 17036 return state; 17037 } 17038 function defaultTemplates(state = {}, action) { 17039 switch (action.type) { 17040 case "RECEIVE_DEFAULT_TEMPLATE": 17041 return { 17042 ...state, 17043 [JSON.stringify(action.query)]: action.templateId 17044 }; 17045 } 17046 return state; 17047 } 17048 function registeredPostMeta(state = {}, action) { 17049 switch (action.type) { 17050 case "RECEIVE_REGISTERED_POST_META": 17051 return { 17052 ...state, 17053 [action.postType]: action.registeredPostMeta 17054 }; 17055 } 17056 return state; 17057 } 17058 function editorSettings(state = null, action) { 17059 switch (action.type) { 17060 case "RECEIVE_EDITOR_SETTINGS": 17061 return action.settings; 17062 } 17063 return state; 17064 } 17065 function editorAssets(state = null, action) { 17066 switch (action.type) { 17067 case "RECEIVE_EDITOR_ASSETS": 17068 return action.assets; 17069 } 17070 return state; 17071 } 17072 function syncConnectionStatuses(state = {}, action) { 17073 switch (action.type) { 17074 case "SET_SYNC_CONNECTION_STATUS": { 17075 const key = `$action.kind}/$action.name}:$action.key}`; 17076 return { 17077 ...state, 17078 [key]: action.status 17079 }; 17080 } 17081 case "CLEAR_SYNC_CONNECTION_STATUS": { 17082 const key = `$action.kind}/$action.name}:$action.key}`; 17083 const { [key]: _, ...rest } = state; 17084 return rest; 17085 } 17086 } 17087 return state; 17088 } 17089 function collaborationSupported(state = true, action) { 17090 switch (action.type) { 17091 case "SET_COLLABORATION_SUPPORTED": 17092 return action.supported; 17093 case "SET_SYNC_CONNECTION_STATUS": 17094 if (ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED === action.status?.error?.code) { 17095 return false; 17096 } 17097 return state; 17098 } 17099 return state; 17100 } 17101 function viewConfigs(state = {}, action) { 17102 switch (action.type) { 17103 case "RECEIVE_VIEW_CONFIG": { 17104 const key = `$action.kind}/$action.name}`; 17105 return { 17106 ...state, 17107 [key]: { 17108 ...state[key], 17109 ...action.config 17110 } 17111 }; 17112 } 17113 } 17114 return state; 17115 } 17116 function fieldsConfigs(state = {}, action) { 17117 switch (action.type) { 17118 case "RECEIVE_FIELDS_CONFIG": 17119 return { 17120 ...state, 17121 [action.kind]: { 17122 ...state[action.kind], 17123 [action.name]: action.config 17124 } 17125 }; 17126 } 17127 return state; 17128 } 17129 function entityActionsConfigs(state = {}, action) { 17130 switch (action.type) { 17131 case "RECEIVE_ENTITY_ACTIONS_CONFIG": 17132 return { 17133 ...state, 17134 [action.kind]: { 17135 ...state[action.kind], 17136 [action.name]: action.config 17137 } 17138 }; 17139 } 17140 return state; 17141 } 17142 var reducer_default2 = (0, import_data8.combineReducers)({ 17143 users, 17144 currentTheme, 17145 currentGlobalStylesId, 17146 currentUser, 17147 themeGlobalStyleVariations, 17148 themeBaseGlobalStyles, 17149 themeGlobalStyleRevisions, 17150 entities, 17151 editsReference, 17152 undoManagerReference, 17153 undoManager, 17154 embedPreviews, 17155 userPermissions, 17156 autosaves, 17157 blockPatterns, 17158 blockPatternCategories, 17159 userPatternCategories, 17160 navigationFallbackId, 17161 defaultTemplates, 17162 registeredPostMeta, 17163 editorSettings, 17164 editorAssets, 17165 syncConnectionStatuses, 17166 collaborationSupported, 17167 viewConfigs, 17168 fieldsConfigs, 17169 entityActionsConfigs 17170 }); 17171 17172 // packages/core-data/build-module/selectors.mjs 17173 var selectors_exports = {}; 17174 __export(selectors_exports, { 17175 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId, 17176 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles, 17177 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations, 17178 __experimentalGetDirtyEntityRecords: () => __experimentalGetDirtyEntityRecords, 17179 __experimentalGetEntitiesBeingSaved: () => __experimentalGetEntitiesBeingSaved, 17180 __experimentalGetEntityRecordNoResolver: () => __experimentalGetEntityRecordNoResolver, 17181 canUser: () => canUser, 17182 canUserEditEntityRecord: () => canUserEditEntityRecord, 17183 getAuthors: () => getAuthors, 17184 getAutosave: () => getAutosave, 17185 getAutosaves: () => getAutosaves, 17186 getBlockPatternCategories: () => getBlockPatternCategories, 17187 getBlockPatterns: () => getBlockPatterns, 17188 getCurrentTheme: () => getCurrentTheme, 17189 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions, 17190 getCurrentUser: () => getCurrentUser, 17191 getDefaultTemplateId: () => getDefaultTemplateId, 17192 getEditedEntityRecord: () => getEditedEntityRecord, 17193 getEmbedPreview: () => getEmbedPreview, 17194 getEntitiesByKind: () => getEntitiesByKind, 17195 getEntitiesConfig: () => getEntitiesConfig, 17196 getEntity: () => getEntity, 17197 getEntityConfig: () => getEntityConfig, 17198 getEntityRecord: () => getEntityRecord, 17199 getEntityRecordEdits: () => getEntityRecordEdits, 17200 getEntityRecordNonTransientEdits: () => getEntityRecordNonTransientEdits, 17201 getEntityRecords: () => getEntityRecords, 17202 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems, 17203 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages, 17204 getLastEntityDeleteError: () => getLastEntityDeleteError, 17205 getLastEntitySaveError: () => getLastEntitySaveError, 17206 getRawEntityRecord: () => getRawEntityRecord, 17207 getRedoEdit: () => getRedoEdit, 17208 getReferenceByDistinctEdits: () => getReferenceByDistinctEdits, 17209 getRevision: () => getRevision, 17210 getRevisions: () => getRevisions, 17211 getThemeSupports: () => getThemeSupports, 17212 getUndoEdit: () => getUndoEdit, 17213 getUserPatternCategories: () => getUserPatternCategories, 17214 getUserQueryResults: () => getUserQueryResults, 17215 hasEditsForEntityRecord: () => hasEditsForEntityRecord, 17216 hasEntityRecord: () => hasEntityRecord, 17217 hasEntityRecords: () => hasEntityRecords, 17218 hasFetchedAutosaves: () => hasFetchedAutosaves, 17219 hasRedo: () => hasRedo, 17220 hasRevision: () => hasRevision, 17221 hasUndo: () => hasUndo, 17222 isAutosavingEntityRecord: () => isAutosavingEntityRecord, 17223 isDeletingEntityRecord: () => isDeletingEntityRecord, 17224 isPreviewEmbedFallback: () => isPreviewEmbedFallback, 17225 isRequestingEmbedPreview: () => isRequestingEmbedPreview, 17226 isSavingEntityRecord: () => isSavingEntityRecord 17227 }); 17228 var import_data10 = __toESM(require_data(), 1); 17229 var import_url2 = __toESM(require_url(), 1); 17230 var import_deprecated2 = __toESM(require_deprecated(), 1); 17231 17232 // packages/core-data/build-module/private-selectors.mjs 17233 var private_selectors_exports = {}; 17234 __export(private_selectors_exports, { 17235 getBlockPatternsForPostType: () => getBlockPatternsForPostType, 17236 getEditorAssets: () => getEditorAssets, 17237 getEditorSettings: () => getEditorSettings, 17238 getEntityActionsConfig: () => getEntityActionsConfig, 17239 getEntityRecordPermissions: () => getEntityRecordPermissions, 17240 getEntityRecordsPermissions: () => getEntityRecordsPermissions, 17241 getEntitySyncConnectionStatus: () => getEntitySyncConnectionStatus, 17242 getFieldsConfig: () => getFieldsConfig, 17243 getHomePage: () => getHomePage, 17244 getNavigationFallbackId: () => getNavigationFallbackId, 17245 getPostsPageId: () => getPostsPageId, 17246 getRegisteredPostMeta: () => getRegisteredPostMeta, 17247 getSyncConnectionStatus: () => getSyncConnectionStatus, 17248 getTemplateId: () => getTemplateId, 17249 getUndoManager: () => getUndoManager, 17250 getViewConfig: () => getViewConfig, 17251 isCollaborationSupported: () => isCollaborationSupported 17252 }); 17253 var import_data9 = __toESM(require_data(), 1); 17254 17255 // packages/core-data/build-module/utils/log-entity-deprecation.mjs 17256 var import_deprecated = __toESM(require_deprecated(), 1); 17257 var loggedAlready = false; 17258 function logEntityDeprecation(kind, name, functionName, { 17259 alternativeFunctionName, 17260 isShorthandSelector = false 17261 } = {}) { 17262 const deprecation = deprecatedEntities[kind]?.[name]; 17263 if (!deprecation) { 17264 return; 17265 } 17266 if (!loggedAlready) { 17267 const { alternative } = deprecation; 17268 const message = isShorthandSelector ? `'$functionName}'` : `The '$kind}', '$name}' entity (used via '$functionName}')`; 17269 let alternativeMessage = `the '$alternative.kind}', '$alternative.name}' entity`; 17270 if (alternativeFunctionName) { 17271 alternativeMessage += ` via the '$alternativeFunctionName}' function`; 17272 } 17273 (0, import_deprecated.default)(message, { 17274 ...deprecation, 17275 alternative: alternativeMessage 17276 }); 17277 } 17278 loggedAlready = true; 17279 setTimeout(() => { 17280 loggedAlready = false; 17281 }, 0); 17282 } 17283 17284 // packages/core-data/build-module/private-selectors.mjs 17285 var EMPTY_OBJECT = {}; 17286 function getUndoManager(state) { 17287 return state.undoManager; 17288 } 17289 function getNavigationFallbackId(state) { 17290 return state.navigationFallbackId; 17291 } 17292 var getBlockPatternsForPostType = (0, import_data9.createRegistrySelector)( 17293 (select6) => (0, import_data9.createSelector)( 17294 (state, postType) => select6(STORE_NAME).getBlockPatterns().filter( 17295 ({ postTypes }) => !postTypes || Array.isArray(postTypes) && postTypes.includes(postType) 17296 ), 17297 () => [select6(STORE_NAME).getBlockPatterns()] 17298 ) 17299 ); 17300 var getEntityRecordsPermissions = (0, import_data9.createRegistrySelector)( 17301 (select6) => (0, import_data9.createSelector)( 17302 (state, kind, name, ids) => { 17303 const normalizedIds = Array.isArray(ids) ? ids : [ids]; 17304 return normalizedIds.map((id2) => ({ 17305 delete: select6(STORE_NAME).canUser("delete", { 17306 kind, 17307 name, 17308 id: id2 17309 }), 17310 update: select6(STORE_NAME).canUser("update", { 17311 kind, 17312 name, 17313 id: id2 17314 }) 17315 })); 17316 }, 17317 (state) => [state.userPermissions] 17318 ) 17319 ); 17320 function getEntityRecordPermissions(state, kind, name, id2) { 17321 logEntityDeprecation(kind, name, "getEntityRecordPermissions"); 17322 return getEntityRecordsPermissions(state, kind, name, id2)[0]; 17323 } 17324 function getRegisteredPostMeta(state, postType) { 17325 return state.registeredPostMeta?.[postType] ?? {}; 17326 } 17327 function normalizePageId(value) { 17328 if (!value || !["number", "string"].includes(typeof value)) { 17329 return null; 17330 } 17331 if (Number(value) === 0) { 17332 return null; 17333 } 17334 return value.toString(); 17335 } 17336 var getHomePage = (0, import_data9.createRegistrySelector)( 17337 (select6) => (0, import_data9.createSelector)( 17338 () => { 17339 const siteData = select6(STORE_NAME).getEntityRecord( 17340 "root", 17341 "__unstableBase" 17342 ); 17343 if (!siteData) { 17344 return null; 17345 } 17346 const homepageId = siteData?.show_on_front === "page" ? normalizePageId(siteData.page_on_front) : null; 17347 if (homepageId) { 17348 return { postType: "page", postId: homepageId }; 17349 } 17350 const frontPageTemplateId = select6( 17351 STORE_NAME 17352 ).getDefaultTemplateId({ 17353 slug: "front-page" 17354 }); 17355 if (frontPageTemplateId) { 17356 return { 17357 postType: "wp_template", 17358 postId: frontPageTemplateId 17359 }; 17360 } 17361 if (frontPageTemplateId === "") { 17362 return EMPTY_OBJECT; 17363 } 17364 return null; 17365 }, 17366 (state) => [ 17367 // Even though getDefaultTemplateId.shouldInvalidate returns true when root/site changes, 17368 // it doesn't seem to invalidate this cache, I'm not sure why. 17369 getEntityRecord(state, "root", "site"), 17370 getEntityRecord(state, "root", "__unstableBase"), 17371 getDefaultTemplateId(state, { 17372 slug: "front-page" 17373 }) 17374 ] 17375 ) 17376 ); 17377 var getPostsPageId = (0, import_data9.createRegistrySelector)((select6) => () => { 17378 const siteData = select6(STORE_NAME).getEntityRecord( 17379 "root", 17380 "__unstableBase" 17381 ); 17382 return siteData?.show_on_front === "page" ? normalizePageId(siteData.page_for_posts) : null; 17383 }); 17384 var getTemplateId = (0, import_data9.createRegistrySelector)( 17385 (select6) => (state, postType, postId) => { 17386 const homepage = unlock(select6(STORE_NAME)).getHomePage(); 17387 if (!homepage) { 17388 return; 17389 } 17390 if (postType === "page" && postType === homepage?.postType && postId.toString() === homepage?.postId) { 17391 const templates = select6(STORE_NAME).getEntityRecords( 17392 "postType", 17393 "wp_template", 17394 { 17395 per_page: -1 17396 } 17397 ); 17398 if (!templates) { 17399 return; 17400 } 17401 const id2 = templates.find( 17402 ({ slug }) => slug === "front-page" 17403 )?.id; 17404 if (id2) { 17405 return id2; 17406 } 17407 } 17408 const editedEntity = select6(STORE_NAME).getEditedEntityRecord( 17409 "postType", 17410 postType, 17411 postId 17412 ); 17413 if (!editedEntity) { 17414 return; 17415 } 17416 const postsPageId = unlock(select6(STORE_NAME)).getPostsPageId(); 17417 if (postType === "page" && postsPageId === postId.toString()) { 17418 return select6(STORE_NAME).getDefaultTemplateId({ 17419 slug: "home" 17420 }); 17421 } 17422 const currentTemplateSlug = editedEntity.template; 17423 if (currentTemplateSlug) { 17424 const currentTemplate = select6(STORE_NAME).getEntityRecords("postType", "wp_template", { 17425 per_page: -1 17426 })?.find(({ slug }) => slug === currentTemplateSlug); 17427 if (currentTemplate) { 17428 return currentTemplate.id; 17429 } 17430 } 17431 let slugToCheck; 17432 if (editedEntity.slug) { 17433 slugToCheck = postType === "page" ? `$postType}-$editedEntity.slug}` : `single-$postType}-$editedEntity.slug}`; 17434 } else { 17435 slugToCheck = postType === "page" ? "page" : `single-$postType}`; 17436 } 17437 return select6(STORE_NAME).getDefaultTemplateId({ 17438 slug: slugToCheck 17439 }); 17440 } 17441 ); 17442 function getEditorSettings(state) { 17443 return state.editorSettings; 17444 } 17445 function getEditorAssets(state) { 17446 return state.editorAssets; 17447 } 17448 function isCollaborationSupported(state) { 17449 return state.collaborationSupported; 17450 } 17451 function getViewConfig(state, kind, name) { 17452 return state.viewConfigs?.[`$kind}/$name}`] ?? { 17453 default_view: void 0, 17454 default_layouts: void 0, 17455 view_list: void 0, 17456 form: void 0 17457 }; 17458 } 17459 function getFieldsConfig(state, kind, name) { 17460 return state.fieldsConfigs?.[kind]?.[name]; 17461 } 17462 function getEntityActionsConfig(state, kind, name) { 17463 return state.entityActionsConfigs?.[kind]?.[name]; 17464 } 17465 function getSyncConnectionStatus(state) { 17466 if (!state.syncConnectionStatuses) { 17467 return void 0; 17468 } 17469 const PRIORITIZED_STATUSES = ["disconnected", "connecting", "connected"]; 17470 let coalesced; 17471 for (const status of Object.values(state.syncConnectionStatuses)) { 17472 if (!coalesced || PRIORITIZED_STATUSES.indexOf(status.status) < PRIORITIZED_STATUSES.indexOf(coalesced.status)) { 17473 coalesced = status; 17474 } 17475 } 17476 return coalesced; 17477 } 17478 function getEntitySyncConnectionStatus(state, kind, name, recordId) { 17479 return state.syncConnectionStatuses?.[`$kind}/$name}:$recordId}`]; 17480 } 17481 17482 // packages/core-data/build-module/selectors.mjs 17483 var EMPTY_OBJECT2 = {}; 17484 var isRequestingEmbedPreview = (0, import_data10.createRegistrySelector)( 17485 (select6) => (state, url) => { 17486 return select6(STORE_NAME).isResolving("getEmbedPreview", [ 17487 url 17488 ]); 17489 } 17490 ); 17491 function getAuthors(state, query) { 17492 (0, import_deprecated2.default)("select( 'core' ).getAuthors()", { 17493 since: "5.9", 17494 alternative: "select( 'core' ).getUsers({ who: 'authors' })" 17495 }); 17496 const path = (0, import_url2.addQueryArgs)( 17497 "/wp/v2/users/?who=authors&per_page=100", 17498 query 17499 ); 17500 return getUserQueryResults(state, path); 17501 } 17502 function getCurrentUser(state) { 17503 return state.currentUser; 17504 } 17505 var getUserQueryResults = (0, import_data10.createSelector)( 17506 (state, queryID) => { 17507 const queryResults = state.users.queries[queryID] ?? []; 17508 return queryResults.map((id2) => state.users.byId[id2]); 17509 }, 17510 (state, queryID) => [ 17511 state.users.queries[queryID], 17512 state.users.byId 17513 ] 17514 ); 17515 function getEntitiesByKind(state, kind) { 17516 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntitiesByKind()", { 17517 since: "6.0", 17518 alternative: "wp.data.select( 'core' ).getEntitiesConfig()" 17519 }); 17520 return getEntitiesConfig(state, kind); 17521 } 17522 var getEntitiesConfig = (0, import_data10.createSelector)( 17523 (state, kind) => state.entities.config.filter((entity2) => entity2.kind === kind), 17524 /* eslint-disable @typescript-eslint/no-unused-vars */ 17525 (state, kind) => state.entities.config 17526 /* eslint-enable @typescript-eslint/no-unused-vars */ 17527 ); 17528 function getEntity(state, kind, name) { 17529 (0, import_deprecated2.default)("wp.data.select( 'core' ).getEntity()", { 17530 since: "6.0", 17531 alternative: "wp.data.select( 'core' ).getEntityConfig()" 17532 }); 17533 return getEntityConfig(state, kind, name); 17534 } 17535 function getEntityConfig(state, kind, name) { 17536 logEntityDeprecation(kind, name, "getEntityConfig"); 17537 return state.entities.config?.find( 17538 (config) => config.kind === kind && config.name === name 17539 ); 17540 } 17541 var getEntityRecord = ((state, kind, name, recordId, query) => { 17542 logEntityDeprecation(kind, name, "getEntityRecord"); 17543 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 17544 if (!queriedState) { 17545 return void 0; 17546 } 17547 const context = query?.context ?? "default"; 17548 if (!query || !query._fields) { 17549 if (!queriedState.itemIsComplete[context]?.[recordId]) { 17550 return void 0; 17551 } 17552 return queriedState.items[context][recordId]; 17553 } 17554 const item = queriedState.items[context]?.[recordId]; 17555 if (!item) { 17556 return item; 17557 } 17558 return getFilteredItem(item, query._fields); 17559 }); 17560 getEntityRecord.normalizeArgs = (args2) => { 17561 const newArgs = [...args2]; 17562 const recordKey = newArgs?.[2]; 17563 newArgs[2] = isNumericID(recordKey) ? Number(recordKey) : recordKey; 17564 return newArgs; 17565 }; 17566 function hasEntityRecord(state, kind, name, recordId, query) { 17567 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 17568 if (!queriedState) { 17569 return false; 17570 } 17571 const context = query?.context ?? "default"; 17572 if (!query || !query._fields) { 17573 return !!queriedState.itemIsComplete[context]?.[recordId]; 17574 } 17575 const item = queriedState.items[context]?.[recordId]; 17576 if (!item) { 17577 return false; 17578 } 17579 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 17580 for (let i = 0; i < fields.length; i++) { 17581 const path = fields[i].split("."); 17582 let value = item; 17583 for (let p = 0; p < path.length; p++) { 17584 const part = path[p]; 17585 if (!value || !Object.hasOwn(value, part)) { 17586 return false; 17587 } 17588 value = value[part]; 17589 } 17590 } 17591 return true; 17592 } 17593 function __experimentalGetEntityRecordNoResolver(state, kind, name, recordId) { 17594 return getEntityRecord(state, kind, name, recordId); 17595 } 17596 var getRawEntityRecord = (0, import_data10.createSelector)( 17597 (state, kind, name, recordId) => { 17598 logEntityDeprecation(kind, name, "getRawEntityRecord"); 17599 const record = getEntityRecord( 17600 state, 17601 kind, 17602 name, 17603 recordId 17604 ); 17605 const config = getEntityConfig(state, kind, name); 17606 if (!record || !config?.rawAttributes?.length) { 17607 return record; 17608 } 17609 return Object.fromEntries( 17610 Object.keys(record).map((key) => { 17611 if (config.rawAttributes.includes(key)) { 17612 const rawValue = record[key]?.raw; 17613 return [ 17614 key, 17615 rawValue !== void 0 ? rawValue : record[key] 17616 ]; 17617 } 17618 return [key, record[key]]; 17619 }) 17620 ); 17621 }, 17622 (state, kind, name, recordId, query) => { 17623 const context = query?.context ?? "default"; 17624 return [ 17625 state.entities.config, 17626 state.entities.records?.[kind]?.[name]?.queriedData?.items[context]?.[recordId], 17627 state.entities.records?.[kind]?.[name]?.queriedData?.itemIsComplete[context]?.[recordId] 17628 ]; 17629 } 17630 ); 17631 function hasEntityRecords(state, kind, name, query) { 17632 logEntityDeprecation(kind, name, "hasEntityRecords"); 17633 return Array.isArray(getEntityRecords(state, kind, name, query)); 17634 } 17635 var getEntityRecords = ((state, kind, name, query) => { 17636 logEntityDeprecation(kind, name, "getEntityRecords"); 17637 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 17638 if (!queriedState) { 17639 return null; 17640 } 17641 return getQueriedItems(queriedState, query, { 17642 supportsPagination: !!getEntityConfig(state, kind, name)?.supportsPagination 17643 }); 17644 }); 17645 var getEntityRecordsTotalItems = (state, kind, name, query) => { 17646 logEntityDeprecation(kind, name, "getEntityRecordsTotalItems"); 17647 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 17648 if (!queriedState) { 17649 return null; 17650 } 17651 return getQueriedTotalItems(queriedState, query); 17652 }; 17653 var getEntityRecordsTotalPages = (state, kind, name, query) => { 17654 logEntityDeprecation(kind, name, "getEntityRecordsTotalPages"); 17655 const queriedState = state.entities.records?.[kind]?.[name]?.queriedData; 17656 if (!queriedState) { 17657 return null; 17658 } 17659 if (!getEntityConfig(state, kind, name)?.supportsPagination || query?.per_page === -1) { 17660 return 1; 17661 } 17662 const totalItems = getQueriedTotalItems(queriedState, query); 17663 if (!totalItems) { 17664 return totalItems; 17665 } 17666 if (!query?.per_page) { 17667 return getQueriedTotalPages(queriedState, query); 17668 } 17669 return Math.ceil(totalItems / query.per_page); 17670 }; 17671 var __experimentalGetDirtyEntityRecords = (0, import_data10.createSelector)( 17672 (state) => { 17673 const { 17674 entities: { records } 17675 } = state; 17676 const dirtyRecords = []; 17677 Object.keys(records).forEach((kind) => { 17678 Object.keys(records[kind]).forEach((name) => { 17679 const primaryKeys = Object.keys(records[kind][name].edits).filter( 17680 (primaryKey) => ( 17681 // The entity record must exist (not be deleted), 17682 // and it must have edits. 17683 getEntityRecord(state, kind, name, primaryKey) && hasEditsForEntityRecord(state, kind, name, primaryKey) 17684 ) 17685 ); 17686 if (primaryKeys.length) { 17687 const entityConfig = getEntityConfig(state, kind, name); 17688 primaryKeys.forEach((primaryKey) => { 17689 const entityRecord = getEditedEntityRecord( 17690 state, 17691 kind, 17692 name, 17693 primaryKey 17694 ); 17695 dirtyRecords.push({ 17696 // We avoid using primaryKey because it's transformed into a string 17697 // when it's used as an object key. 17698 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 17699 title: entityConfig?.getTitle?.(entityRecord) || "", 17700 name, 17701 kind 17702 }); 17703 }); 17704 } 17705 }); 17706 }); 17707 return dirtyRecords; 17708 }, 17709 (state) => [state.entities.records] 17710 ); 17711 var __experimentalGetEntitiesBeingSaved = (0, import_data10.createSelector)( 17712 (state) => { 17713 const { 17714 entities: { records } 17715 } = state; 17716 const recordsBeingSaved = []; 17717 Object.keys(records).forEach((kind) => { 17718 Object.keys(records[kind]).forEach((name) => { 17719 const primaryKeys = Object.keys(records[kind][name].saving).filter( 17720 (primaryKey) => isSavingEntityRecord(state, kind, name, primaryKey) 17721 ); 17722 if (primaryKeys.length) { 17723 const entityConfig = getEntityConfig(state, kind, name); 17724 primaryKeys.forEach((primaryKey) => { 17725 const entityRecord = getEditedEntityRecord( 17726 state, 17727 kind, 17728 name, 17729 primaryKey 17730 ); 17731 recordsBeingSaved.push({ 17732 // We avoid using primaryKey because it's transformed into a string 17733 // when it's used as an object key. 17734 key: entityRecord ? entityRecord[entityConfig.key || DEFAULT_ENTITY_KEY] : void 0, 17735 title: entityConfig?.getTitle?.(entityRecord) || "", 17736 name, 17737 kind 17738 }); 17739 }); 17740 } 17741 }); 17742 }); 17743 return recordsBeingSaved; 17744 }, 17745 (state) => [state.entities.records] 17746 ); 17747 function getEntityRecordEdits(state, kind, name, recordId) { 17748 logEntityDeprecation(kind, name, "getEntityRecordEdits"); 17749 return state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)]; 17750 } 17751 var getEntityRecordNonTransientEdits = (0, import_data10.createSelector)( 17752 (state, kind, name, recordId) => { 17753 logEntityDeprecation(kind, name, "getEntityRecordNonTransientEdits"); 17754 const { transientEdits } = getEntityConfig(state, kind, name) || {}; 17755 const edits = getEntityRecordEdits(state, kind, name, recordId) || {}; 17756 if (!transientEdits) { 17757 return edits; 17758 } 17759 return Object.keys(edits).reduce((acc, key) => { 17760 if (!transientEdits[key]) { 17761 acc[key] = edits[key]; 17762 } 17763 return acc; 17764 }, {}); 17765 }, 17766 (state, kind, name, recordId) => [ 17767 state.entities.config, 17768 state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)] 17769 ] 17770 ); 17771 function hasEditsForEntityRecord(state, kind, name, recordId) { 17772 logEntityDeprecation(kind, name, "hasEditsForEntityRecord"); 17773 return isSavingEntityRecord(state, kind, name, recordId) || Object.keys( 17774 getEntityRecordNonTransientEdits(state, kind, name, recordId) 17775 ).length > 0; 17776 } 17777 var getEditedEntityRecord = (0, import_data10.createSelector)( 17778 (state, kind, name, recordId) => { 17779 logEntityDeprecation(kind, name, "getEditedEntityRecord"); 17780 const raw = getRawEntityRecord(state, kind, name, recordId); 17781 const edited = getEntityRecordEdits(state, kind, name, recordId); 17782 if (!raw && !edited) { 17783 return false; 17784 } 17785 return { 17786 ...raw, 17787 ...edited 17788 }; 17789 }, 17790 (state, kind, name, recordId, query) => { 17791 const context = query?.context ?? "default"; 17792 return [ 17793 state.entities.config, 17794 state.entities.records?.[kind]?.[name]?.queriedData.items[context]?.[recordId], 17795 state.entities.records?.[kind]?.[name]?.queriedData.itemIsComplete[context]?.[recordId], 17796 state.entities.records?.[kind]?.[name]?.edits?.[String(recordId)] 17797 ]; 17798 } 17799 ); 17800 function isAutosavingEntityRecord(state, kind, name, recordId) { 17801 logEntityDeprecation(kind, name, "isAutosavingEntityRecord"); 17802 const { pending, isAutosave } = state.entities.records?.[kind]?.[name]?.saving?.[recordId] ?? {}; 17803 return Boolean(pending && isAutosave); 17804 } 17805 function isSavingEntityRecord(state, kind, name, recordId) { 17806 logEntityDeprecation(kind, name, "isSavingEntityRecord"); 17807 return state.entities.records?.[kind]?.[name]?.saving?.[String(recordId)]?.pending ?? false; 17808 } 17809 function isDeletingEntityRecord(state, kind, name, recordId) { 17810 logEntityDeprecation(kind, name, "isDeletingEntityRecord"); 17811 return state.entities.records?.[kind]?.[name]?.deleting?.[String(recordId)]?.pending ?? false; 17812 } 17813 function getLastEntitySaveError(state, kind, name, recordId) { 17814 logEntityDeprecation(kind, name, "getLastEntitySaveError"); 17815 return state.entities.records?.[kind]?.[name]?.saving?.[String(recordId)]?.error; 17816 } 17817 function getLastEntityDeleteError(state, kind, name, recordId) { 17818 logEntityDeprecation(kind, name, "getLastEntityDeleteError"); 17819 return state.entities.records?.[kind]?.[name]?.deleting?.[recordId]?.error; 17820 } 17821 function getUndoEdit(state) { 17822 (0, import_deprecated2.default)("select( 'core' ).getUndoEdit()", { 17823 since: "6.3" 17824 }); 17825 return void 0; 17826 } 17827 function getRedoEdit(state) { 17828 (0, import_deprecated2.default)("select( 'core' ).getRedoEdit()", { 17829 since: "6.3" 17830 }); 17831 return void 0; 17832 } 17833 function hasUndo(state) { 17834 return getUndoManager(state).hasUndo(); 17835 } 17836 function hasRedo(state) { 17837 return getUndoManager(state).hasRedo(); 17838 } 17839 function getCurrentTheme(state) { 17840 if (!state.currentTheme) { 17841 return null; 17842 } 17843 return getEntityRecord(state, "root", "theme", state.currentTheme); 17844 } 17845 function __experimentalGetCurrentGlobalStylesId(state) { 17846 return state.currentGlobalStylesId; 17847 } 17848 function getThemeSupports(state) { 17849 return getCurrentTheme(state)?.theme_supports ?? EMPTY_OBJECT2; 17850 } 17851 function getEmbedPreview(state, url) { 17852 return state.embedPreviews[url]; 17853 } 17854 function isPreviewEmbedFallback(state, url) { 17855 const preview = state.embedPreviews[url]; 17856 const oEmbedLinkCheck = '<a href="' + url + '">' + url + "</a>"; 17857 if (!preview) { 17858 return false; 17859 } 17860 return preview.html === oEmbedLinkCheck; 17861 } 17862 function canUser(state, action, resource, id2) { 17863 const isEntity = typeof resource === "object"; 17864 if (isEntity && (!resource.kind || !resource.name)) { 17865 return false; 17866 } 17867 if (isEntity) { 17868 logEntityDeprecation(resource.kind, resource.name, "canUser"); 17869 } 17870 const key = getUserPermissionCacheKey(action, resource, id2); 17871 return state.userPermissions[key]; 17872 } 17873 function canUserEditEntityRecord(state, kind, name, recordId) { 17874 (0, import_deprecated2.default)(`wp.data.select( 'core' ).canUserEditEntityRecord()`, { 17875 since: "6.7", 17876 alternative: `wp.data.select( 'core' ).canUser( 'update', { kind, name, id } )` 17877 }); 17878 return canUser(state, "update", { kind, name, id: recordId }); 17879 } 17880 function getAutosaves(state, postType, postId) { 17881 return state.autosaves[postId]; 17882 } 17883 function getAutosave(state, postType, postId, authorId) { 17884 if (authorId === void 0) { 17885 return; 17886 } 17887 const autosaves2 = state.autosaves[postId]; 17888 return autosaves2?.find( 17889 (autosave) => autosave.author === authorId 17890 ); 17891 } 17892 var hasFetchedAutosaves = (0, import_data10.createRegistrySelector)( 17893 (select6) => (state, postType, postId) => { 17894 return select6(STORE_NAME).hasFinishedResolution("getAutosaves", [ 17895 postType, 17896 postId 17897 ]); 17898 } 17899 ); 17900 function getReferenceByDistinctEdits(state) { 17901 return state.editsReference; 17902 } 17903 function __experimentalGetCurrentThemeBaseGlobalStyles(state) { 17904 const currentTheme2 = getCurrentTheme(state); 17905 if (!currentTheme2) { 17906 return null; 17907 } 17908 return state.themeBaseGlobalStyles[currentTheme2.stylesheet]; 17909 } 17910 function __experimentalGetCurrentThemeGlobalStylesVariations(state) { 17911 const currentTheme2 = getCurrentTheme(state); 17912 if (!currentTheme2) { 17913 return null; 17914 } 17915 return state.themeGlobalStyleVariations[currentTheme2.stylesheet]; 17916 } 17917 function getBlockPatterns(state) { 17918 return state.blockPatterns; 17919 } 17920 function getBlockPatternCategories(state) { 17921 return state.blockPatternCategories; 17922 } 17923 function getUserPatternCategories(state) { 17924 return state.userPatternCategories; 17925 } 17926 function getCurrentThemeGlobalStylesRevisions(state) { 17927 (0, import_deprecated2.default)("select( 'core' ).getCurrentThemeGlobalStylesRevisions()", { 17928 since: "6.5.0", 17929 alternative: "select( 'core' ).getRevisions( 'root', 'globalStyles', ${ recordKey } )" 17930 }); 17931 const currentGlobalStylesId2 = __experimentalGetCurrentGlobalStylesId(state); 17932 if (!currentGlobalStylesId2) { 17933 return null; 17934 } 17935 return state.themeGlobalStyleRevisions[currentGlobalStylesId2]; 17936 } 17937 function getDefaultTemplateId(state, query) { 17938 return state.defaultTemplates[JSON.stringify(query)]; 17939 } 17940 var getRevisions = (state, kind, name, recordKey, query) => { 17941 logEntityDeprecation(kind, name, "getRevisions"); 17942 const queriedStateRevisions = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 17943 if (!queriedStateRevisions) { 17944 return null; 17945 } 17946 return getQueriedItems(queriedStateRevisions, query); 17947 }; 17948 function hasRevision(state, kind, name, recordKey, revisionKey, query) { 17949 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 17950 if (!queriedState) { 17951 return false; 17952 } 17953 const context = query?.context ?? "default"; 17954 if (!query || !query._fields) { 17955 return !!queriedState.itemIsComplete[context]?.[revisionKey]; 17956 } 17957 const item = queriedState.items[context]?.[revisionKey]; 17958 if (!item) { 17959 return false; 17960 } 17961 const fields = get_normalized_comma_separable_default(query._fields) ?? []; 17962 for (let i = 0; i < fields.length; i++) { 17963 const path = fields[i].split("."); 17964 let value = item; 17965 for (let p = 0; p < path.length; p++) { 17966 const part = path[p]; 17967 if (!value || !Object.hasOwn(value, part)) { 17968 return false; 17969 } 17970 value = value[part]; 17971 } 17972 } 17973 return true; 17974 } 17975 var getRevision = (state, kind, name, recordKey, revisionKey, query) => { 17976 logEntityDeprecation(kind, name, "getRevision"); 17977 const queriedState = state.entities.records?.[kind]?.[name]?.revisions?.[recordKey]; 17978 if (!queriedState) { 17979 return void 0; 17980 } 17981 const context = query?.context ?? "default"; 17982 if (!query || !query._fields) { 17983 if (!queriedState.itemIsComplete[context]?.[revisionKey]) { 17984 return void 0; 17985 } 17986 return queriedState.items[context][revisionKey]; 17987 } 17988 const item = queriedState.items[context]?.[revisionKey]; 17989 if (!item) { 17990 return item; 17991 } 17992 return getFilteredItem(item, query._fields); 17993 }; 17994 17995 // packages/core-data/build-module/actions.mjs 17996 var actions_exports = {}; 17997 __export(actions_exports, { 17998 __experimentalBatch: () => __experimentalBatch, 17999 __experimentalReceiveCurrentGlobalStylesId: () => __experimentalReceiveCurrentGlobalStylesId, 18000 __experimentalReceiveThemeBaseGlobalStyles: () => __experimentalReceiveThemeBaseGlobalStyles, 18001 __experimentalReceiveThemeGlobalStyleVariations: () => __experimentalReceiveThemeGlobalStyleVariations, 18002 __experimentalSaveSpecifiedEntityEdits: () => __experimentalSaveSpecifiedEntityEdits, 18003 __unstableCreateUndoLevel: () => __unstableCreateUndoLevel, 18004 addEntities: () => addEntities, 18005 clearEntityRecordEdits: () => clearEntityRecordEdits, 18006 deleteEntityRecord: () => deleteEntityRecord, 18007 editEntityRecord: () => editEntityRecord, 18008 receiveAutosaves: () => receiveAutosaves, 18009 receiveCurrentTheme: () => receiveCurrentTheme, 18010 receiveCurrentUser: () => receiveCurrentUser, 18011 receiveDefaultTemplateId: () => receiveDefaultTemplateId, 18012 receiveEmbedPreview: () => receiveEmbedPreview, 18013 receiveEntityRecords: () => receiveEntityRecords, 18014 receiveNavigationFallbackId: () => receiveNavigationFallbackId, 18015 receiveRevisions: () => receiveRevisions, 18016 receiveThemeGlobalStyleRevisions: () => receiveThemeGlobalStyleRevisions, 18017 receiveThemeSupports: () => receiveThemeSupports, 18018 receiveUploadPermissions: () => receiveUploadPermissions, 18019 receiveUserPermission: () => receiveUserPermission, 18020 receiveUserPermissions: () => receiveUserPermissions, 18021 receiveUserQuery: () => receiveUserQuery, 18022 redo: () => redo, 18023 saveEditedEntityRecord: () => saveEditedEntityRecord, 18024 saveEntityRecord: () => saveEntityRecord, 18025 undo: () => undo 18026 }); 18027 var import_api_fetch5 = __toESM(require_api_fetch(), 1); 18028 var import_url3 = __toESM(require_url(), 1); 18029 var import_deprecated3 = __toESM(require_deprecated(), 1); 18030 18031 // packages/core-data/build-module/batch/default-processor.mjs 18032 var import_api_fetch4 = __toESM(require_api_fetch(), 1); 18033 var maxItems = null; 18034 function chunk(arr, chunkSize) { 18035 const tmp = [...arr]; 18036 const cache3 = []; 18037 while (tmp.length) { 18038 cache3.push(tmp.splice(0, chunkSize)); 18039 } 18040 return cache3; 18041 } 18042 async function defaultProcessor(requests) { 18043 if (maxItems === null) { 18044 const preflightResponse = await (0, import_api_fetch4.default)({ 18045 path: "/batch/v1", 18046 method: "OPTIONS" 18047 }); 18048 maxItems = preflightResponse.endpoints[0].args.requests.maxItems; 18049 } 18050 const results = []; 18051 for (const batchRequests of chunk(requests, maxItems)) { 18052 const batchResponse = await (0, import_api_fetch4.default)({ 18053 path: "/batch/v1", 18054 method: "POST", 18055 data: { 18056 validation: "require-all-validate", 18057 requests: batchRequests.map((request) => ({ 18058 path: request.path, 18059 body: request.data, 18060 // Rename 'data' to 'body'. 18061 method: request.method, 18062 headers: request.headers 18063 })) 18064 } 18065 }); 18066 let batchResults; 18067 if (batchResponse.failed) { 18068 batchResults = batchResponse.responses.map((response) => ({ 18069 error: response?.body 18070 })); 18071 } else { 18072 batchResults = batchResponse.responses.map((response) => { 18073 const result = {}; 18074 if (response.status >= 200 && response.status < 300) { 18075 result.output = response.body; 18076 } else { 18077 result.error = response.body; 18078 } 18079 return result; 18080 }); 18081 } 18082 results.push(...batchResults); 18083 } 18084 return results; 18085 } 18086 18087 // packages/core-data/build-module/batch/create-batch.mjs 18088 function createBatch(processor = defaultProcessor) { 18089 let lastId = 0; 18090 let queue = []; 18091 const pending = new ObservableSet(); 18092 return { 18093 /** 18094 * Adds an input to the batch and returns a promise that is resolved or 18095 * rejected when the input is processed by `batch.run()`. 18096 * 18097 * You may also pass a thunk which allows inputs to be added 18098 * asynchronously. 18099 * 18100 * ``` 18101 * // Both are allowed: 18102 * batch.add( { path: '/v1/books', ... } ); 18103 * batch.add( ( add ) => add( { path: '/v1/books', ... } ) ); 18104 * ``` 18105 * 18106 * If a thunk is passed, `batch.run()` will pause until either: 18107 * 18108 * - The thunk calls its `add` argument, or; 18109 * - The thunk returns a promise and that promise resolves, or; 18110 * - The thunk returns a non-promise. 18111 * 18112 * @param {any|Function} inputOrThunk Input to add or thunk to execute. 18113 * 18114 * @return {Promise|any} If given an input, returns a promise that 18115 * is resolved or rejected when the batch is 18116 * processed. If given a thunk, returns the return 18117 * value of that thunk. 18118 */ 18119 add(inputOrThunk) { 18120 const id2 = ++lastId; 18121 pending.add(id2); 18122 const add = (input) => new Promise((resolve, reject) => { 18123 queue.push({ 18124 input, 18125 resolve, 18126 reject 18127 }); 18128 pending.delete(id2); 18129 }); 18130 if (typeof inputOrThunk === "function") { 18131 return Promise.resolve(inputOrThunk(add)).finally(() => { 18132 pending.delete(id2); 18133 }); 18134 } 18135 return add(inputOrThunk); 18136 }, 18137 /** 18138 * Runs the batch. This calls `batchProcessor` and resolves or rejects 18139 * all promises returned by `add()`. 18140 * 18141 * @return {Promise<boolean>} A promise that resolves to a boolean that is true 18142 * if the processor returned no errors. 18143 */ 18144 async run() { 18145 if (pending.size) { 18146 await new Promise((resolve) => { 18147 const unsubscribe = pending.subscribe(() => { 18148 if (!pending.size) { 18149 unsubscribe(); 18150 resolve(void 0); 18151 } 18152 }); 18153 }); 18154 } 18155 let results; 18156 try { 18157 results = await processor( 18158 queue.map(({ input }) => input) 18159 ); 18160 if (results.length !== queue.length) { 18161 throw new Error( 18162 "run: Array returned by processor must be same size as input array." 18163 ); 18164 } 18165 } catch (error) { 18166 for (const { reject } of queue) { 18167 reject(error); 18168 } 18169 throw error; 18170 } 18171 let isSuccess = true; 18172 results.forEach((result, key) => { 18173 const queueItem = queue[key]; 18174 if (result?.error) { 18175 queueItem?.reject(result.error); 18176 isSuccess = false; 18177 } else { 18178 queueItem?.resolve(result?.output ?? result); 18179 } 18180 }); 18181 queue = []; 18182 return isSuccess; 18183 } 18184 }; 18185 } 18186 var ObservableSet = class { 18187 constructor(...args2) { 18188 this.set = new Set(...args2); 18189 this.subscribers = /* @__PURE__ */ new Set(); 18190 } 18191 get size() { 18192 return this.set.size; 18193 } 18194 add(value) { 18195 this.set.add(value); 18196 this.subscribers.forEach((subscriber) => subscriber()); 18197 return this; 18198 } 18199 delete(value) { 18200 const isSuccess = this.set.delete(value); 18201 this.subscribers.forEach((subscriber) => subscriber()); 18202 return isSuccess; 18203 } 18204 subscribe(subscriber) { 18205 this.subscribers.add(subscriber); 18206 return () => { 18207 this.subscribers.delete(subscriber); 18208 }; 18209 } 18210 }; 18211 18212 // packages/core-data/build-module/utils/sync-undo-levels.mjs 18213 var syncUndoLevelCount = 0; 18214 function createSyncUndoLevelRecord(kind, name, recordId) { 18215 syncUndoLevelCount += 1; 18216 return [ 18217 { 18218 id: { kind, name, recordId, isSyncUndoLevel: true }, 18219 changes: { 18220 level: { 18221 from: syncUndoLevelCount - 1, 18222 to: syncUndoLevelCount 18223 } 18224 } 18225 } 18226 ]; 18227 } 18228 function isSyncUndoLevel(changes) { 18229 return "string" !== typeof changes.id && true === changes.id.isSyncUndoLevel; 18230 } 18231 function getRecordReference(id2) { 18232 if ("string" === typeof id2) { 18233 return void 0; 18234 } 18235 const { kind, name, recordId } = id2; 18236 if ("string" !== typeof kind || "string" !== typeof name) { 18237 return void 0; 18238 } 18239 if ("string" !== typeof recordId && "number" !== typeof recordId) { 18240 return void 0; 18241 } 18242 return { kind, name, recordId }; 18243 } 18244 function isLoadedRecord(syncManager2, record) { 18245 if (!record) { 18246 return false; 18247 } 18248 return Boolean( 18249 syncManager2?.isLoaded?.(record.kind, record.name, record.recordId) 18250 ); 18251 } 18252 function recordEntityEdit(undoManager2, syncManager2, record, isStaged = false) { 18253 const undoHistory = syncManager2?.undoHistory; 18254 undoHistory?.stopCapturing(); 18255 undoHistory?.clearRedo(); 18256 if (!record) { 18257 undoManager2.addRecord(); 18258 return; 18259 } 18260 if (isStaged && undoManager2.hasRedo()) { 18261 undoManager2.addRecord(); 18262 } 18263 undoManager2.addRecord(record, isStaged); 18264 } 18265 function popUndoLevel(undoManager2, syncManager2, type) { 18266 const undoHistory = syncManager2?.undoHistory; 18267 let record; 18268 if ("undo" === type) { 18269 record = undoManager2.undo(); 18270 } else { 18271 record = undoManager2.redo(); 18272 } 18273 if (!record) { 18274 return void 0; 18275 } 18276 const changes = record.filter( 18277 (entry) => !isSyncUndoLevel(entry) && !isLoadedRecord(syncManager2, getRecordReference(entry.id)) 18278 ); 18279 const syncLevel = record.find(isSyncUndoLevel); 18280 let syncLevelRecord; 18281 if (syncLevel) { 18282 syncLevelRecord = getRecordReference(syncLevel.id); 18283 } 18284 let didApplySyncLevel = false; 18285 if (undoHistory && syncLevelRecord && isLoadedRecord(syncManager2, syncLevelRecord)) { 18286 const { kind, name, recordId } = syncLevelRecord; 18287 didApplySyncLevel = undoHistory[type](kind, name, recordId); 18288 } 18289 return { 18290 changes, 18291 didApply: changes.length > 0 || didApplySyncLevel 18292 }; 18293 } 18294 function applyUndoLevel(undoManager2, syncManager2, type) { 18295 syncManager2?.undoHistory?.stopCapturing(); 18296 let level = popUndoLevel(undoManager2, syncManager2, type); 18297 while (level && !level.didApply) { 18298 level = popUndoLevel(undoManager2, syncManager2, type); 18299 } 18300 if (!level) { 18301 return void 0; 18302 } 18303 syncManager2?.undoHistory?.stopCapturing(); 18304 return level.changes; 18305 } 18306 18307 // packages/core-data/build-module/actions.mjs 18308 function addTitleToAutoDraft(record) { 18309 return record.status === "auto-draft" ? { ...record, title: "" } : record; 18310 } 18311 function receiveUserQuery(queryID, users2) { 18312 return { 18313 type: "RECEIVE_USER_QUERY", 18314 users: Array.isArray(users2) ? users2 : [users2], 18315 queryID 18316 }; 18317 } 18318 function receiveCurrentUser(currentUser2) { 18319 return { 18320 type: "RECEIVE_CURRENT_USER", 18321 currentUser: currentUser2 18322 }; 18323 } 18324 function addEntities(entities2) { 18325 return { 18326 type: "ADD_ENTITIES", 18327 entities: entities2 18328 }; 18329 } 18330 function receiveEntityRecords(kind, name, records, query = void 0, invalidateCache = false, edits = void 0, meta = void 0) { 18331 if (kind === "postType") { 18332 records = Array.isArray(records) ? records.map(addTitleToAutoDraft) : addTitleToAutoDraft(records); 18333 } 18334 let action; 18335 if (query) { 18336 action = receiveQueriedItems(records, query, edits, meta); 18337 } else { 18338 action = receiveItems(records, edits, meta); 18339 } 18340 return { 18341 ...action, 18342 kind, 18343 name, 18344 invalidateCache 18345 }; 18346 } 18347 function receiveCurrentTheme(currentTheme2) { 18348 return { 18349 type: "RECEIVE_CURRENT_THEME", 18350 currentTheme: currentTheme2 18351 }; 18352 } 18353 function __experimentalReceiveCurrentGlobalStylesId(currentGlobalStylesId2) { 18354 return { 18355 type: "RECEIVE_CURRENT_GLOBAL_STYLES_ID", 18356 id: currentGlobalStylesId2 18357 }; 18358 } 18359 function __experimentalReceiveThemeBaseGlobalStyles(stylesheet, globalStyles) { 18360 return { 18361 type: "RECEIVE_THEME_GLOBAL_STYLES", 18362 stylesheet, 18363 globalStyles 18364 }; 18365 } 18366 function __experimentalReceiveThemeGlobalStyleVariations(stylesheet, variations) { 18367 return { 18368 type: "RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS", 18369 stylesheet, 18370 variations 18371 }; 18372 } 18373 function receiveThemeSupports() { 18374 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveThemeSupports", { 18375 since: "5.9" 18376 }); 18377 return { 18378 type: "DO_NOTHING" 18379 }; 18380 } 18381 function receiveThemeGlobalStyleRevisions(currentId, revisions) { 18382 (0, import_deprecated3.default)( 18383 "wp.data.dispatch( 'core' ).receiveThemeGlobalStyleRevisions()", 18384 { 18385 since: "6.5.0", 18386 alternative: "wp.data.dispatch( 'core' ).receiveRevisions" 18387 } 18388 ); 18389 return { 18390 type: "RECEIVE_THEME_GLOBAL_STYLE_REVISIONS", 18391 currentId, 18392 revisions 18393 }; 18394 } 18395 function receiveEmbedPreview(url, preview) { 18396 return { 18397 type: "RECEIVE_EMBED_PREVIEW", 18398 url, 18399 preview 18400 }; 18401 } 18402 var deleteEntityRecord = (kind, name, recordId, query, { __unstableFetch = import_api_fetch5.default, throwOnError = false } = {}) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 18403 logEntityDeprecation(kind, name, "deleteEntityRecord"); 18404 const configs = await resolveSelect3.getEntitiesConfig(kind); 18405 const entityConfig = configs.find( 18406 (config) => config.kind === kind && config.name === name 18407 ); 18408 let error; 18409 let deletedRecord = false; 18410 if (!entityConfig) { 18411 return; 18412 } 18413 const lock2 = await dispatch4.__unstableAcquireStoreLock( 18414 STORE_NAME, 18415 ["entities", "records", kind, name, recordId], 18416 { exclusive: true } 18417 ); 18418 try { 18419 dispatch4({ 18420 type: "DELETE_ENTITY_RECORD_START", 18421 kind, 18422 name, 18423 recordId 18424 }); 18425 let hasError = false; 18426 const { baseURL } = entityConfig; 18427 try { 18428 let path = `$baseURL}/$recordId}`; 18429 if (query) { 18430 path = (0, import_url3.addQueryArgs)(path, query); 18431 } 18432 deletedRecord = await __unstableFetch({ 18433 path, 18434 method: "DELETE" 18435 }); 18436 await dispatch4(removeItems(kind, name, recordId, true)); 18437 getEntitySyncManager()?.unload(kind, name, recordId); 18438 } catch (_error) { 18439 hasError = true; 18440 error = _error; 18441 } 18442 dispatch4({ 18443 type: "DELETE_ENTITY_RECORD_FINISH", 18444 kind, 18445 name, 18446 recordId, 18447 error 18448 }); 18449 if (hasError && throwOnError) { 18450 throw error; 18451 } 18452 return deletedRecord; 18453 } finally { 18454 dispatch4.__unstableReleaseStoreLock(lock2); 18455 } 18456 }; 18457 var editEntityRecord = (kind, name, recordId, edits, options = {}) => ({ select: select6, dispatch: dispatch4 }) => { 18458 logEntityDeprecation(kind, name, "editEntityRecord"); 18459 const entityConfig = select6.getEntityConfig(kind, name); 18460 if (!entityConfig) { 18461 throw new Error( 18462 `The entity being edited ($kind}, $name}) does not have a loaded config.` 18463 ); 18464 } 18465 const { mergedEdits = {} } = entityConfig; 18466 const record = select6.getRawEntityRecord(kind, name, recordId); 18467 const editedRecord = select6.getEditedEntityRecord( 18468 kind, 18469 name, 18470 recordId 18471 ); 18472 const editsWithMerges = Object.keys(edits).reduce((acc, key) => { 18473 acc[key] = mergedEdits[key] ? { ...editedRecord[key], ...edits[key] } : edits[key]; 18474 return acc; 18475 }, {}); 18476 const edit = { 18477 kind, 18478 name, 18479 recordId, 18480 // Clear edits when they are equal to their persisted counterparts 18481 // so that the property is not considered dirty. 18482 edits: clearUnchangedEdits(editsWithMerges, record) 18483 }; 18484 const syncManager2 = getEntitySyncManager(); 18485 syncManager2?.update(kind, name, recordId, editsWithMerges, { 18486 isCached: Boolean(options.isCached), 18487 undoIgnore: Boolean(options.undoIgnore) 18488 }); 18489 if (!options.undoIgnore && !syncManager2?.isLoaded?.(kind, name, recordId)) { 18490 recordEntityEdit( 18491 select6.getUndoManager(), 18492 syncManager2, 18493 [ 18494 { 18495 id: { kind, name, recordId }, 18496 changes: Object.keys(edits).reduce((acc, key) => { 18497 acc[key] = { 18498 from: editedRecord[key], 18499 to: edits[key] 18500 }; 18501 return acc; 18502 }, {}) 18503 } 18504 ], 18505 options.isCached 18506 ); 18507 } 18508 dispatch4({ 18509 type: "EDIT_ENTITY_RECORD", 18510 ...edit 18511 }); 18512 }; 18513 var clearEntityRecordEdits = (kind, name, recordId) => ({ select: select6, dispatch: dispatch4 }) => { 18514 const entityConfig = select6.getEntityConfig(kind, name); 18515 logEntityDeprecation(kind, name, "clearEntityRecordEdits"); 18516 if (!entityConfig) { 18517 throw new Error( 18518 `The entity being edited ($kind}, $name}) does not have a loaded config.` 18519 ); 18520 } 18521 const currentEdits = select6.getEntityRecordEdits( 18522 kind, 18523 name, 18524 recordId 18525 ); 18526 if (!currentEdits) { 18527 return; 18528 } 18529 const clearedEdits = Object.keys(currentEdits).reduce( 18530 (acc, key) => { 18531 acc[key] = void 0; 18532 return acc; 18533 }, 18534 {} 18535 ); 18536 dispatch4({ 18537 type: "EDIT_ENTITY_RECORD", 18538 kind, 18539 name, 18540 recordId, 18541 edits: clearedEdits 18542 }); 18543 }; 18544 var undo = () => ({ select: select6, dispatch: dispatch4 }) => { 18545 const undoRecord = applyUndoLevel( 18546 select6.getUndoManager(), 18547 getEntitySyncManager(), 18548 "undo" 18549 ); 18550 if (!undoRecord) { 18551 return; 18552 } 18553 dispatch4({ 18554 type: "UNDO", 18555 record: undoRecord 18556 }); 18557 }; 18558 var redo = () => ({ select: select6, dispatch: dispatch4 }) => { 18559 const redoRecord = applyUndoLevel( 18560 select6.getUndoManager(), 18561 getEntitySyncManager(), 18562 "redo" 18563 ); 18564 if (!redoRecord) { 18565 return; 18566 } 18567 dispatch4({ 18568 type: "REDO", 18569 record: redoRecord 18570 }); 18571 }; 18572 var __unstableCreateUndoLevel = () => ({ select: select6 }) => { 18573 recordEntityEdit(select6.getUndoManager(), getEntitySyncManager()); 18574 }; 18575 var saveEntityRecord = (kind, name, record, options = {}) => async ({ select: select6, resolveSelect: resolveSelect3, dispatch: dispatch4 }) => { 18576 const { 18577 isAutosave = false, 18578 __unstableFetch = import_api_fetch5.default, 18579 throwOnError = false 18580 } = options; 18581 logEntityDeprecation(kind, name, "saveEntityRecord"); 18582 const configs = await resolveSelect3.getEntitiesConfig(kind); 18583 const entityConfig = configs.find( 18584 (config) => config.kind === kind && config.name === name 18585 ); 18586 if (!entityConfig) { 18587 return; 18588 } 18589 const entityIdKey = entityConfig.key ?? DEFAULT_ENTITY_KEY; 18590 const recordId = record[entityIdKey]; 18591 const isNewRecord = !!entityIdKey && !recordId; 18592 const lock2 = await dispatch4.__unstableAcquireStoreLock( 18593 STORE_NAME, 18594 ["entities", "records", kind, name, recordId || v4_default()], 18595 { exclusive: true } 18596 ); 18597 try { 18598 for (const [key, value] of Object.entries(record)) { 18599 if (typeof value === "function") { 18600 const evaluatedValue = value( 18601 select6.getEditedEntityRecord(kind, name, recordId) 18602 ); 18603 dispatch4.editEntityRecord( 18604 kind, 18605 name, 18606 recordId, 18607 { 18608 [key]: evaluatedValue 18609 }, 18610 { undoIgnore: true } 18611 ); 18612 record[key] = evaluatedValue; 18613 } 18614 } 18615 dispatch4({ 18616 type: "SAVE_ENTITY_RECORD_START", 18617 kind, 18618 name, 18619 recordId, 18620 isAutosave 18621 }); 18622 let updatedRecord; 18623 let error; 18624 let hasError = false; 18625 const { baseURL } = entityConfig; 18626 try { 18627 const path = `$baseURL}$recordId ? "/" + recordId : ""}`; 18628 const persistedRecord = !isNewRecord ? select6.getRawEntityRecord(kind, name, recordId) : {}; 18629 const syncManager2 = getEntitySyncManager(); 18630 const syncEdits = isNewRecord ? void 0 : await syncManager2?.beforeSave?.( 18631 kind, 18632 name, 18633 recordId, 18634 record, 18635 { persistedRecord, isAutosave } 18636 ); 18637 if (isAutosave) { 18638 const merged = { ...persistedRecord, ...record }; 18639 const data = [ 18640 "title", 18641 "excerpt", 18642 "content", 18643 "meta" 18644 ].reduce( 18645 (acc, key) => { 18646 if (key in merged) { 18647 acc[key] = merged[key]; 18648 } 18649 return acc; 18650 }, 18651 { 18652 // Do not update the `status` if we have edited it when auto saving. 18653 // It's very important to let the user explicitly save this change, 18654 // because it can lead to unexpected results. An example would be to 18655 // have a draft post and change the status to publish. 18656 status: merged.status === "auto-draft" ? "draft" : void 0 18657 } 18658 ); 18659 updatedRecord = await __unstableFetch({ 18660 path: `$path}/autosaves`, 18661 method: "POST", 18662 data: { ...data, ...syncEdits } 18663 }); 18664 if (persistedRecord.id === updatedRecord.id) { 18665 let newRecord = { 18666 ...persistedRecord, 18667 ...data, 18668 ...updatedRecord 18669 }; 18670 newRecord = Object.keys(newRecord).reduce( 18671 (acc, key) => { 18672 if ([ 18673 "title", 18674 "excerpt", 18675 "content", 18676 "meta" 18677 ].includes(key)) { 18678 acc[key] = newRecord[key]; 18679 } else if (key === "status") { 18680 acc[key] = persistedRecord.status === "auto-draft" && newRecord.status === "draft" ? newRecord.status : persistedRecord.status; 18681 } else { 18682 acc[key] = persistedRecord[key]; 18683 } 18684 return acc; 18685 }, 18686 {} 18687 ); 18688 dispatch4.receiveEntityRecords( 18689 kind, 18690 name, 18691 newRecord, 18692 void 0, 18693 true 18694 ); 18695 } else { 18696 dispatch4.receiveAutosaves( 18697 persistedRecord.id, 18698 updatedRecord 18699 ); 18700 } 18701 } else { 18702 let edits = { ...record, ...syncEdits }; 18703 if (entityConfig.__unstablePrePersist) { 18704 edits = { 18705 ...edits, 18706 ...await entityConfig.__unstablePrePersist( 18707 persistedRecord, 18708 edits 18709 ) 18710 }; 18711 } 18712 updatedRecord = await __unstableFetch({ 18713 path, 18714 method: recordId ? "PUT" : "POST", 18715 data: edits 18716 }); 18717 dispatch4.receiveEntityRecords( 18718 kind, 18719 name, 18720 updatedRecord, 18721 void 0, 18722 true, 18723 record 18724 ); 18725 syncManager2?.afterSave?.(kind, name, recordId, { 18726 savedRecord: updatedRecord, 18727 persistedRecord: isNewRecord ? void 0 : persistedRecord, 18728 edits: record 18729 }); 18730 } 18731 } catch (_error) { 18732 hasError = true; 18733 error = _error; 18734 } 18735 dispatch4({ 18736 type: "SAVE_ENTITY_RECORD_FINISH", 18737 kind, 18738 name, 18739 recordId, 18740 error, 18741 isAutosave 18742 }); 18743 if (hasError && throwOnError) { 18744 throw error; 18745 } 18746 return updatedRecord; 18747 } finally { 18748 dispatch4.__unstableReleaseStoreLock(lock2); 18749 } 18750 }; 18751 var __experimentalBatch = (requests) => async ({ dispatch: dispatch4 }) => { 18752 const batch = createBatch(); 18753 const api = { 18754 saveEntityRecord(kind, name, record, options) { 18755 return batch.add( 18756 (add) => dispatch4.saveEntityRecord(kind, name, record, { 18757 ...options, 18758 __unstableFetch: add 18759 }) 18760 ); 18761 }, 18762 saveEditedEntityRecord(kind, name, recordId, options) { 18763 return batch.add( 18764 (add) => dispatch4.saveEditedEntityRecord(kind, name, recordId, { 18765 ...options, 18766 __unstableFetch: add 18767 }) 18768 ); 18769 }, 18770 deleteEntityRecord(kind, name, recordId, query, options) { 18771 return batch.add( 18772 (add) => dispatch4.deleteEntityRecord(kind, name, recordId, query, { 18773 ...options, 18774 __unstableFetch: add 18775 }) 18776 ); 18777 } 18778 }; 18779 const resultPromises = requests.map((request) => request(api)); 18780 const [, ...results] = await Promise.all([ 18781 batch.run(), 18782 ...resultPromises 18783 ]); 18784 return results; 18785 }; 18786 var saveEditedEntityRecord = (kind, name, recordId, options) => async ({ select: select6, dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 18787 logEntityDeprecation(kind, name, "saveEditedEntityRecord"); 18788 if (!select6.hasEditsForEntityRecord(kind, name, recordId)) { 18789 return; 18790 } 18791 const configs = await resolveSelect3.getEntitiesConfig(kind); 18792 const entityConfig = configs.find( 18793 (config) => config.kind === kind && config.name === name 18794 ); 18795 if (!entityConfig) { 18796 return; 18797 } 18798 const entityIdKey = entityConfig.key || DEFAULT_ENTITY_KEY; 18799 const edits = select6.getEntityRecordNonTransientEdits( 18800 kind, 18801 name, 18802 recordId 18803 ); 18804 const record = { [entityIdKey]: recordId, ...edits }; 18805 return await dispatch4.saveEntityRecord(kind, name, record, options); 18806 }; 18807 var __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({ select: select6, dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 18808 logEntityDeprecation( 18809 kind, 18810 name, 18811 "__experimentalSaveSpecifiedEntityEdits" 18812 ); 18813 if (!select6.hasEditsForEntityRecord(kind, name, recordId)) { 18814 return; 18815 } 18816 const edits = select6.getEntityRecordNonTransientEdits( 18817 kind, 18818 name, 18819 recordId 18820 ); 18821 const editsToSave = {}; 18822 for (const item of itemsToSave) { 18823 setNestedValue(editsToSave, item, getNestedValue(edits, item)); 18824 } 18825 const configs = await resolveSelect3.getEntitiesConfig(kind); 18826 const entityConfig = configs.find( 18827 (config) => config.kind === kind && config.name === name 18828 ); 18829 const entityIdKey = entityConfig?.key || DEFAULT_ENTITY_KEY; 18830 if (recordId) { 18831 editsToSave[entityIdKey] = recordId; 18832 } 18833 return await dispatch4.saveEntityRecord( 18834 kind, 18835 name, 18836 editsToSave, 18837 options 18838 ); 18839 }; 18840 function receiveUploadPermissions(hasUploadPermissions) { 18841 (0, import_deprecated3.default)("wp.data.dispatch( 'core' ).receiveUploadPermissions", { 18842 since: "5.9", 18843 alternative: "receiveUserPermission" 18844 }); 18845 return receiveUserPermission("create/media", hasUploadPermissions); 18846 } 18847 function receiveUserPermission(key, isAllowed) { 18848 return { 18849 type: "RECEIVE_USER_PERMISSION", 18850 key, 18851 isAllowed 18852 }; 18853 } 18854 function receiveUserPermissions(permissions) { 18855 return { 18856 type: "RECEIVE_USER_PERMISSIONS", 18857 permissions 18858 }; 18859 } 18860 function receiveAutosaves(postId, autosaves2) { 18861 return { 18862 type: "RECEIVE_AUTOSAVES", 18863 postId, 18864 autosaves: Array.isArray(autosaves2) ? autosaves2 : [autosaves2] 18865 }; 18866 } 18867 function receiveNavigationFallbackId(fallbackId) { 18868 return { 18869 type: "RECEIVE_NAVIGATION_FALLBACK_ID", 18870 fallbackId 18871 }; 18872 } 18873 function receiveDefaultTemplateId(query, templateId) { 18874 return { 18875 type: "RECEIVE_DEFAULT_TEMPLATE", 18876 query, 18877 templateId 18878 }; 18879 } 18880 var receiveRevisions = (kind, name, recordKey, records, query, invalidateCache = false, meta) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 18881 logEntityDeprecation(kind, name, "receiveRevisions"); 18882 const configs = await resolveSelect3.getEntitiesConfig(kind); 18883 const entityConfig = configs.find( 18884 (config) => config.kind === kind && config.name === name 18885 ); 18886 const key = entityConfig?.revisionKey ?? DEFAULT_ENTITY_KEY; 18887 dispatch4({ 18888 type: "RECEIVE_ITEM_REVISIONS", 18889 key, 18890 items: records, 18891 recordKey, 18892 meta, 18893 query, 18894 kind, 18895 name, 18896 invalidateCache 18897 }); 18898 }; 18899 18900 // packages/core-data/build-module/private-actions.mjs 18901 var private_actions_exports = {}; 18902 __export(private_actions_exports, { 18903 editMediaEntity: () => editMediaEntity, 18904 receiveEditorAssets: () => receiveEditorAssets, 18905 receiveEditorSettings: () => receiveEditorSettings, 18906 receiveEntityActionsConfig: () => receiveEntityActionsConfig, 18907 receiveFieldsConfig: () => receiveFieldsConfig, 18908 receiveRegisteredPostMeta: () => receiveRegisteredPostMeta, 18909 receiveViewConfig: () => receiveViewConfig, 18910 recordSyncUndoLevel: () => recordSyncUndoLevel, 18911 saveDirtyEntities: () => saveDirtyEntities, 18912 setCollaborationSupported: () => setCollaborationSupported, 18913 setSyncConnectionStatus: () => setSyncConnectionStatus 18914 }); 18915 var import_api_fetch6 = __toESM(require_api_fetch(), 1); 18916 var import_notices = __toESM(require_notices(), 1); 18917 var import_block_editor5 = __toESM(require_block_editor(), 1); 18918 var import_html_entities = __toESM(require_html_entities(), 1); 18919 var import_i18n2 = __toESM(require_i18n(), 1); 18920 function receiveRegisteredPostMeta(postType, registeredPostMeta2) { 18921 return { 18922 type: "RECEIVE_REGISTERED_POST_META", 18923 postType, 18924 registeredPostMeta: registeredPostMeta2 18925 }; 18926 } 18927 var editMediaEntity = (recordId, edits = {}, { __unstableFetch = import_api_fetch6.default, throwOnError = false } = {}) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 18928 if (!recordId) { 18929 return; 18930 } 18931 const kind = "postType"; 18932 const name = "attachment"; 18933 const configs = await resolveSelect3.getEntitiesConfig(kind); 18934 const entityConfig = configs.find( 18935 (config) => config.kind === kind && config.name === name 18936 ); 18937 if (!entityConfig) { 18938 return; 18939 } 18940 const lock2 = await dispatch4.__unstableAcquireStoreLock( 18941 STORE_NAME, 18942 ["entities", "records", kind, name, recordId], 18943 { exclusive: true } 18944 ); 18945 let updatedRecord; 18946 let error; 18947 let hasError = false; 18948 try { 18949 dispatch4({ 18950 type: "SAVE_ENTITY_RECORD_START", 18951 kind, 18952 name, 18953 recordId 18954 }); 18955 try { 18956 const path = `$entityConfig.baseURL}/$recordId}/edit`; 18957 const newRecord = await __unstableFetch({ 18958 path, 18959 method: "POST", 18960 data: { 18961 ...edits 18962 } 18963 }); 18964 if (newRecord) { 18965 dispatch4.receiveEntityRecords( 18966 kind, 18967 name, 18968 newRecord, 18969 void 0, 18970 true, 18971 void 0, 18972 void 0 18973 ); 18974 updatedRecord = newRecord; 18975 } 18976 } catch (e) { 18977 error = e; 18978 hasError = true; 18979 } 18980 dispatch4({ 18981 type: "SAVE_ENTITY_RECORD_FINISH", 18982 kind, 18983 name, 18984 recordId, 18985 error 18986 }); 18987 if (hasError && throwOnError) { 18988 throw error; 18989 } 18990 return updatedRecord; 18991 } finally { 18992 dispatch4.__unstableReleaseStoreLock(lock2); 18993 } 18994 }; 18995 function receiveEditorSettings(settings) { 18996 return { 18997 type: "RECEIVE_EDITOR_SETTINGS", 18998 settings 18999 }; 19000 } 19001 function receiveEditorAssets(assets) { 19002 return { 19003 type: "RECEIVE_EDITOR_ASSETS", 19004 assets 19005 }; 19006 } 19007 var setCollaborationSupported = (supported) => ({ dispatch: dispatch4 }) => { 19008 dispatch4({ type: "SET_COLLABORATION_SUPPORTED", supported }); 19009 if (!supported) { 19010 getEntitySyncManager()?.unloadAll(); 19011 } 19012 }; 19013 function receiveViewConfig(kind, name, config) { 19014 return { 19015 type: "RECEIVE_VIEW_CONFIG", 19016 kind, 19017 name, 19018 config 19019 }; 19020 } 19021 function receiveFieldsConfig(kind, name, config) { 19022 return { 19023 type: "RECEIVE_FIELDS_CONFIG", 19024 kind, 19025 name, 19026 config 19027 }; 19028 } 19029 function receiveEntityActionsConfig(kind, name, config) { 19030 return { 19031 type: "RECEIVE_ENTITY_ACTIONS_CONFIG", 19032 kind, 19033 name, 19034 config 19035 }; 19036 } 19037 var recordSyncUndoLevel = (kind, name, recordId) => ({ select: select6, dispatch: dispatch4 }) => { 19038 select6.getUndoManager().addRecord(createSyncUndoLevelRecord(kind, name, recordId)); 19039 dispatch4({ type: "RECORD_SYNC_UNDO_LEVEL" }); 19040 }; 19041 function setSyncConnectionStatus(kind, name, key, status) { 19042 if (!status) { 19043 return { 19044 type: "CLEAR_SYNC_CONNECTION_STATUS", 19045 kind, 19046 name, 19047 key 19048 }; 19049 } 19050 return { 19051 type: "SET_SYNC_CONNECTION_STATUS", 19052 kind, 19053 name, 19054 key, 19055 status 19056 }; 19057 } 19058 var saveDirtyEntities = ({ 19059 onSave, 19060 dirtyEntityRecords = [], 19061 entitiesToSkip = [], 19062 close, 19063 successNoticeContent 19064 } = {}) => ({ registry }) => { 19065 const PUBLISH_ON_SAVE_ENTITIES = [ 19066 { kind: "postType", name: "wp_navigation" } 19067 ]; 19068 const saveNoticeId = "site-editor-save-success"; 19069 const homeUrl = registry.select(STORE_NAME).getEntityRecord("root", "__unstableBase")?.home; 19070 registry.dispatch(import_notices.store).removeNotice(saveNoticeId); 19071 const entitiesToSave = dirtyEntityRecords.filter( 19072 ({ kind, name, key, property }) => { 19073 return !entitiesToSkip.some( 19074 (elt) => elt.kind === kind && elt.name === name && elt.key === key && elt.property === property 19075 ); 19076 } 19077 ); 19078 close?.(entitiesToSave); 19079 const siteItemsToSave = []; 19080 const pendingSavedRecords = []; 19081 entitiesToSave.forEach(({ kind, name, key, property }) => { 19082 if ("root" === kind && "site" === name) { 19083 siteItemsToSave.push(property); 19084 } else { 19085 if (PUBLISH_ON_SAVE_ENTITIES.some( 19086 (typeToPublish) => typeToPublish.kind === kind && typeToPublish.name === name 19087 )) { 19088 registry.dispatch(STORE_NAME).editEntityRecord(kind, name, key, { 19089 status: "publish" 19090 }); 19091 } 19092 pendingSavedRecords.push( 19093 registry.dispatch(STORE_NAME).saveEditedEntityRecord(kind, name, key, { 19094 throwOnError: true 19095 }).catch(ensureError) 19096 ); 19097 } 19098 }); 19099 if (siteItemsToSave.length) { 19100 pendingSavedRecords.push( 19101 registry.dispatch(STORE_NAME).__experimentalSaveSpecifiedEntityEdits( 19102 "root", 19103 "site", 19104 void 0, 19105 siteItemsToSave, 19106 { 19107 throwOnError: true 19108 } 19109 ).catch(ensureError) 19110 ); 19111 } 19112 registry.dispatch(import_block_editor5.store).__unstableMarkLastChangeAsPersistent(); 19113 return Promise.all(pendingSavedRecords).then(async (values) => { 19114 if (onSave) { 19115 await onSave(); 19116 } 19117 return values; 19118 }).then((values) => { 19119 const errors = values.filter((v) => v instanceof Error); 19120 if (errors.length) { 19121 const firstMessage = errors.find( 19122 (e) => e.message 19123 )?.message; 19124 registry.dispatch(import_notices.store).createErrorNotice( 19125 (0, import_html_entities.decodeEntities)( 19126 firstMessage || (0, import_i18n2.__)("Saving failed.") 19127 ), 19128 { 19129 type: "snackbar", 19130 id: saveNoticeId 19131 } 19132 ); 19133 } else { 19134 registry.dispatch(import_notices.store).createSuccessNotice( 19135 successNoticeContent || (0, import_i18n2.__)("Site updated."), 19136 { 19137 type: "snackbar", 19138 id: saveNoticeId, 19139 actions: [ 19140 { 19141 label: (0, import_i18n2.__)("View site"), 19142 url: homeUrl, 19143 openInNewTab: true 19144 } 19145 ] 19146 } 19147 ); 19148 } 19149 }).catch( 19150 (error) => registry.dispatch(import_notices.store).createErrorNotice( 19151 (0, import_html_entities.decodeEntities)( 19152 error?.message || (0, import_i18n2.__)("Saving failed.") 19153 ), 19154 { 19155 type: "snackbar", 19156 id: saveNoticeId 19157 } 19158 ) 19159 ); 19160 function ensureError(error) { 19161 if (error instanceof Error) { 19162 return error; 19163 } 19164 let message; 19165 if (!error) { 19166 } else if (typeof error.message === "string") { 19167 message = error.message; 19168 } else if (typeof error === "string") { 19169 message = error; 19170 } else if ( 19171 // Only consider own method, lest we erroneously end up calling 19172 // `Object#toString` at the end of the prototype chain, thereby 19173 // returning `"[object Object]"`. 19174 Object.hasOwn(error, "toString") && typeof error.toString === "function" 19175 ) { 19176 const result = error.toString(); 19177 if (typeof result === "string") { 19178 message = result; 19179 } 19180 } 19181 return new Error(message, { cause: error }); 19182 } 19183 }; 19184 19185 // packages/core-data/build-module/resolvers.mjs 19186 var resolvers_exports = {}; 19187 __export(resolvers_exports, { 19188 __experimentalGetCurrentGlobalStylesId: () => __experimentalGetCurrentGlobalStylesId2, 19189 __experimentalGetCurrentThemeBaseGlobalStyles: () => __experimentalGetCurrentThemeBaseGlobalStyles2, 19190 __experimentalGetCurrentThemeGlobalStylesVariations: () => __experimentalGetCurrentThemeGlobalStylesVariations2, 19191 canUser: () => canUser2, 19192 canUserEditEntityRecord: () => canUserEditEntityRecord2, 19193 getAuthors: () => getAuthors2, 19194 getAutosave: () => getAutosave2, 19195 getAutosaves: () => getAutosaves2, 19196 getBlockPatternCategories: () => getBlockPatternCategories2, 19197 getBlockPatterns: () => getBlockPatterns2, 19198 getCurrentTheme: () => getCurrentTheme2, 19199 getCurrentThemeGlobalStylesRevisions: () => getCurrentThemeGlobalStylesRevisions2, 19200 getCurrentUser: () => getCurrentUser2, 19201 getDefaultTemplateId: () => getDefaultTemplateId2, 19202 getEditedEntityRecord: () => getEditedEntityRecord2, 19203 getEditorAssets: () => getEditorAssets2, 19204 getEditorSettings: () => getEditorSettings2, 19205 getEmbedPreview: () => getEmbedPreview2, 19206 getEntitiesConfig: () => getEntitiesConfig2, 19207 getEntityActionsConfig: () => getEntityActionsConfig2, 19208 getEntityRecord: () => getEntityRecord2, 19209 getEntityRecords: () => getEntityRecords2, 19210 getEntityRecordsTotalItems: () => getEntityRecordsTotalItems2, 19211 getEntityRecordsTotalPages: () => getEntityRecordsTotalPages2, 19212 getFieldsConfig: () => getFieldsConfig2, 19213 getNavigationFallbackId: () => getNavigationFallbackId2, 19214 getRawEntityRecord: () => getRawEntityRecord2, 19215 getRegisteredPostMeta: () => getRegisteredPostMeta2, 19216 getRevision: () => getRevision2, 19217 getRevisions: () => getRevisions2, 19218 getThemeSupports: () => getThemeSupports2, 19219 getUserPatternCategories: () => getUserPatternCategories2, 19220 getViewConfig: () => getViewConfig2 19221 }); 19222 var import_url6 = __toESM(require_url(), 1); 19223 var import_html_entities3 = __toESM(require_html_entities(), 1); 19224 var import_api_fetch10 = __toESM(require_api_fetch(), 1); 19225 19226 // packages/core-data/build-module/fetch/index.mjs 19227 var import_api_fetch9 = __toESM(require_api_fetch(), 1); 19228 19229 // packages/core-data/build-module/fetch/__experimental-fetch-link-suggestions.mjs 19230 var import_api_fetch7 = __toESM(require_api_fetch(), 1); 19231 var import_url4 = __toESM(require_url(), 1); 19232 var import_html_entities2 = __toESM(require_html_entities(), 1); 19233 var import_i18n3 = __toESM(require_i18n(), 1); 19234 async function fetchLinkSuggestions(search, searchOptions = {}, editorSettings2 = {}) { 19235 const searchOptionsToUse = searchOptions.isInitialSuggestions && searchOptions.initialSuggestionsSearchOptions ? { 19236 ...searchOptions, 19237 ...searchOptions.initialSuggestionsSearchOptions 19238 } : searchOptions; 19239 const { 19240 type, 19241 subtype, 19242 preferTypes, 19243 page, 19244 perPage = searchOptions.isInitialSuggestions ? 3 : 20 19245 } = searchOptionsToUse; 19246 const { disablePostFormats = false } = editorSettings2; 19247 const queries2 = []; 19248 if (!type || type === "post") { 19249 queries2.push( 19250 (0, import_api_fetch7.default)({ 19251 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 19252 search, 19253 page, 19254 per_page: perPage, 19255 type: "post", 19256 subtype 19257 }) 19258 }).then((results2) => { 19259 return results2.map((result) => { 19260 return { 19261 id: result.id, 19262 url: result.url, 19263 title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"), 19264 type: result.subtype || result.type, 19265 kind: "post-type" 19266 }; 19267 }); 19268 }).catch(() => []) 19269 // Fail by returning no results. 19270 ); 19271 } 19272 if (!type || type === "term") { 19273 queries2.push( 19274 (0, import_api_fetch7.default)({ 19275 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 19276 search, 19277 page, 19278 per_page: perPage, 19279 type: "term", 19280 subtype 19281 }) 19282 }).then((results2) => { 19283 return results2.map((result) => { 19284 return { 19285 id: result.id, 19286 url: result.url, 19287 title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"), 19288 type: result.subtype || result.type, 19289 kind: "taxonomy" 19290 }; 19291 }); 19292 }).catch(() => []) 19293 // Fail by returning no results. 19294 ); 19295 } 19296 if (!disablePostFormats && (!type || type === "post-format")) { 19297 queries2.push( 19298 (0, import_api_fetch7.default)({ 19299 path: (0, import_url4.addQueryArgs)("/wp/v2/search", { 19300 search, 19301 page, 19302 per_page: perPage, 19303 type: "post-format", 19304 subtype 19305 }) 19306 }).then((results2) => { 19307 return results2.map((result) => { 19308 return { 19309 id: result.id, 19310 url: result.url, 19311 title: (0, import_html_entities2.decodeEntities)(result.title || "") || (0, import_i18n3.__)("(no title)"), 19312 type: result.subtype || result.type, 19313 kind: "taxonomy" 19314 }; 19315 }); 19316 }).catch(() => []) 19317 // Fail by returning no results. 19318 ); 19319 } 19320 if (!type || type === "attachment") { 19321 queries2.push( 19322 (0, import_api_fetch7.default)({ 19323 path: (0, import_url4.addQueryArgs)("/wp/v2/media", { 19324 search, 19325 page, 19326 per_page: perPage 19327 }) 19328 }).then((results2) => { 19329 return results2.map((result) => { 19330 return { 19331 id: result.id, 19332 url: result.source_url, 19333 title: (0, import_html_entities2.decodeEntities)(result.title.rendered || "") || (0, import_i18n3.__)("(no title)"), 19334 type: result.type, 19335 kind: "media" 19336 }; 19337 }); 19338 }).catch(() => []) 19339 // Fail by returning no results. 19340 ); 19341 } 19342 const responses = await Promise.all(queries2); 19343 let results = responses.flat(); 19344 results = results.filter((result) => !!result.id); 19345 return sortResults({ results, search, preferTypes }); 19346 } 19347 function getTitleMatch(title, search) { 19348 const plain = (text2) => (text2 ?? "").toLowerCase().trim().replace(/[\u2018\u2019]/g, "'").replace(/[\u201c\u201d]/g, '"'); 19349 const haystack = plain(title); 19350 const needle = plain(search); 19351 if (!haystack || !needle) { 19352 return { contains: false, begins: false }; 19353 } 19354 return { 19355 contains: haystack.includes(needle), 19356 begins: haystack.startsWith(needle) 19357 }; 19358 } 19359 var TYPE_ORDER = [ 19360 "post", 19361 "term", 19362 "post-format", 19363 "attachment" 19364 ]; 19365 function getSearchType(result) { 19366 if (result.kind === "media") { 19367 return "attachment"; 19368 } 19369 if (result.type === "post-format") { 19370 return "post-format"; 19371 } 19372 return result.kind === "taxonomy" ? "term" : "post"; 19373 } 19374 function getTypeRank(result, preferTypes = []) { 19375 const searchType = getSearchType(result); 19376 const preferred = preferTypes.findIndex( 19377 (entry) => typeof entry === "string" ? entry === searchType : entry.type === searchType && entry.subtype === result.type 19378 ); 19379 if (preferred !== -1) { 19380 return TYPE_ORDER.length + (preferTypes.length - preferred); 19381 } 19382 return TYPE_ORDER.length - TYPE_ORDER.indexOf(searchType); 19383 } 19384 function countWordsFound(title, searchTokens) { 19385 const titleTokens = tokenize2(title || ""); 19386 return searchTokens.filter( 19387 (searchToken) => titleTokens.some((titleToken) => titleToken.includes(searchToken)) 19388 ).length; 19389 } 19390 function getCoverage(title, searchTokens) { 19391 if (!title || !searchTokens.length) { 19392 return 0; 19393 } 19394 const titleTokens = tokenize2(title); 19395 const covered = searchTokens.reduce((total, searchToken) => { 19396 const best = titleTokens.reduce( 19397 (most, titleToken) => titleToken.includes(searchToken) ? Math.max(most, searchToken.length / titleToken.length) : most, 19398 0 19399 ); 19400 return total + best; 19401 }, 0); 19402 return covered / searchTokens.length * 10; 19403 } 19404 function sortResults({ 19405 results, 19406 search, 19407 preferTypes 19408 }) { 19409 const searchTokens = tokenize2(search); 19410 const scored = results.map((result) => ({ 19411 result, 19412 found: countWordsFound(result.title, searchTokens), 19413 ...getTitleMatch(result.title, search), 19414 type: getTypeRank(result, preferTypes), 19415 score: getCoverage(result.title, searchTokens) 19416 })); 19417 scored.sort( 19418 (a, b) => ( 19419 // Does the title contain all words searched or just one? 19420 // If the search is "black cat" then "Black is my favorite color" should rank lower than "Cats that are black" 19421 b.found - a.found || // Then whether it holds them together, as one string: i.e. "Black cats are great" vs "Cats that are black" 19422 Number(b.contains) - Number(a.contains) || // Matches are equal so far, so enforce banding by type 19423 b.type - a.type || // Within a band, rank matches that start with the search string higher than mid-string matches: 19424 // i.e the search "cat" ranks the title "caterpillar" higher than "concatenate" 19425 Number(b.begins) - Number(a.begins) || // Rank by how much of the matched word the search contains: the search 19426 // "cat" ranks the title "Cats" above the title "Caterpillar" since cat is 75% of "Cats" 19427 // and only 27% of "Caterpillar" 19428 b.score - a.score 19429 ) 19430 ); 19431 return scored.map(({ result }) => result); 19432 } 19433 function tokenize2(text2) { 19434 return text2.toLowerCase().match(/[\p{L}\p{N}]+/gu) || []; 19435 } 19436 19437 // packages/core-data/build-module/fetch/__experimental-fetch-url-data.mjs 19438 var import_api_fetch8 = __toESM(require_api_fetch(), 1); 19439 var import_url5 = __toESM(require_url(), 1); 19440 var CACHE = /* @__PURE__ */ new Map(); 19441 var fetchUrlData = async (url, options = {}) => { 19442 const endpoint = "/wp-block-editor/v1/url-details"; 19443 const args2 = { 19444 url: (0, import_url5.prependHTTP)(url) 19445 }; 19446 if (!(0, import_url5.isURL)(url)) { 19447 return Promise.reject(`$url} is not a valid URL.`); 19448 } 19449 const protocol = (0, import_url5.getProtocol)(url); 19450 if (!protocol || !(0, import_url5.isValidProtocol)(protocol) || !protocol.startsWith("http") || !/^https?:\/\/[^\/\s]/i.test(url)) { 19451 return Promise.reject( 19452 `$url} does not have a valid protocol. URLs must be "http" based` 19453 ); 19454 } 19455 if (CACHE.has(url)) { 19456 return CACHE.get(url); 19457 } 19458 return (0, import_api_fetch8.default)({ 19459 path: (0, import_url5.addQueryArgs)(endpoint, args2), 19460 ...options 19461 }).then((res) => { 19462 CACHE.set(url, res); 19463 return res; 19464 }); 19465 }; 19466 var experimental_fetch_url_data_default = fetchUrlData; 19467 19468 // packages/core-data/build-module/fetch/index.mjs 19469 async function fetchBlockPatterns() { 19470 const restPatterns = await (0, import_api_fetch9.default)({ 19471 path: "/wp/v2/block-patterns/patterns" 19472 }); 19473 if (!restPatterns) { 19474 return []; 19475 } 19476 return restPatterns.map( 19477 (pattern) => Object.fromEntries( 19478 Object.entries(pattern).map(([key, value]) => [ 19479 camelCase(key), 19480 value 19481 ]) 19482 ) 19483 ); 19484 } 19485 19486 // packages/core-data/build-module/parsed-blocks-cache.mjs 19487 var import_data11 = __toESM(require_data(), 1); 19488 var import_blocks5 = __toESM(require_blocks(), 1); 19489 var caches = /* @__PURE__ */ new WeakMap(); 19490 function getCacheKey(kind, name, id2) { 19491 return `$kind}:$name}:$id2}`; 19492 } 19493 function getBlockTypes2() { 19494 return (0, import_data11.select)(import_blocks5.store).getBlockTypes(); 19495 } 19496 function getCachedBlocks(kind, name, id2, content) { 19497 const cached = caches.get(getBlockTypes2())?.get(getCacheKey(kind, name, id2)); 19498 if (cached && cached.content === content) { 19499 return cached.blocks; 19500 } 19501 } 19502 function setCachedBlocks(kind, name, id2, content, blocks) { 19503 const blockTypes = getBlockTypes2(); 19504 let cache3 = caches.get(blockTypes); 19505 if (!cache3) { 19506 cache3 = /* @__PURE__ */ new Map(); 19507 caches.set(blockTypes, cache3); 19508 } 19509 cache3.set(getCacheKey(kind, name, id2), { content, blocks }); 19510 } 19511 19512 // packages/core-data/build-module/resolvers.mjs 19513 var getAuthors2 = (query) => async ({ dispatch: dispatch4 }) => { 19514 const path = (0, import_url6.addQueryArgs)( 19515 "/wp/v2/users/?who=authors&per_page=100", 19516 query 19517 ); 19518 const users2 = await (0, import_api_fetch10.default)({ path }); 19519 dispatch4.receiveUserQuery(path, users2); 19520 }; 19521 var getCurrentUser2 = () => async ({ dispatch: dispatch4 }) => { 19522 const currentUser2 = await (0, import_api_fetch10.default)({ path: "/wp/v2/users/me" }); 19523 dispatch4.receiveCurrentUser(currentUser2); 19524 }; 19525 var getEntityRecord2 = (kind, name, key = "", query) => async ({ select: select6, dispatch: dispatch4, registry, resolveSelect: resolveSelect3 }) => { 19526 const configs = await resolveSelect3.getEntitiesConfig(kind); 19527 const entityConfig = configs.find( 19528 (config) => config.name === name && config.kind === kind 19529 ); 19530 if (!entityConfig) { 19531 return; 19532 } 19533 const lock2 = await dispatch4.__unstableAcquireStoreLock( 19534 STORE_NAME, 19535 ["entities", "records", kind, name, key], 19536 { exclusive: false } 19537 ); 19538 try { 19539 if (query !== void 0 && query._fields) { 19540 query = { 19541 ...query, 19542 _fields: [ 19543 .../* @__PURE__ */ new Set([ 19544 ...get_normalized_comma_separable_default(query._fields) || [], 19545 entityConfig.key || DEFAULT_ENTITY_KEY 19546 ]) 19547 ].join() 19548 }; 19549 } 19550 if (query !== void 0 && query._fields) { 19551 const hasRecord = select6.hasEntityRecord( 19552 kind, 19553 name, 19554 key, 19555 query 19556 ); 19557 if (hasRecord) { 19558 return; 19559 } 19560 } 19561 const { baseURL } = entityConfig; 19562 const path = (0, import_url6.addQueryArgs)(baseURL + (key ? "/" + key : ""), { 19563 ...entityConfig.baseURLParams, 19564 ...query 19565 }); 19566 const response = await (0, import_api_fetch10.default)({ path, parse: false }); 19567 const record = await response.json(); 19568 const permissions = getUserPermissionsFromAllowHeader( 19569 response.headers?.get("allow") 19570 ); 19571 const receiveUserPermissionArgs = {}; 19572 for (const action of ALLOWED_RESOURCE_ACTIONS) { 19573 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 19574 kind, 19575 name, 19576 id: key 19577 })] = permissions[action]; 19578 } 19579 const canUserResolutionsArgs = [[{ kind, name, id: key }]]; 19580 const syncManager2 = select6?.isCollaborationSupported?.() === false ? void 0 : getEntitySyncManager(); 19581 if (syncManager2 && isNumericID(key) && !query && false !== syncManager2.shouldSync?.(kind, name, key)) { 19582 const recordWithTransients = { ...record }; 19583 Object.entries(entityConfig.transientEdits ?? {}).filter( 19584 ([propName, transientConfig]) => void 0 === recordWithTransients[propName] && transientConfig && "object" === typeof transientConfig && "read" in transientConfig && "function" === typeof transientConfig.read 19585 ).forEach(([propName, transientConfig]) => { 19586 recordWithTransients[propName] = transientConfig.read(recordWithTransients); 19587 }); 19588 if (recordWithTransients.blocks && typeof recordWithTransients.content?.raw === "string") { 19589 setCachedBlocks( 19590 kind, 19591 name, 19592 key, 19593 recordWithTransients.content.raw, 19594 recordWithTransients.blocks 19595 ); 19596 } 19597 void syncManager2.load(kind, name, key, recordWithTransients, { 19598 // Handle edits sourced from the sync manager. 19599 editRecord: (edits, options = {}) => { 19600 if (!Object.keys(edits).length) { 19601 return; 19602 } 19603 dispatch4({ 19604 type: "EDIT_ENTITY_RECORD", 19605 kind, 19606 name, 19607 recordId: key, 19608 edits, 19609 meta: { 19610 undo: void 0 19611 }, 19612 options 19613 }); 19614 }, 19615 // Get the current entity record (with edits) 19616 getEditedRecord: async () => await resolveSelect3.getEditedEntityRecord( 19617 kind, 19618 name, 19619 key 19620 ), 19621 // Refetch the current entity record from the database. 19622 refetchRecord: async () => { 19623 dispatch4.receiveEntityRecords( 19624 kind, 19625 name, 19626 await (0, import_api_fetch10.default)({ path, parse: true }), 19627 query 19628 ); 19629 }, 19630 onUndoLevelOpened: () => { 19631 dispatch4.recordSyncUndoLevel(kind, name, key); 19632 } 19633 }); 19634 } 19635 registry.batch(() => { 19636 dispatch4.receiveEntityRecords(kind, name, record, query); 19637 dispatch4.receiveUserPermissions(receiveUserPermissionArgs); 19638 dispatch4.finishResolutions("canUser", canUserResolutionsArgs); 19639 }); 19640 } finally { 19641 dispatch4.__unstableReleaseStoreLock(lock2); 19642 } 19643 }; 19644 getEntityRecord2.shouldInvalidate = (action, kind, name) => { 19645 return kind === "root" && name === "site" && (action.type === "RECEIVE_ITEMS" && // Making sure persistedEdits is set seems to be the only way of 19646 // knowing whether it's an update or fetch. Only an update would 19647 // have persistedEdits. 19648 action.persistedEdits && action.persistedEdits.status !== "auto-draft" || action.type === "REMOVE_ITEMS") && action.kind === "postType" && action.name === "wp_template"; 19649 }; 19650 var getRawEntityRecord2 = forward_resolver_default("getEntityRecord"); 19651 var getEditedEntityRecord2 = forward_resolver_default("getEntityRecord"); 19652 var getEntityRecords2 = (kind, name, query = {}) => async ({ dispatch: dispatch4, registry, resolveSelect: resolveSelect3 }) => { 19653 const configs = await resolveSelect3.getEntitiesConfig(kind); 19654 const entityConfig = configs.find( 19655 (config) => config.name === name && config.kind === kind 19656 ); 19657 if (!entityConfig) { 19658 return; 19659 } 19660 const lock2 = await dispatch4.__unstableAcquireStoreLock( 19661 STORE_NAME, 19662 ["entities", "records", kind, name], 19663 { exclusive: false } 19664 ); 19665 const rawQuery = { ...query }; 19666 const key = entityConfig.key || DEFAULT_ENTITY_KEY; 19667 function getResolutionsArgs(records, recordsQuery) { 19668 const normalizedQuery = normalizeQueryForResolution(recordsQuery); 19669 return records.filter((record) => record?.[key]).map((record) => [ 19670 kind, 19671 name, 19672 record[key], 19673 normalizedQuery 19674 ]); 19675 } 19676 try { 19677 if (query._fields) { 19678 query = { 19679 ...query, 19680 _fields: [ 19681 .../* @__PURE__ */ new Set([ 19682 ...get_normalized_comma_separable_default(query._fields) || [], 19683 key 19684 ]) 19685 ].join() 19686 }; 19687 } 19688 const { baseURL } = entityConfig; 19689 const path = (0, import_url6.addQueryArgs)(baseURL, { 19690 ...entityConfig.baseURLParams, 19691 ...query 19692 }); 19693 let records = [], meta; 19694 if (entityConfig.supportsPagination && query.per_page !== -1) { 19695 const response = await (0, import_api_fetch10.default)({ path, parse: false }); 19696 records = Object.values(await response.json()); 19697 meta = getPaginationMeta(response.headers); 19698 } else if (query.per_page === -1 && query[RECEIVE_INTERMEDIATE_RESULTS] === true) { 19699 let page = 1; 19700 let totalPages; 19701 do { 19702 const response = await (0, import_api_fetch10.default)({ 19703 path: (0, import_url6.addQueryArgs)(path, { page, per_page: 100 }), 19704 parse: false 19705 }); 19706 const pageRecords = Object.values(await response.json()); 19707 const pageMeta = getPaginationMeta(response.headers); 19708 totalPages = pageMeta.totalPages ?? 1; 19709 if (!meta) { 19710 meta = { 19711 totalItems: pageMeta.totalItems, 19712 totalPages: 1 19713 }; 19714 } 19715 records.push(...pageRecords); 19716 registry.batch(() => { 19717 dispatch4.receiveEntityRecords( 19718 kind, 19719 name, 19720 records, 19721 query, 19722 false, 19723 void 0, 19724 meta 19725 ); 19726 dispatch4.finishResolutions( 19727 "getEntityRecord", 19728 getResolutionsArgs(pageRecords, rawQuery) 19729 ); 19730 }); 19731 page++; 19732 } while (page <= totalPages); 19733 } else { 19734 records = Object.values(await (0, import_api_fetch10.default)({ path })); 19735 meta = { 19736 totalItems: records.length, 19737 totalPages: 1 19738 }; 19739 } 19740 if (-1 === query.per_page) { 19741 void getEntitySyncManager()?.loadCollection?.(kind, name, { 19742 refetchRecords: async () => { 19743 dispatch4.receiveEntityRecords( 19744 kind, 19745 name, 19746 await (0, import_api_fetch10.default)({ path, parse: true }), 19747 query 19748 ); 19749 } 19750 }); 19751 } 19752 if (query._fields) { 19753 records = records.map((record) => { 19754 query._fields.split(",").forEach((field) => { 19755 if (!record.hasOwnProperty(field)) { 19756 record[field] = void 0; 19757 } 19758 }); 19759 return record; 19760 }); 19761 } 19762 registry.batch(() => { 19763 dispatch4.receiveEntityRecords( 19764 kind, 19765 name, 19766 records, 19767 query, 19768 false, 19769 void 0, 19770 meta 19771 ); 19772 const targetHints = records.filter( 19773 (record) => !!record?.[key] && !!record?._links?.self?.[0]?.targetHints?.allow 19774 ).map((record) => ({ 19775 id: record[key], 19776 permissions: getUserPermissionsFromAllowHeader( 19777 record._links.self[0].targetHints.allow 19778 ) 19779 })); 19780 const canUserResolutionsArgs = []; 19781 const receiveUserPermissionArgs = {}; 19782 for (const targetHint of targetHints) { 19783 canUserResolutionsArgs.push([ 19784 { kind, name, id: targetHint.id } 19785 ]); 19786 for (const action of ALLOWED_RESOURCE_ACTIONS) { 19787 receiveUserPermissionArgs[getUserPermissionCacheKey(action, { 19788 kind, 19789 name, 19790 id: targetHint.id 19791 })] = targetHint.permissions[action]; 19792 } 19793 } 19794 if (targetHints.length > 0) { 19795 dispatch4.receiveUserPermissions( 19796 receiveUserPermissionArgs 19797 ); 19798 dispatch4.finishResolutions( 19799 "canUser", 19800 canUserResolutionsArgs 19801 ); 19802 } 19803 dispatch4.finishResolutions( 19804 "getEntityRecord", 19805 getResolutionsArgs(records, rawQuery) 19806 ); 19807 dispatch4.__unstableReleaseStoreLock(lock2); 19808 }); 19809 } catch { 19810 dispatch4.__unstableReleaseStoreLock(lock2); 19811 } 19812 }; 19813 getEntityRecords2.shouldInvalidate = (action, kind, name) => { 19814 return (action.type === "RECEIVE_ITEMS" || action.type === "REMOVE_ITEMS") && action.invalidateCache && kind === action.kind && name === action.name; 19815 }; 19816 var getEntityRecordsTotalItems2 = forward_resolver_default("getEntityRecords"); 19817 var getEntityRecordsTotalPages2 = forward_resolver_default("getEntityRecords"); 19818 var getCurrentTheme2 = () => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 19819 const activeThemes = await resolveSelect3.getEntityRecords( 19820 "root", 19821 "theme", 19822 { status: "active" } 19823 ); 19824 dispatch4.receiveCurrentTheme(activeThemes[0]); 19825 }; 19826 var getThemeSupports2 = forward_resolver_default("getCurrentTheme"); 19827 var getEmbedPreview2 = (url) => async ({ dispatch: dispatch4 }) => { 19828 try { 19829 const embedProxyResponse = await (0, import_api_fetch10.default)({ 19830 path: (0, import_url6.addQueryArgs)("/oembed/1.0/proxy", { url }) 19831 }); 19832 dispatch4.receiveEmbedPreview(url, embedProxyResponse); 19833 } catch { 19834 dispatch4.receiveEmbedPreview(url, false); 19835 } 19836 }; 19837 var canUser2 = (resource, id2) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 19838 let resourcePath = null; 19839 if (typeof resource === "object") { 19840 if (!resource.kind || !resource.name) { 19841 throw new Error("The entity resource object is not valid."); 19842 } 19843 const configs = await resolveSelect3.getEntitiesConfig( 19844 resource.kind 19845 ); 19846 const entityConfig = configs.find( 19847 (config) => config.name === resource.name && config.kind === resource.kind 19848 ); 19849 if (!entityConfig) { 19850 return; 19851 } 19852 resourcePath = entityConfig.baseURL + (resource.id ? "/" + resource.id : ""); 19853 } else { 19854 resourcePath = `/wp/v2/$resource}` + (id2 ? "/" + id2 : ""); 19855 } 19856 let response; 19857 try { 19858 response = await (0, import_api_fetch10.default)({ 19859 path: resourcePath, 19860 method: "OPTIONS", 19861 parse: false 19862 }); 19863 } catch { 19864 return; 19865 } 19866 const permissions = getUserPermissionsFromAllowHeader( 19867 response.headers?.get("allow") 19868 ); 19869 const receiveUserPermissionArgs = {}; 19870 for (const action of ALLOWED_RESOURCE_ACTIONS) { 19871 receiveUserPermissionArgs[getUserPermissionCacheKey(action, resource, id2)] = permissions[action]; 19872 } 19873 dispatch4.receiveUserPermissions(receiveUserPermissionArgs); 19874 }; 19875 canUser2.getResolutionArgs = (action, resource, id2) => [resource, id2]; 19876 var canUserEditEntityRecord2 = (kind, name, recordId) => async ({ resolveSelect: resolveSelect3 }) => { 19877 await resolveSelect3.canUser("update", { kind, name, id: recordId }); 19878 }; 19879 var getAutosaves2 = (postType, postId) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 19880 const { 19881 rest_base: restBase, 19882 rest_namespace: restNamespace = "wp/v2", 19883 supports 19884 } = await resolveSelect3.getPostType(postType); 19885 if (!supports?.autosave) { 19886 return; 19887 } 19888 const autosaves2 = await (0, import_api_fetch10.default)({ 19889 path: `/$restNamespace}/$restBase}/$postId}/autosaves?context=edit` 19890 }); 19891 if (autosaves2 && autosaves2.length) { 19892 dispatch4.receiveAutosaves(postId, autosaves2); 19893 } 19894 }; 19895 var getAutosave2 = (postType, postId) => async ({ resolveSelect: resolveSelect3 }) => { 19896 await resolveSelect3.getAutosaves(postType, postId); 19897 }; 19898 var __experimentalGetCurrentGlobalStylesId2 = () => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 19899 const activeThemes = await resolveSelect3.getEntityRecords( 19900 "root", 19901 "theme", 19902 { status: "active" } 19903 ); 19904 const globalStylesURL = activeThemes?.[0]?._links?.["wp:user-global-styles"]?.[0]?.href; 19905 if (!globalStylesURL) { 19906 return; 19907 } 19908 const matches = globalStylesURL.match(/\/(\d+)(?:\?|$)/); 19909 const id2 = matches ? Number(matches[1]) : null; 19910 if (id2) { 19911 dispatch4.__experimentalReceiveCurrentGlobalStylesId(id2); 19912 } 19913 }; 19914 var __experimentalGetCurrentThemeBaseGlobalStyles2 = () => async ({ resolveSelect: resolveSelect3, dispatch: dispatch4 }) => { 19915 const currentTheme2 = await resolveSelect3.getCurrentTheme(); 19916 const themeGlobalStyles = await (0, import_api_fetch10.default)({ 19917 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}?context=view` 19918 }); 19919 dispatch4.__experimentalReceiveThemeBaseGlobalStyles( 19920 currentTheme2.stylesheet, 19921 themeGlobalStyles 19922 ); 19923 }; 19924 var __experimentalGetCurrentThemeGlobalStylesVariations2 = () => async ({ resolveSelect: resolveSelect3, dispatch: dispatch4 }) => { 19925 const currentTheme2 = await resolveSelect3.getCurrentTheme(); 19926 const variations = await (0, import_api_fetch10.default)({ 19927 path: `/wp/v2/global-styles/themes/$currentTheme2.stylesheet}/variations?context=view` 19928 }); 19929 dispatch4.__experimentalReceiveThemeGlobalStyleVariations( 19930 currentTheme2.stylesheet, 19931 variations 19932 ); 19933 }; 19934 var getCurrentThemeGlobalStylesRevisions2 = () => async ({ resolveSelect: resolveSelect3, dispatch: dispatch4 }) => { 19935 const globalStylesId = await resolveSelect3.__experimentalGetCurrentGlobalStylesId(); 19936 const record = globalStylesId ? await resolveSelect3.getEntityRecord( 19937 "root", 19938 "globalStyles", 19939 globalStylesId 19940 ) : void 0; 19941 const revisionsURL = record?._links?.["version-history"]?.[0]?.href; 19942 if (revisionsURL) { 19943 const resetRevisions = await (0, import_api_fetch10.default)({ 19944 url: revisionsURL 19945 }); 19946 const revisions = resetRevisions?.map( 19947 (revision) => Object.fromEntries( 19948 Object.entries(revision).map(([key, value]) => [ 19949 camelCase(key), 19950 value 19951 ]) 19952 ) 19953 ); 19954 dispatch4.receiveThemeGlobalStyleRevisions( 19955 globalStylesId, 19956 revisions 19957 ); 19958 } 19959 }; 19960 getCurrentThemeGlobalStylesRevisions2.shouldInvalidate = (action) => { 19961 return action.type === "SAVE_ENTITY_RECORD_FINISH" && action.kind === "root" && !action.error && action.name === "globalStyles"; 19962 }; 19963 var getBlockPatterns2 = () => async ({ dispatch: dispatch4 }) => { 19964 const patterns = await fetchBlockPatterns(); 19965 dispatch4({ type: "RECEIVE_BLOCK_PATTERNS", patterns }); 19966 }; 19967 var getBlockPatternCategories2 = () => async ({ dispatch: dispatch4 }) => { 19968 const categories = await (0, import_api_fetch10.default)({ 19969 path: "/wp/v2/block-patterns/categories" 19970 }); 19971 dispatch4({ type: "RECEIVE_BLOCK_PATTERN_CATEGORIES", categories }); 19972 }; 19973 var getUserPatternCategories2 = () => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 19974 const patternCategories = await resolveSelect3.getEntityRecords( 19975 "taxonomy", 19976 "wp_pattern_category", 19977 { 19978 per_page: -1, 19979 _fields: "id,name,description,slug", 19980 context: "view" 19981 } 19982 ); 19983 const mappedPatternCategories = patternCategories?.map((userCategory) => ({ 19984 ...userCategory, 19985 label: (0, import_html_entities3.decodeEntities)(userCategory.name), 19986 name: userCategory.slug 19987 })) || []; 19988 dispatch4({ 19989 type: "RECEIVE_USER_PATTERN_CATEGORIES", 19990 patternCategories: mappedPatternCategories 19991 }); 19992 }; 19993 var getNavigationFallbackId2 = () => async ({ dispatch: dispatch4, select: select6, registry }) => { 19994 const fallback = await (0, import_api_fetch10.default)({ 19995 path: (0, import_url6.addQueryArgs)("/wp-block-editor/v1/navigation-fallback", { 19996 _embed: true 19997 }) 19998 }); 19999 const record = fallback?._embedded?.self; 20000 registry.batch(() => { 20001 dispatch4.receiveNavigationFallbackId(fallback?.id); 20002 if (!record) { 20003 return; 20004 } 20005 const existingFallbackEntityRecord = select6.getEntityRecord( 20006 "postType", 20007 "wp_navigation", 20008 fallback.id 20009 ); 20010 const invalidateNavigationQueries = !existingFallbackEntityRecord; 20011 dispatch4.receiveEntityRecords( 20012 "postType", 20013 "wp_navigation", 20014 record, 20015 void 0, 20016 invalidateNavigationQueries 20017 ); 20018 dispatch4.finishResolution("getEntityRecord", [ 20019 "postType", 20020 "wp_navigation", 20021 fallback.id 20022 ]); 20023 }); 20024 }; 20025 var getDefaultTemplateId2 = (query) => async ({ dispatch: dispatch4, registry, resolveSelect: resolveSelect3 }) => { 20026 const template = await (0, import_api_fetch10.default)({ 20027 path: (0, import_url6.addQueryArgs)("/wp/v2/templates/lookup", query) 20028 }); 20029 await resolveSelect3.getEntitiesConfig("postType"); 20030 const id2 = template?.id; 20031 registry.batch(() => { 20032 dispatch4.receiveDefaultTemplateId(query, id2 || ""); 20033 if (id2) { 20034 template.id = id2; 20035 dispatch4.receiveEntityRecords( 20036 "postType", 20037 template.type, 20038 template 20039 ); 20040 dispatch4.finishResolution("getEntityRecord", [ 20041 "postType", 20042 template.type, 20043 id2 20044 ]); 20045 } 20046 }); 20047 }; 20048 var getRevisions2 = (kind, name, recordKey, query = {}) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 20049 const configs = await resolveSelect3.getEntitiesConfig(kind); 20050 const entityConfig = configs.find( 20051 (config) => config.name === name && config.kind === kind 20052 ); 20053 if (!entityConfig) { 20054 return; 20055 } 20056 const rawQuery = { ...query }; 20057 const lock2 = await dispatch4.__unstableAcquireStoreLock( 20058 STORE_NAME, 20059 ["entities", "records", kind, name, recordKey, "revisions"], 20060 { exclusive: false } 20061 ); 20062 try { 20063 if (query._fields) { 20064 query = { 20065 ...query, 20066 _fields: [ 20067 .../* @__PURE__ */ new Set([ 20068 ...get_normalized_comma_separable_default(query._fields) || [], 20069 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 20070 ]) 20071 ].join() 20072 }; 20073 } 20074 const path = (0, import_url6.addQueryArgs)( 20075 entityConfig.getRevisionsUrl(recordKey), 20076 query 20077 ); 20078 let records, response; 20079 const meta = {}; 20080 const isPaginated = entityConfig.supportsPagination && query.per_page !== -1; 20081 try { 20082 response = await (0, import_api_fetch10.default)({ path, parse: !isPaginated }); 20083 } catch { 20084 return; 20085 } 20086 if (response) { 20087 if (isPaginated) { 20088 records = Object.values(await response.json()); 20089 meta.totalItems = getPaginationMeta( 20090 response.headers 20091 ).totalItems; 20092 } else { 20093 records = Object.values(response); 20094 } 20095 if (query._fields) { 20096 records = records.map((record) => { 20097 query._fields.split(",").forEach((field) => { 20098 if (!record.hasOwnProperty(field)) { 20099 record[field] = void 0; 20100 } 20101 }); 20102 return record; 20103 }); 20104 } 20105 await dispatch4.receiveRevisions( 20106 kind, 20107 name, 20108 recordKey, 20109 records, 20110 query, 20111 false, 20112 meta 20113 ); 20114 const key = entityConfig.revisionKey || DEFAULT_ENTITY_KEY; 20115 const normalizedQuery = normalizeQueryForResolution(rawQuery); 20116 const resolutionsArgs = records.filter((record) => record[key]).map((record) => [ 20117 kind, 20118 name, 20119 recordKey, 20120 record[key], 20121 normalizedQuery 20122 ]); 20123 dispatch4.finishResolutions("getRevision", resolutionsArgs); 20124 } 20125 } finally { 20126 dispatch4.__unstableReleaseStoreLock(lock2); 20127 } 20128 }; 20129 getRevisions2.shouldInvalidate = (action, kind, name, recordKey) => action.type === "SAVE_ENTITY_RECORD_FINISH" && name === action.name && kind === action.kind && !action.error && recordKey === action.recordId; 20130 var getRevision2 = (kind, name, recordKey, revisionKey, query) => async ({ select: select6, dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 20131 const configs = await resolveSelect3.getEntitiesConfig(kind); 20132 const entityConfig = configs.find( 20133 (config) => config.name === name && config.kind === kind 20134 ); 20135 if (!entityConfig) { 20136 return; 20137 } 20138 if (query !== void 0 && query._fields) { 20139 query = { 20140 ...query, 20141 _fields: [ 20142 .../* @__PURE__ */ new Set([ 20143 ...get_normalized_comma_separable_default(query._fields) || [], 20144 entityConfig.revisionKey || DEFAULT_ENTITY_KEY 20145 ]) 20146 ].join() 20147 }; 20148 } 20149 const lock2 = await dispatch4.__unstableAcquireStoreLock( 20150 STORE_NAME, 20151 [ 20152 "entities", 20153 "records", 20154 kind, 20155 name, 20156 recordKey, 20157 "revisions", 20158 revisionKey 20159 ], 20160 { exclusive: false } 20161 ); 20162 try { 20163 if (select6.hasRevision(kind, name, recordKey, revisionKey, query)) { 20164 return; 20165 } 20166 const path = (0, import_url6.addQueryArgs)( 20167 entityConfig.getRevisionsUrl(recordKey, revisionKey), 20168 query 20169 ); 20170 let record; 20171 try { 20172 record = await (0, import_api_fetch10.default)({ path }); 20173 } catch { 20174 return; 20175 } 20176 if (record) { 20177 await dispatch4.receiveRevisions( 20178 kind, 20179 name, 20180 recordKey, 20181 record, 20182 query 20183 ); 20184 } 20185 } finally { 20186 dispatch4.__unstableReleaseStoreLock(lock2); 20187 } 20188 }; 20189 var getRegisteredPostMeta2 = (postType) => async ({ dispatch: dispatch4, resolveSelect: resolveSelect3 }) => { 20190 let options; 20191 try { 20192 const { 20193 rest_namespace: restNamespace = "wp/v2", 20194 rest_base: restBase 20195 } = await resolveSelect3.getPostType(postType) || {}; 20196 options = await (0, import_api_fetch10.default)({ 20197 path: `$restNamespace}/$restBase}/?context=edit`, 20198 method: "OPTIONS" 20199 }); 20200 } catch { 20201 return; 20202 } 20203 if (options) { 20204 dispatch4.receiveRegisteredPostMeta( 20205 postType, 20206 options?.schema?.properties?.meta?.properties 20207 ); 20208 } 20209 }; 20210 var getEntitiesConfig2 = (kind) => async ({ dispatch: dispatch4 }) => { 20211 const loader = additionalEntityConfigLoaders.find( 20212 (l) => l.kind === kind 20213 ); 20214 if (!loader) { 20215 return; 20216 } 20217 try { 20218 const configs = await loader.loadEntities(); 20219 if (!configs.length) { 20220 return; 20221 } 20222 dispatch4.addEntities(configs); 20223 } catch { 20224 } 20225 }; 20226 var getEditorSettings2 = () => async ({ dispatch: dispatch4 }) => { 20227 const settings = await (0, import_api_fetch10.default)({ 20228 path: "/wp-block-editor/v1/settings" 20229 }); 20230 dispatch4.receiveEditorSettings(settings); 20231 }; 20232 var getEditorAssets2 = () => async ({ dispatch: dispatch4 }) => { 20233 const assets = await (0, import_api_fetch10.default)({ 20234 path: "/wp-block-editor/v1/assets" 20235 }); 20236 dispatch4.receiveEditorAssets(assets); 20237 }; 20238 var getViewConfig2 = (kind, name, options = {}) => async ({ dispatch: dispatch4 }) => { 20239 const query = { kind, name }; 20240 const fields = get_normalized_comma_separable_default(options.fields); 20241 if (fields?.length) { 20242 query._fields = fields.join(","); 20243 } 20244 const config = await (0, import_api_fetch10.default)({ 20245 path: (0, import_url6.addQueryArgs)("/wp/v2/view-config", query) 20246 }); 20247 dispatch4.receiveViewConfig(kind, name, config); 20248 }; 20249 var getFieldsConfig2 = (kind, name) => async ({ dispatch: dispatch4 }) => { 20250 const config = await (0, import_api_fetch10.default)({ 20251 path: (0, import_url6.addQueryArgs)("/wp/v2/entity-fields", { kind, name }) 20252 }); 20253 dispatch4.receiveFieldsConfig(kind, name, config); 20254 }; 20255 var getEntityActionsConfig2 = (kind, name) => async ({ dispatch: dispatch4 }) => { 20256 const config = await (0, import_api_fetch10.default)({ 20257 path: (0, import_url6.addQueryArgs)("/wp/v2/entity-actions", { kind, name }) 20258 }); 20259 dispatch4.receiveEntityActionsConfig(kind, name, config); 20260 }; 20261 20262 // packages/core-data/build-module/locks/utils.mjs 20263 function deepCopyLocksTreePath(tree, path) { 20264 const newTree = { ...tree }; 20265 let currentNode = newTree; 20266 for (const branchName of path) { 20267 currentNode.children = { 20268 ...currentNode.children, 20269 [branchName]: { 20270 locks: [], 20271 children: {}, 20272 ...currentNode.children[branchName] 20273 } 20274 }; 20275 currentNode = currentNode.children[branchName]; 20276 } 20277 return newTree; 20278 } 20279 function getNode(tree, path) { 20280 let currentNode = tree; 20281 for (const branchName of path) { 20282 const nextNode = currentNode.children[branchName]; 20283 if (!nextNode) { 20284 return null; 20285 } 20286 currentNode = nextNode; 20287 } 20288 return currentNode; 20289 } 20290 function* iteratePath(tree, path) { 20291 let currentNode = tree; 20292 yield currentNode; 20293 for (const branchName of path) { 20294 const nextNode = currentNode.children[branchName]; 20295 if (!nextNode) { 20296 break; 20297 } 20298 yield nextNode; 20299 currentNode = nextNode; 20300 } 20301 } 20302 function* iterateDescendants(node) { 20303 const stack = Object.values(node.children); 20304 while (stack.length) { 20305 const childNode = stack.pop(); 20306 yield childNode; 20307 stack.push(...Object.values(childNode.children)); 20308 } 20309 } 20310 function hasConflictingLock({ exclusive }, locks2) { 20311 if (exclusive && locks2.length) { 20312 return true; 20313 } 20314 if (!exclusive && locks2.filter((lock2) => lock2.exclusive).length) { 20315 return true; 20316 } 20317 return false; 20318 } 20319 20320 // packages/core-data/build-module/locks/reducer.mjs 20321 var DEFAULT_STATE = { 20322 requests: [], 20323 tree: { 20324 locks: [], 20325 children: {} 20326 } 20327 }; 20328 function locks(state = DEFAULT_STATE, action) { 20329 switch (action.type) { 20330 case "ENQUEUE_LOCK_REQUEST": { 20331 const { request } = action; 20332 return { 20333 ...state, 20334 requests: [request, ...state.requests] 20335 }; 20336 } 20337 case "GRANT_LOCK_REQUEST": { 20338 const { lock: lock2, request } = action; 20339 const { store: store2, path } = request; 20340 const storePath = [store2, ...path]; 20341 const newTree = deepCopyLocksTreePath(state.tree, storePath); 20342 const node = getNode(newTree, storePath); 20343 node.locks = [...node.locks, lock2]; 20344 return { 20345 ...state, 20346 requests: state.requests.filter((r2) => r2 !== request), 20347 tree: newTree 20348 }; 20349 } 20350 case "RELEASE_LOCK": { 20351 const { lock: lock2 } = action; 20352 const storePath = [lock2.store, ...lock2.path]; 20353 const newTree = deepCopyLocksTreePath(state.tree, storePath); 20354 const node = getNode(newTree, storePath); 20355 node.locks = node.locks.filter((l) => l !== lock2); 20356 return { 20357 ...state, 20358 tree: newTree 20359 }; 20360 } 20361 } 20362 return state; 20363 } 20364 20365 // packages/core-data/build-module/locks/selectors.mjs 20366 function getPendingLockRequests(state) { 20367 return state.requests; 20368 } 20369 function isLockAvailable(state, store2, path, { exclusive }) { 20370 const storePath = [store2, ...path]; 20371 const locks2 = state.tree; 20372 for (const node2 of iteratePath(locks2, storePath)) { 20373 if (hasConflictingLock({ exclusive }, node2.locks)) { 20374 return false; 20375 } 20376 } 20377 const node = getNode(locks2, storePath); 20378 if (!node) { 20379 return true; 20380 } 20381 for (const descendant of iterateDescendants(node)) { 20382 if (hasConflictingLock({ exclusive }, descendant.locks)) { 20383 return false; 20384 } 20385 } 20386 return true; 20387 } 20388 20389 // packages/core-data/build-module/locks/engine.mjs 20390 function createLocks() { 20391 let state = locks(void 0, { type: "@@INIT" }); 20392 function processPendingLockRequests() { 20393 for (const request of getPendingLockRequests(state)) { 20394 const { store: store2, path, exclusive, notifyAcquired } = request; 20395 if (isLockAvailable(state, store2, path, { exclusive })) { 20396 const lock2 = { store: store2, path, exclusive }; 20397 state = locks(state, { 20398 type: "GRANT_LOCK_REQUEST", 20399 lock: lock2, 20400 request 20401 }); 20402 notifyAcquired(lock2); 20403 } 20404 } 20405 } 20406 function acquire(store2, path, exclusive) { 20407 return new Promise((resolve) => { 20408 state = locks(state, { 20409 type: "ENQUEUE_LOCK_REQUEST", 20410 request: { store: store2, path, exclusive, notifyAcquired: resolve } 20411 }); 20412 processPendingLockRequests(); 20413 }); 20414 } 20415 function release(lock2) { 20416 state = locks(state, { 20417 type: "RELEASE_LOCK", 20418 lock: lock2 20419 }); 20420 processPendingLockRequests(); 20421 } 20422 return { acquire, release }; 20423 } 20424 20425 // packages/core-data/build-module/locks/actions.mjs 20426 function createLocksActions() { 20427 const locks2 = createLocks(); 20428 function __unstableAcquireStoreLock(store2, path, { exclusive }) { 20429 return () => locks2.acquire(store2, path, exclusive); 20430 } 20431 function __unstableReleaseStoreLock(lock2) { 20432 return () => locks2.release(lock2); 20433 } 20434 return { __unstableAcquireStoreLock, __unstableReleaseStoreLock }; 20435 } 20436 20437 // packages/core-data/build-module/dynamic-entities.mjs 20438 var dynamicActions; 20439 var dynamicSelectors; 20440 20441 // packages/core-data/build-module/entity-provider.mjs 20442 var import_element2 = __toESM(require_element(), 1); 20443 20444 // packages/core-data/build-module/entity-context.mjs 20445 var import_element = __toESM(require_element(), 1); 20446 var EntityContext = (0, import_element.createContext)({}); 20447 EntityContext.displayName = "EntityContext"; 20448 20449 // packages/core-data/build-module/entity-provider.mjs 20450 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); 20451 function EntityProvider({ 20452 kind, 20453 type, 20454 id: id2, 20455 revisionId, 20456 children 20457 }) { 20458 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( 20459 PrivateEntityProvider, 20460 { 20461 kind, 20462 type, 20463 id: id2, 20464 revisionId, 20465 children 20466 } 20467 ); 20468 } 20469 function PrivateEntityProvider({ 20470 kind, 20471 type: name, 20472 id: id2, 20473 revisionId, 20474 revision, 20475 children 20476 }) { 20477 const parent = (0, import_element2.useContext)(EntityContext); 20478 const providedRevision = revision ?? revisionId; 20479 const childContext = (0, import_element2.useMemo)( 20480 () => ({ 20481 ...parent, 20482 ...kind && { 20483 [kind]: { 20484 ...parent?.[kind], 20485 [name]: id2 20486 } 20487 }, 20488 ...providedRevision !== void 0 && kind && { 20489 revision: { 20490 ...parent?.revision, 20491 [kind]: { 20492 ...parent?.revision?.[kind], 20493 [name]: providedRevision 20494 } 20495 } 20496 } 20497 }), 20498 [parent, kind, name, id2, providedRevision] 20499 ); 20500 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EntityContext.Provider, { value: childContext, children }); 20501 } 20502 20503 // packages/core-data/build-module/hooks/use-entity-record.mjs 20504 var import_data12 = __toESM(require_data(), 1); 20505 var import_deprecated4 = __toESM(require_deprecated(), 1); 20506 var import_element3 = __toESM(require_element(), 1); 20507 20508 // packages/core-data/build-module/hooks/constants.mjs 20509 var Status = /* @__PURE__ */ ((Status2) => { 20510 Status2["Idle"] = "IDLE"; 20511 Status2["Resolving"] = "RESOLVING"; 20512 Status2["Error"] = "ERROR"; 20513 Status2["Success"] = "SUCCESS"; 20514 return Status2; 20515 })(Status || {}); 20516 20517 // packages/core-data/build-module/hooks/utils.mjs 20518 function getResolutionStatus(resolutionStatus) { 20519 let status; 20520 switch (resolutionStatus) { 20521 case "resolving": 20522 status = Status.Resolving; 20523 break; 20524 case "finished": 20525 status = Status.Success; 20526 break; 20527 case "error": 20528 status = Status.Error; 20529 break; 20530 default: 20531 status = Status.Idle; 20532 } 20533 return { 20534 status, 20535 isResolving: status === Status.Resolving, 20536 hasStarted: status !== Status.Idle, 20537 hasResolved: status === Status.Success || status === Status.Error 20538 }; 20539 } 20540 20541 // packages/core-data/build-module/hooks/use-entity-record.mjs 20542 var EMPTY_OBJECT3 = {}; 20543 function useEntityRecord(kind, name, recordId, options = { enabled: true }) { 20544 const { editEntityRecord: editEntityRecord2, saveEditedEntityRecord: saveEditedEntityRecord2 } = (0, import_data12.useDispatch)(store); 20545 const mutations = (0, import_element3.useMemo)( 20546 () => ({ 20547 edit: (record2, editOptions = {}) => editEntityRecord2(kind, name, recordId, record2, editOptions), 20548 save: (saveOptions = {}) => saveEditedEntityRecord2(kind, name, recordId, { 20549 throwOnError: true, 20550 ...saveOptions 20551 }) 20552 }), 20553 [editEntityRecord2, kind, name, recordId, saveEditedEntityRecord2] 20554 ); 20555 const { record, editedRecord, hasEdits, edits, ...resolution } = (0, import_data12.useSelect)( 20556 (select6) => { 20557 if (!options.enabled) { 20558 return { 20559 record: null, 20560 editedRecord: EMPTY_OBJECT3, 20561 hasEdits: false, 20562 edits: EMPTY_OBJECT3, 20563 ...getResolutionStatus() 20564 }; 20565 } 20566 const storeSelectors = select6(store); 20567 const resolutionStatus = storeSelectors.getResolutionState( 20568 "getEntityRecord", 20569 [kind, name, recordId] 20570 )?.status; 20571 return { 20572 record: storeSelectors.getEntityRecord( 20573 kind, 20574 name, 20575 recordId 20576 ) ?? null, 20577 editedRecord: storeSelectors.getEditedEntityRecord( 20578 kind, 20579 name, 20580 recordId 20581 ), 20582 hasEdits: storeSelectors.hasEditsForEntityRecord( 20583 kind, 20584 name, 20585 recordId 20586 ), 20587 edits: storeSelectors.getEntityRecordNonTransientEdits( 20588 kind, 20589 name, 20590 recordId 20591 ), 20592 ...getResolutionStatus(resolutionStatus) 20593 }; 20594 }, 20595 [kind, name, recordId, options.enabled] 20596 ); 20597 return { 20598 record, 20599 editedRecord, 20600 hasEdits, 20601 edits, 20602 ...resolution, 20603 ...mutations 20604 }; 20605 } 20606 function useDeprecatedEntityRecord(kind, name, recordId, options) { 20607 (0, import_deprecated4.default)(`wp.data.__experimentalUseEntityRecord`, { 20608 alternative: "wp.data.useEntityRecord", 20609 since: "6.1" 20610 }); 20611 return useEntityRecord(kind, name, recordId, options); 20612 } 20613 20614 // packages/core-data/build-module/hooks/use-entity-records.mjs 20615 var import_url7 = __toESM(require_url(), 1); 20616 var import_deprecated5 = __toESM(require_deprecated(), 1); 20617 var import_data13 = __toESM(require_data(), 1); 20618 var import_element4 = __toESM(require_element(), 1); 20619 var EMPTY_ARRAY = []; 20620 function useEntityRecords(kind, name, queryArgs = {}, options = { enabled: true }) { 20621 const queryAsString = (0, import_url7.addQueryArgs)("", queryArgs); 20622 const { records, totalItems, totalPages, ...rest } = (0, import_data13.useSelect)( 20623 (select6) => { 20624 if (!options.enabled) { 20625 return { 20626 // Avoiding returning a new reference on every execution. 20627 records: EMPTY_ARRAY, 20628 totalItems: null, 20629 totalPages: null, 20630 ...getResolutionStatus() 20631 }; 20632 } 20633 const storeSelectors = select6(store); 20634 const resolutionStatus = storeSelectors.getResolutionState( 20635 "getEntityRecords", 20636 [kind, name, queryArgs] 20637 )?.status; 20638 return { 20639 records: storeSelectors.getEntityRecords( 20640 kind, 20641 name, 20642 queryArgs 20643 ), 20644 totalItems: storeSelectors.getEntityRecordsTotalItems( 20645 kind, 20646 name, 20647 queryArgs 20648 ), 20649 totalPages: storeSelectors.getEntityRecordsTotalPages( 20650 kind, 20651 name, 20652 queryArgs 20653 ), 20654 ...getResolutionStatus(resolutionStatus) 20655 }; 20656 }, 20657 [kind, name, queryAsString, options.enabled] 20658 ); 20659 return { 20660 records, 20661 totalItems, 20662 totalPages, 20663 ...rest 20664 }; 20665 } 20666 function useDeprecatedEntityRecords(kind, name, queryArgs, options) { 20667 (0, import_deprecated5.default)(`wp.data.__experimentalUseEntityRecords`, { 20668 alternative: "wp.data.useEntityRecords", 20669 since: "6.1" 20670 }); 20671 return useEntityRecords(kind, name, queryArgs, options); 20672 } 20673 function useEntityRecordsWithPermissions(kind, name, queryArgs = {}, options = { enabled: true }) { 20674 const entityConfig = (0, import_data13.useSelect)( 20675 (select6) => select6(store).getEntityConfig(kind, name), 20676 [kind, name] 20677 ); 20678 const { records: data, ...ret } = useEntityRecords( 20679 kind, 20680 name, 20681 { 20682 ...queryArgs, 20683 // If _fields is provided, we need to include _links in the request for permission caching to work. 20684 ...queryArgs._fields ? { 20685 _fields: [ 20686 .../* @__PURE__ */ new Set([ 20687 ...get_normalized_comma_separable_default( 20688 queryArgs._fields 20689 ) || [], 20690 "_links" 20691 ]) 20692 ].join() 20693 } : {} 20694 }, 20695 options 20696 ); 20697 const ids = (0, import_element4.useMemo)( 20698 () => data?.map( 20699 // @ts-expect-error `data` is `unknown[]`, so the callback signature does not line up. 20700 (record) => record[entityConfig?.key ?? "id"] 20701 ) ?? [], 20702 [data, entityConfig?.key] 20703 ); 20704 const permissions = (0, import_data13.useSelect)( 20705 (select6) => { 20706 const { getEntityRecordsPermissions: getEntityRecordsPermissions2 } = unlock( 20707 select6(store) 20708 ); 20709 return getEntityRecordsPermissions2(kind, name, ids); 20710 }, 20711 [ids, kind, name] 20712 ); 20713 const dataWithPermissions = (0, import_element4.useMemo)( 20714 () => data?.map((record, index) => ({ 20715 // @ts-expect-error `record` is `unknown`, which cannot be spread. 20716 ...record, 20717 permissions: permissions[index] 20718 })) ?? [], 20719 [data, permissions] 20720 ); 20721 return { records: dataWithPermissions, ...ret }; 20722 } 20723 20724 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 20725 var import_deprecated6 = __toESM(require_deprecated(), 1); 20726 var import_warning2 = __toESM(require_warning(), 1); 20727 20728 // packages/core-data/build-module/hooks/use-query-select.mjs 20729 var import_data14 = __toESM(require_data(), 1); 20730 20731 // node_modules/.store/memize@2.1.1-roXbtpG2bis3Lggp7SQpAA/node_modules/memize/dist/index.js 20732 function memize(fn, options) { 20733 var size2 = 0; 20734 var head; 20735 var tail; 20736 options = options || {}; 20737 function memoized() { 20738 var node = head, len = arguments.length, args2, i; 20739 searchCache: while (node) { 20740 if (node.args.length !== arguments.length) { 20741 node = node.next; 20742 continue; 20743 } 20744 for (i = 0; i < len; i++) { 20745 if (node.args[i] !== arguments[i]) { 20746 node = node.next; 20747 continue searchCache; 20748 } 20749 } 20750 if (node !== head) { 20751 if (node === tail) { 20752 tail = node.prev; 20753 } 20754 node.prev.next = node.next; 20755 if (node.next) { 20756 node.next.prev = node.prev; 20757 } 20758 node.next = head; 20759 node.prev = null; 20760 head.prev = node; 20761 head = node; 20762 } 20763 return node.val; 20764 } 20765 args2 = new Array(len); 20766 for (i = 0; i < len; i++) { 20767 args2[i] = arguments[i]; 20768 } 20769 node = { 20770 args: args2, 20771 // Generate the result from original function 20772 val: fn.apply(null, args2) 20773 }; 20774 if (head) { 20775 head.prev = node; 20776 node.next = head; 20777 } else { 20778 tail = node; 20779 } 20780 if (size2 === /** @type {MemizeOptions} */ 20781 options.maxSize) { 20782 tail = /** @type {MemizeCacheNode} */ 20783 tail.prev; 20784 tail.next = null; 20785 } else { 20786 size2++; 20787 } 20788 head = node; 20789 return node.val; 20790 } 20791 memoized.clear = function() { 20792 head = null; 20793 tail = null; 20794 size2 = 0; 20795 }; 20796 return memoized; 20797 } 20798 20799 // packages/core-data/build-module/hooks/use-query-select.mjs 20800 var META_SELECTORS = [ 20801 "getIsResolving", 20802 "hasStartedResolution", 20803 "hasFinishedResolution", 20804 "isResolving", 20805 "getCachedResolvers" 20806 ]; 20807 function useQuerySelect(mapQuerySelect, deps) { 20808 return (0, import_data14.useSelect)((select6, registry) => { 20809 const resolve = (store2) => enrichSelectors(select6(store2)); 20810 return mapQuerySelect(resolve, registry); 20811 }, deps); 20812 } 20813 var enrichSelectors = memize(((selectors) => { 20814 const resolvers = {}; 20815 for (const selectorName in selectors) { 20816 if (META_SELECTORS.includes(selectorName)) { 20817 continue; 20818 } 20819 Object.defineProperty(resolvers, selectorName, { 20820 get: () => (...args2) => { 20821 const data = selectors[selectorName](...args2); 20822 const resolutionStatus = selectors.getResolutionState( 20823 selectorName, 20824 args2 20825 )?.status; 20826 return { 20827 data, 20828 ...getResolutionStatus(resolutionStatus) 20829 }; 20830 } 20831 }); 20832 } 20833 return resolvers; 20834 })); 20835 20836 // packages/core-data/build-module/hooks/use-resource-permissions.mjs 20837 function useResourcePermissions(resource, id2) { 20838 const isEntity = typeof resource === "object"; 20839 const resourceAsString = isEntity ? JSON.stringify(resource) : resource; 20840 if (isEntity && typeof id2 !== "undefined") { 20841 (0, import_warning2.default)( 20842 `When 'resource' is an entity object, passing 'id' as a separate argument isn't supported.` 20843 ); 20844 } 20845 return useQuerySelect( 20846 (resolve) => { 20847 const hasId = isEntity ? !!resource.id : !!id2; 20848 const { canUser: canUser3 } = resolve(store); 20849 const collectionResource = isEntity ? { kind: resource.kind, name: resource.name } : resource; 20850 const create9 = canUser3("create", collectionResource); 20851 if (!hasId) { 20852 const read2 = canUser3("read", collectionResource); 20853 const isResolving2 = create9.isResolving || read2.isResolving; 20854 const hasResolved2 = create9.hasResolved && read2.hasResolved; 20855 let status2 = Status.Idle; 20856 if (isResolving2) { 20857 status2 = Status.Resolving; 20858 } else if (hasResolved2) { 20859 status2 = Status.Success; 20860 } 20861 return { 20862 status: status2, 20863 isResolving: isResolving2, 20864 hasResolved: hasResolved2, 20865 canCreate: create9.hasResolved && create9.data, 20866 canRead: read2.hasResolved && read2.data 20867 }; 20868 } 20869 const read = canUser3("read", resource, id2); 20870 const update = canUser3("update", resource, id2); 20871 const _delete = canUser3("delete", resource, id2); 20872 const isResolving = read.isResolving || create9.isResolving || update.isResolving || _delete.isResolving; 20873 const hasResolved = read.hasResolved && create9.hasResolved && update.hasResolved && _delete.hasResolved; 20874 let status = Status.Idle; 20875 if (isResolving) { 20876 status = Status.Resolving; 20877 } else if (hasResolved) { 20878 status = Status.Success; 20879 } 20880 return { 20881 status, 20882 isResolving, 20883 hasResolved, 20884 canRead: hasResolved && read.data, 20885 canCreate: hasResolved && create9.data, 20886 canUpdate: hasResolved && update.data, 20887 canDelete: hasResolved && _delete.data 20888 }; 20889 }, 20890 [resourceAsString, id2] 20891 ); 20892 } 20893 var use_resource_permissions_default = useResourcePermissions; 20894 function useDeprecatedResourcePermissions(resource, id2) { 20895 (0, import_deprecated6.default)(`wp.data.__experimentalUseResourcePermissions`, { 20896 alternative: "wp.data.useResourcePermissions", 20897 since: "6.1" 20898 }); 20899 return useResourcePermissions(resource, id2); 20900 } 20901 20902 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 20903 var import_element6 = __toESM(require_element(), 1); 20904 var import_data15 = __toESM(require_data(), 1); 20905 var import_blocks6 = __toESM(require_blocks(), 1); 20906 20907 // packages/core-data/build-module/hooks/use-entity-id.mjs 20908 var import_element5 = __toESM(require_element(), 1); 20909 function useEntityId(kind, name) { 20910 const context = (0, import_element5.useContext)(EntityContext); 20911 return context?.[kind]?.[name]; 20912 } 20913 20914 // packages/core-data/build-module/footnotes/index.mjs 20915 var import_rich_text4 = __toESM(require_rich_text(), 1); 20916 var import_warning3 = __toESM(require_warning(), 1); 20917 20918 // packages/core-data/build-module/footnotes/get-rich-text-values-cached.mjs 20919 var import_block_editor6 = __toESM(require_block_editor(), 1); 20920 var unlockedApis; 20921 var cache = /* @__PURE__ */ new WeakMap(); 20922 function getRichTextValuesCached(block) { 20923 if (!unlockedApis) { 20924 unlockedApis = unlock(import_block_editor6.privateApis); 20925 } 20926 if (!cache.has(block)) { 20927 const values = unlockedApis.getRichTextValues([block]); 20928 cache.set(block, values); 20929 } 20930 return cache.get(block); 20931 } 20932 20933 // packages/core-data/build-module/footnotes/get-footnotes-order.mjs 20934 var cache2 = /* @__PURE__ */ new WeakMap(); 20935 function getBlockFootnotesOrder(block) { 20936 if (!cache2.has(block)) { 20937 const order = []; 20938 for (const value of getRichTextValuesCached(block)) { 20939 if (!value) { 20940 continue; 20941 } 20942 value.replacements.forEach(({ type, attributes }) => { 20943 if (type === "core/footnote") { 20944 order.push(attributes["data-fn"]); 20945 } 20946 }); 20947 } 20948 cache2.set(block, order); 20949 } 20950 return cache2.get(block); 20951 } 20952 function getFootnotesOrder(blocks) { 20953 return blocks.flatMap(getBlockFootnotesOrder); 20954 } 20955 20956 // packages/core-data/build-module/footnotes/index.mjs 20957 var oldFootnotes = {}; 20958 function updateFootnotesFromMeta(blocks, meta) { 20959 const output = { blocks }; 20960 if (!meta) { 20961 return output; 20962 } 20963 if (meta.footnotes === void 0) { 20964 return output; 20965 } 20966 const newOrder = getFootnotesOrder(blocks); 20967 let parsed; 20968 try { 20969 parsed = JSON.parse(meta.footnotes || "[]"); 20970 } catch { 20971 } 20972 let footnotes = []; 20973 if (Array.isArray(parsed)) { 20974 footnotes = parsed; 20975 } else { 20976 (0, import_warning3.default)("Footnotes post meta is not a JSON array; ignoring it."); 20977 } 20978 const currentOrder = footnotes.map((fn) => fn.id); 20979 if (currentOrder.join("") === newOrder.join("")) { 20980 return output; 20981 } 20982 const newFootnotes = newOrder.map( 20983 (fnId) => footnotes.find((fn) => fn.id === fnId) || oldFootnotes[fnId] || { 20984 id: fnId, 20985 content: "" 20986 } 20987 ); 20988 function updateAttributes(attributes) { 20989 if (!attributes || Array.isArray(attributes) || typeof attributes !== "object") { 20990 return attributes; 20991 } 20992 attributes = { ...attributes }; 20993 for (const key in attributes) { 20994 const value = attributes[key]; 20995 if (Array.isArray(value)) { 20996 attributes[key] = value.map(updateAttributes); 20997 continue; 20998 } 20999 if (typeof value !== "string" && !(value instanceof import_rich_text4.RichTextData)) { 21000 continue; 21001 } 21002 const richTextValue = typeof value === "string" ? import_rich_text4.RichTextData.fromHTMLString(value) : new import_rich_text4.RichTextData(value); 21003 let hasFootnotes = false; 21004 richTextValue.replacements.forEach((replacement) => { 21005 if (replacement.type === "core/footnote") { 21006 const id2 = replacement.attributes["data-fn"]; 21007 const index = newOrder.indexOf(id2); 21008 const countValue = (0, import_rich_text4.create)({ 21009 html: replacement.innerHTML 21010 }); 21011 countValue.text = String(index + 1); 21012 countValue.formats = Array.from( 21013 { length: countValue.text.length }, 21014 () => countValue.formats[0] 21015 ); 21016 countValue.replacements = Array.from( 21017 { length: countValue.text.length }, 21018 () => countValue.replacements[0] 21019 ); 21020 replacement.innerHTML = (0, import_rich_text4.toHTMLString)({ 21021 value: countValue 21022 }); 21023 hasFootnotes = true; 21024 } 21025 }); 21026 if (hasFootnotes) { 21027 attributes[key] = typeof value === "string" ? richTextValue.toHTMLString() : richTextValue; 21028 } 21029 } 21030 return attributes; 21031 } 21032 function updateBlocksAttributes(__blocks) { 21033 return __blocks.map((block) => { 21034 return { 21035 ...block, 21036 attributes: updateAttributes(block.attributes), 21037 innerBlocks: updateBlocksAttributes(block.innerBlocks) 21038 }; 21039 }); 21040 } 21041 const newBlocks = updateBlocksAttributes(blocks); 21042 oldFootnotes = { 21043 ...oldFootnotes, 21044 ...footnotes.reduce((acc, fn) => { 21045 if (!newOrder.includes(fn.id)) { 21046 acc[fn.id] = fn; 21047 } 21048 return acc; 21049 }, {}) 21050 }; 21051 return { 21052 meta: { 21053 ...meta, 21054 footnotes: JSON.stringify(newFootnotes) 21055 }, 21056 blocks: newBlocks 21057 }; 21058 } 21059 21060 // packages/core-data/build-module/hooks/use-entity-block-editor.mjs 21061 var EMPTY_ARRAY2 = []; 21062 function useEntityBlockEditor(kind, name, { id: _id } = {}) { 21063 const providerId = useEntityId(kind, name); 21064 const id2 = _id ?? providerId; 21065 const { content, editedBlocks, meta } = (0, import_data15.useSelect)( 21066 (select6) => { 21067 if (!id2) { 21068 return {}; 21069 } 21070 const { getEditedEntityRecord: getEditedEntityRecord3 } = select6(STORE_NAME); 21071 const editedRecord = getEditedEntityRecord3(kind, name, id2); 21072 return { 21073 editedBlocks: editedRecord.blocks, 21074 content: editedRecord.content, 21075 meta: editedRecord.meta 21076 }; 21077 }, 21078 [kind, name, id2] 21079 ); 21080 const { __unstableCreateUndoLevel: __unstableCreateUndoLevel2, editEntityRecord: editEntityRecord2 } = (0, import_data15.useDispatch)(STORE_NAME); 21081 const blocks = (0, import_element6.useMemo)(() => { 21082 if (!id2) { 21083 return void 0; 21084 } 21085 if (editedBlocks) { 21086 return editedBlocks; 21087 } 21088 if (!content || typeof content !== "string") { 21089 return EMPTY_ARRAY2; 21090 } 21091 let _blocks = getCachedBlocks(kind, name, id2, content); 21092 if (!_blocks) { 21093 _blocks = (0, import_blocks6.parse)(content); 21094 setCachedBlocks(kind, name, id2, content, _blocks); 21095 } 21096 return _blocks; 21097 }, [kind, name, id2, editedBlocks, content]); 21098 const onChange = (0, import_element6.useCallback)( 21099 (newBlocks, options) => { 21100 const noChange = blocks === newBlocks; 21101 if (noChange) { 21102 return __unstableCreateUndoLevel2(kind, name, id2); 21103 } 21104 const { selection, ...rest } = options; 21105 const edits = { 21106 selection, 21107 content: ({ blocks: blocksForSerialization = [] }) => (0, import_blocks6.__unstableSerializeAndClean)(blocksForSerialization), 21108 ...updateFootnotesFromMeta(newBlocks, meta) 21109 }; 21110 editEntityRecord2(kind, name, id2, edits, { 21111 isCached: false, 21112 ...rest 21113 }); 21114 }, 21115 [ 21116 kind, 21117 name, 21118 id2, 21119 blocks, 21120 meta, 21121 __unstableCreateUndoLevel2, 21122 editEntityRecord2 21123 ] 21124 ); 21125 const onInput = (0, import_element6.useCallback)( 21126 (newBlocks, options) => { 21127 const { selection, ...rest } = options; 21128 const edits = { 21129 selection, 21130 ...updateFootnotesFromMeta(newBlocks, meta) 21131 }; 21132 editEntityRecord2(kind, name, id2, edits, { 21133 isCached: true, 21134 ...rest 21135 }); 21136 }, 21137 [kind, name, id2, meta, editEntityRecord2] 21138 ); 21139 return [blocks, onInput, onChange]; 21140 } 21141 21142 // packages/core-data/build-module/hooks/use-entity-prop.mjs 21143 var import_element7 = __toESM(require_element(), 1); 21144 var import_data16 = __toESM(require_data(), 1); 21145 var REVISION_QUERY = { 21146 context: "edit", 21147 _fields: "id,date,author,meta,title,excerpt,content.raw" 21148 }; 21149 function useEntityProp(kind, name, prop, _id) { 21150 const providerId = useEntityId(kind, name); 21151 const id2 = _id ?? providerId; 21152 const context = (0, import_element7.useContext)(EntityContext); 21153 const providedRevision = String(id2) === String(providerId) ? context?.revision?.[kind]?.[name] : void 0; 21154 const revisionRecord = typeof providedRevision === "object" ? providedRevision : void 0; 21155 const revisionId = revisionRecord ? void 0 : providedRevision; 21156 const isRevision = !!(revisionRecord || revisionId); 21157 const { value, fullValue } = (0, import_data16.useSelect)( 21158 (select6) => { 21159 if (revisionRecord ? prop in revisionRecord : revisionId) { 21160 const revision = revisionRecord ?? select6(STORE_NAME).getRevision( 21161 kind, 21162 name, 21163 id2, 21164 revisionId, 21165 REVISION_QUERY 21166 ); 21167 const propValue = revision?.[prop]; 21168 if (propValue === void 0) { 21169 return {}; 21170 } 21171 const isRawAttribute = propValue !== null && typeof propValue === "object" && "raw" in propValue; 21172 return { 21173 value: isRawAttribute ? propValue.raw : propValue, 21174 fullValue: propValue 21175 }; 21176 } 21177 const { getEntityRecord: getEntityRecord3, getEditedEntityRecord: getEditedEntityRecord3 } = select6(STORE_NAME); 21178 const record = getEntityRecord3(kind, name, id2); 21179 const editedRecord = getEditedEntityRecord3(kind, name, id2); 21180 return record && editedRecord ? { 21181 value: editedRecord[prop], 21182 fullValue: record[prop] 21183 } : {}; 21184 }, 21185 [kind, name, id2, prop, revisionId, revisionRecord] 21186 ); 21187 const { editEntityRecord: editEntityRecord2 } = (0, import_data16.useDispatch)(STORE_NAME); 21188 const setValue = (0, import_element7.useCallback)( 21189 (newValue) => { 21190 if (isRevision) { 21191 return; 21192 } 21193 editEntityRecord2(kind, name, id2, { 21194 [prop]: newValue 21195 }); 21196 }, 21197 [editEntityRecord2, kind, name, id2, prop, isRevision] 21198 ); 21199 return [value, setValue, fullValue]; 21200 } 21201 21202 // packages/core-data/build-module/hooks/use-post-editor-awareness-state.mjs 21203 var import_compose3 = __toESM(require_compose(), 1); 21204 var import_element8 = __toESM(require_element(), 1); 21205 var defaultResolvedSelection = { 21206 richTextOffset: null, 21207 localClientId: null, 21208 attributeKey: null 21209 }; 21210 var defaultState = { 21211 activeCollaborators: [], 21212 resolveSelection: () => defaultResolvedSelection, 21213 getDebugData: () => ({ 21214 doc: {}, 21215 clients: {}, 21216 collaboratorMap: {} 21217 }), 21218 isCurrentCollaboratorDisconnected: false 21219 }; 21220 function getAwarenessState(awareness, newState) { 21221 const activeCollaborators = (newState ?? awareness.getCurrentState()).filter( 21222 (collaborator) => isCollaboratorInfo(collaborator.collaboratorInfo) 21223 ); 21224 return { 21225 activeCollaborators, 21226 resolveSelection: (selection, blocks) => awareness.convertSelectionStateToAbsolute(selection, blocks), 21227 getDebugData: () => awareness.getDebugData(), 21228 isCurrentCollaboratorDisconnected: activeCollaborators.find((collaborator) => collaborator.isMe)?.isConnected === false 21229 }; 21230 } 21231 function usePostEditorAwarenessState(postId, postType) { 21232 const [state, setState] = (0, import_element8.useState)(defaultState); 21233 (0, import_element8.useEffect)(() => { 21234 if (null === postId || null === postType) { 21235 setState(defaultState); 21236 return; 21237 } 21238 const objectType = `postType/$postType}`; 21239 const objectId = postId.toString(); 21240 const awareness = getSyncManager()?.getAwareness( 21241 objectType, 21242 objectId 21243 ); 21244 if (!awareness) { 21245 setState(defaultState); 21246 return; 21247 } 21248 awareness.setUp(); 21249 setState(getAwarenessState(awareness)); 21250 const unsubscribe = awareness?.onStateChange( 21251 (newState) => { 21252 setState(getAwarenessState(awareness, newState)); 21253 } 21254 ); 21255 return unsubscribe; 21256 }, [postId, postType]); 21257 return state; 21258 } 21259 function useActiveCollaborators(postId, postType) { 21260 return usePostEditorAwarenessState(postId, postType).activeCollaborators; 21261 } 21262 function useResolvedSelection(postId, postType) { 21263 const blocks = usePostContentBlocks(); 21264 const awarenessState = usePostEditorAwarenessState(postId, postType); 21265 return (0, import_element8.useCallback)( 21266 (selection) => awarenessState.resolveSelection(selection, blocks), 21267 [blocks, awarenessState] 21268 ); 21269 } 21270 function useLastPostSave(postId, postType) { 21271 const [lastSave, setLastSave] = (0, import_element8.useState)(null); 21272 (0, import_element8.useEffect)(() => { 21273 if (null === postId || null === postType) { 21274 setLastSave(null); 21275 return; 21276 } 21277 const awareness = getSyncManager()?.getAwareness( 21278 `postType/$postType}`, 21279 postId.toString() 21280 ); 21281 if (!awareness) { 21282 setLastSave(null); 21283 return; 21284 } 21285 awareness.setUp(); 21286 const stateMap = awareness.doc.getMap("state"); 21287 const recordMap = awareness.doc.getMap("document"); 21288 const setupTime = Date.now(); 21289 const observer = (event) => { 21290 if (event.keysChanged.has("savedAt")) { 21291 const savedAt = stateMap.get("savedAt"); 21292 const savedByClientId = stateMap.get("savedBy"); 21293 if (typeof savedAt === "number" && typeof savedByClientId === "number" && savedAt > setupTime) { 21294 const postStatus = recordMap.get("status"); 21295 setLastSave({ savedAt, savedByClientId, postStatus }); 21296 } 21297 } 21298 }; 21299 stateMap.observe(observer); 21300 return () => { 21301 stateMap.unobserve(observer); 21302 }; 21303 }, [postId, postType]); 21304 return lastSave; 21305 } 21306 function useOnCollaboratorJoin(postId, postType, callback) { 21307 const { activeCollaborators } = usePostEditorAwarenessState( 21308 postId, 21309 postType 21310 ); 21311 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 21312 (0, import_element8.useEffect)(() => { 21313 if (!prevCollaborators || prevCollaborators.length === 0) { 21314 return; 21315 } 21316 const prevMap = new Map( 21317 prevCollaborators.map((collaborator) => [ 21318 collaborator.clientId, 21319 collaborator 21320 ]) 21321 ); 21322 const me = activeCollaborators.find( 21323 (collaborator) => collaborator.isMe 21324 ); 21325 for (const collaborator of activeCollaborators) { 21326 if (!prevMap.has(collaborator.clientId) && !collaborator.isMe) { 21327 callback(collaborator, me); 21328 } 21329 } 21330 }, [activeCollaborators, prevCollaborators, callback]); 21331 } 21332 function useOnCollaboratorLeave(postId, postType, callback) { 21333 const { activeCollaborators } = usePostEditorAwarenessState( 21334 postId, 21335 postType 21336 ); 21337 const prevCollaborators = (0, import_compose3.usePrevious)(activeCollaborators); 21338 (0, import_element8.useEffect)(() => { 21339 if (!prevCollaborators || prevCollaborators.length === 0) { 21340 return; 21341 } 21342 const newMap = new Map( 21343 activeCollaborators.map((collaborator) => [ 21344 collaborator.clientId, 21345 collaborator 21346 ]) 21347 ); 21348 for (const prevCollab of prevCollaborators) { 21349 if (prevCollab.isMe || !prevCollab.isConnected) { 21350 continue; 21351 } 21352 const newCollab = newMap.get(prevCollab.clientId); 21353 if (!newCollab?.isConnected) { 21354 callback(prevCollab); 21355 } 21356 } 21357 }, [activeCollaborators, prevCollaborators, callback]); 21358 } 21359 function useOnPostSave(postId, postType, callback) { 21360 const { activeCollaborators } = usePostEditorAwarenessState( 21361 postId, 21362 postType 21363 ); 21364 const lastPostSave = useLastPostSave(postId, postType); 21365 const prevPostSave = (0, import_compose3.usePrevious)(lastPostSave); 21366 (0, import_element8.useEffect)(() => { 21367 if (!lastPostSave) { 21368 return; 21369 } 21370 if (prevPostSave && lastPostSave.savedAt === prevPostSave.savedAt) { 21371 return; 21372 } 21373 const saver = activeCollaborators.find( 21374 (collaborator) => collaborator.clientId === lastPostSave.savedByClientId && !collaborator.isMe 21375 ); 21376 if (!saver) { 21377 return; 21378 } 21379 callback(lastPostSave, saver, prevPostSave ?? null); 21380 }, [lastPostSave, prevPostSave, activeCollaborators, callback]); 21381 } 21382 21383 // packages/icons/build-module/library/footer.mjs 21384 var import_primitives = __toESM(require_primitives(), 1); 21385 var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); 21386 var footer_default = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_primitives.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [ 21387 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primitives.Path, { d: "M9.75 4.75H18C18.6904 4.75 19.25 5.30964 19.25 6V14.25M9.75 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V14.25M9.75 4.75V14.25M19.25 14.25V18C19.25 18.6904 18.6904 19.25 18 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V14.25M19.25 14.25H9.75M9.75 14.25H4.75" }), 21388 /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_primitives.Path, { d: "M19.25 15.5V18C19.25 18.6904 18.6904 19.25 18 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V15.5C4.75 14.8096 5.30964 14.25 6 14.25H18C18.6904 14.25 19.25 14.8096 19.25 15.5Z", fill: "currentColor" }) 21389 ] }); 21390 21391 // packages/icons/build-module/library/header.mjs 21392 var import_primitives2 = __toESM(require_primitives(), 1); 21393 var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); 21394 var header_default = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_primitives2.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [ 21395 /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_primitives2.Path, { d: "M9.75 19.25H18C18.6904 19.25 19.25 18.6904 19.25 18V9.75M9.75 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V9.75M9.75 19.25V9.75M19.25 9.75V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V9.75M19.25 9.75H9.75M9.75 9.75H4.75" }), 21396 /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_primitives2.Path, { d: "M19.25 8.5V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V8.5C4.75 9.19036 5.30964 9.75 6 9.75H18C18.6904 9.75 19.25 9.19036 19.25 8.5Z", fill: "currentColor" }) 21397 ] }); 21398 21399 // packages/icons/build-module/library/layout.mjs 21400 var import_primitives3 = __toESM(require_primitives(), 1); 21401 var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); 21402 var layout_default = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_primitives3.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_primitives3.Path, { d: "M9.75 19.25H18C18.6904 19.25 19.25 18.6904 19.25 18V9.75M9.75 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V9.75M9.75 19.25V9.75M19.25 9.75V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V9.75M19.25 9.75H9.75M9.75 9.75H4.75" }) }); 21403 21404 // packages/icons/build-module/library/navigation-overlay.mjs 21405 var import_primitives4 = __toESM(require_primitives(), 1); 21406 var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); 21407 var navigation_overlay_default = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_primitives4.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [ 21408 /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_primitives4.Path, { d: "M4.75 9.25V16C4.75 16.6904 5.30964 17.25 6 17.25H8M4.75 9.25V6C4.75 5.30964 5.30964 4.75 6 4.75H16C16.6904 4.75 17.25 5.30964 17.25 6V8M4.75 9.25H8" }), 21409 /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_primitives4.Path, { d: "M10.75 11.25C10.75 10.9739 10.9739 10.75 11.25 10.75H18.75C19.0261 10.75 19.25 10.9739 19.25 11.25V18.75C19.25 19.0261 19.0261 19.25 18.75 19.25H11.25C10.9739 19.25 10.75 19.0261 10.75 18.75V11.25Z", fill: "currentColor" }) 21410 ] }); 21411 21412 // packages/icons/build-module/library/sidebar.mjs 21413 var import_primitives5 = __toESM(require_primitives(), 1); 21414 var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1); 21415 var sidebar_default = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_primitives5.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [ 21416 /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_primitives5.Path, { d: "M9.75 19.25H18C18.6904 19.25 19.25 18.6904 19.25 18V9.75M9.75 19.25H6C5.30964 19.25 4.75 18.6904 4.75 18V9.75M9.75 19.25V9.75M19.25 9.75V6C19.25 5.30964 18.6904 4.75 18 4.75H6C5.30964 4.75 4.75 5.30964 4.75 6V9.75M19.25 9.75H9.75M9.75 9.75H4.75" }), 21417 /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_primitives5.Path, { d: "M6 19.25H9.75V9.75H4.75V18C4.75 18.6904 5.30964 19.25 6 19.25Z", fill: "currentColor" }) 21418 ] }); 21419 21420 // packages/icons/build-module/library/symbol-filled.mjs 21421 var import_primitives6 = __toESM(require_primitives(), 1); 21422 var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1); 21423 var symbol_filled_default = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_primitives6.SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", style: { fill: "none" }, stroke: "currentColor", strokeWidth: "1.5", children: [ 21424 /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_primitives6.Path, { d: "M15.2071 6.20711L20.2929 11.2929C20.6834 11.6834 20.6834 12.3166 20.2929 12.7071L15.2071 17.7929C14.8166 18.1834 14.1834 18.1834 13.7929 17.7929L8.70711 12.7071C8.31658 12.3166 8.31658 11.6834 8.70711 11.2929L13.7929 6.20711C14.1834 5.81658 14.8166 5.81658 15.2071 6.20711Z", fill: "currentColor" }), 21425 /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_primitives6.Path, { d: "M9.5 5.5L3.70711 11.2929C3.31658 11.6834 3.31658 12.3166 3.70711 12.7071L9.5 18.5" }) 21426 ] }); 21427 21428 // packages/core-data/build-module/utils/get-template-part-icon.mjs 21429 function getTemplatePartIcon(areaOrIconName) { 21430 if ("header" === areaOrIconName) { 21431 return header_default; 21432 } else if ("footer" === areaOrIconName) { 21433 return footer_default; 21434 } else if ("sidebar" === areaOrIconName) { 21435 return sidebar_default; 21436 } else if ("navigation-overlay" === areaOrIconName) { 21437 return navigation_overlay_default; 21438 } 21439 return symbol_filled_default; 21440 } 21441 21442 // packages/core-data/build-module/utils/get-template-info.mjs 21443 var EMPTY_OBJECT4 = {}; 21444 var getTemplateInfo = (params2) => { 21445 if (!params2) { 21446 return EMPTY_OBJECT4; 21447 } 21448 const { templateTypes, templateAreas, template } = params2; 21449 const { description, slug, title, area } = template; 21450 const { title: defaultTitle, description: defaultDescription } = Object.values(templateTypes).find((type) => type.slug === slug) ?? EMPTY_OBJECT4; 21451 const templateTitle = typeof title === "string" ? title : title?.rendered; 21452 const templateDescription = typeof description === "string" ? description : description?.raw; 21453 const templateAreasWithIcon = templateAreas?.map((item) => ({ 21454 ...item, 21455 icon: getTemplatePartIcon(item.icon) 21456 })); 21457 const templateIcon = templateAreasWithIcon?.find((item) => area === item.area)?.icon || layout_default; 21458 return { 21459 title: templateTitle && templateTitle !== slug ? templateTitle : defaultTitle || slug, 21460 description: templateDescription || defaultDescription, 21461 icon: templateIcon 21462 }; 21463 }; 21464 21465 // node_modules/.store/clsx@2.1.1-XOLP1vUL9vEGfpiXm37fAw/node_modules/clsx/dist/clsx.mjs 21466 function r(e) { 21467 var t, f, n = ""; 21468 if ("string" == typeof e || "number" == typeof e) n += e; 21469 else if ("object" == typeof e) if (Array.isArray(e)) { 21470 var o = e.length; 21471 for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f); 21472 } else for (f in e) e[f] && (n && (n += " "), n += f); 21473 return n; 21474 } 21475 function clsx() { 21476 for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t); 21477 return n; 21478 } 21479 var clsx_default = clsx; 21480 21481 // packages/core-data/build-module/components/entities-saved-states/index.mjs 21482 var import_components3 = __toESM(require_components(), 1); 21483 var import_i18n7 = __toESM(require_i18n(), 1); 21484 var import_element10 = __toESM(require_element(), 1); 21485 var import_compose4 = __toESM(require_compose(), 1); 21486 var import_data20 = __toESM(require_data(), 1); 21487 21488 // packages/core-data/build-module/components/entities-saved-states/entity-type-list.mjs 21489 var import_i18n6 = __toESM(require_i18n(), 1); 21490 var import_data18 = __toESM(require_data(), 1); 21491 var import_components2 = __toESM(require_components(), 1); 21492 21493 // packages/global-styles-engine/build-module/utils/get-global-styles-changes.mjs 21494 var import_i18n4 = __toESM(require_i18n(), 1); 21495 var import_blocks7 = __toESM(require_blocks(), 1); 21496 var globalStylesChangesCache = /* @__PURE__ */ new Map(); 21497 var EMPTY_ARRAY3 = []; 21498 var translationMap = { 21499 caption: (0, import_i18n4.__)("Caption"), 21500 link: (0, import_i18n4.__)("Link"), 21501 button: (0, import_i18n4.__)("Button"), 21502 heading: (0, import_i18n4.__)("Heading"), 21503 h1: (0, import_i18n4.__)("H1"), 21504 h2: (0, import_i18n4.__)("H2"), 21505 h3: (0, import_i18n4.__)("H3"), 21506 h4: (0, import_i18n4.__)("H4"), 21507 h5: (0, import_i18n4.__)("H5"), 21508 h6: (0, import_i18n4.__)("H6"), 21509 "settings.color": (0, import_i18n4.__)("Color"), 21510 "settings.typography": (0, import_i18n4.__)("Typography"), 21511 "settings.shadow": (0, import_i18n4.__)("Shadow"), 21512 "settings.layout": (0, import_i18n4.__)("Layout"), 21513 "styles.color": (0, import_i18n4.__)("Colors"), 21514 "styles.spacing": (0, import_i18n4.__)("Spacing"), 21515 "styles.background": (0, import_i18n4.__)("Background"), 21516 "styles.typography": (0, import_i18n4.__)("Typography"), 21517 "styles.border": (0, import_i18n4.__)("Border"), 21518 "styles.shadow": (0, import_i18n4.__)("Shadow"), 21519 "styles.outline": (0, import_i18n4.__)("Outline"), 21520 "styles.filter": (0, import_i18n4.__)("Filter"), 21521 "styles.dimensions": (0, import_i18n4.__)("Dimensions") 21522 }; 21523 var getBlockNames = memize( 21524 () => (0, import_blocks7.getBlockTypes)().reduce( 21525 (accumulator, { 21526 name, 21527 title 21528 }) => { 21529 accumulator[name] = title; 21530 return accumulator; 21531 }, 21532 {} 21533 ) 21534 ); 21535 var isObject2 = (obj) => obj !== null && typeof obj === "object"; 21536 function getTranslation(key) { 21537 if (translationMap[key]) { 21538 return translationMap[key]; 21539 } 21540 const keyArray = key.split("."); 21541 if (keyArray?.[0] === "blocks") { 21542 const blockName = getBlockNames()?.[keyArray[1]]; 21543 return blockName || keyArray[1]; 21544 } 21545 if (keyArray?.[0] === "elements") { 21546 return translationMap[keyArray[1]] || keyArray[1]; 21547 } 21548 return void 0; 21549 } 21550 function deepCompare(changedObject, originalObject, parentPath = "") { 21551 if (!isObject2(changedObject) && !isObject2(originalObject)) { 21552 return changedObject !== originalObject ? parentPath.split(".").slice(0, 2).join(".") : void 0; 21553 } 21554 changedObject = isObject2(changedObject) ? changedObject : {}; 21555 originalObject = isObject2(originalObject) ? originalObject : {}; 21556 const allKeys = /* @__PURE__ */ new Set([ 21557 ...Object.keys(changedObject), 21558 ...Object.keys(originalObject) 21559 ]); 21560 let diffs = []; 21561 for (const key of allKeys) { 21562 const path = parentPath ? parentPath + "." + key : key; 21563 const changedPath = deepCompare( 21564 changedObject[key], 21565 originalObject[key], 21566 path 21567 ); 21568 if (changedPath) { 21569 diffs = diffs.concat(changedPath); 21570 } 21571 } 21572 return diffs; 21573 } 21574 var COMPARED_STYLE_KEYS = [ 21575 "background", 21576 "color", 21577 "typography", 21578 "spacing", 21579 "border", 21580 "shadow", 21581 "outline", 21582 "filter", 21583 "dimensions" 21584 ]; 21585 function pickComparedStyles(config) { 21586 return Object.fromEntries( 21587 COMPARED_STYLE_KEYS.map((key) => [key, config?.styles?.[key]]) 21588 ); 21589 } 21590 function getGlobalStylesChangelist(next, previous) { 21591 const cacheKey = JSON.stringify({ next, previous }); 21592 if (globalStylesChangesCache.has(cacheKey)) { 21593 return globalStylesChangesCache.get(cacheKey); 21594 } 21595 const changedValueTree = deepCompare( 21596 { 21597 styles: pickComparedStyles(next), 21598 blocks: next?.styles?.blocks, 21599 elements: next?.styles?.elements, 21600 settings: next?.settings 21601 }, 21602 { 21603 styles: pickComparedStyles(previous), 21604 blocks: previous?.styles?.blocks, 21605 elements: previous?.styles?.elements, 21606 settings: previous?.settings 21607 } 21608 ); 21609 if (!changedValueTree || Array.isArray(changedValueTree) && !changedValueTree.length) { 21610 globalStylesChangesCache.set(cacheKey, []); 21611 return []; 21612 } 21613 const changedValueArray = Array.isArray(changedValueTree) ? changedValueTree : [changedValueTree]; 21614 const result = [...new Set(changedValueArray)].reduce((acc, curr) => { 21615 const translation = getTranslation(curr); 21616 if (translation) { 21617 acc.push([curr.split(".")[0], translation]); 21618 } 21619 return acc; 21620 }, []); 21621 globalStylesChangesCache.set(cacheKey, result); 21622 return result; 21623 } 21624 function getGlobalStylesChanges(next, previous, options = {}) { 21625 let changeList = getGlobalStylesChangelist(next, previous); 21626 const changesLength = changeList.length; 21627 const { maxResults } = options; 21628 if (changesLength) { 21629 if (!!maxResults && changesLength > maxResults) { 21630 changeList = changeList.slice(0, maxResults); 21631 } 21632 return Object.entries( 21633 changeList.reduce((acc, curr) => { 21634 const group = acc[curr[0]] || []; 21635 if (!group.includes(curr[1])) { 21636 acc[curr[0]] = [...group, curr[1]]; 21637 } 21638 return acc; 21639 }, {}) 21640 ).map(([key, changeValues]) => { 21641 const changeValuesLength = changeValues.length; 21642 const joinedChangesValue = changeValues.join( 21643 /* translators: Used between list items, there is a space after the comma. */ 21644 (0, import_i18n4.__)(", ") 21645 // eslint-disable-line @wordpress/i18n-no-flanking-whitespace 21646 ); 21647 switch (key) { 21648 case "blocks": { 21649 return (0, import_i18n4.sprintf)( 21650 // translators: %s: a list of block names separated by a comma. 21651 (0, import_i18n4._n)("%s block.", "%s blocks.", changeValuesLength), 21652 joinedChangesValue 21653 ); 21654 } 21655 case "elements": { 21656 return (0, import_i18n4.sprintf)( 21657 // translators: %s: a list of element names separated by a comma. 21658 (0, import_i18n4._n)("%s element.", "%s elements.", changeValuesLength), 21659 joinedChangesValue 21660 ); 21661 } 21662 case "settings": { 21663 return (0, import_i18n4.sprintf)( 21664 // translators: %s: a list of theme.json setting labels separated by a comma. 21665 (0, import_i18n4.__)("%s settings."), 21666 joinedChangesValue 21667 ); 21668 } 21669 case "styles": { 21670 return (0, import_i18n4.sprintf)( 21671 // translators: %s: a list of theme.json top-level styles labels separated by a comma. 21672 (0, import_i18n4.__)("%s styles."), 21673 joinedChangesValue 21674 ); 21675 } 21676 default: { 21677 return (0, import_i18n4.sprintf)( 21678 // translators: %s: a list of global styles changes separated by a comma. 21679 (0, import_i18n4.__)("%s."), 21680 joinedChangesValue 21681 ); 21682 } 21683 } 21684 }); 21685 } 21686 return EMPTY_ARRAY3; 21687 } 21688 21689 // packages/core-data/build-module/components/entities-saved-states/entity-record-item.mjs 21690 var import_components = __toESM(require_components(), 1); 21691 var import_i18n5 = __toESM(require_i18n(), 1); 21692 var import_data17 = __toESM(require_data(), 1); 21693 var import_html_entities4 = __toESM(require_html_entities(), 1); 21694 var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1); 21695 function EntityRecordItem({ record, checked, onChange }) { 21696 const { name, kind, title, key } = record; 21697 const { entityRecordTitle } = (0, import_data17.useSelect)( 21698 (select6) => { 21699 if ("postType" !== kind || "wp_template" !== name) { 21700 return { 21701 entityRecordTitle: title 21702 }; 21703 } 21704 const template = select6(STORE_NAME).getEditedEntityRecord( 21705 kind, 21706 name, 21707 key 21708 ); 21709 const { default_template_types: templateTypes = [] } = select6(STORE_NAME).getCurrentTheme() ?? {}; 21710 return { 21711 entityRecordTitle: getTemplateInfo({ 21712 template, 21713 templateTypes 21714 }).title 21715 }; 21716 }, 21717 [name, kind, title, key] 21718 ); 21719 return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components.PanelRow, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)( 21720 import_components.CheckboxControl, 21721 { 21722 label: (0, import_html_entities4.decodeEntities)(entityRecordTitle) || (0, import_i18n5.__)("Untitled"), 21723 checked, 21724 onChange, 21725 className: "entities-saved-states__change-control" 21726 } 21727 ) }) }); 21728 } 21729 21730 // packages/core-data/build-module/components/entities-saved-states/entity-type-list.mjs 21731 var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1); 21732 function getEntityDescription(entity2, count) { 21733 switch (entity2) { 21734 case "site": 21735 return 1 === count ? (0, import_i18n6.__)("This change will affect your whole site.") : (0, import_i18n6.__)("These changes will affect your whole site."); 21736 case "wp_template": 21737 return (0, import_i18n6.__)( 21738 "This change will affect other parts of your site that use this template." 21739 ); 21740 case "page": 21741 case "post": 21742 return (0, import_i18n6.__)("The following has been modified."); 21743 } 21744 } 21745 function GlobalStylesDescription({ record }) { 21746 const { editedRecord, savedRecord } = (0, import_data18.useSelect)( 21747 (select6) => { 21748 const { getEditedEntityRecord: getEditedEntityRecord3, getEntityRecord: getEntityRecord3 } = select6(STORE_NAME); 21749 return { 21750 editedRecord: getEditedEntityRecord3( 21751 record.kind, 21752 record.name, 21753 record.key 21754 ), 21755 savedRecord: getEntityRecord3( 21756 record.kind, 21757 record.name, 21758 record.key 21759 ) 21760 }; 21761 }, 21762 [record.kind, record.name, record.key] 21763 ); 21764 const globalStylesChanges = getGlobalStylesChanges( 21765 editedRecord, 21766 savedRecord, 21767 { 21768 maxResults: 10 21769 } 21770 ); 21771 return globalStylesChanges.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "entities-saved-states__changes", children: globalStylesChanges.map((change) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { children: change }, change)) }) : null; 21772 } 21773 function EntityDescription({ record, count }) { 21774 if ("globalStyles" === record?.name) { 21775 return null; 21776 } 21777 const description = getEntityDescription(record?.name, count); 21778 return description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_components2.PanelRow, { children: description }) : null; 21779 } 21780 function EntityTypeList({ 21781 list, 21782 unselectedEntities, 21783 setUnselectedEntities 21784 }) { 21785 const count = list.length; 21786 const firstRecord = list[0]; 21787 const entityConfig = (0, import_data18.useSelect)( 21788 (select6) => select6(STORE_NAME).getEntityConfig( 21789 firstRecord.kind, 21790 firstRecord.name 21791 ), 21792 [firstRecord.kind, firstRecord.name] 21793 ); 21794 let entityLabel = entityConfig.label; 21795 if (firstRecord?.name === "wp_template_part") { 21796 entityLabel = 1 === count ? (0, import_i18n6.__)("Template Part") : (0, import_i18n6.__)("Template Parts"); 21797 } 21798 return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)( 21799 import_components2.PanelBody, 21800 { 21801 title: entityLabel, 21802 initialOpen: true, 21803 className: "entities-saved-states__panel-body", 21804 children: [ 21805 /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EntityDescription, { record: firstRecord, count }), 21806 list.map((record) => { 21807 return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)( 21808 EntityRecordItem, 21809 { 21810 record, 21811 checked: !unselectedEntities.some( 21812 (elt) => elt.kind === record.kind && elt.name === record.name && elt.key === record.key && elt.property === record.property 21813 ), 21814 onChange: (value) => setUnselectedEntities(record, value) 21815 }, 21816 record.key || record.property 21817 ); 21818 }), 21819 "globalStyles" === firstRecord?.name && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GlobalStylesDescription, { record: firstRecord }) 21820 ] 21821 } 21822 ); 21823 } 21824 21825 // packages/core-data/build-module/components/entities-saved-states/hooks/use-is-dirty.mjs 21826 var import_data19 = __toESM(require_data(), 1); 21827 var import_element9 = __toESM(require_element(), 1); 21828 var useIsDirty = () => { 21829 const { editedEntities, siteEdits, siteEntityConfig } = (0, import_data19.useSelect)( 21830 (select6) => { 21831 const { 21832 __experimentalGetDirtyEntityRecords: __experimentalGetDirtyEntityRecords2, 21833 getEntityRecordEdits: getEntityRecordEdits2, 21834 getEntityConfig: getEntityConfig2 21835 } = select6(STORE_NAME); 21836 return { 21837 editedEntities: __experimentalGetDirtyEntityRecords2(), 21838 siteEdits: getEntityRecordEdits2("root", "site"), 21839 siteEntityConfig: getEntityConfig2("root", "site") 21840 }; 21841 }, 21842 [] 21843 ); 21844 const dirtyEntityRecords = (0, import_element9.useMemo)(() => { 21845 const editedEntitiesWithoutSite = editedEntities.filter( 21846 (record) => !(record.kind === "root" && record.name === "site") 21847 ); 21848 const siteEntityLabels = siteEntityConfig?.meta?.labels ?? {}; 21849 const { 21850 title: siteTitleEdit, 21851 description: siteDescriptionEdit, 21852 site_logo: siteLogoEdit, 21853 site_icon: siteIconEdit, 21854 ...otherSiteEdits 21855 } = siteEdits ?? {}; 21856 const orderedSiteProperties = [ 21857 siteTitleEdit !== void 0 && "title", 21858 siteDescriptionEdit !== void 0 && "description", 21859 siteLogoEdit !== void 0 && "site_logo", 21860 siteIconEdit !== void 0 && "site_icon", 21861 ...Object.keys(otherSiteEdits) 21862 ].filter(Boolean); 21863 const editedSiteEntities = orderedSiteProperties.map( 21864 (property) => ({ 21865 kind: "root", 21866 name: "site", 21867 title: siteEntityLabels[property] || property, 21868 property 21869 }) 21870 ); 21871 return [...editedEntitiesWithoutSite, ...editedSiteEntities]; 21872 }, [editedEntities, siteEdits, siteEntityConfig]); 21873 const [unselectedEntities, _setUnselectedEntities] = (0, import_element9.useState)([]); 21874 const setUnselectedEntities = ({ kind, name, key, property }, checked) => { 21875 if (checked) { 21876 _setUnselectedEntities( 21877 unselectedEntities.filter( 21878 (elt) => elt.kind !== kind || elt.name !== name || elt.key !== key || elt.property !== property 21879 ) 21880 ); 21881 } else { 21882 _setUnselectedEntities([ 21883 ...unselectedEntities, 21884 { kind, name, key, property } 21885 ]); 21886 } 21887 }; 21888 const isDirty = dirtyEntityRecords.length - unselectedEntities.length > 0; 21889 return { 21890 dirtyEntityRecords, 21891 isDirty, 21892 setUnselectedEntities, 21893 unselectedEntities 21894 }; 21895 }; 21896 21897 // packages/core-data/build-module/components/entities-saved-states/index.mjs 21898 var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1); 21899 function EntitiesSavedStates({ 21900 close, 21901 renderDialog, 21902 variant 21903 }) { 21904 const isDirtyProps = useIsDirty(); 21905 return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 21906 EntitiesSavedStatesExtensible, 21907 { 21908 close, 21909 renderDialog, 21910 variant, 21911 ...isDirtyProps 21912 } 21913 ); 21914 } 21915 function EntitiesSavedStatesExtensible({ 21916 additionalPrompt = void 0, 21917 close, 21918 onSave = void 0, 21919 saveEnabled: saveEnabledProp = void 0, 21920 saveLabel = (0, import_i18n7.__)("Save"), 21921 renderDialog, 21922 dirtyEntityRecords, 21923 isDirty, 21924 setUnselectedEntities, 21925 unselectedEntities, 21926 variant = "default", 21927 successNoticeContent 21928 }) { 21929 const saveButtonRef = (0, import_element10.useRef)(); 21930 const { saveDirtyEntities: saveDirtyEntities2 } = unlock((0, import_data20.useDispatch)(STORE_NAME)); 21931 const partitionedSavables = dirtyEntityRecords.reduce((acc, record) => { 21932 const { name } = record; 21933 if (!acc[name]) { 21934 acc[name] = []; 21935 } 21936 acc[name].push(record); 21937 return acc; 21938 }, {}); 21939 const { 21940 site: siteSavables, 21941 wp_template: templateSavables, 21942 wp_template_part: templatePartSavables, 21943 ...contentSavables 21944 } = partitionedSavables; 21945 const sortedPartitionedSavables = [ 21946 siteSavables, 21947 templateSavables, 21948 templatePartSavables, 21949 ...Object.values(contentSavables) 21950 ].filter(Array.isArray); 21951 const saveEnabled = saveEnabledProp ?? isDirty; 21952 const dismissPanel = (0, import_element10.useCallback)(() => close(), [close]); 21953 const [saveDialogRef, saveDialogProps] = (0, import_compose4.__experimentalUseDialog)({ 21954 onClose: () => dismissPanel() 21955 }); 21956 const dialogLabelId = (0, import_compose4.useInstanceId)( 21957 EntitiesSavedStatesExtensible, 21958 "entities-saved-states__panel-label" 21959 ); 21960 const dialogDescriptionId = (0, import_compose4.useInstanceId)( 21961 EntitiesSavedStatesExtensible, 21962 "entities-saved-states__panel-description" 21963 ); 21964 const selectItemsToSaveDescription = !!dirtyEntityRecords.length ? (0, import_i18n7.__)("Select the items you want to save.") : void 0; 21965 const isInline = variant === "inline"; 21966 const actionButtons = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [ 21967 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 21968 import_components3.FlexItem, 21969 { 21970 isBlock: isInline ? false : true, 21971 as: import_components3.Button, 21972 variant: isInline ? "tertiary" : "secondary", 21973 size: isInline ? void 0 : "compact", 21974 onClick: dismissPanel, 21975 children: (0, import_i18n7.__)("Cancel") 21976 } 21977 ), 21978 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 21979 import_components3.FlexItem, 21980 { 21981 isBlock: isInline ? false : true, 21982 as: import_components3.Button, 21983 ref: saveButtonRef, 21984 variant: "primary", 21985 size: isInline ? void 0 : "compact", 21986 disabled: !saveEnabled, 21987 accessibleWhenDisabled: true, 21988 onClick: () => saveDirtyEntities2({ 21989 onSave, 21990 dirtyEntityRecords, 21991 entitiesToSkip: unselectedEntities, 21992 close, 21993 successNoticeContent 21994 }), 21995 className: "entities-saved-states__save-button", 21996 children: saveLabel 21997 } 21998 ) 21999 ] }); 22000 return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)( 22001 "div", 22002 { 22003 ref: renderDialog ? saveDialogRef : void 0, 22004 ...renderDialog && saveDialogProps, 22005 className: clsx_default("entities-saved-states__panel", { 22006 "is-inline": isInline 22007 }), 22008 role: renderDialog ? "dialog" : void 0, 22009 "aria-labelledby": renderDialog ? dialogLabelId : void 0, 22010 "aria-describedby": renderDialog ? dialogDescriptionId : void 0, 22011 children: [ 22012 !isInline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components3.Flex, { className: "entities-saved-states__panel-header", gap: 2, children: actionButtons }), 22013 /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "entities-saved-states__text-prompt", children: [ 22014 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "entities-saved-states__text-prompt--header-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 22015 "strong", 22016 { 22017 id: renderDialog ? dialogLabelId : void 0, 22018 className: "entities-saved-states__text-prompt--header", 22019 children: (0, import_i18n7.__)("Are you ready to save?") 22020 } 22021 ) }), 22022 /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { id: renderDialog ? dialogDescriptionId : void 0, children: [ 22023 additionalPrompt, 22024 /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "entities-saved-states__text-prompt--changes-count", children: isDirty ? (0, import_element10.createInterpolateElement)( 22025 (0, import_i18n7.sprintf)( 22026 /* translators: %d: number of site changes waiting to be saved. */ 22027 (0, import_i18n7._n)( 22028 "There is <strong>%d site change</strong> waiting to be saved.", 22029 "There are <strong>%d site changes</strong> waiting to be saved.", 22030 dirtyEntityRecords.length 22031 ), 22032 dirtyEntityRecords.length 22033 ), 22034 { strong: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", {}) } 22035 ) : selectItemsToSaveDescription }) 22036 ] }) 22037 ] }), 22038 sortedPartitionedSavables.map((list) => { 22039 return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 22040 EntityTypeList, 22041 { 22042 list, 22043 unselectedEntities, 22044 setUnselectedEntities 22045 }, 22046 list[0].name 22047 ); 22048 }), 22049 isInline && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)( 22050 import_components3.Flex, 22051 { 22052 direction: "row", 22053 justify: "flex-end", 22054 className: "entities-saved-states__panel-footer", 22055 children: actionButtons 22056 } 22057 ) 22058 ] 22059 } 22060 ); 22061 } 22062 22063 // packages/core-data/build-module/private-apis.mjs 22064 var lockedApis = { 22065 PrivateEntityProvider, 22066 EntitiesSavedStates, 22067 EntitiesSavedStatesExtensible, 22068 getTemplateInfo, 22069 getTemplatePartIcon, 22070 useEntitiesSavedStatesIsDirty: useIsDirty, 22071 useEntityRecordsWithPermissions, 22072 RECEIVE_INTERMEDIATE_RESULTS, 22073 CRDT_AUTOSAVE_SNAPSHOT_KEY, 22074 entityContainsSnapshot, 22075 getEntitySnapshot, 22076 retrySyncConnection, 22077 useActiveCollaborators, 22078 useResolvedSelection, 22079 useOnCollaboratorJoin, 22080 useOnCollaboratorLeave, 22081 useOnPostSave, 22082 SelectionType, 22083 SelectionDirection 22084 }; 22085 var privateApis = {}; 22086 lock(privateApis, lockedApis); 22087 22088 // packages/core-data/build-module/index.mjs 22089 var entitiesConfig2 = [ 22090 ...rootEntitiesConfig, 22091 ...additionalEntityConfigLoaders.filter((config) => !!config.name) 22092 ]; 22093 var entitySelectors = entitiesConfig2.reduce((result, entity2) => { 22094 const { kind, name, plural } = entity2; 22095 const getEntityRecordMethodName = getMethodName(kind, name); 22096 result[getEntityRecordMethodName] = (state, key, query) => { 22097 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 22098 isShorthandSelector: true, 22099 alternativeFunctionName: "getEntityRecord" 22100 }); 22101 return getEntityRecord(state, kind, name, key, query); 22102 }; 22103 if (plural) { 22104 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 22105 result[getEntityRecordsMethodName] = (state, query) => { 22106 logEntityDeprecation(kind, name, getEntityRecordsMethodName, { 22107 isShorthandSelector: true, 22108 alternativeFunctionName: "getEntityRecords" 22109 }); 22110 return getEntityRecords(state, kind, name, query); 22111 }; 22112 } 22113 return result; 22114 }, {}); 22115 var entityResolvers = entitiesConfig2.reduce((result, entity2) => { 22116 const { kind, name, plural } = entity2; 22117 const getEntityRecordMethodName = getMethodName(kind, name); 22118 result[getEntityRecordMethodName] = (key, query) => { 22119 logEntityDeprecation(kind, name, getEntityRecordMethodName, { 22120 isShorthandSelector: true, 22121 alternativeFunctionName: "getEntityRecord" 22122 }); 22123 return getEntityRecord2(kind, name, key, query); 22124 }; 22125 if (plural) { 22126 const getEntityRecordsMethodName = getMethodName(kind, plural, "get"); 22127 result[getEntityRecordsMethodName] = (...args2) => { 22128 logEntityDeprecation(kind, plural, getEntityRecordsMethodName, { 22129 isShorthandSelector: true, 22130 alternativeFunctionName: "getEntityRecords" 22131 }); 22132 return getEntityRecords2(kind, name, ...args2); 22133 }; 22134 result[getEntityRecordsMethodName].shouldInvalidate = (action) => getEntityRecords2.shouldInvalidate(action, kind, name); 22135 } 22136 return result; 22137 }, {}); 22138 var entityActions = entitiesConfig2.reduce((result, entity2) => { 22139 const { kind, name } = entity2; 22140 const saveEntityRecordMethodName = getMethodName(kind, name, "save"); 22141 result[saveEntityRecordMethodName] = (record, options) => { 22142 logEntityDeprecation(kind, name, saveEntityRecordMethodName, { 22143 isShorthandSelector: true, 22144 alternativeFunctionName: "saveEntityRecord" 22145 }); 22146 return saveEntityRecord(kind, name, record, options); 22147 }; 22148 const deleteEntityRecordMethodName = getMethodName(kind, name, "delete"); 22149 result[deleteEntityRecordMethodName] = (key, query, options) => { 22150 logEntityDeprecation(kind, name, deleteEntityRecordMethodName, { 22151 isShorthandSelector: true, 22152 alternativeFunctionName: "deleteEntityRecord" 22153 }); 22154 return deleteEntityRecord(kind, name, key, query, options); 22155 }; 22156 return result; 22157 }, {}); 22158 var storeConfig = () => ({ 22159 reducer: reducer_default2, 22160 actions: { 22161 ...dynamicActions, 22162 ...actions_exports, 22163 ...entityActions, 22164 ...createLocksActions() 22165 }, 22166 selectors: { 22167 ...dynamicSelectors, 22168 ...selectors_exports, 22169 ...entitySelectors 22170 }, 22171 resolvers: { ...resolvers_exports, ...entityResolvers } 22172 }); 22173 var store = (0, import_data21.createReduxStore)(STORE_NAME, storeConfig()); 22174 unlock(store).registerPrivateSelectors(private_selectors_exports); 22175 unlock(store).registerPrivateActions(private_actions_exports); 22176 (0, import_data21.register)(store); 22177 return __toCommonJS(index_exports); 22178 })(); 22179 (window.wp ||= {}).coreData = wp.coreData; 22180 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Wed Oct 21 08:20:34 2026 | Cross-referenced by PHPXref |