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,478 @@
1
+ import { openDB } from 'idb';
2
+
3
+ // src/persistence/types.ts
4
+ var ConflictError = class extends Error {
5
+ constructor(message, remote) {
6
+ super(message);
7
+ this.remote = remote;
8
+ this.name = "ConflictError";
9
+ }
10
+ };
11
+
12
+ // src/persistence/memory.ts
13
+ var MemoryStore = class {
14
+ constructor() {
15
+ this.docs = /* @__PURE__ */ new Map();
16
+ this.outbox = /* @__PURE__ */ new Map();
17
+ this.assets = /* @__PURE__ */ new Map();
18
+ }
19
+ async getDocument(id) {
20
+ return this.docs.get(id) ?? null;
21
+ }
22
+ async putDocument(record) {
23
+ this.docs.set(record.id, structuredCloneSafe(record));
24
+ }
25
+ async deleteDocument(id) {
26
+ this.docs.delete(id);
27
+ }
28
+ async listDocuments() {
29
+ return [...this.docs.values()];
30
+ }
31
+ async enqueue(entry) {
32
+ this.outbox.set(entry.id, { ...entry });
33
+ }
34
+ async dequeue(id) {
35
+ this.outbox.delete(id);
36
+ }
37
+ async listOutbox() {
38
+ return [...this.outbox.values()];
39
+ }
40
+ async putAsset(key, blob) {
41
+ this.assets.set(key, blob);
42
+ }
43
+ async getAsset(key) {
44
+ return this.assets.get(key) ?? null;
45
+ }
46
+ async deleteAsset(key) {
47
+ this.assets.delete(key);
48
+ }
49
+ async clear() {
50
+ this.docs.clear();
51
+ this.outbox.clear();
52
+ this.assets.clear();
53
+ }
54
+ };
55
+ function structuredCloneSafe(value) {
56
+ if (typeof structuredClone === "function") {
57
+ try {
58
+ return structuredClone(value);
59
+ } catch {
60
+ }
61
+ }
62
+ return JSON.parse(JSON.stringify(value));
63
+ }
64
+ var DB_VERSION = 1;
65
+ var STORE_DOCS = "documents";
66
+ var STORE_OUTBOX = "outbox";
67
+ var STORE_ASSETS = "assets";
68
+ var IndexedDBStore = class _IndexedDBStore {
69
+ constructor(dbName = "react-next-editor") {
70
+ this.dbPromise = null;
71
+ this.fallback = null;
72
+ this.dbName = dbName;
73
+ }
74
+ /** Whether IndexedDB is usable in the current environment. */
75
+ static isSupported() {
76
+ return typeof indexedDB !== "undefined";
77
+ }
78
+ async db() {
79
+ if (!_IndexedDBStore.isSupported()) {
80
+ if (!this.fallback) this.fallback = new MemoryStore();
81
+ return null;
82
+ }
83
+ if (!this.dbPromise) {
84
+ this.dbPromise = openDB(this.dbName, DB_VERSION, {
85
+ upgrade(db) {
86
+ if (!db.objectStoreNames.contains(STORE_DOCS)) {
87
+ db.createObjectStore(STORE_DOCS, { keyPath: "id" });
88
+ }
89
+ if (!db.objectStoreNames.contains(STORE_OUTBOX)) {
90
+ db.createObjectStore(STORE_OUTBOX, { keyPath: "id" });
91
+ }
92
+ if (!db.objectStoreNames.contains(STORE_ASSETS)) {
93
+ db.createObjectStore(STORE_ASSETS);
94
+ }
95
+ }
96
+ }).catch((err) => {
97
+ console.error("[react-next-editor] IndexedDB unavailable, using memory store.", err);
98
+ this.fallback = new MemoryStore();
99
+ throw err;
100
+ });
101
+ }
102
+ try {
103
+ return await this.dbPromise;
104
+ } catch {
105
+ return null;
106
+ }
107
+ }
108
+ async getDocument(id) {
109
+ const db = await this.db();
110
+ if (!db) return this.fallback.getDocument(id);
111
+ return await db.get(STORE_DOCS, id) ?? null;
112
+ }
113
+ async putDocument(record) {
114
+ const db = await this.db();
115
+ if (!db) return this.fallback.putDocument(record);
116
+ await db.put(STORE_DOCS, record);
117
+ }
118
+ async deleteDocument(id) {
119
+ const db = await this.db();
120
+ if (!db) return this.fallback.deleteDocument(id);
121
+ await db.delete(STORE_DOCS, id);
122
+ }
123
+ async listDocuments() {
124
+ const db = await this.db();
125
+ if (!db) return this.fallback.listDocuments();
126
+ return db.getAll(STORE_DOCS);
127
+ }
128
+ async enqueue(entry) {
129
+ const db = await this.db();
130
+ if (!db) return this.fallback.enqueue(entry);
131
+ await db.put(STORE_OUTBOX, entry);
132
+ }
133
+ async dequeue(id) {
134
+ const db = await this.db();
135
+ if (!db) return this.fallback.dequeue(id);
136
+ await db.delete(STORE_OUTBOX, id);
137
+ }
138
+ async listOutbox() {
139
+ const db = await this.db();
140
+ if (!db) return this.fallback.listOutbox();
141
+ return db.getAll(STORE_OUTBOX);
142
+ }
143
+ async putAsset(key, blob) {
144
+ const db = await this.db();
145
+ if (!db) return this.fallback.putAsset(key, blob);
146
+ await db.put(STORE_ASSETS, blob, key);
147
+ }
148
+ async getAsset(key) {
149
+ const db = await this.db();
150
+ if (!db) return this.fallback.getAsset(key);
151
+ return await db.get(STORE_ASSETS, key) ?? null;
152
+ }
153
+ async deleteAsset(key) {
154
+ const db = await this.db();
155
+ if (!db) return this.fallback.deleteAsset(key);
156
+ await db.delete(STORE_ASSETS, key);
157
+ }
158
+ async clear() {
159
+ const db = await this.db();
160
+ if (!db) return this.fallback.clear();
161
+ await Promise.all([
162
+ db.clear(STORE_DOCS),
163
+ db.clear(STORE_OUTBOX),
164
+ db.clear(STORE_ASSETS)
165
+ ]);
166
+ }
167
+ };
168
+ async function requestPersistentStorage() {
169
+ try {
170
+ if (typeof navigator !== "undefined" && navigator.storage?.persist) {
171
+ return await navigator.storage.persist();
172
+ }
173
+ } catch {
174
+ }
175
+ return false;
176
+ }
177
+
178
+ // src/persistence/autosave.ts
179
+ var DocumentPersistence = class {
180
+ constructor(options) {
181
+ this.current = null;
182
+ this.timer = null;
183
+ this.pending = null;
184
+ this.destroyed = false;
185
+ this.writing = false;
186
+ this.id = options.documentId;
187
+ this.store = options.store;
188
+ this.debounceMs = options.debounceMs ?? 800;
189
+ this.onStatus = options.onStatus;
190
+ this.metadata = options.metadata;
191
+ }
192
+ emit(status, detail) {
193
+ this.onStatus?.(status, detail);
194
+ }
195
+ /** Load the latest locally-persisted document (crash/reload recovery, F-11.9). */
196
+ async load() {
197
+ const record = await this.store.getDocument(this.id);
198
+ this.current = record;
199
+ return record;
200
+ }
201
+ /** The current stored record, if loaded/saved. */
202
+ getRecord() {
203
+ return this.current;
204
+ }
205
+ /** Whether there are unsynced local changes. */
206
+ isDirty() {
207
+ return this.current?.dirty ?? false;
208
+ }
209
+ /** Schedule a debounced save of the latest document JSON (F-4.8). */
210
+ scheduleSave(doc) {
211
+ if (this.destroyed) return;
212
+ this.pending = doc;
213
+ this.emit("savingLocal");
214
+ if (this.timer) clearTimeout(this.timer);
215
+ this.timer = setTimeout(() => {
216
+ void this.flush();
217
+ }, this.debounceMs);
218
+ }
219
+ /** Immediately persist any pending document (e.g. on blur/unmount). */
220
+ async flush() {
221
+ if (this.timer) {
222
+ clearTimeout(this.timer);
223
+ this.timer = null;
224
+ }
225
+ if (this.pending == null) return;
226
+ const doc = this.pending;
227
+ this.pending = null;
228
+ await this.saveNow(doc);
229
+ }
230
+ /**
231
+ * Persist a document to the local store, atomically bump the revision, mark it
232
+ * dirty and enqueue it in the outbox for later upload. Writes are serialized to
233
+ * avoid partial saves (NF-9).
234
+ */
235
+ async saveNow(doc) {
236
+ if (this.writing) {
237
+ this.pending = doc;
238
+ return this.current ?? this.makeRecord(doc);
239
+ }
240
+ this.writing = true;
241
+ try {
242
+ const record = this.makeRecord(doc);
243
+ await this.store.putDocument(record);
244
+ await this.store.enqueue({
245
+ id: this.id,
246
+ rev: record.rev,
247
+ queuedAt: record.updatedAt,
248
+ attempts: 0
249
+ });
250
+ this.current = record;
251
+ this.emit("savedLocal");
252
+ return record;
253
+ } catch (err) {
254
+ this.emit("syncFailed", { error: err?.message });
255
+ throw err;
256
+ } finally {
257
+ this.writing = false;
258
+ if (this.pending != null) {
259
+ const next = this.pending;
260
+ this.pending = null;
261
+ await this.saveNow(next);
262
+ }
263
+ }
264
+ }
265
+ makeRecord(doc) {
266
+ const prev = this.current;
267
+ return {
268
+ id: this.id,
269
+ doc,
270
+ rev: (prev?.rev ?? 0) + 1,
271
+ baseVersion: prev?.baseVersion ?? null,
272
+ dirty: true,
273
+ updatedAt: Date.now(),
274
+ metadata: this.metadata ?? prev?.metadata
275
+ };
276
+ }
277
+ /** Mark the document as synced after a successful remote save (NF-10). */
278
+ async markSynced(version, serverDoc) {
279
+ if (!this.current) return;
280
+ const record = {
281
+ ...this.current,
282
+ doc: serverDoc ?? this.current.doc,
283
+ baseVersion: version,
284
+ dirty: false
285
+ };
286
+ await this.store.putDocument(record);
287
+ await this.store.dequeue(this.id);
288
+ this.current = record;
289
+ this.emit("synced");
290
+ }
291
+ /** Purge this document's locally-persisted data and outbox entry (F-12.7). */
292
+ async clearLocal() {
293
+ await this.store.deleteDocument(this.id);
294
+ await this.store.dequeue(this.id);
295
+ this.current = null;
296
+ }
297
+ /** Stop the autosave timer and flush pending work. */
298
+ async destroy() {
299
+ this.destroyed = true;
300
+ await this.flush();
301
+ }
302
+ };
303
+
304
+ // src/sync/connectivity.ts
305
+ var ConnectivityMonitor = class {
306
+ constructor(options = {}) {
307
+ this.timer = null;
308
+ this.started = false;
309
+ this.handleOnline = () => void this.check();
310
+ this.handleOffline = () => this.set(false);
311
+ this.ping = options.ping;
312
+ this.intervalMs = options.intervalMs ?? 3e4;
313
+ this.onChange = options.onChange;
314
+ this.online = typeof navigator !== "undefined" ? navigator.onLine : true;
315
+ }
316
+ isOnline() {
317
+ return this.online;
318
+ }
319
+ start() {
320
+ if (this.started || typeof window === "undefined") return;
321
+ this.started = true;
322
+ window.addEventListener("online", this.handleOnline);
323
+ window.addEventListener("offline", this.handleOffline);
324
+ if (this.intervalMs > 0) {
325
+ this.timer = setInterval(() => void this.check(), this.intervalMs);
326
+ }
327
+ void this.check();
328
+ }
329
+ stop() {
330
+ if (!this.started || typeof window === "undefined") return;
331
+ this.started = false;
332
+ window.removeEventListener("online", this.handleOnline);
333
+ window.removeEventListener("offline", this.handleOffline);
334
+ if (this.timer) {
335
+ clearInterval(this.timer);
336
+ this.timer = null;
337
+ }
338
+ }
339
+ /** Re-evaluate connectivity now, confirming reachability via ping when set. */
340
+ async check() {
341
+ const navOnline = typeof navigator !== "undefined" ? navigator.onLine : true;
342
+ if (!navOnline) {
343
+ this.set(false);
344
+ return false;
345
+ }
346
+ if (!this.ping) {
347
+ this.set(true);
348
+ return true;
349
+ }
350
+ try {
351
+ const reachable = await this.ping();
352
+ this.set(reachable);
353
+ return reachable;
354
+ } catch {
355
+ this.set(false);
356
+ return false;
357
+ }
358
+ }
359
+ set(online) {
360
+ if (online !== this.online) {
361
+ this.online = online;
362
+ this.onChange?.(online);
363
+ }
364
+ }
365
+ };
366
+
367
+ // src/sync/engine.ts
368
+ var MAX_BACKOFF_MS = 5 * 6e4;
369
+ var SyncEngine = class {
370
+ constructor(options) {
371
+ this.flushing = false;
372
+ this.abortController = null;
373
+ this.store = options.store;
374
+ this.remote = options.remote;
375
+ this.maxAttempts = options.maxAttempts ?? 6;
376
+ this.baseDelayMs = options.baseDelayMs ?? 1e3;
377
+ this.onStatus = options.onStatus;
378
+ this.onConflict = options.onConflict;
379
+ }
380
+ emit(status, detail) {
381
+ this.onStatus?.(status, detail);
382
+ }
383
+ /**
384
+ * Process every queued document once. Re-entrancy-safe: concurrent calls are
385
+ * coalesced. Returns the number of documents successfully synced.
386
+ */
387
+ async flush() {
388
+ if (this.flushing) return 0;
389
+ this.flushing = true;
390
+ this.abortController = new AbortController();
391
+ const signal = this.abortController.signal;
392
+ let synced = 0;
393
+ try {
394
+ const entries = await this.store.listOutbox();
395
+ if (entries.length === 0) return 0;
396
+ this.emit("syncing");
397
+ const now = Date.now();
398
+ for (const entry of entries) {
399
+ if (signal.aborted) break;
400
+ if (entry.nextAttemptAt && entry.nextAttemptAt > now) continue;
401
+ const record = await this.store.getDocument(entry.id);
402
+ if (!record || !record.dirty || record.rev !== entry.rev) {
403
+ await this.store.dequeue(entry.id);
404
+ continue;
405
+ }
406
+ try {
407
+ const result = await this.remote.save(record, signal);
408
+ const latest = await this.store.getDocument(entry.id);
409
+ if (latest && latest.rev === record.rev) {
410
+ await this.store.putDocument({
411
+ ...latest,
412
+ doc: result.doc ?? latest.doc,
413
+ baseVersion: result.version,
414
+ dirty: false
415
+ });
416
+ await this.store.dequeue(entry.id);
417
+ } else {
418
+ await this.store.dequeue(entry.id);
419
+ }
420
+ synced++;
421
+ } catch (err) {
422
+ if (err instanceof ConflictError) {
423
+ await this.store.enqueue({
424
+ ...entry,
425
+ attempts: entry.attempts + 1,
426
+ lastError: "conflict",
427
+ nextAttemptAt: Number.MAX_SAFE_INTEGER
428
+ // park until resolved
429
+ });
430
+ this.onConflict?.(record, err.remote);
431
+ this.emit("syncFailed", { error: "conflict" });
432
+ continue;
433
+ }
434
+ const attempts = entry.attempts + 1;
435
+ const backoff = Math.min(MAX_BACKOFF_MS, this.baseDelayMs * 2 ** entry.attempts);
436
+ await this.store.enqueue({
437
+ ...entry,
438
+ attempts,
439
+ lastError: err?.message ?? "upload failed",
440
+ nextAttemptAt: attempts >= this.maxAttempts ? Number.MAX_SAFE_INTEGER : Date.now() + backoff
441
+ });
442
+ this.emit("syncFailed", { error: err?.message });
443
+ }
444
+ }
445
+ const remaining = await this.store.listOutbox();
446
+ this.emit(remaining.length === 0 ? "synced" : "savedLocal");
447
+ return synced;
448
+ } finally {
449
+ this.flushing = false;
450
+ this.abortController = null;
451
+ }
452
+ }
453
+ /** Abort an in-flight flush (e.g. on going offline or unmount). */
454
+ cancel() {
455
+ this.abortController?.abort();
456
+ }
457
+ /**
458
+ * Re-queue a parked/conflicted document for another attempt (used by a
459
+ * host-defined conflict resolution flow after the user chooses to overwrite).
460
+ */
461
+ async retry(id, baseVersion) {
462
+ const record = await this.store.getDocument(id);
463
+ if (!record) return;
464
+ if (baseVersion !== void 0) {
465
+ await this.store.putDocument({ ...record, baseVersion });
466
+ }
467
+ await this.store.enqueue({
468
+ id,
469
+ rev: record.rev,
470
+ queuedAt: Date.now(),
471
+ attempts: 0
472
+ });
473
+ }
474
+ };
475
+
476
+ export { ConflictError, ConnectivityMonitor, DocumentPersistence, IndexedDBStore, MemoryStore, SyncEngine, requestPersistentStorage };
477
+ //# sourceMappingURL=chunk-O4GTLC3T.js.map
478
+ //# sourceMappingURL=chunk-O4GTLC3T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/persistence/types.ts","../src/persistence/memory.ts","../src/persistence/indexeddb.ts","../src/persistence/autosave.ts","../src/sync/connectivity.ts","../src/sync/engine.ts"],"names":[],"mappings":"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","file":"chunk-O4GTLC3T.js","sourcesContent":["import type { DocumentJSON, SaveStatus } from '../config/types';\n\n/**\n * Persistence and sync adapter interfaces (F-10.12). The editor core knows\n * nothing about REST or IndexedDB; consumers inject implementations of these\n * interfaces so the same editor works against any backend/storage. Default\n * IndexedDB and in-memory implementations ship with the package.\n */\n\n/** A stored document record: canonical JSON plus sync metadata. */\nexport interface StoredDocument {\n id: string;\n /** Canonical ProseMirror document JSON (F-8.1, C-5). */\n doc: DocumentJSON;\n /** Monotonic local revision, bumped on every local save. */\n rev: number;\n /** Server-acknowledged version, for optimistic-concurrency conflict checks. */\n baseVersion?: string | number | null;\n /** Whether the record has unsynced local changes. */\n dirty: boolean;\n updatedAt: number;\n /** Arbitrary per-document metadata supplied by the host. */\n metadata?: Record<string, unknown>;\n}\n\n/** An entry in the durable outbox of documents awaiting upload (F-9.5). */\nexport interface OutboxEntry {\n id: string;\n rev: number;\n queuedAt: number;\n attempts: number;\n lastError?: string | null;\n nextAttemptAt?: number;\n}\n\n/**\n * Local, durable document store (F-9.2, NF-9). The default implementation uses\n * IndexedDB; an in-memory implementation is provided for SSR/tests.\n */\nexport interface LocalStoreAdapter {\n getDocument(id: string): Promise<StoredDocument | null>;\n putDocument(record: StoredDocument): Promise<void>;\n deleteDocument(id: string): Promise<void>;\n listDocuments(): Promise<StoredDocument[]>;\n\n /** Outbox operations for the sync engine. */\n enqueue(entry: OutboxEntry): Promise<void>;\n dequeue(id: string): Promise<void>;\n listOutbox(): Promise<OutboxEntry[]>;\n\n /** Binary asset (offline image) operations (F-9.10). */\n putAsset?(key: string, blob: Blob): Promise<void>;\n getAsset?(key: string): Promise<Blob | null>;\n deleteAsset?(key: string): Promise<void>;\n\n /** Purge all locally persisted data (F-12.7). */\n clear(): Promise<void>;\n}\n\n/** Result of a remote save, carrying the new server version (NF-10). */\nexport interface RemoteSaveResult {\n version: string | number;\n /** Optional canonical document returned by the server (e.g. rewritten asset URLs). */\n doc?: DocumentJSON;\n}\n\n/** Raised by a {@link RemoteSyncAdapter} when a stale write is rejected (F-9.9). */\nexport class ConflictError extends Error {\n constructor(\n message: string,\n public readonly remote?: { version: string | number; doc?: DocumentJSON },\n ) {\n super(message);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * Remote document API (F-9.6, F-9.7). Injected by the host using its own auth\n * (F-12.4). Implementations MUST use HTTPS (F-12.3) and SHOULD be idempotent\n * (NF-10). On a version conflict, throw {@link ConflictError}.\n */\nexport interface RemoteSyncAdapter {\n /** Create or update the document on the server; returns the new version. */\n save(record: StoredDocument, signal?: AbortSignal): Promise<RemoteSaveResult>;\n /** Fetch the latest server copy, or null if it does not exist. */\n fetch?(id: string, signal?: AbortSignal): Promise<StoredDocument | null>;\n /** Best-effort reachability check used for connectivity confirmation (§8.7). */\n ping?(signal?: AbortSignal): Promise<boolean>;\n}\n\n/** Uploads offline-inserted assets and returns canonical URLs (F-9.10, F-12.5). */\nexport interface AssetUploadAdapter {\n upload(blob: Blob, meta: { filename?: string; mime: string }): Promise<{ url: string }>;\n}\n\n/** Listener for save/sync status transitions (F-9.4, F-10.15). */\nexport type SaveStatusListener = (status: SaveStatus, detail?: { error?: string }) => void;\n","import type { LocalStoreAdapter, OutboxEntry, StoredDocument } from './types';\n\n/**\n * In-memory {@link LocalStoreAdapter}. Used as an SSR-safe fallback when\n * IndexedDB is unavailable and as a test double. Not durable across reloads.\n */\nexport class MemoryStore implements LocalStoreAdapter {\n private docs = new Map<string, StoredDocument>();\n private outbox = new Map<string, OutboxEntry>();\n private assets = new Map<string, Blob>();\n\n async getDocument(id: string): Promise<StoredDocument | null> {\n return this.docs.get(id) ?? null;\n }\n\n async putDocument(record: StoredDocument): Promise<void> {\n this.docs.set(record.id, structuredCloneSafe(record));\n }\n\n async deleteDocument(id: string): Promise<void> {\n this.docs.delete(id);\n }\n\n async listDocuments(): Promise<StoredDocument[]> {\n return [...this.docs.values()];\n }\n\n async enqueue(entry: OutboxEntry): Promise<void> {\n this.outbox.set(entry.id, { ...entry });\n }\n\n async dequeue(id: string): Promise<void> {\n this.outbox.delete(id);\n }\n\n async listOutbox(): Promise<OutboxEntry[]> {\n return [...this.outbox.values()];\n }\n\n async putAsset(key: string, blob: Blob): Promise<void> {\n this.assets.set(key, blob);\n }\n\n async getAsset(key: string): Promise<Blob | null> {\n return this.assets.get(key) ?? null;\n }\n\n async deleteAsset(key: string): Promise<void> {\n this.assets.delete(key);\n }\n\n async clear(): Promise<void> {\n this.docs.clear();\n this.outbox.clear();\n this.assets.clear();\n }\n}\n\nfunction structuredCloneSafe<T>(value: T): T {\n if (typeof structuredClone === 'function') {\n try {\n return structuredClone(value);\n } catch {\n /* fall through */\n }\n }\n return JSON.parse(JSON.stringify(value)) as T;\n}\n","import { type IDBPDatabase, openDB } from 'idb';\nimport type { LocalStoreAdapter, OutboxEntry, StoredDocument } from './types';\nimport { MemoryStore } from './memory';\n\nconst DB_VERSION = 1;\nconst STORE_DOCS = 'documents';\nconst STORE_OUTBOX = 'outbox';\nconst STORE_ASSETS = 'assets';\n\n/**\n * Durable {@link LocalStoreAdapter} backed by IndexedDB (§8.7). `localStorage`\n * is explicitly rejected (too small, synchronous, string-only). Falls back to an\n * in-memory store when IndexedDB is unavailable (SSR, private mode) so the\n * editor never crashes (F-11.1).\n */\nexport class IndexedDBStore implements LocalStoreAdapter {\n private dbName: string;\n private dbPromise: Promise<IDBPDatabase> | null = null;\n private fallback: MemoryStore | null = null;\n\n constructor(dbName = 'react-next-editor') {\n this.dbName = dbName;\n }\n\n /** Whether IndexedDB is usable in the current environment. */\n static isSupported(): boolean {\n return typeof indexedDB !== 'undefined';\n }\n\n private async db(): Promise<IDBPDatabase | null> {\n if (!IndexedDBStore.isSupported()) {\n if (!this.fallback) this.fallback = new MemoryStore();\n return null;\n }\n if (!this.dbPromise) {\n this.dbPromise = openDB(this.dbName, DB_VERSION, {\n upgrade(db) {\n if (!db.objectStoreNames.contains(STORE_DOCS)) {\n db.createObjectStore(STORE_DOCS, { keyPath: 'id' });\n }\n if (!db.objectStoreNames.contains(STORE_OUTBOX)) {\n db.createObjectStore(STORE_OUTBOX, { keyPath: 'id' });\n }\n if (!db.objectStoreNames.contains(STORE_ASSETS)) {\n db.createObjectStore(STORE_ASSETS);\n }\n },\n }).catch((err) => {\n // eslint-disable-next-line no-console\n console.error('[react-next-editor] IndexedDB unavailable, using memory store.', err);\n this.fallback = new MemoryStore();\n throw err;\n });\n }\n try {\n return await this.dbPromise;\n } catch {\n return null;\n }\n }\n\n async getDocument(id: string): Promise<StoredDocument | null> {\n const db = await this.db();\n if (!db) return this.fallback!.getDocument(id);\n return (await db.get(STORE_DOCS, id)) ?? null;\n }\n\n async putDocument(record: StoredDocument): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.putDocument(record);\n await db.put(STORE_DOCS, record);\n }\n\n async deleteDocument(id: string): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.deleteDocument(id);\n await db.delete(STORE_DOCS, id);\n }\n\n async listDocuments(): Promise<StoredDocument[]> {\n const db = await this.db();\n if (!db) return this.fallback!.listDocuments();\n return db.getAll(STORE_DOCS);\n }\n\n async enqueue(entry: OutboxEntry): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.enqueue(entry);\n await db.put(STORE_OUTBOX, entry);\n }\n\n async dequeue(id: string): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.dequeue(id);\n await db.delete(STORE_OUTBOX, id);\n }\n\n async listOutbox(): Promise<OutboxEntry[]> {\n const db = await this.db();\n if (!db) return this.fallback!.listOutbox();\n return db.getAll(STORE_OUTBOX);\n }\n\n async putAsset(key: string, blob: Blob): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.putAsset(key, blob);\n await db.put(STORE_ASSETS, blob, key);\n }\n\n async getAsset(key: string): Promise<Blob | null> {\n const db = await this.db();\n if (!db) return this.fallback!.getAsset(key);\n return (await db.get(STORE_ASSETS, key)) ?? null;\n }\n\n async deleteAsset(key: string): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.deleteAsset(key);\n await db.delete(STORE_ASSETS, key);\n }\n\n async clear(): Promise<void> {\n const db = await this.db();\n if (!db) return this.fallback!.clear();\n await Promise.all([\n db.clear(STORE_DOCS),\n db.clear(STORE_OUTBOX),\n db.clear(STORE_ASSETS),\n ]);\n }\n}\n\n/**\n * Request persistent storage to reduce eviction risk for unsynced data (F-9.11).\n * Resolves to whether persistence was granted; never throws.\n */\nexport async function requestPersistentStorage(): Promise<boolean> {\n try {\n if (typeof navigator !== 'undefined' && navigator.storage?.persist) {\n return await navigator.storage.persist();\n }\n } catch {\n /* ignore */\n }\n return false;\n}\n","import type { DocumentJSON, SaveStatus } from '../config/types';\nimport type { LocalStoreAdapter, SaveStatusListener, StoredDocument } from './types';\n\nexport interface DocumentPersistenceOptions {\n documentId: string;\n store: LocalStoreAdapter;\n /** Debounce window for autosave writes (default 800ms). */\n debounceMs?: number;\n /** Initial metadata to attach to the stored record. */\n metadata?: Record<string, unknown>;\n onStatus?: SaveStatusListener;\n}\n\n/**\n * Manages local-first persistence for a single document (F-8.x, F-9.2, NF-9):\n * debounced autosave of `doc.toJSON()` to the durable store, dirty-flag and\n * outbox maintenance for later sync, and crash/reload recovery via {@link load}.\n * The local store is the source of truth during editing; the network is never in\n * the critical path (C-7, NF-8).\n */\nexport class DocumentPersistence {\n private readonly id: string;\n private readonly store: LocalStoreAdapter;\n private readonly debounceMs: number;\n private readonly onStatus?: SaveStatusListener;\n private metadata?: Record<string, unknown>;\n\n private current: StoredDocument | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private pending: DocumentJSON | null = null;\n private destroyed = false;\n private writing = false;\n\n constructor(options: DocumentPersistenceOptions) {\n this.id = options.documentId;\n this.store = options.store;\n this.debounceMs = options.debounceMs ?? 800;\n this.onStatus = options.onStatus;\n this.metadata = options.metadata;\n }\n\n private emit(status: SaveStatus, detail?: { error?: string }): void {\n this.onStatus?.(status, detail);\n }\n\n /** Load the latest locally-persisted document (crash/reload recovery, F-11.9). */\n async load(): Promise<StoredDocument | null> {\n const record = await this.store.getDocument(this.id);\n this.current = record;\n return record;\n }\n\n /** The current stored record, if loaded/saved. */\n getRecord(): StoredDocument | null {\n return this.current;\n }\n\n /** Whether there are unsynced local changes. */\n isDirty(): boolean {\n return this.current?.dirty ?? false;\n }\n\n /** Schedule a debounced save of the latest document JSON (F-4.8). */\n scheduleSave(doc: DocumentJSON): void {\n if (this.destroyed) return;\n this.pending = doc;\n this.emit('savingLocal');\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n void this.flush();\n }, this.debounceMs);\n }\n\n /** Immediately persist any pending document (e.g. on blur/unmount). */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.pending == null) return;\n const doc = this.pending;\n this.pending = null;\n await this.saveNow(doc);\n }\n\n /**\n * Persist a document to the local store, atomically bump the revision, mark it\n * dirty and enqueue it in the outbox for later upload. Writes are serialized to\n * avoid partial saves (NF-9).\n */\n async saveNow(doc: DocumentJSON): Promise<StoredDocument> {\n if (this.writing) {\n // Coalesce concurrent writes: keep the latest as pending and return current.\n this.pending = doc;\n return this.current ?? this.makeRecord(doc);\n }\n this.writing = true;\n try {\n const record = this.makeRecord(doc);\n await this.store.putDocument(record);\n await this.store.enqueue({\n id: this.id,\n rev: record.rev,\n queuedAt: record.updatedAt,\n attempts: 0,\n });\n this.current = record;\n this.emit('savedLocal');\n return record;\n } catch (err) {\n this.emit('syncFailed', { error: (err as Error)?.message });\n throw err;\n } finally {\n this.writing = false;\n if (this.pending != null) {\n const next = this.pending;\n this.pending = null;\n await this.saveNow(next);\n }\n }\n }\n\n private makeRecord(doc: DocumentJSON): StoredDocument {\n const prev = this.current;\n return {\n id: this.id,\n doc,\n rev: (prev?.rev ?? 0) + 1,\n baseVersion: prev?.baseVersion ?? null,\n dirty: true,\n updatedAt: Date.now(),\n metadata: this.metadata ?? prev?.metadata,\n };\n }\n\n /** Mark the document as synced after a successful remote save (NF-10). */\n async markSynced(version: string | number, serverDoc?: DocumentJSON): Promise<void> {\n if (!this.current) return;\n const record: StoredDocument = {\n ...this.current,\n doc: serverDoc ?? this.current.doc,\n baseVersion: version,\n dirty: false,\n };\n await this.store.putDocument(record);\n await this.store.dequeue(this.id);\n this.current = record;\n this.emit('synced');\n }\n\n /** Purge this document's locally-persisted data and outbox entry (F-12.7). */\n async clearLocal(): Promise<void> {\n await this.store.deleteDocument(this.id);\n await this.store.dequeue(this.id);\n this.current = null;\n }\n\n /** Stop the autosave timer and flush pending work. */\n async destroy(): Promise<void> {\n this.destroyed = true;\n await this.flush();\n }\n}\n","/**\n * Connectivity detection (§8.7). Listens to `online`/`offline` events but does\n * NOT trust `navigator.onLine` alone (it reports interface presence, not API\n * reachability); when a `ping` is provided, real reachability is confirmed\n * before reporting \"online\". Safe to construct in any environment.\n */\nexport interface ConnectivityOptions {\n /** Confirms real API reachability (e.g. a HEAD to the data API). */\n ping?: (signal?: AbortSignal) => Promise<boolean>;\n /** Polling interval in ms while running (default 30s). 0 disables polling. */\n intervalMs?: number;\n onChange?: (online: boolean) => void;\n}\n\nexport class ConnectivityMonitor {\n private readonly ping?: (signal?: AbortSignal) => Promise<boolean>;\n private readonly intervalMs: number;\n private readonly onChange?: (online: boolean) => void;\n private online: boolean;\n private timer: ReturnType<typeof setInterval> | null = null;\n private started = false;\n\n constructor(options: ConnectivityOptions = {}) {\n this.ping = options.ping;\n this.intervalMs = options.intervalMs ?? 30_000;\n this.onChange = options.onChange;\n this.online = typeof navigator !== 'undefined' ? navigator.onLine : true;\n }\n\n isOnline(): boolean {\n return this.online;\n }\n\n private readonly handleOnline = () => void this.check();\n private readonly handleOffline = () => this.set(false);\n\n start(): void {\n if (this.started || typeof window === 'undefined') return;\n this.started = true;\n window.addEventListener('online', this.handleOnline);\n window.addEventListener('offline', this.handleOffline);\n if (this.intervalMs > 0) {\n this.timer = setInterval(() => void this.check(), this.intervalMs);\n }\n void this.check();\n }\n\n stop(): void {\n if (!this.started || typeof window === 'undefined') return;\n this.started = false;\n window.removeEventListener('online', this.handleOnline);\n window.removeEventListener('offline', this.handleOffline);\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n /** Re-evaluate connectivity now, confirming reachability via ping when set. */\n async check(): Promise<boolean> {\n const navOnline = typeof navigator !== 'undefined' ? navigator.onLine : true;\n if (!navOnline) {\n this.set(false);\n return false;\n }\n if (!this.ping) {\n this.set(true);\n return true;\n }\n try {\n const reachable = await this.ping();\n this.set(reachable);\n return reachable;\n } catch {\n this.set(false);\n return false;\n }\n }\n\n private set(online: boolean): void {\n if (online !== this.online) {\n this.online = online;\n this.onChange?.(online);\n }\n }\n}\n","import type { SaveStatus } from '../config/types';\nimport {\n ConflictError,\n type LocalStoreAdapter,\n type RemoteSyncAdapter,\n type SaveStatusListener,\n type StoredDocument,\n} from '../persistence/types';\n\nexport interface SyncEngineOptions {\n store: LocalStoreAdapter;\n remote: RemoteSyncAdapter;\n /** Max upload attempts before a document is parked for manual retry (default 6). */\n maxAttempts?: number;\n /** Base backoff delay in ms (default 1000). Doubles per attempt, capped at 5min. */\n baseDelayMs?: number;\n onStatus?: SaveStatusListener;\n /** Invoked when a version conflict is detected (F-9.9). */\n onConflict?: (local: StoredDocument, remote?: { version: string | number }) => void;\n}\n\nconst MAX_BACKOFF_MS = 5 * 60_000;\n\n/**\n * Flushes the durable outbox to the REST API on demand/reconnect (F-9.6–F-9.8).\n * Idempotent uploads, exponential backoff on transient failure, and a\n * version-guard conflict path (G-2 default). Edits are never lost: a document\n * stays dirty and queued until the server confirms it.\n */\nexport class SyncEngine {\n private readonly store: LocalStoreAdapter;\n private readonly remote: RemoteSyncAdapter;\n private readonly maxAttempts: number;\n private readonly baseDelayMs: number;\n private readonly onStatus?: SaveStatusListener;\n private readonly onConflict?: SyncEngineOptions['onConflict'];\n\n private flushing = false;\n private abortController: AbortController | null = null;\n\n constructor(options: SyncEngineOptions) {\n this.store = options.store;\n this.remote = options.remote;\n this.maxAttempts = options.maxAttempts ?? 6;\n this.baseDelayMs = options.baseDelayMs ?? 1000;\n this.onStatus = options.onStatus;\n this.onConflict = options.onConflict;\n }\n\n private emit(status: SaveStatus, detail?: { error?: string }): void {\n this.onStatus?.(status, detail);\n }\n\n /**\n * Process every queued document once. Re-entrancy-safe: concurrent calls are\n * coalesced. Returns the number of documents successfully synced.\n */\n async flush(): Promise<number> {\n if (this.flushing) return 0;\n this.flushing = true;\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n let synced = 0;\n\n try {\n const entries = await this.store.listOutbox();\n if (entries.length === 0) return 0;\n this.emit('syncing');\n const now = Date.now();\n\n for (const entry of entries) {\n if (signal.aborted) break;\n if (entry.nextAttemptAt && entry.nextAttemptAt > now) continue;\n\n const record = await this.store.getDocument(entry.id);\n if (!record || !record.dirty || record.rev !== entry.rev) {\n // Stale or already-synced entry; clear it.\n await this.store.dequeue(entry.id);\n continue;\n }\n\n try {\n const result = await this.remote.save(record, signal);\n // Only clear the dirty flag if no newer local revision arrived meanwhile.\n const latest = await this.store.getDocument(entry.id);\n if (latest && latest.rev === record.rev) {\n await this.store.putDocument({\n ...latest,\n doc: result.doc ?? latest.doc,\n baseVersion: result.version,\n dirty: false,\n });\n await this.store.dequeue(entry.id);\n } else {\n // A newer edit exists; leave it queued under its own rev.\n await this.store.dequeue(entry.id);\n }\n synced++;\n } catch (err) {\n if (err instanceof ConflictError) {\n await this.store.enqueue({\n ...entry,\n attempts: entry.attempts + 1,\n lastError: 'conflict',\n nextAttemptAt: Number.MAX_SAFE_INTEGER, // park until resolved\n });\n this.onConflict?.(record, err.remote);\n this.emit('syncFailed', { error: 'conflict' });\n continue;\n }\n const attempts = entry.attempts + 1;\n const backoff = Math.min(MAX_BACKOFF_MS, this.baseDelayMs * 2 ** entry.attempts);\n await this.store.enqueue({\n ...entry,\n attempts,\n lastError: (err as Error)?.message ?? 'upload failed',\n nextAttemptAt:\n attempts >= this.maxAttempts ? Number.MAX_SAFE_INTEGER : Date.now() + backoff,\n });\n this.emit('syncFailed', { error: (err as Error)?.message });\n }\n }\n\n const remaining = await this.store.listOutbox();\n this.emit(remaining.length === 0 ? 'synced' : 'savedLocal');\n return synced;\n } finally {\n this.flushing = false;\n this.abortController = null;\n }\n }\n\n /** Abort an in-flight flush (e.g. on going offline or unmount). */\n cancel(): void {\n this.abortController?.abort();\n }\n\n /**\n * Re-queue a parked/conflicted document for another attempt (used by a\n * host-defined conflict resolution flow after the user chooses to overwrite).\n */\n async retry(id: string, baseVersion?: string | number | null): Promise<void> {\n const record = await this.store.getDocument(id);\n if (!record) return;\n if (baseVersion !== undefined) {\n await this.store.putDocument({ ...record, baseVersion });\n }\n await this.store.enqueue({\n id,\n rev: record.rev,\n queuedAt: Date.now(),\n attempts: 0,\n });\n }\n}\n"]}
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ var chunk5F6SPYCN_cjs = require('./chunk-5F6SPYCN.cjs');
4
+ var prosemirrorModel = require('prosemirror-model');
5
+
6
+ var mammothPromise = null;
7
+ async function loadMammoth() {
8
+ if (!mammothPromise) {
9
+ mammothPromise = (async () => {
10
+ try {
11
+ const spec = "mammoth";
12
+ const mod = await import(spec);
13
+ return mod.default ?? mod;
14
+ } catch {
15
+ throw new Error(
16
+ "react-next-editor: DOCX import requires 'mammoth'. Install it (npm i mammoth)."
17
+ );
18
+ }
19
+ })();
20
+ }
21
+ return mammothPromise;
22
+ }
23
+ var DEFAULT_STYLE_MAP = [
24
+ "p[style-name='Title'] => h1:fresh",
25
+ "p[style-name='Subtitle'] => h2:fresh",
26
+ "p[style-name='Heading 7'] => h6:fresh",
27
+ "p[style-name='Heading 8'] => h6:fresh",
28
+ "p[style-name='Heading 9'] => h6:fresh",
29
+ "p[style-name='Quote'] => blockquote:fresh",
30
+ "p[style-name='Intense Quote'] => blockquote:fresh",
31
+ "p[style-name='Caption'] => p.rne-caption:fresh > em",
32
+ "r[style-name='Strong'] => strong",
33
+ "r[style-name='Emphasis'] => em",
34
+ "r[style-name='Book Title'] => em"
35
+ ];
36
+ async function buildMammothInput(input) {
37
+ const isBlob = typeof Blob !== "undefined" && input instanceof Blob;
38
+ if (typeof Buffer !== "undefined") {
39
+ if (Buffer.isBuffer(input)) return { buffer: input };
40
+ if (input instanceof Uint8Array) return { buffer: Buffer.from(input) };
41
+ if (input instanceof ArrayBuffer) return { buffer: Buffer.from(new Uint8Array(input)) };
42
+ if (isBlob) return { buffer: Buffer.from(new Uint8Array(await input.arrayBuffer())) };
43
+ }
44
+ if (input instanceof ArrayBuffer) return { arrayBuffer: input };
45
+ if (isBlob) return { arrayBuffer: await input.arrayBuffer() };
46
+ if (input instanceof Uint8Array) {
47
+ return {
48
+ arrayBuffer: input.buffer.slice(
49
+ input.byteOffset,
50
+ input.byteOffset + input.byteLength
51
+ )
52
+ };
53
+ }
54
+ throw new Error("react-next-editor: unsupported DOCX input type.");
55
+ }
56
+ async function importDocx(input, schema, options = {}) {
57
+ if (typeof document === "undefined") {
58
+ throw new Error("react-next-editor: importDocx requires a DOM (browser or jsdom).");
59
+ }
60
+ const mammoth = await loadMammoth();
61
+ const mammothInput = await buildMammothInput(input);
62
+ const { value: rawHtml, messages } = await mammoth.convertToHtml(mammothInput, {
63
+ styleMap: [...DEFAULT_STYLE_MAP, ...options.styleMap ?? []],
64
+ includeDefaultStyleMap: true,
65
+ // Preserve blank paragraphs so Word's spacing-by-empty-paragraph survives.
66
+ ignoreEmptyParagraphs: false
67
+ });
68
+ const html = await chunk5F6SPYCN_cjs.sanitizeHtml(rawHtml);
69
+ const container = document.createElement("div");
70
+ container.innerHTML = html;
71
+ const parsed = prosemirrorModel.DOMParser.fromSchema(schema).parse(container);
72
+ parsed.check();
73
+ return {
74
+ doc: parsed.toJSON(),
75
+ warnings: messages.map((m) => m.message),
76
+ html
77
+ };
78
+ }
79
+
80
+ exports.importDocx = importDocx;
81
+ //# sourceMappingURL=chunk-ODHABIIC.cjs.map
82
+ //# sourceMappingURL=chunk-ODHABIIC.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/import/docx.ts"],"names":["sanitizeHtml","PMDOMParser"],"mappings":"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","file":"chunk-ODHABIIC.cjs","sourcesContent":["import { DOMParser as PMDOMParser, type Schema } from 'prosemirror-model';\nimport type { DocumentJSON } from '../config/types';\nimport { sanitizeHtml } from '../security/sanitize';\n\n/**\n * Best-effort DOCX import (F-7.2 / F-7.3). External `.docx` files are converted\n * to HTML with `mammoth` (BSD), sanitized (§5.12), then parsed into the editor\n * schema via ProseMirror's DOMParser. Fidelity is best-effort: supported\n * structures (headings, lists, tables, bold/italic/underline, links, images)\n * map across; unsupported Word constructs degrade gracefully. `mammoth` is an\n * optional dependency, lazily imported, so it never bloats the editor bundle.\n *\n * Browser-oriented (needs a DOM to parse HTML). For server-side import, run in\n * an environment that provides `document` (e.g. jsdom).\n */\n\nexport interface DocxImportResult {\n /** The imported document as ProseMirror JSON. */\n doc: DocumentJSON;\n /** Non-fatal conversion warnings from mammoth (unsupported features, etc.). */\n warnings: string[];\n /** The sanitized intermediate HTML (useful for debugging/inspection). */\n html: string;\n}\n\nexport interface DocxImportOptions {\n /**\n * Additional mammoth style mappings (e.g. `\"p[style-name='Quote'] => blockquote\"`).\n * Merged with the built-in defaults.\n */\n styleMap?: string[];\n}\n\n/** Input accepted by mammoth: an ArrayBuffer (browser) or a Buffer (Node). */\ntype MammothInput = { arrayBuffer: ArrayBuffer } | { buffer: Uint8Array };\n\n/** Minimal structural type for the parts of mammoth we use. */\ninterface MammothModule {\n convertToHtml(\n input: MammothInput,\n options?: {\n styleMap?: string[];\n includeDefaultStyleMap?: boolean;\n ignoreEmptyParagraphs?: boolean;\n },\n ): Promise<{ value: string; messages: Array<{ type: string; message: string }> }>;\n}\n\nlet mammothPromise: Promise<MammothModule> | null = null;\nasync function loadMammoth(): Promise<MammothModule> {\n if (!mammothPromise) {\n mammothPromise = (async () => {\n try {\n // Variable specifier so the optional dependency is not resolved at\n // type-check/build time when it is absent.\n const spec = 'mammoth';\n const mod = (await import(spec)) as { default?: MammothModule } & MammothModule;\n return (mod.default ?? mod) as MammothModule;\n } catch {\n throw new Error(\n \"react-next-editor: DOCX import requires 'mammoth'. Install it (npm i mammoth).\",\n );\n }\n })();\n }\n return mammothPromise;\n}\n\n/**\n * Default style mappings improving fidelity for common Word styles. Mammoth's\n * built-in map already covers Heading 1–6, bold/italic, lists, tables, links and\n * images; these extend it to titles, quotes, captions and higher heading levels\n * so more structure survives import.\n */\nconst DEFAULT_STYLE_MAP = [\n \"p[style-name='Title'] => h1:fresh\",\n \"p[style-name='Subtitle'] => h2:fresh\",\n \"p[style-name='Heading 7'] => h6:fresh\",\n \"p[style-name='Heading 8'] => h6:fresh\",\n \"p[style-name='Heading 9'] => h6:fresh\",\n \"p[style-name='Quote'] => blockquote:fresh\",\n \"p[style-name='Intense Quote'] => blockquote:fresh\",\n \"p[style-name='Caption'] => p.rne-caption:fresh > em\",\n \"r[style-name='Strong'] => strong\",\n \"r[style-name='Emphasis'] => em\",\n \"r[style-name='Book Title'] => em\",\n];\n\n/**\n * Build the mammoth input. In Node (server/tests) a `Buffer` is used to avoid\n * cross-realm `instanceof ArrayBuffer` issues; in the browser an `ArrayBuffer`\n * is passed.\n */\nasync function buildMammothInput(input: ArrayBuffer | Uint8Array | Blob): Promise<MammothInput> {\n const isBlob = typeof Blob !== 'undefined' && input instanceof Blob;\n if (typeof Buffer !== 'undefined') {\n if (Buffer.isBuffer(input)) return { buffer: input };\n if (input instanceof Uint8Array) return { buffer: Buffer.from(input) };\n if (input instanceof ArrayBuffer) return { buffer: Buffer.from(new Uint8Array(input)) };\n if (isBlob) return { buffer: Buffer.from(new Uint8Array(await input.arrayBuffer())) };\n }\n if (input instanceof ArrayBuffer) return { arrayBuffer: input };\n if (isBlob) return { arrayBuffer: await input.arrayBuffer() };\n if (input instanceof Uint8Array) {\n return {\n arrayBuffer: input.buffer.slice(\n input.byteOffset,\n input.byteOffset + input.byteLength,\n ) as ArrayBuffer,\n };\n }\n throw new Error('react-next-editor: unsupported DOCX input type.');\n}\n\n/**\n * Import a `.docx` file into the given schema. Returns the document JSON plus\n * any conversion warnings. Never throws on unsupported content — only on a\n * genuinely unreadable file or a missing DOM/mammoth.\n */\nexport async function importDocx(\n input: ArrayBuffer | Uint8Array | Blob,\n schema: Schema,\n options: DocxImportOptions = {},\n): Promise<DocxImportResult> {\n if (typeof document === 'undefined') {\n throw new Error('react-next-editor: importDocx requires a DOM (browser or jsdom).');\n }\n\n const mammoth = await loadMammoth();\n const mammothInput = await buildMammothInput(input);\n\n const { value: rawHtml, messages } = await mammoth.convertToHtml(mammothInput, {\n styleMap: [...DEFAULT_STYLE_MAP, ...(options.styleMap ?? [])],\n includeDefaultStyleMap: true,\n // Preserve blank paragraphs so Word's spacing-by-empty-paragraph survives.\n ignoreEmptyParagraphs: false,\n });\n\n const html = await sanitizeHtml(rawHtml);\n\n const container = document.createElement('div');\n container.innerHTML = html;\n const parsed = PMDOMParser.fromSchema(schema).parse(container);\n // Guarantee a valid, renderable document (F-11.5). Throws here only if the\n // schema cannot represent the content at all — caught by the caller.\n parsed.check();\n\n return {\n doc: parsed.toJSON() as DocumentJSON,\n warnings: messages.map((m) => m.message),\n html,\n };\n}\n"]}
@@ -0,0 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export { __export };
8
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
9
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map