@wordpress/core-data
Version:
Access to and manipulation of core WordPress entities.
261 lines (259 loc) • 8.57 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// packages/core-data/src/utils/crdt.ts
var crdt_exports = {};
__export(crdt_exports, {
applyPostChangesToCRDTDoc: () => applyPostChangesToCRDTDoc,
defaultApplyChangesToCRDTDoc: () => defaultApplyChangesToCRDTDoc,
defaultGetChangesFromCRDTDoc: () => defaultGetChangesFromCRDTDoc,
getPostChangesFromCRDTDoc: () => getPostChangesFromCRDTDoc
});
module.exports = __toCommonJS(crdt_exports);
var import_es6 = __toESM(require("fast-deep-equal/es6"));
var import_blocks = require("@wordpress/blocks");
var import_sync = require("@wordpress/sync");
var import_crdt_blocks = require("./crdt-blocks");
var import_sync2 = require("../sync");
var lastSelection = null;
var allowedPostProperties = /* @__PURE__ */ new Set([
"author",
"blocks",
"comment_status",
"date",
"excerpt",
"featured_media",
"format",
"ping_status",
"meta",
"slug",
"status",
"sticky",
"tags",
"template",
"title"
]);
var disallowedPostMetaKeys = /* @__PURE__ */ new Set([
import_sync2.WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE
]);
function defaultApplyChangesToCRDTDoc(ydoc, changes) {
const ymap = ydoc.getMap(import_sync2.CRDT_RECORD_MAP_KEY);
Object.entries(changes).forEach(([key, newValue]) => {
if ("function" === typeof newValue) {
return;
}
function setValue(updatedValue) {
ymap.set(key, updatedValue);
}
switch (key) {
// Add support for additional data types here.
default: {
const currentValue = ymap.get(key);
mergeValue(currentValue, newValue, setValue);
}
}
});
}
function applyPostChangesToCRDTDoc(ydoc, changes, _postType) {
const ymap = ydoc.getMap(import_sync2.CRDT_RECORD_MAP_KEY);
Object.entries(changes).forEach(([key, newValue]) => {
if (!allowedPostProperties.has(key)) {
return;
}
if ("function" === typeof newValue) {
return;
}
function setValue(updatedValue) {
ymap.set(key, updatedValue);
}
switch (key) {
case "blocks": {
let currentBlocks = ymap.get("blocks");
if (!(currentBlocks instanceof import_sync.Y.Array)) {
currentBlocks = new import_sync.Y.Array();
setValue(currentBlocks);
}
const newBlocks = newValue ?? [];
(0, import_crdt_blocks.mergeCrdtBlocks)(currentBlocks, newBlocks, lastSelection);
break;
}
case "excerpt": {
const currentValue = ymap.get("excerpt");
const rawNewValue = getRawValue(newValue);
mergeValue(currentValue, rawNewValue, setValue);
break;
}
// "Meta" is overloaded term; here, it refers to post meta.
case "meta": {
let metaMap = ymap.get("meta");
if (!(metaMap instanceof import_sync.Y.Map)) {
metaMap = new import_sync.Y.Map();
setValue(metaMap);
}
Object.entries(newValue ?? {}).forEach(
([metaKey, metaValue]) => {
if (disallowedPostMetaKeys.has(metaKey)) {
return;
}
mergeValue(
metaMap.get(metaKey),
// current value in CRDT
metaValue,
// new value from changes
(updatedMetaValue) => {
metaMap.set(metaKey, updatedMetaValue);
}
);
}
);
break;
}
case "slug": {
if (!newValue) {
break;
}
const currentValue = ymap.get("slug");
mergeValue(currentValue, newValue, setValue);
break;
}
case "title": {
const currentValue = ymap.get("title");
let rawNewValue = getRawValue(newValue);
if (!currentValue && "Auto Draft" === rawNewValue) {
rawNewValue = "";
}
mergeValue(currentValue, rawNewValue, setValue);
break;
}
// Add support for additional data types here.
default: {
const currentValue = ymap.get(key);
mergeValue(currentValue, newValue, setValue);
}
}
});
if ("selection" in changes) {
lastSelection = changes.selection?.selectionStart ?? null;
}
}
function defaultGetChangesFromCRDTDoc(crdtDoc) {
return crdtDoc.getMap(import_sync2.CRDT_RECORD_MAP_KEY).toJSON();
}
function getPostChangesFromCRDTDoc(ydoc, editedRecord, _postType) {
const ymap = ydoc.getMap(import_sync2.CRDT_RECORD_MAP_KEY);
let allowedMetaChanges = {};
const changes = Object.fromEntries(
Object.entries(ymap.toJSON()).filter(([key, newValue]) => {
if (!allowedPostProperties.has(key)) {
return false;
}
const currentValue = editedRecord[key];
switch (key) {
case "blocks": {
if (ydoc.meta?.get(import_sync2.CRDT_DOC_META_PERSISTENCE_KEY) && editedRecord.content) {
const blocks = ymap.get("blocks");
return (0, import_blocks.__unstableSerializeAndClean)(
blocks.toJSON()
).trim() !== editedRecord.content.raw.trim();
}
return true;
}
case "date": {
const currentDateIsFloating = ["draft", "auto-draft", "pending"].includes(
ymap.get("status")
) && (null === currentValue || editedRecord.modified === currentValue);
if (!newValue && currentDateIsFloating) {
return false;
}
return haveValuesChanged(currentValue, newValue);
}
case "meta": {
allowedMetaChanges = Object.fromEntries(
Object.entries(newValue ?? {}).filter(
([metaKey]) => !disallowedPostMetaKeys.has(metaKey)
)
);
const mergedValue = {
...currentValue,
...allowedMetaChanges
};
return haveValuesChanged(currentValue, mergedValue);
}
case "status": {
if ("auto-draft" === newValue) {
return false;
}
return haveValuesChanged(currentValue, newValue);
}
case "excerpt":
case "title": {
return haveValuesChanged(
getRawValue(currentValue),
newValue
);
}
// Add support for additional data types here.
default: {
return haveValuesChanged(currentValue, newValue);
}
}
})
);
if ("object" === typeof changes.meta) {
changes.meta = {
...editedRecord.meta,
...allowedMetaChanges
};
}
return changes;
}
function getRawValue(value) {
if ("string" === typeof value) {
return value;
}
if (value && "object" === typeof value && "raw" in value && "string" === typeof value.raw) {
return value.raw;
}
return void 0;
}
function haveValuesChanged(currentValue, newValue) {
return !(0, import_es6.default)(currentValue, newValue);
}
function mergeValue(currentValue, newValue, setValue) {
if (haveValuesChanged(currentValue, newValue)) {
setValue(newValue);
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
applyPostChangesToCRDTDoc,
defaultApplyChangesToCRDTDoc,
defaultGetChangesFromCRDTDoc,
getPostChangesFromCRDTDoc
});
//# sourceMappingURL=crdt.js.map