react-next-editor-js 0.1.0

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.
Files changed (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +877 -0
  3. package/dist/chunk-3QWXTDLY.cjs +486 -0
  4. package/dist/chunk-3QWXTDLY.cjs.map +1 -0
  5. package/dist/chunk-5F6SPYCN.cjs +180 -0
  6. package/dist/chunk-5F6SPYCN.cjs.map +1 -0
  7. package/dist/chunk-6NTSXJX4.js +174 -0
  8. package/dist/chunk-6NTSXJX4.js.map +1 -0
  9. package/dist/chunk-7VYJDBH7.js +261 -0
  10. package/dist/chunk-7VYJDBH7.js.map +1 -0
  11. package/dist/chunk-DBSFCCBG.cjs +1712 -0
  12. package/dist/chunk-DBSFCCBG.cjs.map +1 -0
  13. package/dist/chunk-EFE6RHDL.cjs +4 -0
  14. package/dist/chunk-EFE6RHDL.cjs.map +1 -0
  15. package/dist/chunk-G6YRIEK4.js +3 -0
  16. package/dist/chunk-G6YRIEK4.js.map +1 -0
  17. package/dist/chunk-GFNFJ3FL.cjs +119 -0
  18. package/dist/chunk-GFNFJ3FL.cjs.map +1 -0
  19. package/dist/chunk-IG2YLUFW.js +114 -0
  20. package/dist/chunk-IG2YLUFW.js.map +1 -0
  21. package/dist/chunk-JQXTWLHL.js +176 -0
  22. package/dist/chunk-JQXTWLHL.js.map +1 -0
  23. package/dist/chunk-NJCEHQV3.cjs +454 -0
  24. package/dist/chunk-NJCEHQV3.cjs.map +1 -0
  25. package/dist/chunk-O4GTLC3T.js +478 -0
  26. package/dist/chunk-O4GTLC3T.js.map +1 -0
  27. package/dist/chunk-ODHABIIC.cjs +82 -0
  28. package/dist/chunk-ODHABIIC.cjs.map +1 -0
  29. package/dist/chunk-PZ5AY32C.js +9 -0
  30. package/dist/chunk-PZ5AY32C.js.map +1 -0
  31. package/dist/chunk-Q7SFCCGT.cjs +11 -0
  32. package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
  33. package/dist/chunk-QIUIYBCZ.js +80 -0
  34. package/dist/chunk-QIUIYBCZ.js.map +1 -0
  35. package/dist/chunk-QROUNVQK.js +450 -0
  36. package/dist/chunk-QROUNVQK.js.map +1 -0
  37. package/dist/chunk-T6FR37IC.js +41 -0
  38. package/dist/chunk-T6FR37IC.js.map +1 -0
  39. package/dist/chunk-TI44I654.cjs +265 -0
  40. package/dist/chunk-TI44I654.cjs.map +1 -0
  41. package/dist/chunk-TXPLBAH5.cjs +47 -0
  42. package/dist/chunk-TXPLBAH5.cjs.map +1 -0
  43. package/dist/chunk-U3O54IYI.cjs +187 -0
  44. package/dist/chunk-U3O54IYI.cjs.map +1 -0
  45. package/dist/chunk-VLC7SZMT.js +1669 -0
  46. package/dist/chunk-VLC7SZMT.js.map +1 -0
  47. package/dist/core/index.cjs +232 -0
  48. package/dist/core/index.cjs.map +1 -0
  49. package/dist/core/index.d.cts +122 -0
  50. package/dist/core/index.d.ts +122 -0
  51. package/dist/core/index.js +7 -0
  52. package/dist/core/index.js.map +1 -0
  53. package/dist/defaults-EQD5QKCU.js +4 -0
  54. package/dist/defaults-EQD5QKCU.js.map +1 -0
  55. package/dist/defaults-MLYXD2BG.cjs +49 -0
  56. package/dist/defaults-MLYXD2BG.cjs.map +1 -0
  57. package/dist/docx-BUrf4PFj.d.ts +49 -0
  58. package/dist/docx-DLfSdvXm.d.cts +49 -0
  59. package/dist/docx-LDETXV3L.js +5 -0
  60. package/dist/docx-LDETXV3L.js.map +1 -0
  61. package/dist/docx-N2LKIOK3.cjs +14 -0
  62. package/dist/docx-N2LKIOK3.cjs.map +1 -0
  63. package/dist/export/index.cjs +54 -0
  64. package/dist/export/index.cjs.map +1 -0
  65. package/dist/export/index.d.cts +60 -0
  66. package/dist/export/index.d.ts +60 -0
  67. package/dist/export/index.js +9 -0
  68. package/dist/export/index.js.map +1 -0
  69. package/dist/html-5BXJPQU3.js +7 -0
  70. package/dist/html-5BXJPQU3.js.map +1 -0
  71. package/dist/html-KU2KHLRF.cjs +24 -0
  72. package/dist/html-KU2KHLRF.cjs.map +1 -0
  73. package/dist/import/index.cjs +15 -0
  74. package/dist/import/index.cjs.map +1 -0
  75. package/dist/import/index.d.cts +37 -0
  76. package/dist/import/index.d.ts +37 -0
  77. package/dist/import/index.js +6 -0
  78. package/dist/import/index.js.map +1 -0
  79. package/dist/index.cjs +1035 -0
  80. package/dist/index.cjs.map +1 -0
  81. package/dist/index.d.cts +248 -0
  82. package/dist/index.d.ts +248 -0
  83. package/dist/index.js +885 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/persistence/index.cjs +37 -0
  86. package/dist/persistence/index.cjs.map +1 -0
  87. package/dist/persistence/index.d.cts +279 -0
  88. package/dist/persistence/index.d.ts +279 -0
  89. package/dist/persistence/index.js +4 -0
  90. package/dist/persistence/index.js.map +1 -0
  91. package/dist/sanitize-7IZ-SW1f.d.ts +361 -0
  92. package/dist/sanitize-CvmgqbsA.d.cts +361 -0
  93. package/dist/server/index.cjs +400 -0
  94. package/dist/server/index.cjs.map +1 -0
  95. package/dist/server/index.d.cts +229 -0
  96. package/dist/server/index.d.ts +229 -0
  97. package/dist/server/index.js +390 -0
  98. package/dist/server/index.js.map +1 -0
  99. package/dist/styles.css +680 -0
  100. package/dist/types-B4z0Quvv.d.cts +193 -0
  101. package/dist/types-B4z0Quvv.d.ts +193 -0
  102. package/package.json +183 -0
@@ -0,0 +1,279 @@
1
+ import { D as DocumentJSON, S as SaveStatus } from '../types-B4z0Quvv.js';
2
+
3
+ /**
4
+ * Persistence and sync adapter interfaces (F-10.12). The editor core knows
5
+ * nothing about REST or IndexedDB; consumers inject implementations of these
6
+ * interfaces so the same editor works against any backend/storage. Default
7
+ * IndexedDB and in-memory implementations ship with the package.
8
+ */
9
+ /** A stored document record: canonical JSON plus sync metadata. */
10
+ interface StoredDocument {
11
+ id: string;
12
+ /** Canonical ProseMirror document JSON (F-8.1, C-5). */
13
+ doc: DocumentJSON;
14
+ /** Monotonic local revision, bumped on every local save. */
15
+ rev: number;
16
+ /** Server-acknowledged version, for optimistic-concurrency conflict checks. */
17
+ baseVersion?: string | number | null;
18
+ /** Whether the record has unsynced local changes. */
19
+ dirty: boolean;
20
+ updatedAt: number;
21
+ /** Arbitrary per-document metadata supplied by the host. */
22
+ metadata?: Record<string, unknown>;
23
+ }
24
+ /** An entry in the durable outbox of documents awaiting upload (F-9.5). */
25
+ interface OutboxEntry {
26
+ id: string;
27
+ rev: number;
28
+ queuedAt: number;
29
+ attempts: number;
30
+ lastError?: string | null;
31
+ nextAttemptAt?: number;
32
+ }
33
+ /**
34
+ * Local, durable document store (F-9.2, NF-9). The default implementation uses
35
+ * IndexedDB; an in-memory implementation is provided for SSR/tests.
36
+ */
37
+ interface LocalStoreAdapter {
38
+ getDocument(id: string): Promise<StoredDocument | null>;
39
+ putDocument(record: StoredDocument): Promise<void>;
40
+ deleteDocument(id: string): Promise<void>;
41
+ listDocuments(): Promise<StoredDocument[]>;
42
+ /** Outbox operations for the sync engine. */
43
+ enqueue(entry: OutboxEntry): Promise<void>;
44
+ dequeue(id: string): Promise<void>;
45
+ listOutbox(): Promise<OutboxEntry[]>;
46
+ /** Binary asset (offline image) operations (F-9.10). */
47
+ putAsset?(key: string, blob: Blob): Promise<void>;
48
+ getAsset?(key: string): Promise<Blob | null>;
49
+ deleteAsset?(key: string): Promise<void>;
50
+ /** Purge all locally persisted data (F-12.7). */
51
+ clear(): Promise<void>;
52
+ }
53
+ /** Result of a remote save, carrying the new server version (NF-10). */
54
+ interface RemoteSaveResult {
55
+ version: string | number;
56
+ /** Optional canonical document returned by the server (e.g. rewritten asset URLs). */
57
+ doc?: DocumentJSON;
58
+ }
59
+ /** Raised by a {@link RemoteSyncAdapter} when a stale write is rejected (F-9.9). */
60
+ declare class ConflictError extends Error {
61
+ readonly remote?: {
62
+ version: string | number;
63
+ doc?: DocumentJSON;
64
+ } | undefined;
65
+ constructor(message: string, remote?: {
66
+ version: string | number;
67
+ doc?: DocumentJSON;
68
+ } | undefined);
69
+ }
70
+ /**
71
+ * Remote document API (F-9.6, F-9.7). Injected by the host using its own auth
72
+ * (F-12.4). Implementations MUST use HTTPS (F-12.3) and SHOULD be idempotent
73
+ * (NF-10). On a version conflict, throw {@link ConflictError}.
74
+ */
75
+ interface RemoteSyncAdapter {
76
+ /** Create or update the document on the server; returns the new version. */
77
+ save(record: StoredDocument, signal?: AbortSignal): Promise<RemoteSaveResult>;
78
+ /** Fetch the latest server copy, or null if it does not exist. */
79
+ fetch?(id: string, signal?: AbortSignal): Promise<StoredDocument | null>;
80
+ /** Best-effort reachability check used for connectivity confirmation (§8.7). */
81
+ ping?(signal?: AbortSignal): Promise<boolean>;
82
+ }
83
+ /** Uploads offline-inserted assets and returns canonical URLs (F-9.10, F-12.5). */
84
+ interface AssetUploadAdapter {
85
+ upload(blob: Blob, meta: {
86
+ filename?: string;
87
+ mime: string;
88
+ }): Promise<{
89
+ url: string;
90
+ }>;
91
+ }
92
+ /** Listener for save/sync status transitions (F-9.4, F-10.15). */
93
+ type SaveStatusListener = (status: SaveStatus, detail?: {
94
+ error?: string;
95
+ }) => void;
96
+
97
+ /**
98
+ * In-memory {@link LocalStoreAdapter}. Used as an SSR-safe fallback when
99
+ * IndexedDB is unavailable and as a test double. Not durable across reloads.
100
+ */
101
+ declare class MemoryStore implements LocalStoreAdapter {
102
+ private docs;
103
+ private outbox;
104
+ private assets;
105
+ getDocument(id: string): Promise<StoredDocument | null>;
106
+ putDocument(record: StoredDocument): Promise<void>;
107
+ deleteDocument(id: string): Promise<void>;
108
+ listDocuments(): Promise<StoredDocument[]>;
109
+ enqueue(entry: OutboxEntry): Promise<void>;
110
+ dequeue(id: string): Promise<void>;
111
+ listOutbox(): Promise<OutboxEntry[]>;
112
+ putAsset(key: string, blob: Blob): Promise<void>;
113
+ getAsset(key: string): Promise<Blob | null>;
114
+ deleteAsset(key: string): Promise<void>;
115
+ clear(): Promise<void>;
116
+ }
117
+
118
+ /**
119
+ * Durable {@link LocalStoreAdapter} backed by IndexedDB (§8.7). `localStorage`
120
+ * is explicitly rejected (too small, synchronous, string-only). Falls back to an
121
+ * in-memory store when IndexedDB is unavailable (SSR, private mode) so the
122
+ * editor never crashes (F-11.1).
123
+ */
124
+ declare class IndexedDBStore implements LocalStoreAdapter {
125
+ private dbName;
126
+ private dbPromise;
127
+ private fallback;
128
+ constructor(dbName?: string);
129
+ /** Whether IndexedDB is usable in the current environment. */
130
+ static isSupported(): boolean;
131
+ private db;
132
+ getDocument(id: string): Promise<StoredDocument | null>;
133
+ putDocument(record: StoredDocument): Promise<void>;
134
+ deleteDocument(id: string): Promise<void>;
135
+ listDocuments(): Promise<StoredDocument[]>;
136
+ enqueue(entry: OutboxEntry): Promise<void>;
137
+ dequeue(id: string): Promise<void>;
138
+ listOutbox(): Promise<OutboxEntry[]>;
139
+ putAsset(key: string, blob: Blob): Promise<void>;
140
+ getAsset(key: string): Promise<Blob | null>;
141
+ deleteAsset(key: string): Promise<void>;
142
+ clear(): Promise<void>;
143
+ }
144
+ /**
145
+ * Request persistent storage to reduce eviction risk for unsynced data (F-9.11).
146
+ * Resolves to whether persistence was granted; never throws.
147
+ */
148
+ declare function requestPersistentStorage(): Promise<boolean>;
149
+
150
+ interface DocumentPersistenceOptions {
151
+ documentId: string;
152
+ store: LocalStoreAdapter;
153
+ /** Debounce window for autosave writes (default 800ms). */
154
+ debounceMs?: number;
155
+ /** Initial metadata to attach to the stored record. */
156
+ metadata?: Record<string, unknown>;
157
+ onStatus?: SaveStatusListener;
158
+ }
159
+ /**
160
+ * Manages local-first persistence for a single document (F-8.x, F-9.2, NF-9):
161
+ * debounced autosave of `doc.toJSON()` to the durable store, dirty-flag and
162
+ * outbox maintenance for later sync, and crash/reload recovery via {@link load}.
163
+ * The local store is the source of truth during editing; the network is never in
164
+ * the critical path (C-7, NF-8).
165
+ */
166
+ declare class DocumentPersistence {
167
+ private readonly id;
168
+ private readonly store;
169
+ private readonly debounceMs;
170
+ private readonly onStatus?;
171
+ private metadata?;
172
+ private current;
173
+ private timer;
174
+ private pending;
175
+ private destroyed;
176
+ private writing;
177
+ constructor(options: DocumentPersistenceOptions);
178
+ private emit;
179
+ /** Load the latest locally-persisted document (crash/reload recovery, F-11.9). */
180
+ load(): Promise<StoredDocument | null>;
181
+ /** The current stored record, if loaded/saved. */
182
+ getRecord(): StoredDocument | null;
183
+ /** Whether there are unsynced local changes. */
184
+ isDirty(): boolean;
185
+ /** Schedule a debounced save of the latest document JSON (F-4.8). */
186
+ scheduleSave(doc: DocumentJSON): void;
187
+ /** Immediately persist any pending document (e.g. on blur/unmount). */
188
+ flush(): Promise<void>;
189
+ /**
190
+ * Persist a document to the local store, atomically bump the revision, mark it
191
+ * dirty and enqueue it in the outbox for later upload. Writes are serialized to
192
+ * avoid partial saves (NF-9).
193
+ */
194
+ saveNow(doc: DocumentJSON): Promise<StoredDocument>;
195
+ private makeRecord;
196
+ /** Mark the document as synced after a successful remote save (NF-10). */
197
+ markSynced(version: string | number, serverDoc?: DocumentJSON): Promise<void>;
198
+ /** Purge this document's locally-persisted data and outbox entry (F-12.7). */
199
+ clearLocal(): Promise<void>;
200
+ /** Stop the autosave timer and flush pending work. */
201
+ destroy(): Promise<void>;
202
+ }
203
+
204
+ /**
205
+ * Connectivity detection (§8.7). Listens to `online`/`offline` events but does
206
+ * NOT trust `navigator.onLine` alone (it reports interface presence, not API
207
+ * reachability); when a `ping` is provided, real reachability is confirmed
208
+ * before reporting "online". Safe to construct in any environment.
209
+ */
210
+ interface ConnectivityOptions {
211
+ /** Confirms real API reachability (e.g. a HEAD to the data API). */
212
+ ping?: (signal?: AbortSignal) => Promise<boolean>;
213
+ /** Polling interval in ms while running (default 30s). 0 disables polling. */
214
+ intervalMs?: number;
215
+ onChange?: (online: boolean) => void;
216
+ }
217
+ declare class ConnectivityMonitor {
218
+ private readonly ping?;
219
+ private readonly intervalMs;
220
+ private readonly onChange?;
221
+ private online;
222
+ private timer;
223
+ private started;
224
+ constructor(options?: ConnectivityOptions);
225
+ isOnline(): boolean;
226
+ private readonly handleOnline;
227
+ private readonly handleOffline;
228
+ start(): void;
229
+ stop(): void;
230
+ /** Re-evaluate connectivity now, confirming reachability via ping when set. */
231
+ check(): Promise<boolean>;
232
+ private set;
233
+ }
234
+
235
+ interface SyncEngineOptions {
236
+ store: LocalStoreAdapter;
237
+ remote: RemoteSyncAdapter;
238
+ /** Max upload attempts before a document is parked for manual retry (default 6). */
239
+ maxAttempts?: number;
240
+ /** Base backoff delay in ms (default 1000). Doubles per attempt, capped at 5min. */
241
+ baseDelayMs?: number;
242
+ onStatus?: SaveStatusListener;
243
+ /** Invoked when a version conflict is detected (F-9.9). */
244
+ onConflict?: (local: StoredDocument, remote?: {
245
+ version: string | number;
246
+ }) => void;
247
+ }
248
+ /**
249
+ * Flushes the durable outbox to the REST API on demand/reconnect (F-9.6–F-9.8).
250
+ * Idempotent uploads, exponential backoff on transient failure, and a
251
+ * version-guard conflict path (G-2 default). Edits are never lost: a document
252
+ * stays dirty and queued until the server confirms it.
253
+ */
254
+ declare class SyncEngine {
255
+ private readonly store;
256
+ private readonly remote;
257
+ private readonly maxAttempts;
258
+ private readonly baseDelayMs;
259
+ private readonly onStatus?;
260
+ private readonly onConflict?;
261
+ private flushing;
262
+ private abortController;
263
+ constructor(options: SyncEngineOptions);
264
+ private emit;
265
+ /**
266
+ * Process every queued document once. Re-entrancy-safe: concurrent calls are
267
+ * coalesced. Returns the number of documents successfully synced.
268
+ */
269
+ flush(): Promise<number>;
270
+ /** Abort an in-flight flush (e.g. on going offline or unmount). */
271
+ cancel(): void;
272
+ /**
273
+ * Re-queue a parked/conflicted document for another attempt (used by a
274
+ * host-defined conflict resolution flow after the user chooses to overwrite).
275
+ */
276
+ retry(id: string, baseVersion?: string | number | null): Promise<void>;
277
+ }
278
+
279
+ export { type AssetUploadAdapter, ConflictError, ConnectivityMonitor, type ConnectivityOptions, DocumentPersistence, type DocumentPersistenceOptions, IndexedDBStore, type LocalStoreAdapter, MemoryStore, type OutboxEntry, type RemoteSaveResult, type RemoteSyncAdapter, type SaveStatusListener, type StoredDocument, SyncEngine, type SyncEngineOptions, requestPersistentStorage };
@@ -0,0 +1,4 @@
1
+ export { ConflictError, ConnectivityMonitor, DocumentPersistence, IndexedDBStore, MemoryStore, SyncEngine, requestPersistentStorage } from '../chunk-O4GTLC3T.js';
2
+ import '../chunk-PZ5AY32C.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,361 @@
1
+ import { Schema, Node, MarkType, Attrs, NodeType } from 'prosemirror-model';
2
+ import { F as FeatureFlags, D as DocumentJSON, P as PageConfig, a as EditorStrings, d as ToolbarItemId, b as PageSize, T as ThemeTokens } from './types-B4z0Quvv.js';
3
+ import * as prosemirror_state from 'prosemirror-state';
4
+ import { Command, EditorState, PluginKey, Plugin, Transaction } from 'prosemirror-state';
5
+ import { DecorationSet } from 'prosemirror-view';
6
+
7
+ /**
8
+ * Build a ProseMirror {@link Schema} from a set of enabled features. The schema
9
+ * is the backbone of the editor (NF-7): nodes/marks, commands, persistence and
10
+ * the serializers all derive from it. Disabled features are omitted so an
11
+ * invalid or unsupported document is structurally impossible (F-11.5).
12
+ *
13
+ * Core nodes (`doc`, `paragraph`, `text`, `hard_break`) are always present.
14
+ */
15
+ declare function buildSchema(features?: Partial<FeatureFlags>): Schema;
16
+ /** A schema with all features enabled — convenient for tests and full editors. */
17
+ declare const defaultSchema: Schema;
18
+
19
+ /** Permitted text-alignment values. `null` means "inherit / default (left in LTR)". */
20
+ type TextAlign = 'left' | 'center' | 'right' | 'justify' | null;
21
+ /** Maximum indent levels, to bound the document and prevent runaway nesting. */
22
+ declare const MAX_INDENT = 12;
23
+ /** Indent step in em units, applied as `margin-left`. */
24
+ declare const INDENT_STEP_EM = 3;
25
+ /**
26
+ * Shared block attributes for paragraph and heading nodes: text alignment,
27
+ * indentation level, and line height. Validity is enforced here so the document
28
+ * can never hold an out-of-range value (F-11.5).
29
+ */
30
+ declare const blockAttrs: {
31
+ align: {
32
+ default: TextAlign;
33
+ };
34
+ indent: {
35
+ default: number;
36
+ };
37
+ lineHeight: {
38
+ default: number | null;
39
+ };
40
+ };
41
+ /** Read block attributes from a DOM element during paste/parse. */
42
+ declare function readBlockAttrs(dom: HTMLElement): {
43
+ align: TextAlign;
44
+ indent: number;
45
+ lineHeight: number | null;
46
+ };
47
+ /** Build the DOM attribute object (style/class) for a block node's attributes. */
48
+ declare function blockDOMAttrs(node: Node, extra?: Record<string, string>): Record<string, string>;
49
+ /** Clamp an indent value into the valid range. */
50
+ declare function clampIndent(value: number): number;
51
+ /** Type guard for a valid alignment value. */
52
+ declare function isTextAlign(value: unknown): value is Exclude<TextAlign, null>;
53
+
54
+ /**
55
+ * A toolbar-aware command: the ProseMirror {@link Command} to dispatch plus
56
+ * optional predicates the toolbar uses to reflect active and enabled state
57
+ * (F-10.6, NF-4).
58
+ */
59
+ interface EditorCommand {
60
+ run: Command;
61
+ /** Whether the command's formatting is currently applied to the selection. */
62
+ isActive?: (state: EditorState) => boolean;
63
+ /** Whether the command can currently run. Defaults to `run(state)` (dry run). */
64
+ isEnabled?: (state: EditorState) => boolean;
65
+ }
66
+ /** Determine whether a mark is active across the current selection. */
67
+ declare function isMarkActive(state: EditorState, type: MarkType): boolean;
68
+ /** Return the attributes of an active mark, or null if not present. */
69
+ declare function getActiveMarkAttrs(state: EditorState, type: MarkType): Attrs | null;
70
+ /**
71
+ * Whether every selected top-level block is of `type` (optionally matching the
72
+ * given attributes). Used to reflect heading/alignment/list active state.
73
+ */
74
+ declare function isBlockActive(state: EditorState, type: NodeType, attrs?: Record<string, unknown>): boolean;
75
+ /** Whether an ancestor of the selection is of the given node type. */
76
+ declare function isInNode(state: EditorState, type: NodeType): boolean;
77
+ /** Default enabled-check: run the command without a dispatch function. */
78
+ declare function defaultEnabled(run: Command): (state: EditorState) => boolean;
79
+
80
+ /**
81
+ * Apply a mark (with attributes) across the selection, replacing any existing
82
+ * mark of the same type. For an empty selection the mark is stored for the next
83
+ * typed input. Used by attribute marks (font, size, color, highlight).
84
+ */
85
+ declare function setMark(type: MarkType, attrs?: Record<string, unknown>): Command;
86
+ /** Remove a mark from the selection (and from stored marks when empty). */
87
+ declare function unsetMark(type: MarkType): Command;
88
+ /** Parametric mark commands (need a runtime value from the UI). */
89
+ declare function createParametricMarkCommands(schema: Schema): {
90
+ setFontFamily: (family: string) => Command;
91
+ clearFontFamily: () => Command;
92
+ setFontSize: (size: number) => Command;
93
+ clearFontSize: () => Command;
94
+ setTextColor: (color: string) => Command;
95
+ clearTextColor: () => Command;
96
+ setHighlight: (color: string) => Command;
97
+ clearHighlight: () => Command;
98
+ getActiveFontFamily: (state: Parameters<typeof getActiveMarkAttrs>[0]) => string | null;
99
+ getActiveFontSize: (state: Parameters<typeof getActiveMarkAttrs>[0]) => number | null;
100
+ getActiveTextColor: (state: Parameters<typeof getActiveMarkAttrs>[0]) => string | null;
101
+ };
102
+
103
+ /** Set an attribute on every textblock in the selection that supports it. */
104
+ declare function setTextblockAttr(attr: string, value: unknown): Command;
105
+ /** Whether every selected textblock has the given attribute value. */
106
+ declare function isTextblockAttrActive(state: EditorState, attr: string, value: unknown): boolean;
107
+ /** Shift indentation of selected textblocks by `delta`, clamped to valid range. */
108
+ declare function changeIndent(delta: number): Command;
109
+ /** Parametric block commands needing a runtime value. */
110
+ declare function createParametricBlockCommands(schema: Schema): {
111
+ setParagraph: () => Command;
112
+ setHeading: (level: number) => Command;
113
+ setAlign: (align: Exclude<TextAlign, null>) => Command;
114
+ setLineHeight: (lineHeight: number | null) => Command;
115
+ };
116
+
117
+ interface LinkAttrs {
118
+ href: string;
119
+ title?: string | null;
120
+ target?: string;
121
+ }
122
+ /** Apply or update a link over the selection (or insert the URL as linked text). */
123
+ declare function setLink(type: MarkType, attrs: LinkAttrs): Command;
124
+ /** Remove the link mark, expanding an empty selection to the full link range. */
125
+ declare function removeLink(type: MarkType): Command;
126
+ declare function createLinkCommands(schema: Schema): {
127
+ commands: Record<string, EditorCommand>;
128
+ setLink: (_attrs: LinkAttrs) => Command;
129
+ removeLink: Command;
130
+ getActiveLink: (_state: EditorState) => LinkAttrs | null;
131
+ isLinkActive: (_state: EditorState) => boolean;
132
+ };
133
+
134
+ interface ImageAttrs {
135
+ src: string;
136
+ alt?: string | null;
137
+ title?: string | null;
138
+ width?: number | null;
139
+ }
140
+ /** Insert an inline image at the selection, after validating the source. */
141
+ declare function insertImage(schema: Schema, attrs: ImageAttrs): Command;
142
+ /** Build a `rows × cols` table node, optionally with a header row. */
143
+ declare function createTableNode(schema: Schema, rows: number, cols: number, withHeaderRow: boolean): Node | null;
144
+ /** Insert a table at the selection. */
145
+ declare function insertTable(schema: Schema, rows?: number, cols?: number, withHeaderRow?: boolean): Command;
146
+
147
+ /** The full set of commands derived from a schema, ready for toolbar/keymap use. */
148
+ interface CommandSet {
149
+ /** Static, parameter-free commands keyed by toolbar item id. */
150
+ registry: Record<string, EditorCommand>;
151
+ /** Parametric mark commands (font family/size, colors). */
152
+ marks: ReturnType<typeof createParametricMarkCommands>;
153
+ /** Parametric block commands (heading level, alignment, line height). */
154
+ blocks: ReturnType<typeof createParametricBlockCommands>;
155
+ /** Link commands (set/remove/inspect). */
156
+ links: ReturnType<typeof createLinkCommands>;
157
+ /** Insert helpers needing arguments. */
158
+ insert: {
159
+ image: (attrs: ImageAttrs) => ReturnType<typeof insertImage>;
160
+ table: (rows?: number, cols?: number, withHeaderRow?: boolean) => ReturnType<typeof insertTable>;
161
+ };
162
+ }
163
+ /**
164
+ * Assemble every command for a schema. Commands whose feature is disabled are
165
+ * omitted from the registry, so the toolbar and keymap reference only what the
166
+ * document can actually contain.
167
+ */
168
+ declare function createCommands(schema: Schema): CommandSet;
169
+ /** Generic editing commands occasionally useful to consumers. */
170
+ declare const editingCommands: {
171
+ selectAll: prosemirror_state.Command;
172
+ selectParentNode: prosemirror_state.Command;
173
+ deleteSelection: prosemirror_state.Command;
174
+ joinBackward: prosemirror_state.Command;
175
+ joinForward: prosemirror_state.Command;
176
+ };
177
+
178
+ interface PageBreak {
179
+ /** Position before the unit that starts the new page. */
180
+ pos: number;
181
+ /** Height of the spacer widget to insert before that unit (px). */
182
+ spacerHeight: number;
183
+ /** 0-based index of the page this break begins. */
184
+ pageIndex: number;
185
+ /** True when the break falls inside a block (between lines) rather than at a block boundary. */
186
+ inline: boolean;
187
+ }
188
+ interface PaginationResult {
189
+ breaks: PageBreak[];
190
+ pageCount: number;
191
+ /** Rendered Y (px) where each page's content begins (page 0 at 0). */
192
+ pageContentTops: number[];
193
+ }
194
+
195
+ /**
196
+ * Visual pagination plugin (F-5.3–F-5.5). Measures the document's top-level
197
+ * blocks, computes page breaks at block boundaries, inserts transparent spacer
198
+ * widget decorations so content visually flows across discrete page sheets, and
199
+ * imperatively renders the page-sheet background layer with repeating
200
+ * headers/footers and live page numbers.
201
+ *
202
+ * It NEVER mutates the document — pagination is purely visual (widget
203
+ * decorations + a sibling background layer). All measurement is wrapped so a
204
+ * failure degrades gracefully to single-flow rendering (F-11.1).
205
+ */
206
+ declare const paginationKey: PluginKey<PaginationPluginState>;
207
+ /** Concrete pixel geometry for the current page configuration. */
208
+ interface PaginationGeometry {
209
+ pageWidthPx: number;
210
+ pageHeightPx: number;
211
+ marginTopPx: number;
212
+ marginBottomPx: number;
213
+ marginLeftPx: number;
214
+ contentWidthPx: number;
215
+ /** Usable content height per page (page height − top/bottom margins). */
216
+ contentHeightPx: number;
217
+ /** bottom margin + page gap + top margin. */
218
+ interPageOffsetPx: number;
219
+ }
220
+ interface PaginationRunningElement {
221
+ show?: boolean;
222
+ /** Static text; `{page}` and `{pages}` are replaced with the live numbers. */
223
+ text?: string;
224
+ /** Horizontal alignment within the content width. Default: header left, footer center. */
225
+ align?: 'left' | 'center' | 'right';
226
+ }
227
+ interface PaginationOptions {
228
+ /** Returns the current pixel geometry, or null to disable pagination. */
229
+ getGeometry: () => PaginationGeometry | null;
230
+ /** Returns the background-layer element the plugin renders sheets into. */
231
+ getBackgroundLayer: () => HTMLElement | null;
232
+ header?: PaginationRunningElement;
233
+ footer?: PaginationRunningElement & {
234
+ pageNumbers?: boolean;
235
+ };
236
+ /** Called when the page count changes. */
237
+ onPageCount?: (count: number) => void;
238
+ /**
239
+ * Receives a `requestMeasure` callback the consumer can invoke to force a
240
+ * re-measure (e.g. after changing page geometry at runtime).
241
+ */
242
+ register?: (requestMeasure: () => void) => void;
243
+ }
244
+ interface PaginationPluginState {
245
+ result: PaginationResult | null;
246
+ decorations: DecorationSet;
247
+ }
248
+ declare function paginationPlugin(options: PaginationOptions): Plugin<PaginationPluginState>;
249
+
250
+ interface BuildPluginsOptions {
251
+ /** Placeholder text shown when the document is empty. */
252
+ placeholder?: string;
253
+ /** Enable undo/redo history (default true). */
254
+ history?: boolean;
255
+ /** Additional plugins appended after the built-ins (extension API). */
256
+ extraPlugins?: Plugin[];
257
+ /** Visual pagination options. When provided, the pagination plugin is added. */
258
+ pagination?: PaginationOptions;
259
+ /**
260
+ * Optional hook invoked for every dispatched transaction (used by the React
261
+ * layer to surface change/selection events without re-rendering the surface).
262
+ */
263
+ appendTransaction?: (transactions: readonly Transaction[], oldState: EditorState, newState: EditorState) => Transaction | null | undefined;
264
+ }
265
+ /**
266
+ * Assemble the full plugin stack for a schema. The stack is feature-aware: table
267
+ * and history plugins are only added when supported. The order places input
268
+ * rules and keymaps first, structural helpers next, and table editing last.
269
+ */
270
+ declare function buildPlugins(schema: Schema, options?: BuildPluginsOptions): Plugin[];
271
+
272
+ type EditorContent = DocumentJSON | string | null | undefined;
273
+ /**
274
+ * Build a document node from arbitrary initial content, defensively (F-11.4):
275
+ * - `null`/`undefined` → an empty document;
276
+ * - a string → paragraphs split on newlines (plain-text initial content);
277
+ * - ProseMirror JSON → parsed and integrity-checked, falling back to empty on
278
+ * any error so malformed input can never crash the editor.
279
+ */
280
+ declare function createDoc(schema: Schema, content: EditorContent): Node;
281
+ interface CreateEditorStateOptions {
282
+ schema: Schema;
283
+ plugins: Plugin[];
284
+ content?: EditorContent;
285
+ }
286
+ /** Construct the initial {@link EditorState} for the editor. */
287
+ declare function createEditorState(options: CreateEditorStateOptions): EditorState;
288
+
289
+ interface DocumentStats {
290
+ words: number;
291
+ characters: number;
292
+ charactersNoSpaces: number;
293
+ }
294
+ /**
295
+ * Compute word and character counts for a document (F-4.5). Walks text nodes
296
+ * directly — cheap and lean for large documents (NF-1).
297
+ */
298
+ declare function countDocument(doc: Node): DocumentStats;
299
+
300
+ /** All features enabled by default; integrations opt out per instance. */
301
+ declare const DEFAULT_FEATURES: FeatureFlags;
302
+ /** Physical page dimensions in millimetres for the supported standard sizes. */
303
+ declare const PAGE_DIMENSIONS_MM: Record<Exclude<PageSize, 'custom'>, {
304
+ width: number;
305
+ height: number;
306
+ }>;
307
+ declare const DEFAULT_PAGE: PageConfig;
308
+ /** Resolve a {@link PageConfig} to concrete content-box dimensions in millimetres. */
309
+ declare function resolvePageDimensions(page: PageConfig): {
310
+ width: number;
311
+ height: number;
312
+ };
313
+ /** Default English UI strings (NF-6: externalized for localization). */
314
+ declare const DEFAULT_STRINGS: EditorStrings;
315
+ /** Font families offered by the font picker. Consumers can override via config. */
316
+ declare const DEFAULT_FONT_FAMILIES: string[];
317
+ /** Font sizes (pt) offered by the size picker. */
318
+ declare const DEFAULT_FONT_SIZES: number[];
319
+ /** A palette of colors offered by the color/highlight pickers. */
320
+ declare const DEFAULT_COLOR_PALETTE: string[];
321
+ /** Default toolbar layout, grouped. Filtered by enabled features at render time. */
322
+ declare const DEFAULT_TOOLBAR_GROUPS: ToolbarItemId[][];
323
+ /** Map a {@link ThemeTokens} object to a CSS custom-property style record. */
324
+ declare function themeToCssVars(theme: ThemeTokens | undefined): Record<string, string>;
325
+
326
+ /**
327
+ * Security primitives (§5.12). These functions are the single ingress point for
328
+ * untrusted content: pasted/imported HTML, link and image URLs. They are
329
+ * dependency-light and (for URLs) DOM-free so the schema can be imported in
330
+ * Node for export/tests without pulling a DOM library.
331
+ */
332
+ /**
333
+ * Validate and normalize a hyperlink URL. Returns the cleaned URL, or `null` if
334
+ * the URL is missing or uses an unsafe scheme (e.g. `javascript:`). Relative and
335
+ * fragment/anchor URLs are allowed (F-12.2, F-12.5).
336
+ */
337
+ declare function sanitizeUrl(raw: string | null | undefined): string | null;
338
+ /**
339
+ * Validate an image source. Accepts http(s)/blob URLs and `data:image/*` URIs,
340
+ * rejecting SVG data URIs and any active-content scheme (F-12.5).
341
+ */
342
+ declare function sanitizeImageSrc(raw: string | null | undefined): string | null;
343
+ /**
344
+ * Preload the DOM sanitizer so a later synchronous paste can be cleaned without
345
+ * waiting. Safe to call in the browser on editor mount. No-op in Node.
346
+ */
347
+ declare function preloadSanitizer(): Promise<void>;
348
+ /**
349
+ * Sanitize an HTML string synchronously, best-effort: uses the cached DOM
350
+ * sanitizer if it has been loaded, otherwise applies {@link basicScrubHtml} as a
351
+ * fallback. Use for the paste transform (which must be synchronous).
352
+ */
353
+ declare function sanitizeHtmlSync(html: string): string;
354
+ /**
355
+ * Sanitize an HTML string for safe parsing into the editor. No script, inline
356
+ * event handlers, or active content survives (F-12.1, F-12.2). When no DOM
357
+ * sanitizer is available a regex scrub is applied as a fallback.
358
+ */
359
+ declare function sanitizeHtml(html: string): Promise<string>;
360
+
361
+ export { setLink as $, getActiveMarkAttrs as A, type BuildPluginsOptions as B, type CommandSet as C, DEFAULT_COLOR_PALETTE as D, type EditorCommand as E, insertImage as F, insertTable as G, isBlockActive as H, INDENT_STEP_EM as I, isInNode as J, isMarkActive as K, type LinkAttrs as L, MAX_INDENT as M, isTextAlign as N, isTextblockAttrActive as O, PAGE_DIMENSIONS_MM as P, paginationKey as Q, paginationPlugin as R, preloadSanitizer as S, type TextAlign as T, readBlockAttrs as U, removeLink as V, resolvePageDimensions as W, sanitizeHtml as X, sanitizeHtmlSync as Y, sanitizeImageSrc as Z, sanitizeUrl as _, type CreateEditorStateOptions as a, setMark as a0, setTextblockAttr as a1, themeToCssVars as a2, unsetMark as a3, DEFAULT_FEATURES as b, DEFAULT_FONT_FAMILIES as c, DEFAULT_FONT_SIZES as d, DEFAULT_PAGE as e, DEFAULT_STRINGS as f, DEFAULT_TOOLBAR_GROUPS as g, type DocumentStats as h, type EditorContent as i, type ImageAttrs as j, type PaginationGeometry as k, type PaginationOptions as l, blockAttrs as m, blockDOMAttrs as n, buildPlugins as o, buildSchema as p, changeIndent as q, clampIndent as r, countDocument as s, createCommands as t, createDoc as u, createEditorState as v, createTableNode as w, defaultEnabled as x, defaultSchema as y, editingCommands as z };