@openeditor/core 0.0.51 → 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +147 -1
- package/dist/index.js +490 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,149 @@
|
|
|
1
|
+
declare const OPENEDITOR_CUSTOM_BLOCK_NODE: "customBlock";
|
|
2
|
+
|
|
3
|
+
type OpenEditorCustomBlockId = `${string}.${string}`;
|
|
4
|
+
/** A block-owned object. Runtime parsing still requires JSON-only plain data. */
|
|
5
|
+
type OpenEditorCustomBlockData = object;
|
|
6
|
+
type OpenEditorCustomBlockEnvelope<TData extends OpenEditorCustomBlockData = OpenEditorCustomBlockData> = {
|
|
7
|
+
blockId: OpenEditorCustomBlockId;
|
|
8
|
+
version: number;
|
|
9
|
+
data: TData;
|
|
10
|
+
};
|
|
11
|
+
type OpenEditorCustomBlockNode<TData extends OpenEditorCustomBlockData = OpenEditorCustomBlockData> = ProseMirrorNode & {
|
|
12
|
+
type: typeof OPENEDITOR_CUSTOM_BLOCK_NODE;
|
|
13
|
+
attrs: OpenEditorCustomBlockEnvelope<TData> & Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
type OpenEditorCustomBlockDiagnostic = {
|
|
16
|
+
path: string;
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
type OpenEditorCustomBlockAssetReference = {
|
|
20
|
+
id: string;
|
|
21
|
+
path: string;
|
|
22
|
+
};
|
|
23
|
+
type OpenEditorCustomBlockManifest = {
|
|
24
|
+
id: OpenEditorCustomBlockId;
|
|
25
|
+
label: string;
|
|
26
|
+
version: number;
|
|
27
|
+
};
|
|
28
|
+
type OpenEditorCustomBlockMigration = (input: {
|
|
29
|
+
version: number;
|
|
30
|
+
data: Readonly<OpenEditorCustomBlockData>;
|
|
31
|
+
}) => OpenEditorCustomBlockEnvelope;
|
|
32
|
+
type OpenEditorCustomBlockStaticContext<TData extends OpenEditorCustomBlockData> = {
|
|
33
|
+
data: Readonly<TData>;
|
|
34
|
+
renderDocument: (document: OpenEditorDocument) => OpenEditorCustomBlockSafeHtml;
|
|
35
|
+
documentToText: (document: OpenEditorDocument) => string;
|
|
36
|
+
};
|
|
37
|
+
type OpenEditorCustomBlockSafeHtml = string | number | null | false | {
|
|
38
|
+
tag: "div" | "span" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "article" | "section" | "aside" | "blockquote" | "figure" | "figcaption" | "ul" | "ol" | "li" | "dl" | "dt" | "dd" | "table" | "caption" | "thead" | "tbody" | "tr" | "th" | "td" | "strong" | "em" | "u" | "s" | "code" | "pre" | "a" | "img" | "br" | "hr";
|
|
39
|
+
attrs?: Readonly<Partial<Record<"aria-label" | "aria-current" | "role" | "title" | "href" | "src" | "alt" | "width" | "height" | "start" | "colspan" | "rowspan" | "scope", string | number | undefined>>>;
|
|
40
|
+
children?: readonly OpenEditorCustomBlockSafeHtml[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The complete non-React contract for one installed block. The block package
|
|
44
|
+
* owns parsing because OpenEditor cannot know a third-party data model.
|
|
45
|
+
*/
|
|
46
|
+
type OpenEditorCustomBlockDefinition<TData extends OpenEditorCustomBlockData = any> = {
|
|
47
|
+
id: OpenEditorCustomBlockId;
|
|
48
|
+
label: string;
|
|
49
|
+
version: number;
|
|
50
|
+
createData: () => TData;
|
|
51
|
+
parseData: (data: unknown) => TData;
|
|
52
|
+
migrate?: OpenEditorCustomBlockMigration;
|
|
53
|
+
assets?: (data: Readonly<TData>) => readonly OpenEditorCustomBlockAssetReference[];
|
|
54
|
+
toHtml: (context: OpenEditorCustomBlockStaticContext<TData>) => OpenEditorCustomBlockSafeHtml;
|
|
55
|
+
toText: (context: OpenEditorCustomBlockStaticContext<TData>) => string;
|
|
56
|
+
manifest: OpenEditorCustomBlockManifest;
|
|
57
|
+
};
|
|
58
|
+
type UnavailableStatus = "missing" | "disabled" | "incompatible" | "invalid";
|
|
59
|
+
type OpenEditorResolvedCustomBlock<TData extends OpenEditorCustomBlockData = OpenEditorCustomBlockData> = {
|
|
60
|
+
status: "ready";
|
|
61
|
+
definition: OpenEditorCustomBlockDefinition<TData>;
|
|
62
|
+
node: OpenEditorCustomBlockNode<TData>;
|
|
63
|
+
data: TData;
|
|
64
|
+
migrated: boolean;
|
|
65
|
+
} | {
|
|
66
|
+
status: UnavailableStatus;
|
|
67
|
+
node: ProseMirrorNode;
|
|
68
|
+
blockId?: string;
|
|
69
|
+
diagnostics: readonly OpenEditorCustomBlockDiagnostic[];
|
|
70
|
+
};
|
|
71
|
+
type OpenEditorCustomBlockRegistry = {
|
|
72
|
+
definitions: readonly OpenEditorCustomBlockDefinition[];
|
|
73
|
+
manifests: readonly OpenEditorCustomBlockManifest[];
|
|
74
|
+
get: (id: string) => OpenEditorCustomBlockDefinition | undefined;
|
|
75
|
+
isEnabled: (id: string) => boolean;
|
|
76
|
+
resolve: (node: ProseMirrorNode) => OpenEditorResolvedCustomBlock;
|
|
77
|
+
validate: (envelope: unknown) => {
|
|
78
|
+
valid: true;
|
|
79
|
+
envelope: OpenEditorCustomBlockEnvelope;
|
|
80
|
+
} | {
|
|
81
|
+
valid: false;
|
|
82
|
+
diagnostics: readonly OpenEditorCustomBlockDiagnostic[];
|
|
83
|
+
};
|
|
84
|
+
assets: (envelope: unknown) => readonly OpenEditorCustomBlockAssetReference[];
|
|
85
|
+
toHtml: (node: ProseMirrorNode) => string;
|
|
86
|
+
toText: (node: ProseMirrorNode) => string;
|
|
87
|
+
};
|
|
88
|
+
type OpenEditorCustomBlockIcon = {
|
|
89
|
+
id: string;
|
|
90
|
+
label: string;
|
|
91
|
+
};
|
|
92
|
+
type OpenEditorCustomBlockAsset = {
|
|
93
|
+
id: string;
|
|
94
|
+
kind: "raster";
|
|
95
|
+
alt: string;
|
|
96
|
+
width?: number;
|
|
97
|
+
height?: number;
|
|
98
|
+
};
|
|
99
|
+
type OpenEditorCustomBlockHost = {
|
|
100
|
+
resolveUrl: (value: string, context: "navigation" | "asset") => string | null;
|
|
101
|
+
links?: {
|
|
102
|
+
resolve: (destination: {
|
|
103
|
+
href: string;
|
|
104
|
+
kind?: string;
|
|
105
|
+
}) => {
|
|
106
|
+
href: string;
|
|
107
|
+
external: boolean;
|
|
108
|
+
label?: string;
|
|
109
|
+
} | null;
|
|
110
|
+
};
|
|
111
|
+
navigate?: (url: string) => void | Promise<void>;
|
|
112
|
+
icons?: {
|
|
113
|
+
list: () => readonly OpenEditorCustomBlockIcon[];
|
|
114
|
+
render: (id: string) => unknown;
|
|
115
|
+
};
|
|
116
|
+
assets?: {
|
|
117
|
+
pick?: () => Promise<OpenEditorCustomBlockAsset | null>;
|
|
118
|
+
resolve: (id: string) => Promise<{
|
|
119
|
+
src: string;
|
|
120
|
+
alt: string;
|
|
121
|
+
} | null>;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
declare const defineOpenEditorCustomBlock: <TData extends OpenEditorCustomBlockData>(input: Omit<OpenEditorCustomBlockDefinition<TData>, "manifest">) => OpenEditorCustomBlockDefinition<TData>;
|
|
125
|
+
declare const createOpenEditorCustomBlockRegistry: (definitions: readonly OpenEditorCustomBlockDefinition[], options?: {
|
|
126
|
+
disabled?: readonly string[];
|
|
127
|
+
renderDocument?: (document: OpenEditorDocument) => OpenEditorCustomBlockSafeHtml;
|
|
128
|
+
documentToText?: (document: OpenEditorDocument) => string;
|
|
129
|
+
}) => OpenEditorCustomBlockRegistry;
|
|
130
|
+
declare const createOpenEditorCustomBlockNode: <TData extends OpenEditorCustomBlockData>(registry: OpenEditorCustomBlockRegistry, id: string, data?: TData, options?: {
|
|
131
|
+
instanceId?: string;
|
|
132
|
+
createInstanceId?: () => string;
|
|
133
|
+
}) => OpenEditorCustomBlockNode<TData>;
|
|
134
|
+
declare const resolveOpenEditorCustomBlockNode: (registry: OpenEditorCustomBlockRegistry, node: ProseMirrorNode) => OpenEditorResolvedCustomBlock<object>;
|
|
135
|
+
declare const validateOpenEditorCustomBlockEnvelope: (value: unknown, registry: Pick<OpenEditorCustomBlockRegistry, "validate">) => {
|
|
136
|
+
valid: true;
|
|
137
|
+
envelope: OpenEditorCustomBlockEnvelope;
|
|
138
|
+
} | {
|
|
139
|
+
valid: false;
|
|
140
|
+
diagnostics: readonly OpenEditorCustomBlockDiagnostic[];
|
|
141
|
+
};
|
|
142
|
+
declare const extractOpenEditorCustomBlockAssetReferences: (value: unknown, registry: Pick<OpenEditorCustomBlockRegistry, "assets">) => readonly OpenEditorCustomBlockAssetReference[];
|
|
143
|
+
declare const conformOpenEditorCustomBlock: (definition: OpenEditorCustomBlockDefinition) => readonly OpenEditorCustomBlockDiagnostic[];
|
|
144
|
+
declare const escapeOpenEditorCustomBlockHtml: (value: unknown) => string;
|
|
145
|
+
declare const renderOpenEditorCustomBlockSafeHtml: (value: OpenEditorCustomBlockSafeHtml) => string;
|
|
146
|
+
|
|
1
147
|
type JsonPrimitive = string | number | boolean | null;
|
|
2
148
|
type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
|
|
3
149
|
type JsonObject = {
|
|
@@ -462,4 +608,4 @@ type OpenEditorTheme = {
|
|
|
462
608
|
declare const openEditorThemeCssName: (token: OpenEditorThemeToken) => `--oe-${string}`;
|
|
463
609
|
declare const getOpenEditorThemeEntries: (theme: Partial<OpenEditorTheme>) => readonly (readonly [string, string])[];
|
|
464
610
|
|
|
465
|
-
export { type BlockGroup, type BlockRegistry, type BlockSpec, type CreateOpenEditorDocumentContractOptions, DEFAULT_CALLOUT_EMOJI, DEFAULT_DOCUMENT_VALIDATION_LIMITS, DEFAULT_PAGE_EMOJI, type DocumentValidationCode, type DocumentValidationIssue, type DocumentValidationLimits, type DocumentValidationResult, type EditorCommand, type EditorPlatform, type EditorSelection, type EditorTransaction, type JsonObject, type JsonPrimitive, type JsonValue, OPENEDITOR_BLOCK_ID_ATTR, OPENEDITOR_DOCUMENT_FORMAT_VERSION, type OpenEditorAttachmentRuntime, type OpenEditorAttachmentSnapshot, type OpenEditorAttachmentUploadCallbacks, type OpenEditorAttachmentUploadInput, type OpenEditorAttachmentValidationResult, type OpenEditorAttributesSpec, type OpenEditorAuthoringCapabilities, type OpenEditorBlock, type OpenEditorBlockLocation, type OpenEditorBlockRef, type OpenEditorCommand, type OpenEditorConfig, type OpenEditorContentSpec, type OpenEditorController, type OpenEditorDocument, type OpenEditorDocumentContract, type OpenEditorDocumentMeta, OpenEditorDocumentParseError, type OpenEditorEventHandlers, type OpenEditorFeatureName, type OpenEditorFeatureSet, type OpenEditorImageRuntime, type OpenEditorImageSnapshot, type OpenEditorImageUploadCallbacks, type OpenEditorImageUploadInput, type OpenEditorImageValidationResult, type OpenEditorMarkName, type OpenEditorMarkSpec, type OpenEditorNodeSpec, type OpenEditorNodeValidator, type OpenEditorPageRuntime, type OpenEditorPageSnapshot, type OpenEditorPageUpdate, type OpenEditorTheme, type OpenEditorThemeToken, type OpenEditorUrlContext, type OpenEditorUrlPolicy, type OpenEditorValueSchema, type OpenEditorValueValidationContext, type OpenEditorValueValidator, type PlatformSupport, type PlatformSupportIssue, type PlatformSupportLevel, type PlatformSupportResult, type ProseMirrorAttrs, type ProseMirrorDocument, type ProseMirrorMark, type ProseMirrorNode, type SerializedEditorState, type ValidateDocumentOptions, applyCommand, canonicalSerializeJson, cloneNode, createAttachmentSnapshot, createBlockId, createBlockRegistry, createDocument, createEditorState, createOpenEditorDocumentContract, createTextNode, createTransaction, deleteTopLevelBlock, duplicateTopLevelBlock, ensureBlockIds, findBlockLocation, findBlockSpecForNode, fingerprintOpenEditorDocument, fromProseMirrorDocument, getBlockId, getDocumentText, getOpenEditorThemeEntries, getPlatformDocument, getPlatformSupport, importProseMirrorDocument, isOpenEditorBlockEnabled, isOpenEditorDocument, moveTopLevelBlock, normalizeDocument, normalizeEmoji, openEditorExternalMediaUrlPolicy, openEditorNavigationUrlPolicy, openEditorThemeCssName, openEditorThemeTokenNames, openEditorUnsafeUrlPolicy, openEditorUntrustedDocumentUrlPolicy, parseEditorState, parseOpenEditorDocument, replaceTopLevelNode, replaceTopLevelRange, serializeEditorState, textBlock, toProseMirrorDocument, validateDocument, withBlockId };
|
|
611
|
+
export { type BlockGroup, type BlockRegistry, type BlockSpec, type CreateOpenEditorDocumentContractOptions, DEFAULT_CALLOUT_EMOJI, DEFAULT_DOCUMENT_VALIDATION_LIMITS, DEFAULT_PAGE_EMOJI, type DocumentValidationCode, type DocumentValidationIssue, type DocumentValidationLimits, type DocumentValidationResult, type EditorCommand, type EditorPlatform, type EditorSelection, type EditorTransaction, type JsonObject, type JsonPrimitive, type JsonValue, OPENEDITOR_BLOCK_ID_ATTR, OPENEDITOR_CUSTOM_BLOCK_NODE, OPENEDITOR_DOCUMENT_FORMAT_VERSION, type OpenEditorAttachmentRuntime, type OpenEditorAttachmentSnapshot, type OpenEditorAttachmentUploadCallbacks, type OpenEditorAttachmentUploadInput, type OpenEditorAttachmentValidationResult, type OpenEditorAttributesSpec, type OpenEditorAuthoringCapabilities, type OpenEditorBlock, type OpenEditorBlockLocation, type OpenEditorBlockRef, type OpenEditorCommand, type OpenEditorConfig, type OpenEditorContentSpec, type OpenEditorController, type OpenEditorCustomBlockAsset, type OpenEditorCustomBlockAssetReference, type OpenEditorCustomBlockData, type OpenEditorCustomBlockDefinition, type OpenEditorCustomBlockDiagnostic, type OpenEditorCustomBlockEnvelope, type OpenEditorCustomBlockHost, type OpenEditorCustomBlockIcon, type OpenEditorCustomBlockId, type JsonObject as OpenEditorCustomBlockJsonObject, type JsonValue as OpenEditorCustomBlockJsonValue, type OpenEditorCustomBlockManifest, type OpenEditorCustomBlockMigration, type OpenEditorCustomBlockNode, type OpenEditorCustomBlockRegistry, type OpenEditorCustomBlockSafeHtml, type OpenEditorCustomBlockStaticContext, type OpenEditorDocument, type OpenEditorDocumentContract, type OpenEditorDocumentMeta, OpenEditorDocumentParseError, type OpenEditorEventHandlers, type OpenEditorFeatureName, type OpenEditorFeatureSet, type OpenEditorImageRuntime, type OpenEditorImageSnapshot, type OpenEditorImageUploadCallbacks, type OpenEditorImageUploadInput, type OpenEditorImageValidationResult, type OpenEditorMarkName, type OpenEditorMarkSpec, type OpenEditorNodeSpec, type OpenEditorNodeValidator, type OpenEditorPageRuntime, type OpenEditorPageSnapshot, type OpenEditorPageUpdate, type OpenEditorResolvedCustomBlock, type OpenEditorTheme, type OpenEditorThemeToken, type OpenEditorUrlContext, type OpenEditorUrlPolicy, type OpenEditorValueSchema, type OpenEditorValueValidationContext, type OpenEditorValueValidator, type PlatformSupport, type PlatformSupportIssue, type PlatformSupportLevel, type PlatformSupportResult, type ProseMirrorAttrs, type ProseMirrorDocument, type ProseMirrorMark, type ProseMirrorNode, type SerializedEditorState, type ValidateDocumentOptions, applyCommand, canonicalSerializeJson, cloneNode, conformOpenEditorCustomBlock, createAttachmentSnapshot, createBlockId, createBlockRegistry, createDocument, createEditorState, createOpenEditorCustomBlockNode, createOpenEditorCustomBlockRegistry, createOpenEditorDocumentContract, createTextNode, createTransaction, defineOpenEditorCustomBlock, deleteTopLevelBlock, duplicateTopLevelBlock, ensureBlockIds, escapeOpenEditorCustomBlockHtml, extractOpenEditorCustomBlockAssetReferences, findBlockLocation, findBlockSpecForNode, fingerprintOpenEditorDocument, fromProseMirrorDocument, getBlockId, getDocumentText, getOpenEditorThemeEntries, getPlatformDocument, getPlatformSupport, importProseMirrorDocument, isOpenEditorBlockEnabled, isOpenEditorDocument, moveTopLevelBlock, normalizeDocument, normalizeEmoji, openEditorExternalMediaUrlPolicy, openEditorNavigationUrlPolicy, openEditorThemeCssName, openEditorThemeTokenNames, openEditorUnsafeUrlPolicy, openEditorUntrustedDocumentUrlPolicy, parseEditorState, parseOpenEditorDocument, renderOpenEditorCustomBlockSafeHtml, replaceTopLevelNode, replaceTopLevelRange, resolveOpenEditorCustomBlockNode, serializeEditorState, textBlock, toProseMirrorDocument, validateDocument, validateOpenEditorCustomBlockEnvelope, withBlockId };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,490 @@
|
|
|
1
|
+
// src/custom-block.ts
|
|
2
|
+
var OPENEDITOR_CUSTOM_BLOCK_NODE = "customBlock";
|
|
3
|
+
var ID_PATTERN = /^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)+$/;
|
|
4
|
+
var DEFINITION_BRAND = /* @__PURE__ */ Symbol.for("@openeditor/custom-block/definition");
|
|
5
|
+
var LIMITS = {
|
|
6
|
+
depth: 32,
|
|
7
|
+
values: 1e4,
|
|
8
|
+
stringLength: 1e6,
|
|
9
|
+
arrayLength: 1e4,
|
|
10
|
+
objectKeys: 1e4
|
|
11
|
+
};
|
|
12
|
+
var plainObject = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
13
|
+
var positiveInteger = (value) => typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
14
|
+
var clone = (value) => structuredClone(value);
|
|
15
|
+
var deepFreeze = (value) => {
|
|
16
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
17
|
+
Object.freeze(value);
|
|
18
|
+
for (const child of Object.values(value))
|
|
19
|
+
deepFreeze(child);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var inspectJson = (value, path = "$.data", depth = 0, budget = { values: 0 }) => {
|
|
24
|
+
budget.values += 1;
|
|
25
|
+
if (budget.values > LIMITS.values)
|
|
26
|
+
return [{ path, message: "Custom block data exceeds the value limit." }];
|
|
27
|
+
if (depth > LIMITS.depth)
|
|
28
|
+
return [{ path, message: "Custom block data exceeds the nesting limit." }];
|
|
29
|
+
if (typeof value === "string" && value.length > LIMITS.stringLength)
|
|
30
|
+
return [{ path, message: "String exceeds the size limit." }];
|
|
31
|
+
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value))
|
|
32
|
+
return [];
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
if (value.length > LIMITS.arrayLength)
|
|
35
|
+
return [{ path, message: "Array exceeds the size limit." }];
|
|
36
|
+
return value.flatMap(
|
|
37
|
+
(item, index) => inspectJson(item, `${path}[${index}]`, depth + 1, budget)
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (plainObject(value)) {
|
|
41
|
+
const entries = Object.entries(value);
|
|
42
|
+
if (entries.length > LIMITS.objectKeys)
|
|
43
|
+
return [{ path, message: "Object exceeds the key limit." }];
|
|
44
|
+
return entries.flatMap(
|
|
45
|
+
([key, item]) => inspectJson(item, `${path}.${key}`, depth + 1, budget)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return [{ path, message: "Custom block data must contain only JSON values." }];
|
|
49
|
+
};
|
|
50
|
+
var envelopeFrom = (value) => {
|
|
51
|
+
if (!plainObject(value)) return null;
|
|
52
|
+
const blockId = value.blockId;
|
|
53
|
+
const version = value.version;
|
|
54
|
+
const data = value.data;
|
|
55
|
+
return typeof blockId === "string" && ID_PATTERN.test(blockId) && positiveInteger(version) && plainObject(data) ? {
|
|
56
|
+
blockId,
|
|
57
|
+
version,
|
|
58
|
+
data
|
|
59
|
+
} : null;
|
|
60
|
+
};
|
|
61
|
+
var defineOpenEditorCustomBlock = (input) => {
|
|
62
|
+
if (!ID_PATTERN.test(input.id))
|
|
63
|
+
throw new Error(
|
|
64
|
+
`OpenEditor custom block IDs must be namespaced lowercase identifiers. Received "${input.id}".`
|
|
65
|
+
);
|
|
66
|
+
if (!positiveInteger(input.version))
|
|
67
|
+
throw new Error(
|
|
68
|
+
"OpenEditor custom block versions must be positive integers."
|
|
69
|
+
);
|
|
70
|
+
if (!input.label.trim() || input.label.length > 200)
|
|
71
|
+
throw new Error(
|
|
72
|
+
"OpenEditor custom block labels must be nonempty strings of 200 characters or less."
|
|
73
|
+
);
|
|
74
|
+
const manifest = deepFreeze({
|
|
75
|
+
id: input.id,
|
|
76
|
+
label: input.label,
|
|
77
|
+
version: input.version
|
|
78
|
+
});
|
|
79
|
+
const definition = { ...input, manifest };
|
|
80
|
+
Object.defineProperty(definition, DEFINITION_BRAND, { value: true });
|
|
81
|
+
return Object.freeze(definition);
|
|
82
|
+
};
|
|
83
|
+
var parseDefinitionData = (definition, data) => {
|
|
84
|
+
const diagnostics = inspectJson(data);
|
|
85
|
+
if (diagnostics.length) return { valid: false, diagnostics };
|
|
86
|
+
try {
|
|
87
|
+
const parsed = definition.parseData(deepFreeze(clone(data)));
|
|
88
|
+
const parsedDiagnostics = inspectJson(parsed);
|
|
89
|
+
if (!plainObject(parsed) || parsedDiagnostics.length)
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
diagnostics: parsedDiagnostics.length ? parsedDiagnostics : [{ path: "$.data", message: "The block parser must return an object." }]
|
|
93
|
+
};
|
|
94
|
+
return { valid: true, data: deepFreeze(clone(parsed)) };
|
|
95
|
+
} catch (error) {
|
|
96
|
+
return {
|
|
97
|
+
valid: false,
|
|
98
|
+
diagnostics: [
|
|
99
|
+
{
|
|
100
|
+
path: "$.data",
|
|
101
|
+
message: error instanceof Error ? error.message : "Custom block data is invalid."
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var createOpenEditorCustomBlockRegistry = (definitions, options = {}) => {
|
|
108
|
+
const byId = /* @__PURE__ */ new Map();
|
|
109
|
+
for (const definition of definitions) {
|
|
110
|
+
if (definition[DEFINITION_BRAND] !== true || !Object.isFrozen(definition) || !ID_PATTERN.test(definition.id) || !positiveInteger(definition.version))
|
|
111
|
+
throw new Error(`Invalid custom block definition "${definition.id ?? "unknown"}".`);
|
|
112
|
+
if (byId.has(definition.id))
|
|
113
|
+
throw new Error(`Duplicate custom block ID "${definition.id}".`);
|
|
114
|
+
byId.set(definition.id, definition);
|
|
115
|
+
}
|
|
116
|
+
const disabled = new Set(options.disabled ?? []);
|
|
117
|
+
const resolveEnvelope = (raw) => {
|
|
118
|
+
const initial = envelopeFrom(raw);
|
|
119
|
+
if (!initial)
|
|
120
|
+
return {
|
|
121
|
+
status: "invalid",
|
|
122
|
+
diagnostics: [
|
|
123
|
+
{
|
|
124
|
+
path: "$",
|
|
125
|
+
message: "Expected a valid OpenEditor custom block envelope."
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
};
|
|
129
|
+
const definition = byId.get(initial.blockId);
|
|
130
|
+
if (!definition)
|
|
131
|
+
return { status: "missing", blockId: initial.blockId, diagnostics: [] };
|
|
132
|
+
if (disabled.has(initial.blockId))
|
|
133
|
+
return { status: "disabled", blockId: initial.blockId, diagnostics: [] };
|
|
134
|
+
if (initial.version > definition.version)
|
|
135
|
+
return {
|
|
136
|
+
status: "incompatible",
|
|
137
|
+
blockId: initial.blockId,
|
|
138
|
+
diagnostics: [
|
|
139
|
+
{
|
|
140
|
+
path: "$.version",
|
|
141
|
+
message: `Stored version ${initial.version} is newer than supported version ${definition.version}.`
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
};
|
|
145
|
+
let envelope = clone(initial);
|
|
146
|
+
let attempts = 0;
|
|
147
|
+
while (envelope.version < definition.version) {
|
|
148
|
+
if (!definition.migrate)
|
|
149
|
+
return {
|
|
150
|
+
status: "incompatible",
|
|
151
|
+
blockId: initial.blockId,
|
|
152
|
+
diagnostics: [
|
|
153
|
+
{
|
|
154
|
+
path: "$.version",
|
|
155
|
+
message: `No migration exists from version ${envelope.version}.`
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
};
|
|
159
|
+
try {
|
|
160
|
+
const next = definition.migrate({
|
|
161
|
+
version: envelope.version,
|
|
162
|
+
data: deepFreeze(clone(envelope.data))
|
|
163
|
+
});
|
|
164
|
+
const checked = envelopeFrom(next);
|
|
165
|
+
if (!checked || checked.blockId !== definition.id || checked.version <= envelope.version || checked.version > definition.version)
|
|
166
|
+
throw new Error("The custom block migration returned an invalid envelope.");
|
|
167
|
+
envelope = checked;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
return {
|
|
170
|
+
status: "invalid",
|
|
171
|
+
blockId: initial.blockId,
|
|
172
|
+
diagnostics: [
|
|
173
|
+
{
|
|
174
|
+
path: "$.data",
|
|
175
|
+
message: error instanceof Error ? error.message : "Migration failed."
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
attempts += 1;
|
|
181
|
+
if (attempts > 100)
|
|
182
|
+
return {
|
|
183
|
+
status: "invalid",
|
|
184
|
+
blockId: initial.blockId,
|
|
185
|
+
diagnostics: [
|
|
186
|
+
{ path: "$.version", message: "Migration exceeded the step limit." }
|
|
187
|
+
]
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const parsed = parseDefinitionData(definition, envelope.data);
|
|
191
|
+
return parsed.valid ? {
|
|
192
|
+
status: "ready",
|
|
193
|
+
definition,
|
|
194
|
+
envelope: { ...envelope, data: parsed.data },
|
|
195
|
+
migrated: envelope.version !== initial.version
|
|
196
|
+
} : {
|
|
197
|
+
status: "invalid",
|
|
198
|
+
blockId: initial.blockId,
|
|
199
|
+
diagnostics: parsed.diagnostics
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
const resolve = (node) => {
|
|
203
|
+
const resolved = resolveEnvelope(node.attrs);
|
|
204
|
+
if (node.type !== OPENEDITOR_CUSTOM_BLOCK_NODE)
|
|
205
|
+
return {
|
|
206
|
+
status: "invalid",
|
|
207
|
+
node,
|
|
208
|
+
diagnostics: [
|
|
209
|
+
{ path: "$.type", message: "Expected a customBlock node." }
|
|
210
|
+
]
|
|
211
|
+
};
|
|
212
|
+
if (resolved.status !== "ready") return { ...resolved, node };
|
|
213
|
+
if (typeof node.attrs?.["openeditor-id"] !== "string" || !node.attrs["openeditor-id"].trim())
|
|
214
|
+
return {
|
|
215
|
+
status: "invalid",
|
|
216
|
+
node,
|
|
217
|
+
blockId: resolved.definition.id,
|
|
218
|
+
diagnostics: [
|
|
219
|
+
{
|
|
220
|
+
path: "$.attrs.openeditor-id",
|
|
221
|
+
message: "Custom block instance ID is required."
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
};
|
|
225
|
+
const migratedNode = {
|
|
226
|
+
...node,
|
|
227
|
+
attrs: { ...node.attrs, ...resolved.envelope }
|
|
228
|
+
};
|
|
229
|
+
return {
|
|
230
|
+
status: "ready",
|
|
231
|
+
definition: resolved.definition,
|
|
232
|
+
data: resolved.envelope.data,
|
|
233
|
+
migrated: resolved.migrated,
|
|
234
|
+
node: migratedNode
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
const renderNestedHtml = (document) => {
|
|
238
|
+
const valid = validateDocument(document);
|
|
239
|
+
if (!valid.valid) return "";
|
|
240
|
+
return {
|
|
241
|
+
tag: "div",
|
|
242
|
+
children: document.content.map((node) => {
|
|
243
|
+
if (node.type === "text") return node.text ?? "";
|
|
244
|
+
if (node.type === OPENEDITOR_CUSTOM_BLOCK_NODE) {
|
|
245
|
+
const nested = resolve(node);
|
|
246
|
+
return nested.status === "ready" ? nested.definition.toHtml({
|
|
247
|
+
data: nested.data,
|
|
248
|
+
renderDocument: options.renderDocument ?? renderNestedHtml,
|
|
249
|
+
documentToText: options.documentToText ?? renderNestedText
|
|
250
|
+
}) : `[${String(node.attrs?.blockId ?? "custom block")}: ${nested.status}]`;
|
|
251
|
+
}
|
|
252
|
+
const children = node.content?.map(
|
|
253
|
+
(child) => renderNestedHtml({ type: "doc", version: 1, content: [child] })
|
|
254
|
+
);
|
|
255
|
+
return {
|
|
256
|
+
tag: node.type === "paragraph" ? "p" : "div",
|
|
257
|
+
children
|
|
258
|
+
};
|
|
259
|
+
})
|
|
260
|
+
};
|
|
261
|
+
};
|
|
262
|
+
const renderNestedText = (document) => {
|
|
263
|
+
const visit = (node) => {
|
|
264
|
+
if (node.type === OPENEDITOR_CUSTOM_BLOCK_NODE) {
|
|
265
|
+
const nested = resolve(node);
|
|
266
|
+
return nested.status === "ready" ? nested.definition.toText({
|
|
267
|
+
data: nested.data,
|
|
268
|
+
renderDocument: options.renderDocument ?? renderNestedHtml,
|
|
269
|
+
documentToText: options.documentToText ?? renderNestedText
|
|
270
|
+
}) : "";
|
|
271
|
+
}
|
|
272
|
+
if (node.text) return node.text;
|
|
273
|
+
return node.content?.map(visit).filter(Boolean).join("\n") ?? "";
|
|
274
|
+
};
|
|
275
|
+
return document.content.map(visit).filter(Boolean).join("\n").trim();
|
|
276
|
+
};
|
|
277
|
+
const fallbackLabel = (node, status) => `Custom block ${String(node.attrs?.blockId ?? "unknown")} is unavailable: ${status}.`;
|
|
278
|
+
const registry = {
|
|
279
|
+
definitions: Object.freeze([...definitions]),
|
|
280
|
+
manifests: Object.freeze(definitions.map((item) => item.manifest)),
|
|
281
|
+
get: (id) => byId.get(id),
|
|
282
|
+
isEnabled: (id) => byId.has(id) && !disabled.has(id),
|
|
283
|
+
resolve,
|
|
284
|
+
validate: (raw) => {
|
|
285
|
+
const result = resolveEnvelope(raw);
|
|
286
|
+
return result.status === "ready" ? { valid: true, envelope: result.envelope } : { valid: false, diagnostics: result.diagnostics };
|
|
287
|
+
},
|
|
288
|
+
assets: (raw) => {
|
|
289
|
+
const result = resolveEnvelope(raw);
|
|
290
|
+
if (result.status !== "ready" || !result.definition.assets) return [];
|
|
291
|
+
try {
|
|
292
|
+
return result.definition.assets(result.envelope.data).filter(
|
|
293
|
+
(reference) => typeof reference.id === "string" && reference.id.length > 0 && typeof reference.path === "string" && reference.path.startsWith("$.data")
|
|
294
|
+
);
|
|
295
|
+
} catch {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
toHtml: (node) => {
|
|
300
|
+
const result = resolve(node);
|
|
301
|
+
if (result.status !== "ready")
|
|
302
|
+
return `<p role="status" data-openeditor-custom-block-error="${escapeOpenEditorCustomBlockHtml(result.status)}">${escapeOpenEditorCustomBlockHtml(fallbackLabel(node, result.status))}</p>`;
|
|
303
|
+
try {
|
|
304
|
+
return renderOpenEditorCustomBlockSafeHtml(
|
|
305
|
+
result.definition.toHtml({
|
|
306
|
+
data: result.data,
|
|
307
|
+
renderDocument: options.renderDocument ?? renderNestedHtml,
|
|
308
|
+
documentToText: options.documentToText ?? renderNestedText
|
|
309
|
+
})
|
|
310
|
+
);
|
|
311
|
+
} catch {
|
|
312
|
+
return `<p role="status" data-openeditor-custom-block-error="invalid">${escapeOpenEditorCustomBlockHtml(fallbackLabel(node, "invalid"))}</p>`;
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
toText: (node) => {
|
|
316
|
+
const result = resolve(node);
|
|
317
|
+
if (result.status !== "ready") return fallbackLabel(node, result.status);
|
|
318
|
+
try {
|
|
319
|
+
return result.definition.toText({
|
|
320
|
+
data: result.data,
|
|
321
|
+
renderDocument: options.renderDocument ?? renderNestedHtml,
|
|
322
|
+
documentToText: options.documentToText ?? renderNestedText
|
|
323
|
+
});
|
|
324
|
+
} catch {
|
|
325
|
+
return fallbackLabel(node, "invalid");
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
return Object.freeze(registry);
|
|
330
|
+
};
|
|
331
|
+
var createOpenEditorCustomBlockNode = (registry, id, data, options = {}) => {
|
|
332
|
+
const definition = registry.get(id);
|
|
333
|
+
if (!definition)
|
|
334
|
+
throw new Error(`OpenEditor custom block "${id}" is not registered.`);
|
|
335
|
+
const node = {
|
|
336
|
+
type: OPENEDITOR_CUSTOM_BLOCK_NODE,
|
|
337
|
+
attrs: {
|
|
338
|
+
"openeditor-id": options.instanceId ?? options.createInstanceId?.() ?? crypto.randomUUID(),
|
|
339
|
+
blockId: definition.id,
|
|
340
|
+
version: definition.version,
|
|
341
|
+
data: data ?? definition.createData()
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const resolved = registry.resolve(node);
|
|
345
|
+
if (resolved.status !== "ready")
|
|
346
|
+
throw new Error(
|
|
347
|
+
`Invalid initial data for custom block "${id}": ${resolved.diagnostics.map((item) => item.message).join(" ")}`
|
|
348
|
+
);
|
|
349
|
+
return resolved.node;
|
|
350
|
+
};
|
|
351
|
+
var resolveOpenEditorCustomBlockNode = (registry, node) => registry.resolve(node);
|
|
352
|
+
var validateOpenEditorCustomBlockEnvelope = (value, registry) => registry.validate(value);
|
|
353
|
+
var extractOpenEditorCustomBlockAssetReferences = (value, registry) => registry.assets(value);
|
|
354
|
+
var conformOpenEditorCustomBlock = (definition) => {
|
|
355
|
+
try {
|
|
356
|
+
const registry = createOpenEditorCustomBlockRegistry([definition]);
|
|
357
|
+
const node = createOpenEditorCustomBlockNode(
|
|
358
|
+
registry,
|
|
359
|
+
definition.id,
|
|
360
|
+
void 0,
|
|
361
|
+
{ instanceId: "conformance-instance" }
|
|
362
|
+
);
|
|
363
|
+
const html = registry.toHtml(node);
|
|
364
|
+
const text = registry.toText(node);
|
|
365
|
+
return html.includes('data-openeditor-custom-block-error="invalid"') || text === `Custom block ${definition.id} is unavailable: invalid.` ? [
|
|
366
|
+
{
|
|
367
|
+
path: "$.staticExport",
|
|
368
|
+
message: "Custom block static export failed conformance."
|
|
369
|
+
}
|
|
370
|
+
] : [];
|
|
371
|
+
} catch (error) {
|
|
372
|
+
return [
|
|
373
|
+
{
|
|
374
|
+
path: "$",
|
|
375
|
+
message: error instanceof Error ? error.message : "Custom block conformance failed."
|
|
376
|
+
}
|
|
377
|
+
];
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
var escapeOpenEditorCustomBlockHtml = (value) => String(value).replace(
|
|
381
|
+
/[&<>"']/g,
|
|
382
|
+
(character) => ({
|
|
383
|
+
"&": "&",
|
|
384
|
+
"<": "<",
|
|
385
|
+
">": ">",
|
|
386
|
+
'"': """,
|
|
387
|
+
"'": "'"
|
|
388
|
+
})[character]
|
|
389
|
+
);
|
|
390
|
+
var SAFE_TAGS = /* @__PURE__ */ new Set([
|
|
391
|
+
"div",
|
|
392
|
+
"span",
|
|
393
|
+
"p",
|
|
394
|
+
"h1",
|
|
395
|
+
"h2",
|
|
396
|
+
"h3",
|
|
397
|
+
"h4",
|
|
398
|
+
"h5",
|
|
399
|
+
"h6",
|
|
400
|
+
"article",
|
|
401
|
+
"section",
|
|
402
|
+
"aside",
|
|
403
|
+
"blockquote",
|
|
404
|
+
"figure",
|
|
405
|
+
"figcaption",
|
|
406
|
+
"ul",
|
|
407
|
+
"ol",
|
|
408
|
+
"li",
|
|
409
|
+
"dl",
|
|
410
|
+
"dt",
|
|
411
|
+
"dd",
|
|
412
|
+
"table",
|
|
413
|
+
"caption",
|
|
414
|
+
"thead",
|
|
415
|
+
"tbody",
|
|
416
|
+
"tr",
|
|
417
|
+
"th",
|
|
418
|
+
"td",
|
|
419
|
+
"strong",
|
|
420
|
+
"em",
|
|
421
|
+
"u",
|
|
422
|
+
"s",
|
|
423
|
+
"code",
|
|
424
|
+
"pre",
|
|
425
|
+
"a",
|
|
426
|
+
"img",
|
|
427
|
+
"br",
|
|
428
|
+
"hr"
|
|
429
|
+
]);
|
|
430
|
+
var SAFE_ATTRS = /* @__PURE__ */ new Set([
|
|
431
|
+
"aria-label",
|
|
432
|
+
"aria-current",
|
|
433
|
+
"role",
|
|
434
|
+
"title",
|
|
435
|
+
"href",
|
|
436
|
+
"src",
|
|
437
|
+
"alt",
|
|
438
|
+
"width",
|
|
439
|
+
"height",
|
|
440
|
+
"start",
|
|
441
|
+
"colspan",
|
|
442
|
+
"rowspan",
|
|
443
|
+
"scope"
|
|
444
|
+
]);
|
|
445
|
+
var safeStaticUrl = (value, context) => {
|
|
446
|
+
const normalized = value.trim();
|
|
447
|
+
if (!normalized) return null;
|
|
448
|
+
const scheme = /^([a-z][a-z\d+.-]*):/i.exec(normalized)?.[1]?.toLowerCase();
|
|
449
|
+
if (!scheme)
|
|
450
|
+
return normalized.startsWith("//") || normalized.includes("\\") ? null : normalized;
|
|
451
|
+
const allowed = context === "asset" ? ["http", "https"] : ["http", "https", "mailto", "tel"];
|
|
452
|
+
return allowed.includes(scheme) ? normalized : null;
|
|
453
|
+
};
|
|
454
|
+
var renderOpenEditorCustomBlockSafeHtml = (value) => {
|
|
455
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
456
|
+
let nodes = 0;
|
|
457
|
+
let stringBytes = 0;
|
|
458
|
+
const count = (rendered) => {
|
|
459
|
+
stringBytes += rendered.length;
|
|
460
|
+
if (stringBytes > LIMITS.stringLength)
|
|
461
|
+
throw new Error("Safe HTML output exceeds its text limit.");
|
|
462
|
+
return rendered;
|
|
463
|
+
};
|
|
464
|
+
const render = (item, depth) => {
|
|
465
|
+
nodes += 1;
|
|
466
|
+
if (nodes > LIMITS.values || depth > LIMITS.depth)
|
|
467
|
+
throw new Error("Safe HTML output exceeds its structural limit.");
|
|
468
|
+
if (item && typeof item === "object") {
|
|
469
|
+
if (seen.has(item)) throw new Error("Safe HTML output must not contain cycles.");
|
|
470
|
+
seen.add(item);
|
|
471
|
+
}
|
|
472
|
+
if (item === null || item === false) return "";
|
|
473
|
+
if (typeof item === "string" || typeof item === "number")
|
|
474
|
+
return count(escapeOpenEditorCustomBlockHtml(item));
|
|
475
|
+
if (!plainObject(item) || typeof item.tag !== "string" || !SAFE_TAGS.has(item.tag))
|
|
476
|
+
return "";
|
|
477
|
+
const attrs = Object.entries(item.attrs ?? {}).flatMap(([name, raw]) => {
|
|
478
|
+
if (raw === void 0 || !SAFE_ATTRS.has(name)) return [];
|
|
479
|
+
const safe = name === "href" ? safeStaticUrl(String(raw), "navigation") : name === "src" ? safeStaticUrl(String(raw), "asset") : String(raw);
|
|
480
|
+
return safe === null ? [] : [count(` ${name}="${escapeOpenEditorCustomBlockHtml(safe)}"`)];
|
|
481
|
+
}).join("");
|
|
482
|
+
const children = (item.children ?? []).map((child) => render(child, depth + 1)).join("");
|
|
483
|
+
return ["img", "br", "hr"].includes(item.tag) ? `<${item.tag}${attrs}>` : `<${item.tag}${attrs}>${children}</${item.tag}>`;
|
|
484
|
+
};
|
|
485
|
+
return render(value, 0);
|
|
486
|
+
};
|
|
487
|
+
|
|
1
488
|
// src/index.ts
|
|
2
489
|
var OPENEDITOR_DOCUMENT_FORMAT_VERSION = 1;
|
|
3
490
|
var OPENEDITOR_URL_SCHEME = /^([a-z][a-z\d+.-]*):/i;
|
|
@@ -214,10 +701,10 @@ var cloneAndFreezeContractValue = (value) => {
|
|
|
214
701
|
if (Array.isArray(value)) {
|
|
215
702
|
return Object.freeze(value.map((child) => cloneAndFreezeContractValue(child)));
|
|
216
703
|
}
|
|
217
|
-
const
|
|
704
|
+
const clone2 = Object.fromEntries(Object.entries(value).map(
|
|
218
705
|
([key, child]) => [key, cloneAndFreezeContractValue(child)]
|
|
219
706
|
));
|
|
220
|
-
return Object.freeze(
|
|
707
|
+
return Object.freeze(clone2);
|
|
221
708
|
};
|
|
222
709
|
var createReadonlyMap = (source) => {
|
|
223
710
|
let view;
|
|
@@ -808,6 +1295,6 @@ var openEditorThemeTokenNames = [
|
|
|
808
1295
|
var openEditorThemeCssName = (token) => `--oe-${token.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Za-z])(\d)/g, "$1-$2").replace(/(\d)([A-Z])/g, "$1-$2").toLowerCase()}`;
|
|
809
1296
|
var getOpenEditorThemeEntries = (theme) => openEditorThemeTokenNames.flatMap((token) => theme[token] === void 0 ? [] : [[openEditorThemeCssName(token), theme[token]]]);
|
|
810
1297
|
|
|
811
|
-
export { DEFAULT_CALLOUT_EMOJI, DEFAULT_DOCUMENT_VALIDATION_LIMITS, DEFAULT_PAGE_EMOJI, OPENEDITOR_BLOCK_ID_ATTR, OPENEDITOR_DOCUMENT_FORMAT_VERSION, OpenEditorDocumentParseError, applyCommand, canonicalSerializeJson, cloneNode, createAttachmentSnapshot, createBlockId, createBlockRegistry, createDocument, createEditorState, createOpenEditorDocumentContract, createTextNode, createTransaction, deleteTopLevelBlock, duplicateTopLevelBlock, ensureBlockIds, findBlockLocation, findBlockSpecForNode, fingerprintOpenEditorDocument, fromProseMirrorDocument, getBlockId, getDocumentText, getOpenEditorThemeEntries, getPlatformDocument, getPlatformSupport, importProseMirrorDocument, isOpenEditorBlockEnabled, isOpenEditorDocument, moveTopLevelBlock, normalizeDocument, normalizeEmoji, openEditorExternalMediaUrlPolicy, openEditorNavigationUrlPolicy, openEditorThemeCssName, openEditorThemeTokenNames, openEditorUnsafeUrlPolicy, openEditorUntrustedDocumentUrlPolicy, parseEditorState, parseOpenEditorDocument, replaceTopLevelNode, replaceTopLevelRange, serializeEditorState, textBlock, toProseMirrorDocument, validateDocument, withBlockId };
|
|
1298
|
+
export { DEFAULT_CALLOUT_EMOJI, DEFAULT_DOCUMENT_VALIDATION_LIMITS, DEFAULT_PAGE_EMOJI, OPENEDITOR_BLOCK_ID_ATTR, OPENEDITOR_CUSTOM_BLOCK_NODE, OPENEDITOR_DOCUMENT_FORMAT_VERSION, OpenEditorDocumentParseError, applyCommand, canonicalSerializeJson, cloneNode, conformOpenEditorCustomBlock, createAttachmentSnapshot, createBlockId, createBlockRegistry, createDocument, createEditorState, createOpenEditorCustomBlockNode, createOpenEditorCustomBlockRegistry, createOpenEditorDocumentContract, createTextNode, createTransaction, defineOpenEditorCustomBlock, deleteTopLevelBlock, duplicateTopLevelBlock, ensureBlockIds, escapeOpenEditorCustomBlockHtml, extractOpenEditorCustomBlockAssetReferences, findBlockLocation, findBlockSpecForNode, fingerprintOpenEditorDocument, fromProseMirrorDocument, getBlockId, getDocumentText, getOpenEditorThemeEntries, getPlatformDocument, getPlatformSupport, importProseMirrorDocument, isOpenEditorBlockEnabled, isOpenEditorDocument, moveTopLevelBlock, normalizeDocument, normalizeEmoji, openEditorExternalMediaUrlPolicy, openEditorNavigationUrlPolicy, openEditorThemeCssName, openEditorThemeTokenNames, openEditorUnsafeUrlPolicy, openEditorUntrustedDocumentUrlPolicy, parseEditorState, parseOpenEditorDocument, renderOpenEditorCustomBlockSafeHtml, replaceTopLevelNode, replaceTopLevelRange, resolveOpenEditorCustomBlockNode, serializeEditorState, textBlock, toProseMirrorDocument, validateDocument, validateOpenEditorCustomBlockEnvelope, withBlockId };
|
|
812
1299
|
//# sourceMappingURL=index.js.map
|
|
813
1300
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["content"],"mappings":"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","file":"index.js","sourcesContent":["export type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[];\nexport type JsonObject = { [key: string]: JsonValue | undefined };\n\nexport type ProseMirrorAttrs = Record<string, unknown>;\n\nexport type ProseMirrorMark = {\n type: string;\n attrs?: ProseMirrorAttrs;\n};\n\nexport type ProseMirrorNode = {\n type: string;\n attrs?: ProseMirrorAttrs;\n content?: ProseMirrorNode[];\n marks?: ProseMirrorMark[];\n text?: string;\n};\n\nexport type OpenEditorBlock = ProseMirrorNode & {\n attrs?: ProseMirrorAttrs & {\n \"openeditor-id\"?: string;\n };\n};\n\n/** Stable identity used by commands and interaction adapters. */\nexport type OpenEditorBlockRef = {\n id: string;\n nodeType: string;\n blockName?: string;\n};\n\nexport type OpenEditorBlockLocation = OpenEditorBlockRef & {\n parentId: string | null;\n index: number;\n path: readonly number[];\n};\n\nexport type OpenEditorDocumentMeta = {\n id?: string;\n title?: string;\n source?: string;\n createdAt?: string;\n updatedAt?: string;\n platform?: EditorPlatform;\n /** Consumer-defined schema version. The OpenEditor JSON format remains independently versioned. */\n schemaVersion?: string;\n custom?: Record<string, unknown>;\n};\n\nexport const OPENEDITOR_DOCUMENT_FORMAT_VERSION = 1 as const;\n\nexport type OpenEditorDocument = {\n type: \"doc\";\n version: typeof OPENEDITOR_DOCUMENT_FORMAT_VERSION;\n content: OpenEditorBlock[];\n meta?: OpenEditorDocumentMeta;\n};\n\nexport type ProseMirrorDocument = {\n type: \"doc\";\n content: ProseMirrorNode[];\n};\n\nexport type EditorPlatform = \"web\" | \"native\";\n\nexport type PlatformSupportLevel = \"supported\" | \"unsupported\";\n\nexport type PlatformSupport = {\n web: PlatformSupportLevel;\n native: PlatformSupportLevel;\n};\n\nexport type BlockGroup = \"text\" | \"media\" | \"layout\" | \"structure\" | \"embed\";\n\nexport type BlockSpec = {\n name: string;\n /** ProseMirror node type. Defaults to `name`. */\n nodeType?: string;\n label: string;\n group: BlockGroup;\n defaultNode: () => OpenEditorBlock;\n /** False for internal schema carriers that cannot be inserted directly. */\n insertable?: boolean;\n matchNode?: (node: ProseMirrorNode) => boolean;\n support?: PlatformSupport;\n /** Optional portable contract used by server-side validation and schema-aware consumers. */\n schema?: Omit<OpenEditorNodeSpec, \"type\">;\n};\n\nexport type BlockRegistry = ReadonlyMap<string, BlockSpec>;\n\nexport type OpenEditorValueValidationContext = {\n path: string;\n};\n\nexport type OpenEditorValueValidator = (\n value: unknown,\n context: OpenEditorValueValidationContext,\n) => string | readonly string[] | null | undefined;\n\ntype OpenEditorValueSchemaBase = {\n nullable?: boolean;\n enum?: readonly JsonValue[];\n validate?: OpenEditorValueValidator;\n};\n\nexport type OpenEditorValueSchema = OpenEditorValueSchemaBase & (\n | { type: \"any\" }\n | { type: \"string\"; minLength?: number; maxLength?: number; pattern?: string }\n | { type: \"number\"; integer?: boolean; minimum?: number; maximum?: number }\n | { type: \"boolean\" }\n | { type: \"null\" }\n | {\n type: \"array\";\n items?: OpenEditorValueSchema;\n minItems?: number;\n maxItems?: number;\n }\n | {\n type: \"object\";\n properties?: Readonly<Record<string, OpenEditorValueSchema>>;\n required?: readonly string[];\n additionalProperties?: boolean | OpenEditorValueSchema;\n }\n);\n\nexport type OpenEditorAttributesSpec = {\n properties?: Readonly<Record<string, OpenEditorValueSchema>>;\n required?: readonly string[];\n /** Defaults to false for contract-aware validation. */\n additionalProperties?: boolean | OpenEditorValueSchema;\n};\n\nexport type OpenEditorContentSpec = {\n allowedTypes?: readonly string[];\n minItems?: number;\n maxItems?: number;\n};\n\nexport type OpenEditorNodeValidator = (\n node: ProseMirrorNode,\n context: OpenEditorValueValidationContext,\n) => string | readonly string[] | null | undefined;\n\n/** Portable validation contract for one ProseMirror node type. */\nexport type OpenEditorNodeSpec = {\n type: string;\n attributes?: OpenEditorAttributesSpec;\n content?: OpenEditorContentSpec | false;\n text?: \"required\" | \"allowed\" | \"forbidden\";\n marks?: false | readonly string[];\n validate?: OpenEditorNodeValidator;\n};\n\nexport type OpenEditorMarkSpec = {\n type: string;\n attributes?: OpenEditorAttributesSpec;\n};\n\nexport type OpenEditorDocumentContract = {\n formatVersion: typeof OPENEDITOR_DOCUMENT_FORMAT_VERSION;\n schemaVersion: string;\n /** Optional portable constraint for the document root's direct children. */\n rootContent?: OpenEditorContentSpec;\n nodes: ReadonlyMap<string, OpenEditorNodeSpec>;\n marks: ReadonlyMap<string, OpenEditorMarkSpec>;\n};\n\nexport type CreateOpenEditorDocumentContractOptions = {\n schemaVersion: string;\n blockSpecs?: readonly BlockSpec[];\n nodeSpecs?: readonly OpenEditorNodeSpec[];\n markSpecs?: readonly OpenEditorMarkSpec[];\n rootContent?: OpenEditorContentSpec;\n};\n\nexport type EditorSelection =\n | { type: \"none\" }\n | { type: \"text\"; anchor: number; head: number }\n | { type: \"node\"; from: number; to: number; nodeType?: string }\n | { type: \"block\"; blockId: string };\n\nexport type OpenEditorMarkName =\n | \"bold\"\n | \"italic\"\n | \"underline\"\n | \"strike\"\n | \"code\"\n | \"link\";\n\nexport type OpenEditorFeatureName =\n | \"headings\"\n | \"lists\"\n | \"taskLists\"\n | \"quotes\"\n | \"codeBlocks\"\n | \"dividers\"\n | \"links\"\n | \"images\"\n | \"columns\"\n | \"tables\"\n | \"toggleLists\"\n | \"callouts\"\n | \"diagrams\"\n | \"pages\"\n | \"attachments\";\n\n/** Durable image data stored by the editor. Resolved preview URLs stay runtime-owned. */\nexport type OpenEditorImageSnapshot = {\n imageId: string | null;\n src: string | null;\n alt: string;\n width: number | null;\n height: number | null;\n};\n\n/** A host-selected image. `source` is platform-specific and is never serialized. */\nexport type OpenEditorImageUploadInput<TSource = unknown> = {\n name: string;\n mimeType: string | null;\n size: number | null;\n source: TSource;\n};\n\nexport type OpenEditorImageUploadCallbacks = {\n onProgress?: (progress: number) => void;\n signal?: AbortSignal;\n};\n\nexport type OpenEditorImageValidationResult =\n | { accepted: true }\n | { accepted: false; message: string };\n\n/** Host-owned image selection, storage, validation, and URL resolution. */\nexport type OpenEditorImageRuntime<TSource = unknown> = {\n selectImage?: (options?: { signal?: AbortSignal }) =>\n | Promise<OpenEditorImageUploadInput<TSource> | null>\n | OpenEditorImageUploadInput<TSource>\n | null;\n validateImage?: (\n input: OpenEditorImageUploadInput<TSource>,\n ) => OpenEditorImageValidationResult | Promise<OpenEditorImageValidationResult>;\n uploadImage?: (\n input: OpenEditorImageUploadInput<TSource>,\n callbacks?: OpenEditorImageUploadCallbacks,\n ) => Promise<OpenEditorImageSnapshot>;\n resolveImage?: (imageId: string, options?: { signal?: AbortSignal }) =>\n Promise<OpenEditorImageSnapshot | null>;\n replaceImage?: (\n imageId: string,\n input: OpenEditorImageUploadInput<TSource>,\n callbacks?: OpenEditorImageUploadCallbacks,\n ) => Promise<OpenEditorImageSnapshot>;\n};\n\n/** Durable, portable attributes stored on an attachment node. */\nexport type OpenEditorAttachmentSnapshot = {\n attachmentId: string | null;\n name: string;\n mimeType: string | null;\n size: number | null;\n url: string | null;\n};\n\n/**\n * A host-selected local file. `source` is deliberately opaque: on web it may\n * be a File, while native hosts typically use a picker result or local URI.\n * OpenEditor never serializes it.\n */\nexport type OpenEditorAttachmentUploadInput<TSource = unknown> = {\n name: string;\n mimeType: string | null;\n size: number | null;\n source: TSource;\n};\n\nexport type OpenEditorAttachmentUploadCallbacks = {\n onProgress?: (progress: number) => void;\n signal?: AbortSignal;\n};\n\nexport type OpenEditorAttachmentValidationResult =\n | { accepted: true }\n | { accepted: false; message: string };\n\n/** Host-owned storage, picker, policy, resolution, and platform actions. */\nexport type OpenEditorAttachmentRuntime<TSource = unknown> = {\n selectAttachment?: (options?: { signal?: AbortSignal }) =>\n | Promise<OpenEditorAttachmentUploadInput<TSource> | null>\n | OpenEditorAttachmentUploadInput<TSource>\n | null;\n validateAttachment?: (\n input: OpenEditorAttachmentUploadInput<TSource>,\n ) => OpenEditorAttachmentValidationResult | Promise<OpenEditorAttachmentValidationResult>;\n uploadAttachment?: (\n input: OpenEditorAttachmentUploadInput<TSource>,\n callbacks?: OpenEditorAttachmentUploadCallbacks,\n ) => Promise<OpenEditorAttachmentSnapshot>;\n resolveAttachment?: (attachmentId: string, options?: { signal?: AbortSignal }) =>\n Promise<OpenEditorAttachmentSnapshot | null>;\n openAttachment?: (attachment: OpenEditorAttachmentSnapshot) => void | Promise<void>;\n renameAttachment?: (attachmentId: string, name: string) => void | Promise<void>;\n replaceAttachment?: (\n attachmentId: string,\n input: OpenEditorAttachmentUploadInput<TSource>,\n callbacks?: OpenEditorAttachmentUploadCallbacks,\n ) => Promise<OpenEditorAttachmentSnapshot>;\n};\n\nexport type OpenEditorPageSnapshot = {\n pageId: string;\n title: string;\n icon?: string | null;\n href?: string | null;\n};\n\nexport type OpenEditorPageUpdate = {\n title?: string;\n icon?: string | null;\n};\n\n/** Host-owned page identity, persistence, navigation, and metadata lifecycle. */\nexport type OpenEditorPageRuntime = {\n createPage?: (input: { title: string; icon?: string | null }) => Promise<OpenEditorPageSnapshot>;\n resolvePage?: (pageId: string) => Promise<OpenEditorPageSnapshot | null>;\n updatePage?: (\n pageId: string,\n update: OpenEditorPageUpdate,\n ) => Promise<OpenEditorPageSnapshot | void> | OpenEditorPageSnapshot | void;\n openPage?: (page: OpenEditorPageSnapshot) => Promise<void> | void;\n};\n\n/** Built-in URL-bearing surfaces rendered from portable document data. */\nexport type OpenEditorUrlContext = \"link\" | \"image\" | \"page\" | \"attachment\";\n\n/**\n * Returns the URL that may be rendered for a context, or `null` to omit the\n * navigation/resource. Policies are pure so the same contract can be shared by\n * React viewers, HTML exporters, and other public renderers.\n */\nexport type OpenEditorUrlPolicy = (\n value: string,\n context: OpenEditorUrlContext,\n) => string | null;\n\nconst OPENEDITOR_URL_SCHEME = /^([a-z][a-z\\d+.-]*):/i;\nconst OPENEDITOR_URL_CONTROL_CHARACTER = /[\\u0000-\\u001f\\u007f]/;\nconst OPENEDITOR_NAVIGATION_SCHEMES: Readonly<Record<Exclude<OpenEditorUrlContext, \"image\">, ReadonlySet<string>>> = {\n link: new Set([\"http\", \"https\", \"mailto\", \"tel\"]),\n page: new Set([\"http\", \"https\"]),\n attachment: new Set([\"http\", \"https\"]),\n};\n\nconst normalizePolicyUrl = (value: string) => {\n const normalized = value.trim();\n return !normalized || OPENEDITOR_URL_CONTROL_CHARACTER.test(normalized) ? null : normalized;\n};\n\n/**\n * Safe policy for user-activated navigation. Ordinary relative references are\n * preserved and explicit schemes are allowlisted by navigation context.\n */\nexport const openEditorNavigationUrlPolicy: OpenEditorUrlPolicy = (value, context) => {\n const normalized = normalizePolicyUrl(value);\n if (!normalized || context === \"image\") return null;\n\n const scheme = OPENEDITOR_URL_SCHEME.exec(normalized)?.[1]?.toLowerCase();\n if (!scheme) return normalized;\n return OPENEDITOR_NAVIGATION_SCHEMES[context].has(scheme) ? normalized : null;\n};\n\n/**\n * Default for rendering untrusted documents. Navigation remains available,\n * while every image URL is blocked so rendering cannot silently contact an\n * external or same-origin tracking endpoint.\n */\nexport const openEditorUntrustedDocumentUrlPolicy: OpenEditorUrlPolicy = (value, context) =>\n context === \"image\" ? null : openEditorNavigationUrlPolicy(value, context);\n\n/**\n * Explicit opt-in for hosts that intentionally allow HTTP(S) or relative image\n * loading. This is not safe as an untrusted-document rendering default.\n */\nexport const openEditorExternalMediaUrlPolicy: OpenEditorUrlPolicy = (value, context) => {\n if (context !== \"image\") return openEditorNavigationUrlPolicy(value, context);\n const normalized = normalizePolicyUrl(value);\n if (!normalized) return null;\n const scheme = OPENEDITOR_URL_SCHEME.exec(normalized)?.[1]?.toLowerCase();\n return !scheme || scheme === \"http\" || scheme === \"https\" ? normalized : null;\n};\n\n/** Explicit trusted-host escape hatch. Never use this for untrusted documents. */\nexport const openEditorUnsafeUrlPolicy: OpenEditorUrlPolicy = (value) => {\n const normalized = value.trim();\n return normalized || null;\n};\n\nexport const createAttachmentSnapshot = (\n attrs: Partial<OpenEditorAttachmentSnapshot> = {},\n): OpenEditorAttachmentSnapshot => ({\n attachmentId: typeof attrs.attachmentId === \"string\" ? attrs.attachmentId : null,\n name: typeof attrs.name === \"string\" ? attrs.name : \"\",\n mimeType: typeof attrs.mimeType === \"string\" ? attrs.mimeType : null,\n size: typeof attrs.size === \"number\" && Number.isFinite(attrs.size) && attrs.size >= 0 ? attrs.size : null,\n url: typeof attrs.url === \"string\" ? attrs.url : null,\n});\n\nexport type OpenEditorFeatureSet = Readonly<Record<OpenEditorFeatureName, boolean>>;\n\n/** Controls which schema-supported blocks may be created by an editor surface. */\nexport type OpenEditorAuthoringCapabilities = {\n enabledBlocks?: readonly string[];\n};\n\nexport const isOpenEditorBlockEnabled = (\n blockName: string,\n capabilities?: OpenEditorAuthoringCapabilities,\n): boolean => capabilities?.enabledBlocks === undefined\n || capabilities.enabledBlocks.includes(blockName);\n\nexport const DEFAULT_CALLOUT_EMOJI = \"💡\";\nexport const DEFAULT_PAGE_EMOJI = \"📄\";\n\nexport const normalizeEmoji = (value: unknown, fallback: string) =>\n typeof value === \"string\" && value.trim() ? value.trim() : fallback;\n\nexport type SerializedEditorState = {\n document: OpenEditorDocument;\n selection?: EditorSelection;\n};\n\nexport type EditorTransaction = {\n before: OpenEditorDocument;\n after: OpenEditorDocument;\n command?: OpenEditorCommand;\n timestamp: string;\n};\n\nexport type OpenEditorCommand =\n | { type: \"setContent\"; document: OpenEditorDocument }\n | { type: \"insertBlock\"; block: string; at?: number; attrs?: ProseMirrorAttrs }\n | { type: \"moveBlock\"; from: number; to: number }\n | { type: \"duplicateBlock\"; index: number }\n | { type: \"deleteBlock\"; index: number }\n | { type: \"setLink\"; href?: string }\n | { type: \"toggleMark\"; mark: OpenEditorMarkName }\n | { type: \"undo\" }\n | { type: \"redo\" }\n | { type: \"setSelection\"; selection: EditorSelection };\n\nexport type EditorCommand = OpenEditorCommand;\n\nexport type OpenEditorEventHandlers = {\n onChange?: (document: OpenEditorDocument) => void;\n onSelectionChange?: (selection: EditorSelection) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n onReady?: (controller: OpenEditorController) => void;\n onCommand?: (command: OpenEditorCommand, transaction: EditorTransaction) => void;\n};\n\nexport type OpenEditorConfig = OpenEditorEventHandlers & {\n initialDocument?: OpenEditorDocument;\n editable?: boolean;\n placeholder?: string;\n enabledBlocks?: readonly string[];\n theme?: Record<string, string | number>;\n};\n\nexport type OpenEditorController = {\n getContent: () => OpenEditorDocument;\n setContent: (document: OpenEditorDocument) => void;\n getSelection: () => EditorSelection;\n execute: (command: OpenEditorCommand) => void;\n};\n\nexport type DocumentValidationIssue = {\n path: string;\n message: string;\n code?: DocumentValidationCode;\n};\n\nexport type DocumentValidationCode =\n | \"invalid_document\"\n | \"invalid_document_type\"\n | \"unsupported_format_version\"\n | \"schema_version_mismatch\"\n | \"invalid_meta\"\n | \"invalid_node\"\n | \"invalid_node_type\"\n | \"unknown_node_type\"\n | \"invalid_text\"\n | \"unexpected_text\"\n | \"invalid_attrs\"\n | \"missing_attribute\"\n | \"unknown_attribute\"\n | \"unknown_property\"\n | \"invalid_attribute\"\n | \"invalid_marks\"\n | \"invalid_mark\"\n | \"unknown_mark_type\"\n | \"disallowed_mark\"\n | \"invalid_content\"\n | \"disallowed_child\"\n | \"duplicate_node_id\"\n | \"missing_node_id\"\n | \"non_json_value\"\n | \"cyclic_value\"\n | \"limit_depth\"\n | \"limit_nodes\"\n | \"limit_marks\"\n | \"limit_text\"\n | \"limit_attributes\"\n | \"custom_validation\";\n\nexport type DocumentValidationResult = {\n valid: boolean;\n issues: DocumentValidationIssue[];\n};\n\nexport type DocumentValidationLimits = {\n maxDepth: number;\n maxNodes: number;\n maxMarksPerNode: number;\n maxTextLength: number;\n maxTotalTextLength: number;\n maxAttributeDepth: number;\n maxArrayItems: number;\n maxObjectKeys: number;\n /** Global JSON value budget, including metadata and attributes. */\n maxJsonValues: number;\n requireNodeIds: boolean;\n};\n\nexport type ValidateDocumentOptions = {\n contract?: OpenEditorDocumentContract;\n limits?: Partial<DocumentValidationLimits>;\n /** Reject a document whose meta.schemaVersion differs from the configured contract. */\n requireSchemaVersion?: boolean;\n};\n\nexport const DEFAULT_DOCUMENT_VALIDATION_LIMITS: Readonly<DocumentValidationLimits> = {\n maxDepth: 128,\n maxNodes: 100_000,\n maxMarksPerNode: 64,\n maxTextLength: 1_000_000,\n maxTotalTextLength: 10_000_000,\n maxAttributeDepth: 32,\n maxArrayItems: 100_000,\n maxObjectKeys: 10_000,\n maxJsonValues: 500_000,\n requireNodeIds: false,\n};\n\nexport type PlatformSupportIssue = {\n path: string;\n block: string;\n platform: EditorPlatform;\n support: PlatformSupportLevel;\n};\n\nexport type PlatformSupportResult = {\n platform: EditorPlatform;\n document: OpenEditorDocument;\n issues: PlatformSupportIssue[];\n};\n\nexport const OPENEDITOR_BLOCK_ID_ATTR = \"openeditor-id\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst normalizeMeta = (meta?: OpenEditorDocumentMeta): OpenEditorDocumentMeta | undefined =>\n meta && Object.keys(meta).length ? { ...meta } : undefined;\n\nconst cloneAttrs = (attrs?: ProseMirrorAttrs): ProseMirrorAttrs | undefined =>\n attrs ? { ...attrs } : undefined;\n\nconst cloneMark = (mark: ProseMirrorMark): ProseMirrorMark => ({\n type: mark.type,\n ...(mark.attrs ? { attrs: cloneAttrs(mark.attrs) } : {}),\n});\n\nconst cloneNodeShallow = <T extends ProseMirrorNode>(node: T): T => ({\n ...node,\n ...(node.attrs ? { attrs: cloneAttrs(node.attrs) } : {}),\n ...(node.marks ? { marks: node.marks.map(cloneMark) } : {}),\n});\n\nexport const cloneNode = <T extends ProseMirrorNode>(node: T): T => ({\n ...cloneNodeShallow(node),\n ...(node.content ? { content: node.content.map(cloneNode) } : {}),\n});\n\nexport const createBlockId = (prefix = \"oe\"): string => {\n const random =\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : Math.random().toString(36).slice(2);\n\n return `${prefix}_${random.replaceAll(\"-\", \"\").slice(0, 24)}`;\n};\n\nconst cloneNodeWithIds = (\n node: ProseMirrorNode,\n createId: () => string,\n seenIds: Set<string>,\n): ProseMirrorNode => {\n if (node.type === \"text\") return cloneNode(node);\n const cloned = cloneNodeShallow(node);\n const existingId = getBlockId(cloned);\n let id = existingId && !seenIds.has(existingId) ? existingId : createId();\n while (!id.trim() || seenIds.has(id)) id = createId();\n seenIds.add(id);\n const withId = withBlockId(cloned, id);\n return {\n ...withId,\n ...(node.content\n ? { content: node.content.map((child) => cloneNodeWithIds(child, createId, seenIds)) }\n : {}),\n };\n};\n\nconst createDocumentWithIds = (\n content: ProseMirrorNode[] = [],\n meta?: OpenEditorDocumentMeta,\n createId: () => string = createBlockId,\n): OpenEditorDocument => {\n const normalizedMeta = normalizeMeta(meta);\n const seenIds = new Set<string>();\n return {\n type: \"doc\",\n version: 1,\n content: content.map((node) => cloneNodeWithIds(node, createId, seenIds)) as OpenEditorBlock[],\n ...(normalizedMeta ? { meta: normalizedMeta } : {}),\n };\n};\n\nexport const createDocument = (\n content: ProseMirrorNode[] = [],\n meta?: OpenEditorDocumentMeta,\n): OpenEditorDocument => createDocumentWithIds(content, meta);\n\nexport const createEditorState = (\n document: OpenEditorDocument,\n selection: EditorSelection = { type: \"none\" },\n): SerializedEditorState => ({\n document: normalizeDocument(document),\n selection,\n});\n\nexport const toProseMirrorDocument = (document: OpenEditorDocument): ProseMirrorDocument => ({\n type: \"doc\",\n content: document.content.map(cloneNode),\n});\n\nexport const fromProseMirrorDocument = (\n document: ProseMirrorDocument,\n meta?: OpenEditorDocumentMeta,\n): OpenEditorDocument => createDocument(document.content, meta);\n\nexport const createTextNode = (text: string, marks?: ProseMirrorMark[]): ProseMirrorNode => ({\n type: \"text\",\n text,\n ...(marks?.length ? { marks: marks.map(cloneMark) } : {}),\n});\n\nexport const textBlock = (type: string, text: string, attrs?: ProseMirrorAttrs): OpenEditorBlock => ({\n type,\n ...(attrs ? { attrs: cloneAttrs(attrs) } : {}),\n content: text ? [createTextNode(text)] : [],\n});\n\nexport const createBlockRegistry = (specs: readonly BlockSpec[]): BlockRegistry => {\n const registry = new Map<string, BlockSpec>();\n const nodeTypes = new Map<string, string>();\n\n for (const spec of specs) {\n if (!spec.name.trim()) {\n throw new Error(\"OpenEditor block names must not be empty.\");\n }\n if (registry.has(spec.name)) {\n throw new Error(`Duplicate OpenEditor block name \"${spec.name}\".`);\n }\n\n const nodeType = spec.nodeType ?? spec.name;\n const existing = nodeTypes.get(nodeType);\n if (existing) {\n throw new Error(\n `OpenEditor blocks \"${existing}\" and \"${spec.name}\" both claim node type \"${nodeType}\".`,\n );\n }\n\n registry.set(spec.name, spec);\n nodeTypes.set(nodeType, spec.name);\n }\n\n return registry;\n};\n\nexport const findBlockSpecForNode = (\n registry: BlockRegistry,\n node: ProseMirrorNode,\n): BlockSpec | undefined => {\n for (const spec of registry.values()) {\n if (spec.matchNode?.(node) || (spec.nodeType ?? spec.name) === node.type) {\n return spec;\n }\n }\n\n return undefined;\n};\n\nexport const getBlockId = (node: ProseMirrorNode): string | undefined => {\n const value = node.attrs?.[OPENEDITOR_BLOCK_ID_ATTR];\n return typeof value === \"string\" && value.trim() ? value : undefined;\n};\n\nexport const withBlockId = <T extends ProseMirrorNode>(node: T, id: string): T => ({\n ...node,\n attrs: {\n ...cloneAttrs(node.attrs),\n [OPENEDITOR_BLOCK_ID_ATTR]: id,\n },\n});\n\nexport const ensureBlockIds = (\n document: OpenEditorDocument,\n createId: () => string = createBlockId,\n): OpenEditorDocument => createDocumentWithIds(document.content, document.meta, createId);\n\nexport const findBlockLocation = (\n document: OpenEditorDocument,\n id: string,\n): OpenEditorBlockLocation | null => {\n const visit = (\n nodes: readonly ProseMirrorNode[],\n parentId: string | null,\n path: readonly number[],\n ): OpenEditorBlockLocation | null => {\n for (let index = 0; index < nodes.length; index += 1) {\n const node = nodes[index];\n if (!node) continue;\n const nodeId = getBlockId(node);\n const nodePath = [...path, index];\n if (nodeId === id) {\n return { id, nodeType: node.type, parentId, index, path: nodePath };\n }\n const nested = node.content?.length\n ? visit(node.content, nodeId ?? parentId, nodePath)\n : null;\n if (nested) return nested;\n }\n return null;\n };\n\n return visit(document.content, null, []);\n};\n\nconst normalizeNode = (node: ProseMirrorNode): OpenEditorBlock => {\n if (node.type === \"heading\") {\n const level = typeof node.attrs?.level === \"number\" ? node.attrs.level : 2;\n const content = node.content?.map(normalizeNode);\n\n return {\n ...cloneNode(node),\n attrs: { ...node.attrs, level: Math.min(Math.max(level, 1), 6) },\n ...(content ? { content } : {}),\n };\n }\n\n if (node.type === \"columns\") {\n const content = node.content?.length\n ? node.content.map(normalizeNode)\n : [\n { type: \"column\", content: [textBlock(\"paragraph\", \"\")] },\n { type: \"column\", content: [textBlock(\"paragraph\", \"\")] },\n ];\n\n return {\n ...cloneNode(node),\n attrs: Object.fromEntries(\n Object.entries(node.attrs ?? {}).filter(([name]) => name !== \"count\"),\n ),\n content,\n };\n }\n\n if (node.type === \"column\" && !node.content?.length) {\n return { ...cloneNode(node), content: [textBlock(\"paragraph\", \"\")] };\n }\n\n const content = node.content?.map(normalizeNode);\n return {\n ...cloneNode(node),\n ...(content ? { content } : {}),\n };\n};\n\nexport const normalizeDocument = (document: OpenEditorDocument): OpenEditorDocument =>\n createDocument(document.content.map(normalizeNode), document.meta);\n\nconst cloneAndFreezeContractValue = <T>(value: T): T => {\n if (!value || typeof value !== \"object\") return value;\n if (Array.isArray(value)) {\n return Object.freeze(value.map((child) => cloneAndFreezeContractValue(child))) as T;\n }\n const clone = Object.fromEntries(Object.entries(value as Record<string, unknown>).map(\n ([key, child]) => [key, cloneAndFreezeContractValue(child)],\n ));\n return Object.freeze(clone) as T;\n};\n\nconst createReadonlyMap = <K, V>(source: ReadonlyMap<K, V>): ReadonlyMap<K, V> => {\n let view: ReadonlyMap<K, V>;\n view = Object.freeze({\n get size() { return source.size; },\n get: (key: K) => source.get(key),\n has: (key: K) => source.has(key),\n entries: () => source.entries(),\n keys: () => source.keys(),\n values: () => source.values(),\n forEach: (callback: (value: V, key: K, map: ReadonlyMap<K, V>) => void, thisArg?: unknown) => {\n source.forEach((value, key) => callback.call(thisArg, value, key, view));\n },\n [Symbol.iterator]: () => source[Symbol.iterator](),\n });\n return view;\n};\n\nexport const createOpenEditorDocumentContract = ({\n schemaVersion,\n blockSpecs = [],\n nodeSpecs = [],\n markSpecs = [],\n rootContent,\n}: CreateOpenEditorDocumentContractOptions): OpenEditorDocumentContract => {\n if (!schemaVersion.trim()) throw new Error(\"OpenEditor schema versions must not be empty.\");\n const nodes = new Map<string, OpenEditorNodeSpec>();\n const marks = new Map<string, OpenEditorMarkSpec>();\n\n for (const block of blockSpecs) {\n const type = block.nodeType ?? block.name;\n if (nodes.has(type)) throw new Error(`Duplicate OpenEditor node contract \"${type}\".`);\n nodes.set(type, cloneAndFreezeContractValue({ ...block.schema, type }));\n }\n for (const node of nodeSpecs) {\n if (!node.type.trim()) throw new Error(\"OpenEditor node contract types must not be empty.\");\n if (nodes.has(node.type)) throw new Error(`Duplicate OpenEditor node contract \"${node.type}\".`);\n nodes.set(node.type, cloneAndFreezeContractValue(node));\n }\n for (const mark of markSpecs) {\n if (!mark.type.trim()) throw new Error(\"OpenEditor mark contract types must not be empty.\");\n if (marks.has(mark.type)) throw new Error(`Duplicate OpenEditor mark contract \"${mark.type}\".`);\n marks.set(mark.type, cloneAndFreezeContractValue(mark));\n }\n\n return Object.freeze({\n formatVersion: OPENEDITOR_DOCUMENT_FORMAT_VERSION,\n schemaVersion,\n ...(rootContent ? { rootContent: cloneAndFreezeContractValue(rootContent) } : {}),\n nodes: createReadonlyMap(nodes),\n marks: createReadonlyMap(marks),\n });\n};\n\nconst isPlainRecord = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst formatJsonPathKey = (path: string, key: string) =>\n /^[A-Za-z_$][\\w$-]*$/.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;\n\n/** Deterministic JSON serialization with lexicographically sorted object keys. */\nexport const canonicalSerializeJson = (value: unknown): string => {\n const ancestors = new Set<object>();\n const serialize = (input: unknown): string => {\n if (input === null || typeof input === \"boolean\" || typeof input === \"string\") {\n return JSON.stringify(input);\n }\n if (typeof input === \"number\") {\n if (!Number.isFinite(input)) throw new TypeError(\"Canonical JSON cannot serialize non-finite numbers.\");\n return JSON.stringify(input);\n }\n if (typeof input !== \"object\") throw new TypeError(\"Canonical JSON can only serialize JSON-safe values.\");\n if (!Array.isArray(input) && !isPlainRecord(input)) throw new TypeError(\"Canonical JSON objects must be plain objects.\");\n if (ancestors.has(input)) throw new TypeError(\"Canonical JSON cannot serialize cyclic values.\");\n ancestors.add(input);\n let serialized: string;\n if (Array.isArray(input)) {\n serialized = `[${input.map(serialize).join(\",\")}]`;\n } else {\n serialized = `{${Object.keys(input).sort().map((key) => `${JSON.stringify(key)}:${serialize(input[key])}`).join(\",\")}}`;\n }\n ancestors.delete(input);\n return serialized;\n };\n return serialize(value);\n};\n\n/**\n * Stable non-cryptographic content fingerprint for optimistic concurrency and diffs.\n * Security-sensitive integrity checks should use a cryptographic digest at the host boundary.\n */\nexport const fingerprintOpenEditorDocument = (document: OpenEditorDocument): string => {\n const serialized = canonicalSerializeJson(document);\n let hash = 0xcbf29ce484222325n;\n for (const byte of new TextEncoder().encode(serialized)) {\n hash ^= BigInt(byte);\n hash = BigInt.asUintN(64, hash * 0x100000001b3n);\n }\n return `oe1-fnv1a64-${hash.toString(16).padStart(16, \"0\")}`;\n};\n\nconst validatorMessages = (\n validator: OpenEditorValueValidator | OpenEditorNodeValidator | undefined,\n value: unknown,\n path: string,\n): readonly string[] => {\n if (!validator) return [];\n try {\n const result = validator(value as never, { path });\n if (typeof result === \"string\") return [result];\n return result ?? [];\n } catch (error) {\n return [error instanceof Error ? error.message : \"Custom validator failed.\"];\n }\n};\n\nconst jsonValuesEqual = (left: JsonValue, right: unknown): boolean => {\n try {\n return canonicalSerializeJson(left) === canonicalSerializeJson(right);\n } catch {\n return false;\n }\n};\n\nexport const validateDocument = (\n document: unknown,\n options: ValidateDocumentOptions = {},\n): DocumentValidationResult => {\n const issues: DocumentValidationIssue[] = [];\n const limits = { ...DEFAULT_DOCUMENT_VALIDATION_LIMITS, ...options.limits };\n const push = (path: string, message: string, code: DocumentValidationCode) =>\n issues.push({ path, message, code });\n let nodeCount = 0;\n let totalTextLength = 0;\n let jsonValueCount = 0;\n let jsonValueLimitReported = false;\n const seenIds = new Map<string, string>();\n\n const validateJsonValue = (\n value: unknown,\n path: string,\n depth: number,\n ancestors: Set<object>,\n maximumDepth = limits.maxAttributeDepth,\n countTowardsGlobalBudget = true,\n ): void => {\n if (countTowardsGlobalBudget) {\n jsonValueCount += 1;\n if (jsonValueCount > limits.maxJsonValues) {\n if (!jsonValueLimitReported) {\n push(path, `Document exceeds maximum JSON value count ${limits.maxJsonValues}.`, \"limit_attributes\");\n jsonValueLimitReported = true;\n }\n return;\n }\n }\n if (\n value === null\n || typeof value === \"string\"\n || typeof value === \"boolean\"\n ) return;\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) push(path, \"Numbers must be finite JSON values.\", \"non_json_value\");\n return;\n }\n if (typeof value !== \"object\") {\n push(path, \"Value must be JSON-safe.\", \"non_json_value\");\n return;\n }\n if (ancestors.has(value)) {\n push(path, \"Cyclic values are not valid JSON.\", \"cyclic_value\");\n return;\n }\n if (depth > maximumDepth) {\n push(path, `Value exceeds maximum depth ${maximumDepth}.`, \"limit_attributes\");\n return;\n }\n if (!Array.isArray(value) && !isPlainRecord(value)) {\n push(path, \"Value must be a plain JSON object.\", \"non_json_value\");\n return;\n }\n ancestors.add(value);\n if (Array.isArray(value)) {\n if (value.length > limits.maxArrayItems) {\n push(path, `Array exceeds maximum item count ${limits.maxArrayItems}.`, \"limit_attributes\");\n }\n for (let index = 0; index < value.length; index += 1) {\n if (countTowardsGlobalBudget && jsonValueCount > limits.maxJsonValues) break;\n validateJsonValue(value[index], `${path}.${index}`, depth + 1, ancestors, maximumDepth, countTowardsGlobalBudget);\n }\n } else {\n const entries = Object.entries(value);\n if (entries.length > limits.maxObjectKeys) {\n push(path, `Object exceeds maximum key count ${limits.maxObjectKeys}.`, \"limit_attributes\");\n }\n for (const [key, item] of entries) {\n if (countTowardsGlobalBudget && jsonValueCount > limits.maxJsonValues) break;\n validateJsonValue(item, formatJsonPathKey(path, key), depth + 1, ancestors, maximumDepth, countTowardsGlobalBudget);\n }\n }\n ancestors.delete(value);\n };\n\n const validateValueSchema = (value: unknown, schema: OpenEditorValueSchema, path: string): void => {\n if (value === null && schema.nullable) return;\n let typeValid = true;\n if (schema.type === \"string\") typeValid = typeof value === \"string\";\n else if (schema.type === \"number\") typeValid = typeof value === \"number\" && Number.isFinite(value);\n else if (schema.type === \"boolean\") typeValid = typeof value === \"boolean\";\n else if (schema.type === \"null\") typeValid = value === null;\n else if (schema.type === \"array\") typeValid = Array.isArray(value);\n else if (schema.type === \"object\") typeValid = isPlainRecord(value);\n\n if (!typeValid) {\n push(path, `Attribute must match schema type \"${schema.type}\".`, \"invalid_attribute\");\n return;\n }\n if (schema.enum && !schema.enum.some((candidate) => jsonValuesEqual(candidate, value))) {\n push(path, \"Attribute must be one of the configured enum values.\", \"invalid_attribute\");\n }\n if (schema.type === \"string\" && typeof value === \"string\") {\n if (schema.minLength !== undefined && value.length < schema.minLength) push(path, `String must contain at least ${schema.minLength} characters.`, \"invalid_attribute\");\n if (schema.maxLength !== undefined && value.length > schema.maxLength) push(path, `String must contain at most ${schema.maxLength} characters.`, \"invalid_attribute\");\n if (schema.pattern !== undefined) {\n try {\n if (!new RegExp(schema.pattern).test(value)) push(path, `String must match /${schema.pattern}/.`, \"invalid_attribute\");\n } catch {\n push(path, \"Attribute contract contains an invalid regular expression.\", \"custom_validation\");\n }\n }\n } else if (schema.type === \"number\" && typeof value === \"number\") {\n if (schema.integer && !Number.isInteger(value)) push(path, \"Number must be an integer.\", \"invalid_attribute\");\n if (schema.minimum !== undefined && value < schema.minimum) push(path, `Number must be at least ${schema.minimum}.`, \"invalid_attribute\");\n if (schema.maximum !== undefined && value > schema.maximum) push(path, `Number must be at most ${schema.maximum}.`, \"invalid_attribute\");\n } else if (schema.type === \"array\" && Array.isArray(value)) {\n if (schema.minItems !== undefined && value.length < schema.minItems) push(path, `Array must contain at least ${schema.minItems} items.`, \"invalid_attribute\");\n if (schema.maxItems !== undefined && value.length > schema.maxItems) push(path, `Array must contain at most ${schema.maxItems} items.`, \"invalid_attribute\");\n if (schema.items) value.forEach((item, index) => validateValueSchema(item, schema.items!, `${path}.${index}`));\n } else if (schema.type === \"object\" && isPlainRecord(value)) {\n validateAttributes(value, schema, path);\n }\n for (const message of validatorMessages(schema.validate, value, path)) push(path, message, \"custom_validation\");\n };\n\n const validateAttributes = (\n attrs: Record<string, unknown>,\n spec: OpenEditorAttributesSpec,\n path: string,\n ): void => {\n for (const required of spec.required ?? []) {\n if (!(required in attrs)) push(formatJsonPathKey(path, required), \"Required attribute is missing.\", \"missing_attribute\");\n }\n for (const [name, value] of Object.entries(attrs)) {\n if (name === OPENEDITOR_BLOCK_ID_ATTR) continue;\n const schema = spec.properties?.[name];\n if (schema) {\n validateValueSchema(value, schema, formatJsonPathKey(path, name));\n } else if (spec.additionalProperties === true) {\n continue;\n } else if (typeof spec.additionalProperties === \"object\") {\n validateValueSchema(value, spec.additionalProperties, formatJsonPathKey(path, name));\n } else {\n push(formatJsonPathKey(path, name), `Unknown attribute \"${name}\".`, \"unknown_attribute\");\n }\n }\n };\n\n const validateNode = (node: unknown, path: string, depth: number) => {\n nodeCount += 1;\n if (nodeCount > limits.maxNodes) {\n if (nodeCount === limits.maxNodes + 1) push(path, `Document exceeds maximum node count ${limits.maxNodes}.`, \"limit_nodes\");\n return;\n }\n if (depth > limits.maxDepth) {\n push(path, `Document exceeds maximum node depth ${limits.maxDepth}.`, \"limit_depth\");\n return;\n }\n if (!isRecord(node)) {\n push(path, \"Node must be an object.\", \"invalid_node\");\n return;\n }\n for (const key of Object.keys(node)) {\n if (![\"type\", \"attrs\", \"content\", \"marks\", \"text\"].includes(key)) {\n push(formatJsonPathKey(path, key), `Unknown node property \"${key}\".`, \"unknown_property\");\n }\n }\n\n if (typeof node.type !== \"string\" || !node.type) {\n push(`${path}.type`, \"Node type must be a non-empty string.\", \"invalid_node_type\");\n }\n const nodeSpec = typeof node.type === \"string\" ? options.contract?.nodes.get(node.type) : undefined;\n if (options.contract && typeof node.type === \"string\" && !nodeSpec) push(`${path}.type`, `Unknown node type \"${node.type}\".`, \"unknown_node_type\");\n\n if (\"text\" in node && typeof node.text !== \"string\") {\n push(`${path}.text`, \"Text node content must be a string.\", \"invalid_text\");\n } else if (typeof node.text === \"string\" && node.text.length > limits.maxTextLength) {\n push(`${path}.text`, `Text exceeds maximum length ${limits.maxTextLength}.`, \"limit_text\");\n }\n if (typeof node.text === \"string\") {\n totalTextLength += node.text.length;\n if (totalTextLength > limits.maxTotalTextLength && totalTextLength - node.text.length <= limits.maxTotalTextLength) {\n push(`${path}.text`, `Document exceeds maximum total text length ${limits.maxTotalTextLength}.`, \"limit_text\");\n }\n }\n if (nodeSpec?.text === \"required\" && typeof node.text !== \"string\") push(`${path}.text`, \"Node requires text content.\", \"invalid_text\");\n if (nodeSpec?.text === \"forbidden\" && \"text\" in node) push(`${path}.text`, \"Node does not allow text content.\", \"unexpected_text\");\n\n const nodeId = typeof node.attrs === \"object\" && node.attrs !== null\n ? getBlockId(node as ProseMirrorNode)\n : undefined;\n if (node.type !== \"text\" && limits.requireNodeIds && !nodeId) push(`${path}.attrs.${OPENEDITOR_BLOCK_ID_ATTR}`, \"Node requires a stable OpenEditor ID.\", \"missing_node_id\");\n if (nodeId) {\n const previousPath = seenIds.get(nodeId);\n if (previousPath) push(`${path}.attrs.${OPENEDITOR_BLOCK_ID_ATTR}`, `Node ID \"${nodeId}\" duplicates ${previousPath}.`, \"duplicate_node_id\");\n else seenIds.set(nodeId, path);\n }\n\n if (\"attrs\" in node && node.attrs !== undefined && !isRecord(node.attrs)) {\n push(`${path}.attrs`, \"Node attrs must be an object.\", \"invalid_attrs\");\n } else if (isRecord(node.attrs)) {\n validateJsonValue(node.attrs, `${path}.attrs`, 0, new Set(), limits.maxAttributeDepth, false);\n if (nodeSpec?.attributes) validateAttributes(node.attrs, nodeSpec.attributes, `${path}.attrs`);\n }\n\n if (\"marks\" in node && node.marks !== undefined) {\n if (!Array.isArray(node.marks)) {\n push(`${path}.marks`, \"Marks must be an array.\", \"invalid_marks\");\n } else {\n if (node.marks.length > limits.maxMarksPerNode) push(`${path}.marks`, `Node exceeds maximum mark count ${limits.maxMarksPerNode}.`, \"limit_marks\");\n node.marks.forEach((mark, index) => {\n if (!isRecord(mark) || typeof mark.type !== \"string\" || !mark.type) {\n push(`${path}.marks.${index}`, \"Mark must have a non-empty type.\", \"invalid_mark\");\n return;\n }\n const markPath = `${path}.marks.${index}`;\n for (const key of Object.keys(mark)) {\n if (![\"type\", \"attrs\"].includes(key)) push(formatJsonPathKey(markPath, key), `Unknown mark property \"${key}\".`, \"unknown_property\");\n }\n const markSpec = options.contract?.marks.get(mark.type);\n if (options.contract && !markSpec) push(`${markPath}.type`, `Unknown mark type \"${mark.type}\".`, \"unknown_mark_type\");\n if (nodeSpec?.marks === false || (Array.isArray(nodeSpec?.marks) && !nodeSpec.marks.includes(mark.type))) push(markPath, `Mark \"${mark.type}\" is not allowed on node \"${String(node.type)}\".`, \"disallowed_mark\");\n if (\"attrs\" in mark && mark.attrs !== undefined && !isRecord(mark.attrs)) push(`${markPath}.attrs`, \"Mark attrs must be an object.\", \"invalid_attrs\");\n else if (isRecord(mark.attrs)) {\n validateJsonValue(mark.attrs, `${markPath}.attrs`, 0, new Set(), limits.maxAttributeDepth, false);\n if (markSpec?.attributes) validateAttributes(mark.attrs, markSpec.attributes, `${markPath}.attrs`);\n }\n });\n }\n }\n\n if (\"content\" in node && node.content !== undefined) {\n if (!Array.isArray(node.content)) {\n push(`${path}.content`, \"Node content must be an array.\", \"invalid_content\");\n } else {\n if (nodeSpec?.content === false) push(`${path}.content`, `Node \"${String(node.type)}\" does not allow content.`, \"invalid_content\");\n const contentSpec = nodeSpec?.content;\n if (contentSpec) {\n if (contentSpec.minItems !== undefined && node.content.length < contentSpec.minItems) push(`${path}.content`, `Node requires at least ${contentSpec.minItems} children.`, \"invalid_content\");\n if (contentSpec.maxItems !== undefined && node.content.length > contentSpec.maxItems) push(`${path}.content`, `Node allows at most ${contentSpec.maxItems} children.`, \"invalid_content\");\n if (contentSpec.allowedTypes) node.content.forEach((child, index) => {\n if (isRecord(child) && typeof child.type === \"string\" && !contentSpec.allowedTypes!.includes(child.type)) push(`${path}.content.${index}.type`, `Child type \"${child.type}\" is not allowed in \"${String(node.type)}\".`, \"disallowed_child\");\n });\n }\n node.content.forEach((child, index) => validateNode(child, `${path}.content.${index}`, depth + 1));\n }\n } else if (nodeSpec?.content && (nodeSpec.content.minItems ?? 0) > 0) {\n push(`${path}.content`, `Node requires at least ${nodeSpec.content.minItems} children.`, \"invalid_content\");\n }\n for (const message of validatorMessages(nodeSpec?.validate, node, path)) push(path, message, \"custom_validation\");\n };\n\n if (!isRecord(document)) {\n return {\n valid: false,\n issues: [{ path: \"$\", message: \"Document must be an object.\", code: \"invalid_document\" }],\n };\n }\n\n validateJsonValue(document, \"$\", 0, new Set(), Math.max(limits.maxDepth * 3, limits.maxAttributeDepth));\n for (const key of Object.keys(document)) {\n if (![\"type\", \"version\", \"content\", \"meta\"].includes(key)) push(formatJsonPathKey(\"$\", key), `Unknown document property \"${key}\".`, \"unknown_property\");\n }\n\n if (document.type !== \"doc\") {\n push(\"$.type\", 'Document type must be \"doc\".', \"invalid_document_type\");\n }\n\n if (document.version !== OPENEDITOR_DOCUMENT_FORMAT_VERSION) {\n push(\"$.version\", `Document version must be ${OPENEDITOR_DOCUMENT_FORMAT_VERSION}.`, \"unsupported_format_version\");\n }\n\n if (!Array.isArray(document.content)) {\n push(\"$.content\", \"Document content must be an array.\", \"invalid_content\");\n } else {\n const rootContent = options.contract?.rootContent;\n if (rootContent) {\n if (rootContent.minItems !== undefined && document.content.length < rootContent.minItems) push(\"$.content\", `Document requires at least ${rootContent.minItems} children.`, \"invalid_content\");\n if (rootContent.maxItems !== undefined && document.content.length > rootContent.maxItems) push(\"$.content\", `Document allows at most ${rootContent.maxItems} children.`, \"invalid_content\");\n if (rootContent.allowedTypes) document.content.forEach((child, index) => {\n if (isRecord(child) && typeof child.type === \"string\" && !rootContent.allowedTypes!.includes(child.type)) push(`$.content.${index}.type`, `Node type \"${child.type}\" is not allowed at the document root.`, \"disallowed_child\");\n });\n }\n document.content.forEach((node, index) => validateNode(node, `$.content.${index}`, 1));\n }\n\n if (\"meta\" in document && document.meta !== undefined && !isRecord(document.meta)) {\n push(\"$.meta\", \"Document meta must be an object.\", \"invalid_meta\");\n } else if (isRecord(document.meta) && options.contract) {\n const actualSchemaVersion = document.meta.schemaVersion;\n if (\n (actualSchemaVersion !== undefined || options.requireSchemaVersion)\n && actualSchemaVersion !== options.contract.schemaVersion\n ) push(\"$.meta.schemaVersion\", `Document schema version must be \"${options.contract.schemaVersion}\".`, \"schema_version_mismatch\");\n }\n if (isRecord(document.meta)) {\n for (const key of Object.keys(document.meta)) {\n if (![\"id\", \"title\", \"source\", \"createdAt\", \"updatedAt\", \"platform\", \"schemaVersion\", \"custom\"].includes(key)) push(formatJsonPathKey(\"$.meta\", key), `Unknown document metadata property \"${key}\".`, \"unknown_property\");\n }\n for (const key of [\"id\", \"title\", \"source\", \"createdAt\", \"updatedAt\", \"schemaVersion\"] as const) {\n if (document.meta[key] !== undefined && typeof document.meta[key] !== \"string\") push(`$.meta.${key}`, `Document metadata \"${key}\" must be a string.`, \"invalid_meta\");\n }\n if (document.meta.platform !== undefined && document.meta.platform !== \"web\" && document.meta.platform !== \"native\") push(\"$.meta.platform\", 'Document platform must be \"web\" or \"native\".', \"invalid_meta\");\n if (document.meta.custom !== undefined && !isPlainRecord(document.meta.custom)) push(\"$.meta.custom\", \"Custom document metadata must be a plain object.\", \"invalid_meta\");\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n};\n\nexport const isOpenEditorDocument = (value: unknown): value is OpenEditorDocument =>\n validateDocument(value).valid;\n\nexport class OpenEditorDocumentParseError extends Error {\n readonly validation: DocumentValidationResult;\n\n constructor(validation: DocumentValidationResult) {\n super(validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join(\"\\n\"));\n this.name = \"OpenEditorDocumentParseError\";\n this.validation = validation;\n }\n}\n\nexport const parseOpenEditorDocument = (\n value: unknown,\n options: ValidateDocumentOptions = {},\n): OpenEditorDocument => {\n const validation = validateDocument(value, options);\n if (!validation.valid) throw new OpenEditorDocumentParseError(validation);\n return JSON.parse(JSON.stringify(value)) as OpenEditorDocument;\n};\n\n/** Imports unversioned ProseMirror JSON. Versioned values require strict OpenEditor parsing. */\nexport const importProseMirrorDocument = (\n value: unknown,\n meta?: OpenEditorDocumentMeta,\n): OpenEditorDocument => {\n if (isRecord(value) && \"version\" in value) {\n throw new Error(\"Versioned documents must be parsed with parseOpenEditorDocument().\");\n }\n\n const validation = validateDocument(\n isRecord(value) ? { ...value, version: 1 } : value,\n );\n if (!validation.valid) throw new OpenEditorDocumentParseError(validation);\n return fromProseMirrorDocument(value as ProseMirrorDocument, meta);\n};\n\nexport const serializeEditorState = (state: SerializedEditorState): string =>\n JSON.stringify({\n document: normalizeDocument(state.document),\n ...(state.selection ? { selection: state.selection } : {}),\n });\n\nexport const parseEditorState = (\n value: unknown,\n defaultState: SerializedEditorState = createEditorState(createDocument()),\n): SerializedEditorState => {\n let parsed: unknown;\n\n try {\n parsed = typeof value === \"string\" ? JSON.parse(value) : value;\n } catch {\n return defaultState;\n }\n\n if (!isRecord(parsed)) {\n return defaultState;\n }\n\n try {\n return {\n document: parseOpenEditorDocument(parsed.document),\n selection: isRecord(parsed.selection) ? (parsed.selection as EditorSelection) : defaultState.selection,\n };\n } catch {\n return defaultState;\n }\n};\n\nexport const getPlatformDocument = (\n document: OpenEditorDocument,\n registry: BlockRegistry,\n platform: EditorPlatform,\n): OpenEditorDocument => getPlatformSupport(document, registry, platform).document;\n\nexport const getPlatformSupport = (\n document: OpenEditorDocument,\n registry: BlockRegistry,\n platform: EditorPlatform,\n): PlatformSupportResult => {\n const issues: PlatformSupportIssue[] = [];\n\n const mapNode = (node: OpenEditorBlock, path: string): OpenEditorBlock => {\n const spec = findBlockSpecForNode(registry, node);\n const support = spec?.support?.[platform] ?? \"supported\";\n\n if (support !== \"supported\") {\n issues.push({\n path,\n block: spec?.name ?? node.type,\n platform,\n support,\n });\n }\n\n return normalizeNode({\n ...cloneNode(node),\n content: node.content?.map((child, index) => mapNode(child, `${path}.content.${index}`)),\n });\n };\n\n return {\n platform,\n document: createDocument(\n document.content.map((node, index) => mapNode(node, `$.content.${index}`)),\n { ...document.meta, platform },\n ),\n issues,\n };\n};\n\nconst INLINE_NODE_TYPES = new Set([\"text\", \"hardBreak\"]);\n\nexport const getDocumentText = (node: OpenEditorDocument | ProseMirrorNode): string => {\n if (\"text\" in node && typeof node.text === \"string\") {\n return node.text;\n }\n\n const content = \"content\" in node ? node.content : undefined;\n\n if (!content?.length) {\n return \"\";\n }\n\n const isInlineContainer = content.every(\n (child) => INLINE_NODE_TYPES.has(child.type) || child.type === \"link\",\n );\n const joiner = isInlineContainer ? \"\" : \"\\n\";\n return content.map(getDocumentText).filter(Boolean).join(joiner);\n};\n\nexport const applyCommand = (\n document: OpenEditorDocument,\n registry: BlockRegistry,\n command: OpenEditorCommand,\n): OpenEditorDocument => {\n if (command.type === \"setContent\") {\n return normalizeDocument(command.document);\n }\n\n if (command.type === \"setSelection\") {\n return document;\n }\n\n if (command.type === \"moveBlock\") {\n return moveTopLevelBlock(document, command.from, command.to);\n }\n\n if (command.type === \"duplicateBlock\") {\n return duplicateTopLevelBlock(document, command.index);\n }\n\n if (command.type === \"deleteBlock\") {\n return deleteTopLevelBlock(document, command.index);\n }\n\n if (\n command.type === \"setLink\"\n || command.type === \"toggleMark\"\n || command.type === \"undo\"\n || command.type === \"redo\"\n ) {\n return normalizeDocument(document);\n }\n\n const spec = registry.get(command.block);\n if (!spec) {\n throw new Error(`Unknown block \"${command.block}\"`);\n }\n\n const nextContent = [...document.content];\n const index = command.at ?? nextContent.length;\n const defaultNode = spec.defaultNode();\n const node = command.attrs\n ? { ...defaultNode, attrs: { ...defaultNode.attrs, ...command.attrs } }\n : defaultNode;\n\n nextContent.splice(index, 0, node);\n return normalizeDocument(createDocument(nextContent, document.meta));\n};\n\nexport const replaceTopLevelRange = (\n document: OpenEditorDocument,\n start: number,\n length: number,\n replacement: ProseMirrorNode[],\n): OpenEditorDocument =>\n normalizeDocument({\n ...document,\n content: [\n ...document.content.slice(0, start),\n ...replacement.map(cloneNode),\n ...document.content.slice(start + length),\n ],\n });\n\nexport const replaceTopLevelNode = (\n document: OpenEditorDocument,\n index: number,\n replacement: ProseMirrorNode,\n): OpenEditorDocument =>\n normalizeDocument({\n ...document,\n content: document.content.map((node, nodeIndex) => nodeIndex === index ? cloneNode(replacement) : cloneNode(node)),\n });\n\nexport const moveTopLevelBlock = (\n document: OpenEditorDocument,\n from: number,\n to: number,\n): OpenEditorDocument => {\n if (from < 0 || from >= document.content.length || to < 0 || to >= document.content.length || from === to) {\n return normalizeDocument(document);\n }\n\n const nextContent = document.content.map(cloneNode);\n const [item] = nextContent.splice(from, 1);\n if (!item) {\n return normalizeDocument(document);\n }\n\n nextContent.splice(to, 0, item);\n return normalizeDocument({ ...document, content: nextContent });\n};\n\nexport const duplicateTopLevelBlock = (\n document: OpenEditorDocument,\n index: number,\n): OpenEditorDocument => {\n if (index < 0 || index >= document.content.length) {\n return normalizeDocument(document);\n }\n\n const nextContent = document.content.map(cloneNode);\n nextContent.splice(index + 1, 0, cloneNode(document.content[index]));\n return normalizeDocument({ ...document, content: nextContent });\n};\n\nexport const deleteTopLevelBlock = (\n document: OpenEditorDocument,\n index: number,\n emptyBlock: OpenEditorBlock = textBlock(\"paragraph\", \"\"),\n): OpenEditorDocument => {\n if (document.content.length <= 1) {\n return normalizeDocument({ ...document, content: [cloneNode(emptyBlock)] });\n }\n\n if (index < 0 || index >= document.content.length) {\n return normalizeDocument(document);\n }\n\n return normalizeDocument({\n ...document,\n content: document.content.filter((_, currentIndex) => currentIndex !== index).map(cloneNode),\n });\n};\n\nexport const createTransaction = (\n before: OpenEditorDocument,\n after: OpenEditorDocument,\n command?: EditorCommand,\n): EditorTransaction => ({\n before,\n after,\n ...(command ? { command } : {}),\n timestamp: new Date().toISOString(),\n});\n\nexport const openEditorThemeTokenNames = [\n \"surface\", \"surfaceRaised\", \"surfaceMuted\", \"interactionHover\", \"interactionSelected\", \"blockSurface\",\n \"text\", \"textSoft\", \"heading\", \"muted\", \"placeholder\", \"border\", \"borderStrong\", \"structuralLine\",\n \"accent\", \"accentText\", \"accentStrong\", \"buttonBackground\", \"buttonText\", \"codeBackground\", \"codeText\",\n \"link\", \"linkHover\", \"shadow\", \"fontSans\", \"fontMono\", \"radiusSmall\", \"radiusMedium\", \"radiusLarge\",\n \"spaceBlock\", \"spaceInline\", \"bodyFontSize\", \"bodyLineHeight\", \"headingFont\", \"headingLineHeight\",\n \"headingWeight\", \"heading1Size\", \"heading2Size\", \"heading3Size\", \"heading4Size\", \"heading5Size\", \"heading6Size\",\n] as const;\nexport type OpenEditorThemeToken = (typeof openEditorThemeTokenNames)[number];\nexport type OpenEditorTheme = { surfaceRaised: string } & Partial<Record<Exclude<OpenEditorThemeToken, \"surfaceRaised\">, string>>;\nexport const openEditorThemeCssName = (token: OpenEditorThemeToken) =>\n `--oe-${token.replace(/([a-z])([A-Z])/g, \"$1-$2\").replace(/([A-Za-z])(\\d)/g, \"$1-$2\").replace(/(\\d)([A-Z])/g, \"$1-$2\").toLowerCase()}` as const;\nexport const getOpenEditorThemeEntries = (theme: Partial<OpenEditorTheme>): readonly (readonly [string, string])[] =>\n openEditorThemeTokenNames.flatMap((token) => theme[token] === undefined ? [] : [[openEditorThemeCssName(token), theme[token]!] as const]);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/custom-block.ts","../src/index.ts"],"names":["content","clone"],"mappings":"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","file":"index.js","sourcesContent":["import {\n validateDocument,\n type OpenEditorDocument,\n type ProseMirrorNode,\n} from \"./index\";\n\nexport const OPENEDITOR_CUSTOM_BLOCK_NODE = \"customBlock\" as const;\nexport type {\n JsonObject as OpenEditorCustomBlockJsonObject,\n JsonValue as OpenEditorCustomBlockJsonValue,\n} from \"./index\";\n\nexport type OpenEditorCustomBlockId = `${string}.${string}`;\n/** A block-owned object. Runtime parsing still requires JSON-only plain data. */\nexport type OpenEditorCustomBlockData = object;\nexport type OpenEditorCustomBlockEnvelope<\n TData extends OpenEditorCustomBlockData = OpenEditorCustomBlockData,\n> = {\n blockId: OpenEditorCustomBlockId;\n version: number;\n data: TData;\n};\nexport type OpenEditorCustomBlockNode<\n TData extends OpenEditorCustomBlockData = OpenEditorCustomBlockData,\n> = ProseMirrorNode & {\n type: typeof OPENEDITOR_CUSTOM_BLOCK_NODE;\n attrs: OpenEditorCustomBlockEnvelope<TData> & Record<string, unknown>;\n};\nexport type OpenEditorCustomBlockDiagnostic = {\n path: string;\n message: string;\n};\nexport type OpenEditorCustomBlockAssetReference = {\n id: string;\n path: string;\n};\nexport type OpenEditorCustomBlockManifest = {\n id: OpenEditorCustomBlockId;\n label: string;\n version: number;\n};\nexport type OpenEditorCustomBlockMigration = (input: {\n version: number;\n data: Readonly<OpenEditorCustomBlockData>;\n}) => OpenEditorCustomBlockEnvelope;\nexport type OpenEditorCustomBlockStaticContext<\n TData extends OpenEditorCustomBlockData,\n> = {\n data: Readonly<TData>;\n renderDocument: (document: OpenEditorDocument) => OpenEditorCustomBlockSafeHtml;\n documentToText: (document: OpenEditorDocument) => string;\n};\nexport type OpenEditorCustomBlockSafeHtml =\n | string\n | number\n | null\n | false\n | {\n tag:\n | \"div\"\n | \"span\"\n | \"p\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"article\"\n | \"section\"\n | \"aside\"\n | \"blockquote\"\n | \"figure\"\n | \"figcaption\"\n | \"ul\"\n | \"ol\"\n | \"li\"\n | \"dl\"\n | \"dt\"\n | \"dd\"\n | \"table\"\n | \"caption\"\n | \"thead\"\n | \"tbody\"\n | \"tr\"\n | \"th\"\n | \"td\"\n | \"strong\"\n | \"em\"\n | \"u\"\n | \"s\"\n | \"code\"\n | \"pre\"\n | \"a\"\n | \"img\"\n | \"br\"\n | \"hr\";\n attrs?: Readonly<\n Partial<\n Record<\n | \"aria-label\"\n | \"aria-current\"\n | \"role\"\n | \"title\"\n | \"href\"\n | \"src\"\n | \"alt\"\n | \"width\"\n | \"height\"\n | \"start\"\n | \"colspan\"\n | \"rowspan\"\n | \"scope\",\n string | number | undefined\n >\n >\n >;\n children?: readonly OpenEditorCustomBlockSafeHtml[];\n };\n\n/**\n * The complete non-React contract for one installed block. The block package\n * owns parsing because OpenEditor cannot know a third-party data model.\n */\nexport type OpenEditorCustomBlockDefinition<\n TData extends OpenEditorCustomBlockData = any,\n> = {\n id: OpenEditorCustomBlockId;\n label: string;\n version: number;\n createData: () => TData;\n parseData: (data: unknown) => TData;\n migrate?: OpenEditorCustomBlockMigration;\n assets?: (\n data: Readonly<TData>,\n ) => readonly OpenEditorCustomBlockAssetReference[];\n toHtml: (\n context: OpenEditorCustomBlockStaticContext<TData>,\n ) => OpenEditorCustomBlockSafeHtml;\n toText: (context: OpenEditorCustomBlockStaticContext<TData>) => string;\n manifest: OpenEditorCustomBlockManifest;\n};\n\ntype UnavailableStatus = \"missing\" | \"disabled\" | \"incompatible\" | \"invalid\";\nexport type OpenEditorResolvedCustomBlock<\n TData extends OpenEditorCustomBlockData = OpenEditorCustomBlockData,\n> =\n | {\n status: \"ready\";\n definition: OpenEditorCustomBlockDefinition<TData>;\n node: OpenEditorCustomBlockNode<TData>;\n data: TData;\n migrated: boolean;\n }\n | {\n status: UnavailableStatus;\n node: ProseMirrorNode;\n blockId?: string;\n diagnostics: readonly OpenEditorCustomBlockDiagnostic[];\n };\n\nexport type OpenEditorCustomBlockRegistry = {\n definitions: readonly OpenEditorCustomBlockDefinition[];\n manifests: readonly OpenEditorCustomBlockManifest[];\n get: (id: string) => OpenEditorCustomBlockDefinition | undefined;\n isEnabled: (id: string) => boolean;\n resolve: (node: ProseMirrorNode) => OpenEditorResolvedCustomBlock;\n validate: (envelope: unknown) =>\n | { valid: true; envelope: OpenEditorCustomBlockEnvelope }\n | { valid: false; diagnostics: readonly OpenEditorCustomBlockDiagnostic[] };\n assets: (envelope: unknown) => readonly OpenEditorCustomBlockAssetReference[];\n toHtml: (node: ProseMirrorNode) => string;\n toText: (node: ProseMirrorNode) => string;\n};\n\nexport type OpenEditorCustomBlockIcon = { id: string; label: string };\nexport type OpenEditorCustomBlockAsset = {\n id: string;\n kind: \"raster\";\n alt: string;\n width?: number;\n height?: number;\n};\nexport type OpenEditorCustomBlockHost = {\n resolveUrl: (\n value: string,\n context: \"navigation\" | \"asset\",\n ) => string | null;\n links?: {\n resolve: (destination: { href: string; kind?: string }) => {\n href: string;\n external: boolean;\n label?: string;\n } | null;\n };\n navigate?: (url: string) => void | Promise<void>;\n icons?: {\n list: () => readonly OpenEditorCustomBlockIcon[];\n render: (id: string) => unknown;\n };\n assets?: {\n pick?: () => Promise<OpenEditorCustomBlockAsset | null>;\n resolve: (id: string) => Promise<{ src: string; alt: string } | null>;\n };\n};\n\nconst ID_PATTERN = /^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+$/;\nconst DEFINITION_BRAND = Symbol.for(\"@openeditor/custom-block/definition\");\nconst LIMITS = {\n depth: 32,\n values: 10_000,\n stringLength: 1_000_000,\n arrayLength: 10_000,\n objectKeys: 10_000,\n} as const;\n\nconst plainObject = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\nconst positiveInteger = (value: unknown): value is number =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value > 0;\nconst clone = <T,>(value: T): T => structuredClone(value);\nconst deepFreeze = <T,>(value: T): T => {\n if (value && typeof value === \"object\" && !Object.isFrozen(value)) {\n Object.freeze(value);\n for (const child of Object.values(value as Record<string, unknown>))\n deepFreeze(child);\n }\n return value;\n};\nconst inspectJson = (\n value: unknown,\n path = \"$.data\",\n depth = 0,\n budget = { values: 0 },\n): OpenEditorCustomBlockDiagnostic[] => {\n budget.values += 1;\n if (budget.values > LIMITS.values)\n return [{ path, message: \"Custom block data exceeds the value limit.\" }];\n if (depth > LIMITS.depth)\n return [{ path, message: \"Custom block data exceeds the nesting limit.\" }];\n if (typeof value === \"string\" && value.length > LIMITS.stringLength)\n return [{ path, message: \"String exceeds the size limit.\" }];\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n return [];\n if (Array.isArray(value)) {\n if (value.length > LIMITS.arrayLength)\n return [{ path, message: \"Array exceeds the size limit.\" }];\n return value.flatMap((item, index) =>\n inspectJson(item, `${path}[${index}]`, depth + 1, budget),\n );\n }\n if (plainObject(value)) {\n const entries = Object.entries(value);\n if (entries.length > LIMITS.objectKeys)\n return [{ path, message: \"Object exceeds the key limit.\" }];\n return entries.flatMap(([key, item]) =>\n inspectJson(item, `${path}.${key}`, depth + 1, budget),\n );\n }\n return [{ path, message: \"Custom block data must contain only JSON values.\" }];\n};\n\nconst envelopeFrom = (value: unknown): OpenEditorCustomBlockEnvelope | null => {\n if (!plainObject(value)) return null;\n const blockId = value.blockId;\n const version = value.version;\n const data = value.data;\n return typeof blockId === \"string\" &&\n ID_PATTERN.test(blockId) &&\n positiveInteger(version) &&\n plainObject(data)\n ? {\n blockId: blockId as OpenEditorCustomBlockId,\n version,\n data,\n }\n : null;\n};\n\nexport const defineOpenEditorCustomBlock = <\n TData extends OpenEditorCustomBlockData,\n>(\n input: Omit<OpenEditorCustomBlockDefinition<TData>, \"manifest\">,\n): OpenEditorCustomBlockDefinition<TData> => {\n if (!ID_PATTERN.test(input.id))\n throw new Error(\n `OpenEditor custom block IDs must be namespaced lowercase identifiers. Received \"${input.id}\".`,\n );\n if (!positiveInteger(input.version))\n throw new Error(\n \"OpenEditor custom block versions must be positive integers.\",\n );\n if (!input.label.trim() || input.label.length > 200)\n throw new Error(\n \"OpenEditor custom block labels must be nonempty strings of 200 characters or less.\",\n );\n const manifest = deepFreeze({\n id: input.id,\n label: input.label,\n version: input.version,\n });\n const definition = { ...input, manifest } as OpenEditorCustomBlockDefinition<TData> & {\n [DEFINITION_BRAND]?: true;\n };\n Object.defineProperty(definition, DEFINITION_BRAND, { value: true });\n return Object.freeze(definition);\n};\n\nconst parseDefinitionData = <TData extends OpenEditorCustomBlockData>(\n definition: OpenEditorCustomBlockDefinition<TData>,\n data: unknown,\n):\n | { valid: true; data: TData }\n | { valid: false; diagnostics: readonly OpenEditorCustomBlockDiagnostic[] } => {\n const diagnostics = inspectJson(data);\n if (diagnostics.length) return { valid: false, diagnostics };\n try {\n const parsed = definition.parseData(deepFreeze(clone(data)));\n const parsedDiagnostics = inspectJson(parsed);\n if (!plainObject(parsed) || parsedDiagnostics.length)\n return {\n valid: false,\n diagnostics: parsedDiagnostics.length\n ? parsedDiagnostics\n : [{ path: \"$.data\", message: \"The block parser must return an object.\" }],\n };\n return { valid: true, data: deepFreeze(clone(parsed)) };\n } catch (error) {\n return {\n valid: false,\n diagnostics: [\n {\n path: \"$.data\",\n message:\n error instanceof Error ? error.message : \"Custom block data is invalid.\",\n },\n ],\n };\n }\n};\n\nexport const createOpenEditorCustomBlockRegistry = (\n definitions: readonly OpenEditorCustomBlockDefinition[],\n options: {\n disabled?: readonly string[];\n renderDocument?: (\n document: OpenEditorDocument,\n ) => OpenEditorCustomBlockSafeHtml;\n documentToText?: (document: OpenEditorDocument) => string;\n } = {},\n): OpenEditorCustomBlockRegistry => {\n const byId = new Map<string, OpenEditorCustomBlockDefinition>();\n for (const definition of definitions) {\n if (\n (definition as OpenEditorCustomBlockDefinition & {\n [DEFINITION_BRAND]?: true;\n })[DEFINITION_BRAND] !== true ||\n !Object.isFrozen(definition) ||\n !ID_PATTERN.test(definition.id) ||\n !positiveInteger(definition.version)\n )\n throw new Error(`Invalid custom block definition \"${definition.id ?? \"unknown\"}\".`);\n if (byId.has(definition.id))\n throw new Error(`Duplicate custom block ID \"${definition.id}\".`);\n byId.set(definition.id, definition);\n }\n const disabled = new Set(options.disabled ?? []);\n\n const resolveEnvelope = (\n raw: unknown,\n ):\n | {\n status: \"ready\";\n definition: OpenEditorCustomBlockDefinition;\n envelope: OpenEditorCustomBlockEnvelope;\n migrated: boolean;\n }\n | {\n status: UnavailableStatus;\n blockId?: string;\n diagnostics: readonly OpenEditorCustomBlockDiagnostic[];\n } => {\n const initial = envelopeFrom(raw);\n if (!initial)\n return {\n status: \"invalid\",\n diagnostics: [\n {\n path: \"$\",\n message: \"Expected a valid OpenEditor custom block envelope.\",\n },\n ],\n };\n const definition = byId.get(initial.blockId);\n if (!definition)\n return { status: \"missing\", blockId: initial.blockId, diagnostics: [] };\n if (disabled.has(initial.blockId))\n return { status: \"disabled\", blockId: initial.blockId, diagnostics: [] };\n if (initial.version > definition.version)\n return {\n status: \"incompatible\",\n blockId: initial.blockId,\n diagnostics: [\n {\n path: \"$.version\",\n message: `Stored version ${initial.version} is newer than supported version ${definition.version}.`,\n },\n ],\n };\n\n let envelope = clone(initial);\n let attempts = 0;\n while (envelope.version < definition.version) {\n if (!definition.migrate)\n return {\n status: \"incompatible\",\n blockId: initial.blockId,\n diagnostics: [\n {\n path: \"$.version\",\n message: `No migration exists from version ${envelope.version}.`,\n },\n ],\n };\n try {\n const next = definition.migrate({\n version: envelope.version,\n data: deepFreeze(clone(envelope.data)),\n });\n const checked = envelopeFrom(next);\n if (\n !checked ||\n checked.blockId !== definition.id ||\n checked.version <= envelope.version ||\n checked.version > definition.version\n )\n throw new Error(\"The custom block migration returned an invalid envelope.\");\n envelope = checked;\n } catch (error) {\n return {\n status: \"invalid\",\n blockId: initial.blockId,\n diagnostics: [\n {\n path: \"$.data\",\n message:\n error instanceof Error ? error.message : \"Migration failed.\",\n },\n ],\n };\n }\n attempts += 1;\n if (attempts > 100)\n return {\n status: \"invalid\",\n blockId: initial.blockId,\n diagnostics: [\n { path: \"$.version\", message: \"Migration exceeded the step limit.\" },\n ],\n };\n }\n\n const parsed = parseDefinitionData(definition, envelope.data);\n return parsed.valid\n ? {\n status: \"ready\",\n definition,\n envelope: { ...envelope, data: parsed.data },\n migrated: envelope.version !== initial.version,\n }\n : {\n status: \"invalid\",\n blockId: initial.blockId,\n diagnostics: parsed.diagnostics,\n };\n };\n\n const resolve = (node: ProseMirrorNode): OpenEditorResolvedCustomBlock => {\n const resolved = resolveEnvelope(node.attrs);\n if (node.type !== OPENEDITOR_CUSTOM_BLOCK_NODE)\n return {\n status: \"invalid\",\n node,\n diagnostics: [\n { path: \"$.type\", message: \"Expected a customBlock node.\" },\n ],\n };\n if (resolved.status !== \"ready\") return { ...resolved, node };\n if (\n typeof node.attrs?.[\"openeditor-id\"] !== \"string\" ||\n !node.attrs[\"openeditor-id\"].trim()\n )\n return {\n status: \"invalid\",\n node,\n blockId: resolved.definition.id,\n diagnostics: [\n {\n path: \"$.attrs.openeditor-id\",\n message: \"Custom block instance ID is required.\",\n },\n ],\n };\n const migratedNode = {\n ...node,\n attrs: { ...node.attrs, ...resolved.envelope },\n } as OpenEditorCustomBlockNode;\n return {\n status: \"ready\",\n definition: resolved.definition,\n data: resolved.envelope.data,\n migrated: resolved.migrated,\n node: migratedNode,\n };\n };\n\n const renderNestedHtml = (document: OpenEditorDocument): OpenEditorCustomBlockSafeHtml => {\n const valid = validateDocument(document);\n if (!valid.valid) return \"\";\n return {\n tag: \"div\",\n children: document.content.map((node) => {\n if (node.type === \"text\") return node.text ?? \"\";\n if (node.type === OPENEDITOR_CUSTOM_BLOCK_NODE) {\n const nested = resolve(node);\n return nested.status === \"ready\"\n ? nested.definition.toHtml({\n data: nested.data,\n renderDocument: options.renderDocument ?? renderNestedHtml,\n documentToText: options.documentToText ?? renderNestedText,\n })\n : `[${String(node.attrs?.blockId ?? \"custom block\")}: ${nested.status}]`;\n }\n const children = node.content?.map((child) =>\n renderNestedHtml({ type: \"doc\", version: 1, content: [child] }),\n );\n return {\n tag: node.type === \"paragraph\" ? \"p\" : \"div\",\n children,\n } as OpenEditorCustomBlockSafeHtml;\n }),\n };\n };\n const renderNestedText = (document: OpenEditorDocument): string => {\n const visit = (node: ProseMirrorNode): string => {\n if (node.type === OPENEDITOR_CUSTOM_BLOCK_NODE) {\n const nested = resolve(node);\n return nested.status === \"ready\"\n ? nested.definition.toText({\n data: nested.data,\n renderDocument: options.renderDocument ?? renderNestedHtml,\n documentToText: options.documentToText ?? renderNestedText,\n })\n : \"\";\n }\n if (node.text) return node.text;\n return node.content?.map(visit).filter(Boolean).join(\"\\n\") ?? \"\";\n };\n return document.content.map(visit).filter(Boolean).join(\"\\n\").trim();\n };\n const fallbackLabel = (node: ProseMirrorNode, status: string) =>\n `Custom block ${String(node.attrs?.blockId ?? \"unknown\")} is unavailable: ${status}.`;\n\n const registry: OpenEditorCustomBlockRegistry = {\n definitions: Object.freeze([...definitions]),\n manifests: Object.freeze(definitions.map((item) => item.manifest)),\n get: (id) => byId.get(id),\n isEnabled: (id) => byId.has(id) && !disabled.has(id),\n resolve,\n validate: (raw) => {\n const result = resolveEnvelope(raw);\n return result.status === \"ready\"\n ? { valid: true, envelope: result.envelope }\n : { valid: false, diagnostics: result.diagnostics };\n },\n assets: (raw) => {\n const result = resolveEnvelope(raw);\n if (result.status !== \"ready\" || !result.definition.assets) return [];\n try {\n return result.definition.assets(result.envelope.data).filter(\n (reference) =>\n typeof reference.id === \"string\" &&\n reference.id.length > 0 &&\n typeof reference.path === \"string\" &&\n reference.path.startsWith(\"$.data\"),\n );\n } catch {\n return [];\n }\n },\n toHtml: (node) => {\n const result = resolve(node);\n if (result.status !== \"ready\")\n return `<p role=\"status\" data-openeditor-custom-block-error=\"${escapeOpenEditorCustomBlockHtml(result.status)}\">${escapeOpenEditorCustomBlockHtml(fallbackLabel(node, result.status))}</p>`;\n try {\n return renderOpenEditorCustomBlockSafeHtml(\n result.definition.toHtml({\n data: result.data,\n renderDocument: options.renderDocument ?? renderNestedHtml,\n documentToText: options.documentToText ?? renderNestedText,\n }),\n );\n } catch {\n return `<p role=\"status\" data-openeditor-custom-block-error=\"invalid\">${escapeOpenEditorCustomBlockHtml(fallbackLabel(node, \"invalid\"))}</p>`;\n }\n },\n toText: (node) => {\n const result = resolve(node);\n if (result.status !== \"ready\") return fallbackLabel(node, result.status);\n try {\n return result.definition.toText({\n data: result.data,\n renderDocument: options.renderDocument ?? renderNestedHtml,\n documentToText: options.documentToText ?? renderNestedText,\n });\n } catch {\n return fallbackLabel(node, \"invalid\");\n }\n },\n };\n return Object.freeze(registry);\n};\n\nexport const createOpenEditorCustomBlockNode = <\n TData extends OpenEditorCustomBlockData,\n>(\n registry: OpenEditorCustomBlockRegistry,\n id: string,\n data?: TData,\n options: { instanceId?: string; createInstanceId?: () => string } = {},\n): OpenEditorCustomBlockNode<TData> => {\n const definition = registry.get(id);\n if (!definition)\n throw new Error(`OpenEditor custom block \"${id}\" is not registered.`);\n const node = {\n type: OPENEDITOR_CUSTOM_BLOCK_NODE,\n attrs: {\n \"openeditor-id\":\n options.instanceId ?? options.createInstanceId?.() ?? crypto.randomUUID(),\n blockId: definition.id,\n version: definition.version,\n data: data ?? definition.createData(),\n },\n };\n const resolved = registry.resolve(node);\n if (resolved.status !== \"ready\")\n throw new Error(\n `Invalid initial data for custom block \"${id}\": ${resolved.diagnostics.map((item) => item.message).join(\" \")}`,\n );\n return resolved.node as OpenEditorCustomBlockNode<TData>;\n};\n\nexport const resolveOpenEditorCustomBlockNode = (\n registry: OpenEditorCustomBlockRegistry,\n node: ProseMirrorNode,\n) => registry.resolve(node);\n\nexport const validateOpenEditorCustomBlockEnvelope = (\n value: unknown,\n registry: Pick<OpenEditorCustomBlockRegistry, \"validate\">,\n) => registry.validate(value);\n\nexport const extractOpenEditorCustomBlockAssetReferences = (\n value: unknown,\n registry: Pick<OpenEditorCustomBlockRegistry, \"assets\">,\n) => registry.assets(value);\n\nexport const conformOpenEditorCustomBlock = (\n definition: OpenEditorCustomBlockDefinition,\n): readonly OpenEditorCustomBlockDiagnostic[] => {\n try {\n const registry = createOpenEditorCustomBlockRegistry([definition]);\n const node = createOpenEditorCustomBlockNode(\n registry,\n definition.id,\n undefined,\n { instanceId: \"conformance-instance\" },\n );\n const html = registry.toHtml(node);\n const text = registry.toText(node);\n return html.includes('data-openeditor-custom-block-error=\"invalid\"') ||\n text === `Custom block ${definition.id} is unavailable: invalid.`\n ? [\n {\n path: \"$.staticExport\",\n message: \"Custom block static export failed conformance.\",\n },\n ]\n : [];\n } catch (error) {\n return [\n {\n path: \"$\",\n message:\n error instanceof Error\n ? error.message\n : \"Custom block conformance failed.\",\n },\n ];\n }\n};\n\nexport const escapeOpenEditorCustomBlockHtml = (value: unknown): string =>\n String(value).replace(\n /[&<>\"']/g,\n (character) =>\n ({\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n })[character]!,\n );\nconst SAFE_TAGS = new Set([\n \"div\", \"span\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\n \"article\", \"section\", \"aside\", \"blockquote\", \"figure\", \"figcaption\",\n \"ul\", \"ol\", \"li\", \"dl\", \"dt\", \"dd\", \"table\", \"caption\", \"thead\",\n \"tbody\", \"tr\", \"th\", \"td\", \"strong\", \"em\", \"u\", \"s\", \"code\",\n \"pre\", \"a\", \"img\", \"br\", \"hr\",\n]);\nconst SAFE_ATTRS = new Set([\n \"aria-label\", \"aria-current\", \"role\", \"title\", \"href\", \"src\", \"alt\",\n \"width\", \"height\", \"start\", \"colspan\", \"rowspan\", \"scope\",\n]);\nconst safeStaticUrl = (value: string, context: \"navigation\" | \"asset\") => {\n const normalized = value.trim();\n if (!normalized) return null;\n const scheme = /^([a-z][a-z\\d+.-]*):/i.exec(normalized)?.[1]?.toLowerCase();\n if (!scheme)\n return normalized.startsWith(\"//\") || normalized.includes(\"\\\\\")\n ? null\n : normalized;\n const allowed =\n context === \"asset\"\n ? [\"http\", \"https\"]\n : [\"http\", \"https\", \"mailto\", \"tel\"];\n return allowed.includes(scheme) ? normalized : null;\n};\nexport const renderOpenEditorCustomBlockSafeHtml = (\n value: OpenEditorCustomBlockSafeHtml,\n): string => {\n const seen = new WeakSet<object>();\n let nodes = 0;\n let stringBytes = 0;\n const count = (rendered: string) => {\n stringBytes += rendered.length;\n if (stringBytes > LIMITS.stringLength)\n throw new Error(\"Safe HTML output exceeds its text limit.\");\n return rendered;\n };\n const render = (item: OpenEditorCustomBlockSafeHtml, depth: number): string => {\n nodes += 1;\n if (nodes > LIMITS.values || depth > LIMITS.depth)\n throw new Error(\"Safe HTML output exceeds its structural limit.\");\n if (item && typeof item === \"object\") {\n if (seen.has(item)) throw new Error(\"Safe HTML output must not contain cycles.\");\n seen.add(item);\n }\n if (item === null || item === false) return \"\";\n if (typeof item === \"string\" || typeof item === \"number\")\n return count(escapeOpenEditorCustomBlockHtml(item));\n if (!plainObject(item) || typeof item.tag !== \"string\" || !SAFE_TAGS.has(item.tag))\n return \"\";\n const attrs = Object.entries(item.attrs ?? {})\n .flatMap(([name, raw]) => {\n if (raw === undefined || !SAFE_ATTRS.has(name)) return [];\n const safe =\n name === \"href\"\n ? safeStaticUrl(String(raw), \"navigation\")\n : name === \"src\"\n ? safeStaticUrl(String(raw), \"asset\")\n : String(raw);\n return safe === null\n ? []\n : [count(` ${name}=\"${escapeOpenEditorCustomBlockHtml(safe)}\"`)];\n })\n .join(\"\");\n const children = (item.children ?? [])\n .map((child) => render(child, depth + 1))\n .join(\"\");\n return [\"img\", \"br\", \"hr\"].includes(item.tag)\n ? `<${item.tag}${attrs}>`\n : `<${item.tag}${attrs}>${children}</${item.tag}>`;\n };\n return render(value, 0);\n};\n","export type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonObject | JsonValue[];\nexport type JsonObject = { [key: string]: JsonValue | undefined };\n\nexport type ProseMirrorAttrs = Record<string, unknown>;\n\nexport type ProseMirrorMark = {\n type: string;\n attrs?: ProseMirrorAttrs;\n};\n\nexport type ProseMirrorNode = {\n type: string;\n attrs?: ProseMirrorAttrs;\n content?: ProseMirrorNode[];\n marks?: ProseMirrorMark[];\n text?: string;\n};\n\nexport type OpenEditorBlock = ProseMirrorNode & {\n attrs?: ProseMirrorAttrs & {\n \"openeditor-id\"?: string;\n };\n};\n\n/** Stable identity used by commands and interaction adapters. */\nexport type OpenEditorBlockRef = {\n id: string;\n nodeType: string;\n blockName?: string;\n};\n\nexport type OpenEditorBlockLocation = OpenEditorBlockRef & {\n parentId: string | null;\n index: number;\n path: readonly number[];\n};\n\nexport type OpenEditorDocumentMeta = {\n id?: string;\n title?: string;\n source?: string;\n createdAt?: string;\n updatedAt?: string;\n platform?: EditorPlatform;\n /** Consumer-defined schema version. The OpenEditor JSON format remains independently versioned. */\n schemaVersion?: string;\n custom?: Record<string, unknown>;\n};\n\nexport const OPENEDITOR_DOCUMENT_FORMAT_VERSION = 1 as const;\n\nexport type OpenEditorDocument = {\n type: \"doc\";\n version: typeof OPENEDITOR_DOCUMENT_FORMAT_VERSION;\n content: OpenEditorBlock[];\n meta?: OpenEditorDocumentMeta;\n};\n\nexport type ProseMirrorDocument = {\n type: \"doc\";\n content: ProseMirrorNode[];\n};\n\nexport type EditorPlatform = \"web\" | \"native\";\n\nexport type PlatformSupportLevel = \"supported\" | \"unsupported\";\n\nexport type PlatformSupport = {\n web: PlatformSupportLevel;\n native: PlatformSupportLevel;\n};\n\nexport type BlockGroup = \"text\" | \"media\" | \"layout\" | \"structure\" | \"embed\";\n\nexport type BlockSpec = {\n name: string;\n /** ProseMirror node type. Defaults to `name`. */\n nodeType?: string;\n label: string;\n group: BlockGroup;\n defaultNode: () => OpenEditorBlock;\n /** False for internal schema carriers that cannot be inserted directly. */\n insertable?: boolean;\n matchNode?: (node: ProseMirrorNode) => boolean;\n support?: PlatformSupport;\n /** Optional portable contract used by server-side validation and schema-aware consumers. */\n schema?: Omit<OpenEditorNodeSpec, \"type\">;\n};\n\nexport type BlockRegistry = ReadonlyMap<string, BlockSpec>;\n\nexport type OpenEditorValueValidationContext = {\n path: string;\n};\n\nexport type OpenEditorValueValidator = (\n value: unknown,\n context: OpenEditorValueValidationContext,\n) => string | readonly string[] | null | undefined;\n\ntype OpenEditorValueSchemaBase = {\n nullable?: boolean;\n enum?: readonly JsonValue[];\n validate?: OpenEditorValueValidator;\n};\n\nexport type OpenEditorValueSchema = OpenEditorValueSchemaBase & (\n | { type: \"any\" }\n | { type: \"string\"; minLength?: number; maxLength?: number; pattern?: string }\n | { type: \"number\"; integer?: boolean; minimum?: number; maximum?: number }\n | { type: \"boolean\" }\n | { type: \"null\" }\n | {\n type: \"array\";\n items?: OpenEditorValueSchema;\n minItems?: number;\n maxItems?: number;\n }\n | {\n type: \"object\";\n properties?: Readonly<Record<string, OpenEditorValueSchema>>;\n required?: readonly string[];\n additionalProperties?: boolean | OpenEditorValueSchema;\n }\n);\n\nexport type OpenEditorAttributesSpec = {\n properties?: Readonly<Record<string, OpenEditorValueSchema>>;\n required?: readonly string[];\n /** Defaults to false for contract-aware validation. */\n additionalProperties?: boolean | OpenEditorValueSchema;\n};\n\nexport type OpenEditorContentSpec = {\n allowedTypes?: readonly string[];\n minItems?: number;\n maxItems?: number;\n};\n\nexport type OpenEditorNodeValidator = (\n node: ProseMirrorNode,\n context: OpenEditorValueValidationContext,\n) => string | readonly string[] | null | undefined;\n\n/** Portable validation contract for one ProseMirror node type. */\nexport type OpenEditorNodeSpec = {\n type: string;\n attributes?: OpenEditorAttributesSpec;\n content?: OpenEditorContentSpec | false;\n text?: \"required\" | \"allowed\" | \"forbidden\";\n marks?: false | readonly string[];\n validate?: OpenEditorNodeValidator;\n};\n\nexport type OpenEditorMarkSpec = {\n type: string;\n attributes?: OpenEditorAttributesSpec;\n};\n\nexport type OpenEditorDocumentContract = {\n formatVersion: typeof OPENEDITOR_DOCUMENT_FORMAT_VERSION;\n schemaVersion: string;\n /** Optional portable constraint for the document root's direct children. */\n rootContent?: OpenEditorContentSpec;\n nodes: ReadonlyMap<string, OpenEditorNodeSpec>;\n marks: ReadonlyMap<string, OpenEditorMarkSpec>;\n};\n\nexport type CreateOpenEditorDocumentContractOptions = {\n schemaVersion: string;\n blockSpecs?: readonly BlockSpec[];\n nodeSpecs?: readonly OpenEditorNodeSpec[];\n markSpecs?: readonly OpenEditorMarkSpec[];\n rootContent?: OpenEditorContentSpec;\n};\n\nexport type EditorSelection =\n | { type: \"none\" }\n | { type: \"text\"; anchor: number; head: number }\n | { type: \"node\"; from: number; to: number; nodeType?: string }\n | { type: \"block\"; blockId: string };\n\nexport type OpenEditorMarkName =\n | \"bold\"\n | \"italic\"\n | \"underline\"\n | \"strike\"\n | \"code\"\n | \"link\";\n\nexport type OpenEditorFeatureName =\n | \"headings\"\n | \"lists\"\n | \"taskLists\"\n | \"quotes\"\n | \"codeBlocks\"\n | \"dividers\"\n | \"links\"\n | \"images\"\n | \"columns\"\n | \"tables\"\n | \"toggleLists\"\n | \"callouts\"\n | \"diagrams\"\n | \"pages\"\n | \"attachments\";\n\n/** Durable image data stored by the editor. Resolved preview URLs stay runtime-owned. */\nexport type OpenEditorImageSnapshot = {\n imageId: string | null;\n src: string | null;\n alt: string;\n width: number | null;\n height: number | null;\n};\n\n/** A host-selected image. `source` is platform-specific and is never serialized. */\nexport type OpenEditorImageUploadInput<TSource = unknown> = {\n name: string;\n mimeType: string | null;\n size: number | null;\n source: TSource;\n};\n\nexport type OpenEditorImageUploadCallbacks = {\n onProgress?: (progress: number) => void;\n signal?: AbortSignal;\n};\n\nexport type OpenEditorImageValidationResult =\n | { accepted: true }\n | { accepted: false; message: string };\n\n/** Host-owned image selection, storage, validation, and URL resolution. */\nexport type OpenEditorImageRuntime<TSource = unknown> = {\n selectImage?: (options?: { signal?: AbortSignal }) =>\n | Promise<OpenEditorImageUploadInput<TSource> | null>\n | OpenEditorImageUploadInput<TSource>\n | null;\n validateImage?: (\n input: OpenEditorImageUploadInput<TSource>,\n ) => OpenEditorImageValidationResult | Promise<OpenEditorImageValidationResult>;\n uploadImage?: (\n input: OpenEditorImageUploadInput<TSource>,\n callbacks?: OpenEditorImageUploadCallbacks,\n ) => Promise<OpenEditorImageSnapshot>;\n resolveImage?: (imageId: string, options?: { signal?: AbortSignal }) =>\n Promise<OpenEditorImageSnapshot | null>;\n replaceImage?: (\n imageId: string,\n input: OpenEditorImageUploadInput<TSource>,\n callbacks?: OpenEditorImageUploadCallbacks,\n ) => Promise<OpenEditorImageSnapshot>;\n};\n\n/** Durable, portable attributes stored on an attachment node. */\nexport type OpenEditorAttachmentSnapshot = {\n attachmentId: string | null;\n name: string;\n mimeType: string | null;\n size: number | null;\n url: string | null;\n};\n\n/**\n * A host-selected local file. `source` is deliberately opaque: on web it may\n * be a File, while native hosts typically use a picker result or local URI.\n * OpenEditor never serializes it.\n */\nexport type OpenEditorAttachmentUploadInput<TSource = unknown> = {\n name: string;\n mimeType: string | null;\n size: number | null;\n source: TSource;\n};\n\nexport type OpenEditorAttachmentUploadCallbacks = {\n onProgress?: (progress: number) => void;\n signal?: AbortSignal;\n};\n\nexport type OpenEditorAttachmentValidationResult =\n | { accepted: true }\n | { accepted: false; message: string };\n\n/** Host-owned storage, picker, policy, resolution, and platform actions. */\nexport type OpenEditorAttachmentRuntime<TSource = unknown> = {\n selectAttachment?: (options?: { signal?: AbortSignal }) =>\n | Promise<OpenEditorAttachmentUploadInput<TSource> | null>\n | OpenEditorAttachmentUploadInput<TSource>\n | null;\n validateAttachment?: (\n input: OpenEditorAttachmentUploadInput<TSource>,\n ) => OpenEditorAttachmentValidationResult | Promise<OpenEditorAttachmentValidationResult>;\n uploadAttachment?: (\n input: OpenEditorAttachmentUploadInput<TSource>,\n callbacks?: OpenEditorAttachmentUploadCallbacks,\n ) => Promise<OpenEditorAttachmentSnapshot>;\n resolveAttachment?: (attachmentId: string, options?: { signal?: AbortSignal }) =>\n Promise<OpenEditorAttachmentSnapshot | null>;\n openAttachment?: (attachment: OpenEditorAttachmentSnapshot) => void | Promise<void>;\n renameAttachment?: (attachmentId: string, name: string) => void | Promise<void>;\n replaceAttachment?: (\n attachmentId: string,\n input: OpenEditorAttachmentUploadInput<TSource>,\n callbacks?: OpenEditorAttachmentUploadCallbacks,\n ) => Promise<OpenEditorAttachmentSnapshot>;\n};\n\nexport type OpenEditorPageSnapshot = {\n pageId: string;\n title: string;\n icon?: string | null;\n href?: string | null;\n};\n\nexport type OpenEditorPageUpdate = {\n title?: string;\n icon?: string | null;\n};\n\n/** Host-owned page identity, persistence, navigation, and metadata lifecycle. */\nexport type OpenEditorPageRuntime = {\n createPage?: (input: { title: string; icon?: string | null }) => Promise<OpenEditorPageSnapshot>;\n resolvePage?: (pageId: string) => Promise<OpenEditorPageSnapshot | null>;\n updatePage?: (\n pageId: string,\n update: OpenEditorPageUpdate,\n ) => Promise<OpenEditorPageSnapshot | void> | OpenEditorPageSnapshot | void;\n openPage?: (page: OpenEditorPageSnapshot) => Promise<void> | void;\n};\n\n/** Built-in URL-bearing surfaces rendered from portable document data. */\nexport type OpenEditorUrlContext = \"link\" | \"image\" | \"page\" | \"attachment\";\n\n/**\n * Returns the URL that may be rendered for a context, or `null` to omit the\n * navigation/resource. Policies are pure so the same contract can be shared by\n * React viewers, HTML exporters, and other public renderers.\n */\nexport type OpenEditorUrlPolicy = (\n value: string,\n context: OpenEditorUrlContext,\n) => string | null;\n\nconst OPENEDITOR_URL_SCHEME = /^([a-z][a-z\\d+.-]*):/i;\nconst OPENEDITOR_URL_CONTROL_CHARACTER = /[\\u0000-\\u001f\\u007f]/;\nconst OPENEDITOR_NAVIGATION_SCHEMES: Readonly<Record<Exclude<OpenEditorUrlContext, \"image\">, ReadonlySet<string>>> = {\n link: new Set([\"http\", \"https\", \"mailto\", \"tel\"]),\n page: new Set([\"http\", \"https\"]),\n attachment: new Set([\"http\", \"https\"]),\n};\n\nconst normalizePolicyUrl = (value: string) => {\n const normalized = value.trim();\n return !normalized || OPENEDITOR_URL_CONTROL_CHARACTER.test(normalized) ? null : normalized;\n};\n\n/**\n * Safe policy for user-activated navigation. Ordinary relative references are\n * preserved and explicit schemes are allowlisted by navigation context.\n */\nexport const openEditorNavigationUrlPolicy: OpenEditorUrlPolicy = (value, context) => {\n const normalized = normalizePolicyUrl(value);\n if (!normalized || context === \"image\") return null;\n\n const scheme = OPENEDITOR_URL_SCHEME.exec(normalized)?.[1]?.toLowerCase();\n if (!scheme) return normalized;\n return OPENEDITOR_NAVIGATION_SCHEMES[context].has(scheme) ? normalized : null;\n};\n\n/**\n * Default for rendering untrusted documents. Navigation remains available,\n * while every image URL is blocked so rendering cannot silently contact an\n * external or same-origin tracking endpoint.\n */\nexport const openEditorUntrustedDocumentUrlPolicy: OpenEditorUrlPolicy = (value, context) =>\n context === \"image\" ? null : openEditorNavigationUrlPolicy(value, context);\n\n/**\n * Explicit opt-in for hosts that intentionally allow HTTP(S) or relative image\n * loading. This is not safe as an untrusted-document rendering default.\n */\nexport const openEditorExternalMediaUrlPolicy: OpenEditorUrlPolicy = (value, context) => {\n if (context !== \"image\") return openEditorNavigationUrlPolicy(value, context);\n const normalized = normalizePolicyUrl(value);\n if (!normalized) return null;\n const scheme = OPENEDITOR_URL_SCHEME.exec(normalized)?.[1]?.toLowerCase();\n return !scheme || scheme === \"http\" || scheme === \"https\" ? normalized : null;\n};\n\n/** Explicit trusted-host escape hatch. Never use this for untrusted documents. */\nexport const openEditorUnsafeUrlPolicy: OpenEditorUrlPolicy = (value) => {\n const normalized = value.trim();\n return normalized || null;\n};\n\nexport const createAttachmentSnapshot = (\n attrs: Partial<OpenEditorAttachmentSnapshot> = {},\n): OpenEditorAttachmentSnapshot => ({\n attachmentId: typeof attrs.attachmentId === \"string\" ? attrs.attachmentId : null,\n name: typeof attrs.name === \"string\" ? attrs.name : \"\",\n mimeType: typeof attrs.mimeType === \"string\" ? attrs.mimeType : null,\n size: typeof attrs.size === \"number\" && Number.isFinite(attrs.size) && attrs.size >= 0 ? attrs.size : null,\n url: typeof attrs.url === \"string\" ? attrs.url : null,\n});\n\nexport type OpenEditorFeatureSet = Readonly<Record<OpenEditorFeatureName, boolean>>;\n\n/** Controls which schema-supported blocks may be created by an editor surface. */\nexport type OpenEditorAuthoringCapabilities = {\n enabledBlocks?: readonly string[];\n};\n\nexport const isOpenEditorBlockEnabled = (\n blockName: string,\n capabilities?: OpenEditorAuthoringCapabilities,\n): boolean => capabilities?.enabledBlocks === undefined\n || capabilities.enabledBlocks.includes(blockName);\n\nexport const DEFAULT_CALLOUT_EMOJI = \"💡\";\nexport const DEFAULT_PAGE_EMOJI = \"📄\";\n\nexport const normalizeEmoji = (value: unknown, fallback: string) =>\n typeof value === \"string\" && value.trim() ? value.trim() : fallback;\n\nexport type SerializedEditorState = {\n document: OpenEditorDocument;\n selection?: EditorSelection;\n};\n\nexport type EditorTransaction = {\n before: OpenEditorDocument;\n after: OpenEditorDocument;\n command?: OpenEditorCommand;\n timestamp: string;\n};\n\nexport type OpenEditorCommand =\n | { type: \"setContent\"; document: OpenEditorDocument }\n | { type: \"insertBlock\"; block: string; at?: number; attrs?: ProseMirrorAttrs }\n | { type: \"moveBlock\"; from: number; to: number }\n | { type: \"duplicateBlock\"; index: number }\n | { type: \"deleteBlock\"; index: number }\n | { type: \"setLink\"; href?: string }\n | { type: \"toggleMark\"; mark: OpenEditorMarkName }\n | { type: \"undo\" }\n | { type: \"redo\" }\n | { type: \"setSelection\"; selection: EditorSelection };\n\nexport type EditorCommand = OpenEditorCommand;\n\nexport type OpenEditorEventHandlers = {\n onChange?: (document: OpenEditorDocument) => void;\n onSelectionChange?: (selection: EditorSelection) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n onReady?: (controller: OpenEditorController) => void;\n onCommand?: (command: OpenEditorCommand, transaction: EditorTransaction) => void;\n};\n\nexport type OpenEditorConfig = OpenEditorEventHandlers & {\n initialDocument?: OpenEditorDocument;\n editable?: boolean;\n placeholder?: string;\n enabledBlocks?: readonly string[];\n theme?: Record<string, string | number>;\n};\n\nexport type OpenEditorController = {\n getContent: () => OpenEditorDocument;\n setContent: (document: OpenEditorDocument) => void;\n getSelection: () => EditorSelection;\n execute: (command: OpenEditorCommand) => void;\n};\n\nexport type DocumentValidationIssue = {\n path: string;\n message: string;\n code?: DocumentValidationCode;\n};\n\nexport type DocumentValidationCode =\n | \"invalid_document\"\n | \"invalid_document_type\"\n | \"unsupported_format_version\"\n | \"schema_version_mismatch\"\n | \"invalid_meta\"\n | \"invalid_node\"\n | \"invalid_node_type\"\n | \"unknown_node_type\"\n | \"invalid_text\"\n | \"unexpected_text\"\n | \"invalid_attrs\"\n | \"missing_attribute\"\n | \"unknown_attribute\"\n | \"unknown_property\"\n | \"invalid_attribute\"\n | \"invalid_marks\"\n | \"invalid_mark\"\n | \"unknown_mark_type\"\n | \"disallowed_mark\"\n | \"invalid_content\"\n | \"disallowed_child\"\n | \"duplicate_node_id\"\n | \"missing_node_id\"\n | \"non_json_value\"\n | \"cyclic_value\"\n | \"limit_depth\"\n | \"limit_nodes\"\n | \"limit_marks\"\n | \"limit_text\"\n | \"limit_attributes\"\n | \"custom_validation\";\n\nexport type DocumentValidationResult = {\n valid: boolean;\n issues: DocumentValidationIssue[];\n};\n\nexport type DocumentValidationLimits = {\n maxDepth: number;\n maxNodes: number;\n maxMarksPerNode: number;\n maxTextLength: number;\n maxTotalTextLength: number;\n maxAttributeDepth: number;\n maxArrayItems: number;\n maxObjectKeys: number;\n /** Global JSON value budget, including metadata and attributes. */\n maxJsonValues: number;\n requireNodeIds: boolean;\n};\n\nexport type ValidateDocumentOptions = {\n contract?: OpenEditorDocumentContract;\n limits?: Partial<DocumentValidationLimits>;\n /** Reject a document whose meta.schemaVersion differs from the configured contract. */\n requireSchemaVersion?: boolean;\n};\n\nexport const DEFAULT_DOCUMENT_VALIDATION_LIMITS: Readonly<DocumentValidationLimits> = {\n maxDepth: 128,\n maxNodes: 100_000,\n maxMarksPerNode: 64,\n maxTextLength: 1_000_000,\n maxTotalTextLength: 10_000_000,\n maxAttributeDepth: 32,\n maxArrayItems: 100_000,\n maxObjectKeys: 10_000,\n maxJsonValues: 500_000,\n requireNodeIds: false,\n};\n\nexport type PlatformSupportIssue = {\n path: string;\n block: string;\n platform: EditorPlatform;\n support: PlatformSupportLevel;\n};\n\nexport type PlatformSupportResult = {\n platform: EditorPlatform;\n document: OpenEditorDocument;\n issues: PlatformSupportIssue[];\n};\n\nexport const OPENEDITOR_BLOCK_ID_ATTR = \"openeditor-id\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst normalizeMeta = (meta?: OpenEditorDocumentMeta): OpenEditorDocumentMeta | undefined =>\n meta && Object.keys(meta).length ? { ...meta } : undefined;\n\nconst cloneAttrs = (attrs?: ProseMirrorAttrs): ProseMirrorAttrs | undefined =>\n attrs ? { ...attrs } : undefined;\n\nconst cloneMark = (mark: ProseMirrorMark): ProseMirrorMark => ({\n type: mark.type,\n ...(mark.attrs ? { attrs: cloneAttrs(mark.attrs) } : {}),\n});\n\nconst cloneNodeShallow = <T extends ProseMirrorNode>(node: T): T => ({\n ...node,\n ...(node.attrs ? { attrs: cloneAttrs(node.attrs) } : {}),\n ...(node.marks ? { marks: node.marks.map(cloneMark) } : {}),\n});\n\nexport const cloneNode = <T extends ProseMirrorNode>(node: T): T => ({\n ...cloneNodeShallow(node),\n ...(node.content ? { content: node.content.map(cloneNode) } : {}),\n});\n\nexport const createBlockId = (prefix = \"oe\"): string => {\n const random =\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : Math.random().toString(36).slice(2);\n\n return `${prefix}_${random.replaceAll(\"-\", \"\").slice(0, 24)}`;\n};\n\nconst cloneNodeWithIds = (\n node: ProseMirrorNode,\n createId: () => string,\n seenIds: Set<string>,\n): ProseMirrorNode => {\n if (node.type === \"text\") return cloneNode(node);\n const cloned = cloneNodeShallow(node);\n const existingId = getBlockId(cloned);\n let id = existingId && !seenIds.has(existingId) ? existingId : createId();\n while (!id.trim() || seenIds.has(id)) id = createId();\n seenIds.add(id);\n const withId = withBlockId(cloned, id);\n return {\n ...withId,\n ...(node.content\n ? { content: node.content.map((child) => cloneNodeWithIds(child, createId, seenIds)) }\n : {}),\n };\n};\n\nconst createDocumentWithIds = (\n content: ProseMirrorNode[] = [],\n meta?: OpenEditorDocumentMeta,\n createId: () => string = createBlockId,\n): OpenEditorDocument => {\n const normalizedMeta = normalizeMeta(meta);\n const seenIds = new Set<string>();\n return {\n type: \"doc\",\n version: 1,\n content: content.map((node) => cloneNodeWithIds(node, createId, seenIds)) as OpenEditorBlock[],\n ...(normalizedMeta ? { meta: normalizedMeta } : {}),\n };\n};\n\nexport const createDocument = (\n content: ProseMirrorNode[] = [],\n meta?: OpenEditorDocumentMeta,\n): OpenEditorDocument => createDocumentWithIds(content, meta);\n\nexport const createEditorState = (\n document: OpenEditorDocument,\n selection: EditorSelection = { type: \"none\" },\n): SerializedEditorState => ({\n document: normalizeDocument(document),\n selection,\n});\n\nexport const toProseMirrorDocument = (document: OpenEditorDocument): ProseMirrorDocument => ({\n type: \"doc\",\n content: document.content.map(cloneNode),\n});\n\nexport const fromProseMirrorDocument = (\n document: ProseMirrorDocument,\n meta?: OpenEditorDocumentMeta,\n): OpenEditorDocument => createDocument(document.content, meta);\n\nexport const createTextNode = (text: string, marks?: ProseMirrorMark[]): ProseMirrorNode => ({\n type: \"text\",\n text,\n ...(marks?.length ? { marks: marks.map(cloneMark) } : {}),\n});\n\nexport const textBlock = (type: string, text: string, attrs?: ProseMirrorAttrs): OpenEditorBlock => ({\n type,\n ...(attrs ? { attrs: cloneAttrs(attrs) } : {}),\n content: text ? [createTextNode(text)] : [],\n});\n\nexport const createBlockRegistry = (specs: readonly BlockSpec[]): BlockRegistry => {\n const registry = new Map<string, BlockSpec>();\n const nodeTypes = new Map<string, string>();\n\n for (const spec of specs) {\n if (!spec.name.trim()) {\n throw new Error(\"OpenEditor block names must not be empty.\");\n }\n if (registry.has(spec.name)) {\n throw new Error(`Duplicate OpenEditor block name \"${spec.name}\".`);\n }\n\n const nodeType = spec.nodeType ?? spec.name;\n const existing = nodeTypes.get(nodeType);\n if (existing) {\n throw new Error(\n `OpenEditor blocks \"${existing}\" and \"${spec.name}\" both claim node type \"${nodeType}\".`,\n );\n }\n\n registry.set(spec.name, spec);\n nodeTypes.set(nodeType, spec.name);\n }\n\n return registry;\n};\n\nexport const findBlockSpecForNode = (\n registry: BlockRegistry,\n node: ProseMirrorNode,\n): BlockSpec | undefined => {\n for (const spec of registry.values()) {\n if (spec.matchNode?.(node) || (spec.nodeType ?? spec.name) === node.type) {\n return spec;\n }\n }\n\n return undefined;\n};\n\nexport const getBlockId = (node: ProseMirrorNode): string | undefined => {\n const value = node.attrs?.[OPENEDITOR_BLOCK_ID_ATTR];\n return typeof value === \"string\" && value.trim() ? value : undefined;\n};\n\nexport const withBlockId = <T extends ProseMirrorNode>(node: T, id: string): T => ({\n ...node,\n attrs: {\n ...cloneAttrs(node.attrs),\n [OPENEDITOR_BLOCK_ID_ATTR]: id,\n },\n});\n\nexport const ensureBlockIds = (\n document: OpenEditorDocument,\n createId: () => string = createBlockId,\n): OpenEditorDocument => createDocumentWithIds(document.content, document.meta, createId);\n\nexport const findBlockLocation = (\n document: OpenEditorDocument,\n id: string,\n): OpenEditorBlockLocation | null => {\n const visit = (\n nodes: readonly ProseMirrorNode[],\n parentId: string | null,\n path: readonly number[],\n ): OpenEditorBlockLocation | null => {\n for (let index = 0; index < nodes.length; index += 1) {\n const node = nodes[index];\n if (!node) continue;\n const nodeId = getBlockId(node);\n const nodePath = [...path, index];\n if (nodeId === id) {\n return { id, nodeType: node.type, parentId, index, path: nodePath };\n }\n const nested = node.content?.length\n ? visit(node.content, nodeId ?? parentId, nodePath)\n : null;\n if (nested) return nested;\n }\n return null;\n };\n\n return visit(document.content, null, []);\n};\n\nconst normalizeNode = (node: ProseMirrorNode): OpenEditorBlock => {\n if (node.type === \"heading\") {\n const level = typeof node.attrs?.level === \"number\" ? node.attrs.level : 2;\n const content = node.content?.map(normalizeNode);\n\n return {\n ...cloneNode(node),\n attrs: { ...node.attrs, level: Math.min(Math.max(level, 1), 6) },\n ...(content ? { content } : {}),\n };\n }\n\n if (node.type === \"columns\") {\n const content = node.content?.length\n ? node.content.map(normalizeNode)\n : [\n { type: \"column\", content: [textBlock(\"paragraph\", \"\")] },\n { type: \"column\", content: [textBlock(\"paragraph\", \"\")] },\n ];\n\n return {\n ...cloneNode(node),\n attrs: Object.fromEntries(\n Object.entries(node.attrs ?? {}).filter(([name]) => name !== \"count\"),\n ),\n content,\n };\n }\n\n if (node.type === \"column\" && !node.content?.length) {\n return { ...cloneNode(node), content: [textBlock(\"paragraph\", \"\")] };\n }\n\n const content = node.content?.map(normalizeNode);\n return {\n ...cloneNode(node),\n ...(content ? { content } : {}),\n };\n};\n\nexport const normalizeDocument = (document: OpenEditorDocument): OpenEditorDocument =>\n createDocument(document.content.map(normalizeNode), document.meta);\n\nconst cloneAndFreezeContractValue = <T>(value: T): T => {\n if (!value || typeof value !== \"object\") return value;\n if (Array.isArray(value)) {\n return Object.freeze(value.map((child) => cloneAndFreezeContractValue(child))) as T;\n }\n const clone = Object.fromEntries(Object.entries(value as Record<string, unknown>).map(\n ([key, child]) => [key, cloneAndFreezeContractValue(child)],\n ));\n return Object.freeze(clone) as T;\n};\n\nconst createReadonlyMap = <K, V>(source: ReadonlyMap<K, V>): ReadonlyMap<K, V> => {\n let view: ReadonlyMap<K, V>;\n view = Object.freeze({\n get size() { return source.size; },\n get: (key: K) => source.get(key),\n has: (key: K) => source.has(key),\n entries: () => source.entries(),\n keys: () => source.keys(),\n values: () => source.values(),\n forEach: (callback: (value: V, key: K, map: ReadonlyMap<K, V>) => void, thisArg?: unknown) => {\n source.forEach((value, key) => callback.call(thisArg, value, key, view));\n },\n [Symbol.iterator]: () => source[Symbol.iterator](),\n });\n return view;\n};\n\nexport const createOpenEditorDocumentContract = ({\n schemaVersion,\n blockSpecs = [],\n nodeSpecs = [],\n markSpecs = [],\n rootContent,\n}: CreateOpenEditorDocumentContractOptions): OpenEditorDocumentContract => {\n if (!schemaVersion.trim()) throw new Error(\"OpenEditor schema versions must not be empty.\");\n const nodes = new Map<string, OpenEditorNodeSpec>();\n const marks = new Map<string, OpenEditorMarkSpec>();\n\n for (const block of blockSpecs) {\n const type = block.nodeType ?? block.name;\n if (nodes.has(type)) throw new Error(`Duplicate OpenEditor node contract \"${type}\".`);\n nodes.set(type, cloneAndFreezeContractValue({ ...block.schema, type }));\n }\n for (const node of nodeSpecs) {\n if (!node.type.trim()) throw new Error(\"OpenEditor node contract types must not be empty.\");\n if (nodes.has(node.type)) throw new Error(`Duplicate OpenEditor node contract \"${node.type}\".`);\n nodes.set(node.type, cloneAndFreezeContractValue(node));\n }\n for (const mark of markSpecs) {\n if (!mark.type.trim()) throw new Error(\"OpenEditor mark contract types must not be empty.\");\n if (marks.has(mark.type)) throw new Error(`Duplicate OpenEditor mark contract \"${mark.type}\".`);\n marks.set(mark.type, cloneAndFreezeContractValue(mark));\n }\n\n return Object.freeze({\n formatVersion: OPENEDITOR_DOCUMENT_FORMAT_VERSION,\n schemaVersion,\n ...(rootContent ? { rootContent: cloneAndFreezeContractValue(rootContent) } : {}),\n nodes: createReadonlyMap(nodes),\n marks: createReadonlyMap(marks),\n });\n};\n\nconst isPlainRecord = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n\nconst formatJsonPathKey = (path: string, key: string) =>\n /^[A-Za-z_$][\\w$-]*$/.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;\n\n/** Deterministic JSON serialization with lexicographically sorted object keys. */\nexport const canonicalSerializeJson = (value: unknown): string => {\n const ancestors = new Set<object>();\n const serialize = (input: unknown): string => {\n if (input === null || typeof input === \"boolean\" || typeof input === \"string\") {\n return JSON.stringify(input);\n }\n if (typeof input === \"number\") {\n if (!Number.isFinite(input)) throw new TypeError(\"Canonical JSON cannot serialize non-finite numbers.\");\n return JSON.stringify(input);\n }\n if (typeof input !== \"object\") throw new TypeError(\"Canonical JSON can only serialize JSON-safe values.\");\n if (!Array.isArray(input) && !isPlainRecord(input)) throw new TypeError(\"Canonical JSON objects must be plain objects.\");\n if (ancestors.has(input)) throw new TypeError(\"Canonical JSON cannot serialize cyclic values.\");\n ancestors.add(input);\n let serialized: string;\n if (Array.isArray(input)) {\n serialized = `[${input.map(serialize).join(\",\")}]`;\n } else {\n serialized = `{${Object.keys(input).sort().map((key) => `${JSON.stringify(key)}:${serialize(input[key])}`).join(\",\")}}`;\n }\n ancestors.delete(input);\n return serialized;\n };\n return serialize(value);\n};\n\n/**\n * Stable non-cryptographic content fingerprint for optimistic concurrency and diffs.\n * Security-sensitive integrity checks should use a cryptographic digest at the host boundary.\n */\nexport const fingerprintOpenEditorDocument = (document: OpenEditorDocument): string => {\n const serialized = canonicalSerializeJson(document);\n let hash = 0xcbf29ce484222325n;\n for (const byte of new TextEncoder().encode(serialized)) {\n hash ^= BigInt(byte);\n hash = BigInt.asUintN(64, hash * 0x100000001b3n);\n }\n return `oe1-fnv1a64-${hash.toString(16).padStart(16, \"0\")}`;\n};\n\nconst validatorMessages = (\n validator: OpenEditorValueValidator | OpenEditorNodeValidator | undefined,\n value: unknown,\n path: string,\n): readonly string[] => {\n if (!validator) return [];\n try {\n const result = validator(value as never, { path });\n if (typeof result === \"string\") return [result];\n return result ?? [];\n } catch (error) {\n return [error instanceof Error ? error.message : \"Custom validator failed.\"];\n }\n};\n\nconst jsonValuesEqual = (left: JsonValue, right: unknown): boolean => {\n try {\n return canonicalSerializeJson(left) === canonicalSerializeJson(right);\n } catch {\n return false;\n }\n};\n\nexport const validateDocument = (\n document: unknown,\n options: ValidateDocumentOptions = {},\n): DocumentValidationResult => {\n const issues: DocumentValidationIssue[] = [];\n const limits = { ...DEFAULT_DOCUMENT_VALIDATION_LIMITS, ...options.limits };\n const push = (path: string, message: string, code: DocumentValidationCode) =>\n issues.push({ path, message, code });\n let nodeCount = 0;\n let totalTextLength = 0;\n let jsonValueCount = 0;\n let jsonValueLimitReported = false;\n const seenIds = new Map<string, string>();\n\n const validateJsonValue = (\n value: unknown,\n path: string,\n depth: number,\n ancestors: Set<object>,\n maximumDepth = limits.maxAttributeDepth,\n countTowardsGlobalBudget = true,\n ): void => {\n if (countTowardsGlobalBudget) {\n jsonValueCount += 1;\n if (jsonValueCount > limits.maxJsonValues) {\n if (!jsonValueLimitReported) {\n push(path, `Document exceeds maximum JSON value count ${limits.maxJsonValues}.`, \"limit_attributes\");\n jsonValueLimitReported = true;\n }\n return;\n }\n }\n if (\n value === null\n || typeof value === \"string\"\n || typeof value === \"boolean\"\n ) return;\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) push(path, \"Numbers must be finite JSON values.\", \"non_json_value\");\n return;\n }\n if (typeof value !== \"object\") {\n push(path, \"Value must be JSON-safe.\", \"non_json_value\");\n return;\n }\n if (ancestors.has(value)) {\n push(path, \"Cyclic values are not valid JSON.\", \"cyclic_value\");\n return;\n }\n if (depth > maximumDepth) {\n push(path, `Value exceeds maximum depth ${maximumDepth}.`, \"limit_attributes\");\n return;\n }\n if (!Array.isArray(value) && !isPlainRecord(value)) {\n push(path, \"Value must be a plain JSON object.\", \"non_json_value\");\n return;\n }\n ancestors.add(value);\n if (Array.isArray(value)) {\n if (value.length > limits.maxArrayItems) {\n push(path, `Array exceeds maximum item count ${limits.maxArrayItems}.`, \"limit_attributes\");\n }\n for (let index = 0; index < value.length; index += 1) {\n if (countTowardsGlobalBudget && jsonValueCount > limits.maxJsonValues) break;\n validateJsonValue(value[index], `${path}.${index}`, depth + 1, ancestors, maximumDepth, countTowardsGlobalBudget);\n }\n } else {\n const entries = Object.entries(value);\n if (entries.length > limits.maxObjectKeys) {\n push(path, `Object exceeds maximum key count ${limits.maxObjectKeys}.`, \"limit_attributes\");\n }\n for (const [key, item] of entries) {\n if (countTowardsGlobalBudget && jsonValueCount > limits.maxJsonValues) break;\n validateJsonValue(item, formatJsonPathKey(path, key), depth + 1, ancestors, maximumDepth, countTowardsGlobalBudget);\n }\n }\n ancestors.delete(value);\n };\n\n const validateValueSchema = (value: unknown, schema: OpenEditorValueSchema, path: string): void => {\n if (value === null && schema.nullable) return;\n let typeValid = true;\n if (schema.type === \"string\") typeValid = typeof value === \"string\";\n else if (schema.type === \"number\") typeValid = typeof value === \"number\" && Number.isFinite(value);\n else if (schema.type === \"boolean\") typeValid = typeof value === \"boolean\";\n else if (schema.type === \"null\") typeValid = value === null;\n else if (schema.type === \"array\") typeValid = Array.isArray(value);\n else if (schema.type === \"object\") typeValid = isPlainRecord(value);\n\n if (!typeValid) {\n push(path, `Attribute must match schema type \"${schema.type}\".`, \"invalid_attribute\");\n return;\n }\n if (schema.enum && !schema.enum.some((candidate) => jsonValuesEqual(candidate, value))) {\n push(path, \"Attribute must be one of the configured enum values.\", \"invalid_attribute\");\n }\n if (schema.type === \"string\" && typeof value === \"string\") {\n if (schema.minLength !== undefined && value.length < schema.minLength) push(path, `String must contain at least ${schema.minLength} characters.`, \"invalid_attribute\");\n if (schema.maxLength !== undefined && value.length > schema.maxLength) push(path, `String must contain at most ${schema.maxLength} characters.`, \"invalid_attribute\");\n if (schema.pattern !== undefined) {\n try {\n if (!new RegExp(schema.pattern).test(value)) push(path, `String must match /${schema.pattern}/.`, \"invalid_attribute\");\n } catch {\n push(path, \"Attribute contract contains an invalid regular expression.\", \"custom_validation\");\n }\n }\n } else if (schema.type === \"number\" && typeof value === \"number\") {\n if (schema.integer && !Number.isInteger(value)) push(path, \"Number must be an integer.\", \"invalid_attribute\");\n if (schema.minimum !== undefined && value < schema.minimum) push(path, `Number must be at least ${schema.minimum}.`, \"invalid_attribute\");\n if (schema.maximum !== undefined && value > schema.maximum) push(path, `Number must be at most ${schema.maximum}.`, \"invalid_attribute\");\n } else if (schema.type === \"array\" && Array.isArray(value)) {\n if (schema.minItems !== undefined && value.length < schema.minItems) push(path, `Array must contain at least ${schema.minItems} items.`, \"invalid_attribute\");\n if (schema.maxItems !== undefined && value.length > schema.maxItems) push(path, `Array must contain at most ${schema.maxItems} items.`, \"invalid_attribute\");\n if (schema.items) value.forEach((item, index) => validateValueSchema(item, schema.items!, `${path}.${index}`));\n } else if (schema.type === \"object\" && isPlainRecord(value)) {\n validateAttributes(value, schema, path);\n }\n for (const message of validatorMessages(schema.validate, value, path)) push(path, message, \"custom_validation\");\n };\n\n const validateAttributes = (\n attrs: Record<string, unknown>,\n spec: OpenEditorAttributesSpec,\n path: string,\n ): void => {\n for (const required of spec.required ?? []) {\n if (!(required in attrs)) push(formatJsonPathKey(path, required), \"Required attribute is missing.\", \"missing_attribute\");\n }\n for (const [name, value] of Object.entries(attrs)) {\n if (name === OPENEDITOR_BLOCK_ID_ATTR) continue;\n const schema = spec.properties?.[name];\n if (schema) {\n validateValueSchema(value, schema, formatJsonPathKey(path, name));\n } else if (spec.additionalProperties === true) {\n continue;\n } else if (typeof spec.additionalProperties === \"object\") {\n validateValueSchema(value, spec.additionalProperties, formatJsonPathKey(path, name));\n } else {\n push(formatJsonPathKey(path, name), `Unknown attribute \"${name}\".`, \"unknown_attribute\");\n }\n }\n };\n\n const validateNode = (node: unknown, path: string, depth: number) => {\n nodeCount += 1;\n if (nodeCount > limits.maxNodes) {\n if (nodeCount === limits.maxNodes + 1) push(path, `Document exceeds maximum node count ${limits.maxNodes}.`, \"limit_nodes\");\n return;\n }\n if (depth > limits.maxDepth) {\n push(path, `Document exceeds maximum node depth ${limits.maxDepth}.`, \"limit_depth\");\n return;\n }\n if (!isRecord(node)) {\n push(path, \"Node must be an object.\", \"invalid_node\");\n return;\n }\n for (const key of Object.keys(node)) {\n if (![\"type\", \"attrs\", \"content\", \"marks\", \"text\"].includes(key)) {\n push(formatJsonPathKey(path, key), `Unknown node property \"${key}\".`, \"unknown_property\");\n }\n }\n\n if (typeof node.type !== \"string\" || !node.type) {\n push(`${path}.type`, \"Node type must be a non-empty string.\", \"invalid_node_type\");\n }\n const nodeSpec = typeof node.type === \"string\" ? options.contract?.nodes.get(node.type) : undefined;\n if (options.contract && typeof node.type === \"string\" && !nodeSpec) push(`${path}.type`, `Unknown node type \"${node.type}\".`, \"unknown_node_type\");\n\n if (\"text\" in node && typeof node.text !== \"string\") {\n push(`${path}.text`, \"Text node content must be a string.\", \"invalid_text\");\n } else if (typeof node.text === \"string\" && node.text.length > limits.maxTextLength) {\n push(`${path}.text`, `Text exceeds maximum length ${limits.maxTextLength}.`, \"limit_text\");\n }\n if (typeof node.text === \"string\") {\n totalTextLength += node.text.length;\n if (totalTextLength > limits.maxTotalTextLength && totalTextLength - node.text.length <= limits.maxTotalTextLength) {\n push(`${path}.text`, `Document exceeds maximum total text length ${limits.maxTotalTextLength}.`, \"limit_text\");\n }\n }\n if (nodeSpec?.text === \"required\" && typeof node.text !== \"string\") push(`${path}.text`, \"Node requires text content.\", \"invalid_text\");\n if (nodeSpec?.text === \"forbidden\" && \"text\" in node) push(`${path}.text`, \"Node does not allow text content.\", \"unexpected_text\");\n\n const nodeId = typeof node.attrs === \"object\" && node.attrs !== null\n ? getBlockId(node as ProseMirrorNode)\n : undefined;\n if (node.type !== \"text\" && limits.requireNodeIds && !nodeId) push(`${path}.attrs.${OPENEDITOR_BLOCK_ID_ATTR}`, \"Node requires a stable OpenEditor ID.\", \"missing_node_id\");\n if (nodeId) {\n const previousPath = seenIds.get(nodeId);\n if (previousPath) push(`${path}.attrs.${OPENEDITOR_BLOCK_ID_ATTR}`, `Node ID \"${nodeId}\" duplicates ${previousPath}.`, \"duplicate_node_id\");\n else seenIds.set(nodeId, path);\n }\n\n if (\"attrs\" in node && node.attrs !== undefined && !isRecord(node.attrs)) {\n push(`${path}.attrs`, \"Node attrs must be an object.\", \"invalid_attrs\");\n } else if (isRecord(node.attrs)) {\n validateJsonValue(node.attrs, `${path}.attrs`, 0, new Set(), limits.maxAttributeDepth, false);\n if (nodeSpec?.attributes) validateAttributes(node.attrs, nodeSpec.attributes, `${path}.attrs`);\n }\n\n if (\"marks\" in node && node.marks !== undefined) {\n if (!Array.isArray(node.marks)) {\n push(`${path}.marks`, \"Marks must be an array.\", \"invalid_marks\");\n } else {\n if (node.marks.length > limits.maxMarksPerNode) push(`${path}.marks`, `Node exceeds maximum mark count ${limits.maxMarksPerNode}.`, \"limit_marks\");\n node.marks.forEach((mark, index) => {\n if (!isRecord(mark) || typeof mark.type !== \"string\" || !mark.type) {\n push(`${path}.marks.${index}`, \"Mark must have a non-empty type.\", \"invalid_mark\");\n return;\n }\n const markPath = `${path}.marks.${index}`;\n for (const key of Object.keys(mark)) {\n if (![\"type\", \"attrs\"].includes(key)) push(formatJsonPathKey(markPath, key), `Unknown mark property \"${key}\".`, \"unknown_property\");\n }\n const markSpec = options.contract?.marks.get(mark.type);\n if (options.contract && !markSpec) push(`${markPath}.type`, `Unknown mark type \"${mark.type}\".`, \"unknown_mark_type\");\n if (nodeSpec?.marks === false || (Array.isArray(nodeSpec?.marks) && !nodeSpec.marks.includes(mark.type))) push(markPath, `Mark \"${mark.type}\" is not allowed on node \"${String(node.type)}\".`, \"disallowed_mark\");\n if (\"attrs\" in mark && mark.attrs !== undefined && !isRecord(mark.attrs)) push(`${markPath}.attrs`, \"Mark attrs must be an object.\", \"invalid_attrs\");\n else if (isRecord(mark.attrs)) {\n validateJsonValue(mark.attrs, `${markPath}.attrs`, 0, new Set(), limits.maxAttributeDepth, false);\n if (markSpec?.attributes) validateAttributes(mark.attrs, markSpec.attributes, `${markPath}.attrs`);\n }\n });\n }\n }\n\n if (\"content\" in node && node.content !== undefined) {\n if (!Array.isArray(node.content)) {\n push(`${path}.content`, \"Node content must be an array.\", \"invalid_content\");\n } else {\n if (nodeSpec?.content === false) push(`${path}.content`, `Node \"${String(node.type)}\" does not allow content.`, \"invalid_content\");\n const contentSpec = nodeSpec?.content;\n if (contentSpec) {\n if (contentSpec.minItems !== undefined && node.content.length < contentSpec.minItems) push(`${path}.content`, `Node requires at least ${contentSpec.minItems} children.`, \"invalid_content\");\n if (contentSpec.maxItems !== undefined && node.content.length > contentSpec.maxItems) push(`${path}.content`, `Node allows at most ${contentSpec.maxItems} children.`, \"invalid_content\");\n if (contentSpec.allowedTypes) node.content.forEach((child, index) => {\n if (isRecord(child) && typeof child.type === \"string\" && !contentSpec.allowedTypes!.includes(child.type)) push(`${path}.content.${index}.type`, `Child type \"${child.type}\" is not allowed in \"${String(node.type)}\".`, \"disallowed_child\");\n });\n }\n node.content.forEach((child, index) => validateNode(child, `${path}.content.${index}`, depth + 1));\n }\n } else if (nodeSpec?.content && (nodeSpec.content.minItems ?? 0) > 0) {\n push(`${path}.content`, `Node requires at least ${nodeSpec.content.minItems} children.`, \"invalid_content\");\n }\n for (const message of validatorMessages(nodeSpec?.validate, node, path)) push(path, message, \"custom_validation\");\n };\n\n if (!isRecord(document)) {\n return {\n valid: false,\n issues: [{ path: \"$\", message: \"Document must be an object.\", code: \"invalid_document\" }],\n };\n }\n\n validateJsonValue(document, \"$\", 0, new Set(), Math.max(limits.maxDepth * 3, limits.maxAttributeDepth));\n for (const key of Object.keys(document)) {\n if (![\"type\", \"version\", \"content\", \"meta\"].includes(key)) push(formatJsonPathKey(\"$\", key), `Unknown document property \"${key}\".`, \"unknown_property\");\n }\n\n if (document.type !== \"doc\") {\n push(\"$.type\", 'Document type must be \"doc\".', \"invalid_document_type\");\n }\n\n if (document.version !== OPENEDITOR_DOCUMENT_FORMAT_VERSION) {\n push(\"$.version\", `Document version must be ${OPENEDITOR_DOCUMENT_FORMAT_VERSION}.`, \"unsupported_format_version\");\n }\n\n if (!Array.isArray(document.content)) {\n push(\"$.content\", \"Document content must be an array.\", \"invalid_content\");\n } else {\n const rootContent = options.contract?.rootContent;\n if (rootContent) {\n if (rootContent.minItems !== undefined && document.content.length < rootContent.minItems) push(\"$.content\", `Document requires at least ${rootContent.minItems} children.`, \"invalid_content\");\n if (rootContent.maxItems !== undefined && document.content.length > rootContent.maxItems) push(\"$.content\", `Document allows at most ${rootContent.maxItems} children.`, \"invalid_content\");\n if (rootContent.allowedTypes) document.content.forEach((child, index) => {\n if (isRecord(child) && typeof child.type === \"string\" && !rootContent.allowedTypes!.includes(child.type)) push(`$.content.${index}.type`, `Node type \"${child.type}\" is not allowed at the document root.`, \"disallowed_child\");\n });\n }\n document.content.forEach((node, index) => validateNode(node, `$.content.${index}`, 1));\n }\n\n if (\"meta\" in document && document.meta !== undefined && !isRecord(document.meta)) {\n push(\"$.meta\", \"Document meta must be an object.\", \"invalid_meta\");\n } else if (isRecord(document.meta) && options.contract) {\n const actualSchemaVersion = document.meta.schemaVersion;\n if (\n (actualSchemaVersion !== undefined || options.requireSchemaVersion)\n && actualSchemaVersion !== options.contract.schemaVersion\n ) push(\"$.meta.schemaVersion\", `Document schema version must be \"${options.contract.schemaVersion}\".`, \"schema_version_mismatch\");\n }\n if (isRecord(document.meta)) {\n for (const key of Object.keys(document.meta)) {\n if (![\"id\", \"title\", \"source\", \"createdAt\", \"updatedAt\", \"platform\", \"schemaVersion\", \"custom\"].includes(key)) push(formatJsonPathKey(\"$.meta\", key), `Unknown document metadata property \"${key}\".`, \"unknown_property\");\n }\n for (const key of [\"id\", \"title\", \"source\", \"createdAt\", \"updatedAt\", \"schemaVersion\"] as const) {\n if (document.meta[key] !== undefined && typeof document.meta[key] !== \"string\") push(`$.meta.${key}`, `Document metadata \"${key}\" must be a string.`, \"invalid_meta\");\n }\n if (document.meta.platform !== undefined && document.meta.platform !== \"web\" && document.meta.platform !== \"native\") push(\"$.meta.platform\", 'Document platform must be \"web\" or \"native\".', \"invalid_meta\");\n if (document.meta.custom !== undefined && !isPlainRecord(document.meta.custom)) push(\"$.meta.custom\", \"Custom document metadata must be a plain object.\", \"invalid_meta\");\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n};\n\nexport const isOpenEditorDocument = (value: unknown): value is OpenEditorDocument =>\n validateDocument(value).valid;\n\nexport class OpenEditorDocumentParseError extends Error {\n readonly validation: DocumentValidationResult;\n\n constructor(validation: DocumentValidationResult) {\n super(validation.issues.map((issue) => `${issue.path}: ${issue.message}`).join(\"\\n\"));\n this.name = \"OpenEditorDocumentParseError\";\n this.validation = validation;\n }\n}\n\nexport const parseOpenEditorDocument = (\n value: unknown,\n options: ValidateDocumentOptions = {},\n): OpenEditorDocument => {\n const validation = validateDocument(value, options);\n if (!validation.valid) throw new OpenEditorDocumentParseError(validation);\n return JSON.parse(JSON.stringify(value)) as OpenEditorDocument;\n};\n\n/** Imports unversioned ProseMirror JSON. Versioned values require strict OpenEditor parsing. */\nexport const importProseMirrorDocument = (\n value: unknown,\n meta?: OpenEditorDocumentMeta,\n): OpenEditorDocument => {\n if (isRecord(value) && \"version\" in value) {\n throw new Error(\"Versioned documents must be parsed with parseOpenEditorDocument().\");\n }\n\n const validation = validateDocument(\n isRecord(value) ? { ...value, version: 1 } : value,\n );\n if (!validation.valid) throw new OpenEditorDocumentParseError(validation);\n return fromProseMirrorDocument(value as ProseMirrorDocument, meta);\n};\n\nexport const serializeEditorState = (state: SerializedEditorState): string =>\n JSON.stringify({\n document: normalizeDocument(state.document),\n ...(state.selection ? { selection: state.selection } : {}),\n });\n\nexport const parseEditorState = (\n value: unknown,\n defaultState: SerializedEditorState = createEditorState(createDocument()),\n): SerializedEditorState => {\n let parsed: unknown;\n\n try {\n parsed = typeof value === \"string\" ? JSON.parse(value) : value;\n } catch {\n return defaultState;\n }\n\n if (!isRecord(parsed)) {\n return defaultState;\n }\n\n try {\n return {\n document: parseOpenEditorDocument(parsed.document),\n selection: isRecord(parsed.selection) ? (parsed.selection as EditorSelection) : defaultState.selection,\n };\n } catch {\n return defaultState;\n }\n};\n\nexport const getPlatformDocument = (\n document: OpenEditorDocument,\n registry: BlockRegistry,\n platform: EditorPlatform,\n): OpenEditorDocument => getPlatformSupport(document, registry, platform).document;\n\nexport const getPlatformSupport = (\n document: OpenEditorDocument,\n registry: BlockRegistry,\n platform: EditorPlatform,\n): PlatformSupportResult => {\n const issues: PlatformSupportIssue[] = [];\n\n const mapNode = (node: OpenEditorBlock, path: string): OpenEditorBlock => {\n const spec = findBlockSpecForNode(registry, node);\n const support = spec?.support?.[platform] ?? \"supported\";\n\n if (support !== \"supported\") {\n issues.push({\n path,\n block: spec?.name ?? node.type,\n platform,\n support,\n });\n }\n\n return normalizeNode({\n ...cloneNode(node),\n content: node.content?.map((child, index) => mapNode(child, `${path}.content.${index}`)),\n });\n };\n\n return {\n platform,\n document: createDocument(\n document.content.map((node, index) => mapNode(node, `$.content.${index}`)),\n { ...document.meta, platform },\n ),\n issues,\n };\n};\n\nconst INLINE_NODE_TYPES = new Set([\"text\", \"hardBreak\"]);\n\nexport const getDocumentText = (node: OpenEditorDocument | ProseMirrorNode): string => {\n if (\"text\" in node && typeof node.text === \"string\") {\n return node.text;\n }\n\n const content = \"content\" in node ? node.content : undefined;\n\n if (!content?.length) {\n return \"\";\n }\n\n const isInlineContainer = content.every(\n (child) => INLINE_NODE_TYPES.has(child.type) || child.type === \"link\",\n );\n const joiner = isInlineContainer ? \"\" : \"\\n\";\n return content.map(getDocumentText).filter(Boolean).join(joiner);\n};\n\nexport const applyCommand = (\n document: OpenEditorDocument,\n registry: BlockRegistry,\n command: OpenEditorCommand,\n): OpenEditorDocument => {\n if (command.type === \"setContent\") {\n return normalizeDocument(command.document);\n }\n\n if (command.type === \"setSelection\") {\n return document;\n }\n\n if (command.type === \"moveBlock\") {\n return moveTopLevelBlock(document, command.from, command.to);\n }\n\n if (command.type === \"duplicateBlock\") {\n return duplicateTopLevelBlock(document, command.index);\n }\n\n if (command.type === \"deleteBlock\") {\n return deleteTopLevelBlock(document, command.index);\n }\n\n if (\n command.type === \"setLink\"\n || command.type === \"toggleMark\"\n || command.type === \"undo\"\n || command.type === \"redo\"\n ) {\n return normalizeDocument(document);\n }\n\n const spec = registry.get(command.block);\n if (!spec) {\n throw new Error(`Unknown block \"${command.block}\"`);\n }\n\n const nextContent = [...document.content];\n const index = command.at ?? nextContent.length;\n const defaultNode = spec.defaultNode();\n const node = command.attrs\n ? { ...defaultNode, attrs: { ...defaultNode.attrs, ...command.attrs } }\n : defaultNode;\n\n nextContent.splice(index, 0, node);\n return normalizeDocument(createDocument(nextContent, document.meta));\n};\n\nexport const replaceTopLevelRange = (\n document: OpenEditorDocument,\n start: number,\n length: number,\n replacement: ProseMirrorNode[],\n): OpenEditorDocument =>\n normalizeDocument({\n ...document,\n content: [\n ...document.content.slice(0, start),\n ...replacement.map(cloneNode),\n ...document.content.slice(start + length),\n ],\n });\n\nexport const replaceTopLevelNode = (\n document: OpenEditorDocument,\n index: number,\n replacement: ProseMirrorNode,\n): OpenEditorDocument =>\n normalizeDocument({\n ...document,\n content: document.content.map((node, nodeIndex) => nodeIndex === index ? cloneNode(replacement) : cloneNode(node)),\n });\n\nexport const moveTopLevelBlock = (\n document: OpenEditorDocument,\n from: number,\n to: number,\n): OpenEditorDocument => {\n if (from < 0 || from >= document.content.length || to < 0 || to >= document.content.length || from === to) {\n return normalizeDocument(document);\n }\n\n const nextContent = document.content.map(cloneNode);\n const [item] = nextContent.splice(from, 1);\n if (!item) {\n return normalizeDocument(document);\n }\n\n nextContent.splice(to, 0, item);\n return normalizeDocument({ ...document, content: nextContent });\n};\n\nexport const duplicateTopLevelBlock = (\n document: OpenEditorDocument,\n index: number,\n): OpenEditorDocument => {\n if (index < 0 || index >= document.content.length) {\n return normalizeDocument(document);\n }\n\n const nextContent = document.content.map(cloneNode);\n nextContent.splice(index + 1, 0, cloneNode(document.content[index]));\n return normalizeDocument({ ...document, content: nextContent });\n};\n\nexport const deleteTopLevelBlock = (\n document: OpenEditorDocument,\n index: number,\n emptyBlock: OpenEditorBlock = textBlock(\"paragraph\", \"\"),\n): OpenEditorDocument => {\n if (document.content.length <= 1) {\n return normalizeDocument({ ...document, content: [cloneNode(emptyBlock)] });\n }\n\n if (index < 0 || index >= document.content.length) {\n return normalizeDocument(document);\n }\n\n return normalizeDocument({\n ...document,\n content: document.content.filter((_, currentIndex) => currentIndex !== index).map(cloneNode),\n });\n};\n\nexport const createTransaction = (\n before: OpenEditorDocument,\n after: OpenEditorDocument,\n command?: EditorCommand,\n): EditorTransaction => ({\n before,\n after,\n ...(command ? { command } : {}),\n timestamp: new Date().toISOString(),\n});\n\nexport const openEditorThemeTokenNames = [\n \"surface\", \"surfaceRaised\", \"surfaceMuted\", \"interactionHover\", \"interactionSelected\", \"blockSurface\",\n \"text\", \"textSoft\", \"heading\", \"muted\", \"placeholder\", \"border\", \"borderStrong\", \"structuralLine\",\n \"accent\", \"accentText\", \"accentStrong\", \"buttonBackground\", \"buttonText\", \"codeBackground\", \"codeText\",\n \"link\", \"linkHover\", \"shadow\", \"fontSans\", \"fontMono\", \"radiusSmall\", \"radiusMedium\", \"radiusLarge\",\n \"spaceBlock\", \"spaceInline\", \"bodyFontSize\", \"bodyLineHeight\", \"headingFont\", \"headingLineHeight\",\n \"headingWeight\", \"heading1Size\", \"heading2Size\", \"heading3Size\", \"heading4Size\", \"heading5Size\", \"heading6Size\",\n] as const;\nexport type OpenEditorThemeToken = (typeof openEditorThemeTokenNames)[number];\nexport type OpenEditorTheme = { surfaceRaised: string } & Partial<Record<Exclude<OpenEditorThemeToken, \"surfaceRaised\">, string>>;\nexport const openEditorThemeCssName = (token: OpenEditorThemeToken) =>\n `--oe-${token.replace(/([a-z])([A-Z])/g, \"$1-$2\").replace(/([A-Za-z])(\\d)/g, \"$1-$2\").replace(/(\\d)([A-Z])/g, \"$1-$2\").toLowerCase()}` as const;\nexport const getOpenEditorThemeEntries = (theme: Partial<OpenEditorTheme>): readonly (readonly [string, string])[] =>\n openEditorThemeTokenNames.flatMap((token) => theme[token] === undefined ? [] : [[openEditorThemeCssName(token), theme[token]!] as const]);\n\nexport * from \"./custom-block\";\n"]}
|