@w100n/documents 0.16.3 → 0.17.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 (44) hide show
  1. package/dist/{Compare-M57FG4R3.js → Compare-RHAUAKUJ.js} +2 -2
  2. package/dist/{SheetView-KXFUAILH.js → SheetView-SBLAFGTL.js} +5 -5
  3. package/dist/{TextEditor-RNHXPYJX.js → TextEditor-X2GSL4QM.js} +119 -27
  4. package/dist/TextEditor-X2GSL4QM.js.map +1 -0
  5. package/dist/{chunk-E2FVJNDT.js → chunk-A6AHJCEK.js} +67 -832
  6. package/dist/chunk-A6AHJCEK.js.map +1 -0
  7. package/dist/{chunk-XFLYD3JS.js → chunk-ASTNK6WZ.js} +2 -2
  8. package/dist/{chunk-VNXZVOPN.js → chunk-B7C6NBBQ.js} +929 -1
  9. package/dist/chunk-B7C6NBBQ.js.map +1 -0
  10. package/dist/chunk-FFXAOK4A.js +39 -0
  11. package/dist/chunk-FFXAOK4A.js.map +1 -0
  12. package/dist/{chunk-EQLBYW42.js → chunk-GSIPTCQH.js} +9 -1
  13. package/dist/chunk-GSIPTCQH.js.map +1 -0
  14. package/dist/collab.cjs +170 -2
  15. package/dist/collab.cjs.map +1 -1
  16. package/dist/collab.d.cts +1 -1
  17. package/dist/collab.d.ts +1 -1
  18. package/dist/collab.js +3 -3
  19. package/dist/index.cjs +1212 -536
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.css +324 -0
  22. package/dist/index.css.map +1 -1
  23. package/dist/index.d.cts +12 -3
  24. package/dist/index.d.ts +12 -3
  25. package/dist/index.js +878 -490
  26. package/dist/index.js.map +1 -1
  27. package/dist/kinds.d.cts +1 -1
  28. package/dist/kinds.d.ts +1 -1
  29. package/dist/memory.cjs +3 -2
  30. package/dist/memory.cjs.map +1 -1
  31. package/dist/memory.d.cts +1 -1
  32. package/dist/memory.d.ts +1 -1
  33. package/dist/memory.js +3 -2
  34. package/dist/memory.js.map +1 -1
  35. package/dist/{types-BUO0OzOl.d.cts → types-CHmV8GLx.d.cts} +1 -0
  36. package/dist/{types-BUO0OzOl.d.ts → types-CHmV8GLx.d.ts} +1 -0
  37. package/package.json +1 -1
  38. package/dist/TextEditor-RNHXPYJX.js.map +0 -1
  39. package/dist/chunk-E2FVJNDT.js.map +0 -1
  40. package/dist/chunk-EQLBYW42.js.map +0 -1
  41. package/dist/chunk-VNXZVOPN.js.map +0 -1
  42. /package/dist/{Compare-M57FG4R3.js.map → Compare-RHAUAKUJ.js.map} +0 -0
  43. /package/dist/{SheetView-KXFUAILH.js.map → SheetView-SBLAFGTL.js.map} +0 -0
  44. /package/dist/{chunk-XFLYD3JS.js.map → chunk-ASTNK6WZ.js.map} +0 -0
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QDH7EZAF.js";
5
5
  import {
6
6
  fromMarkdown
7
- } from "./chunk-EQLBYW42.js";
7
+ } from "./chunk-GSIPTCQH.js";
8
8
  import {
9
9
  diff,
10
10
  readDocx
@@ -93,4 +93,4 @@ export {
93
93
  Compare as default,
94
94
  textOf
95
95
  };
96
- //# sourceMappingURL=Compare-M57FG4R3.js.map
96
+ //# sourceMappingURL=Compare-RHAUAKUJ.js.map
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  useLive
4
- } from "./chunk-XFLYD3JS.js";
4
+ } from "./chunk-ASTNK6WZ.js";
5
5
  import {
6
6
  SheetRefusal,
7
7
  build,
@@ -25,13 +25,13 @@ import {
25
25
  strip,
26
26
  worksheets,
27
27
  writeSheet
28
- } from "./chunk-E2FVJNDT.js";
29
- import "./chunk-EQLBYW42.js";
28
+ } from "./chunk-A6AHJCEK.js";
29
+ import "./chunk-GSIPTCQH.js";
30
30
  import {
31
31
  rove,
32
32
  useRestore
33
33
  } from "./chunk-TDP6OJET.js";
34
- import "./chunk-VNXZVOPN.js";
34
+ import "./chunk-B7C6NBBQ.js";
35
35
  import "./chunk-ZAVXCH7V.js";
36
36
  import {
37
37
  span
@@ -970,4 +970,4 @@ export {
970
970
  readSheet,
971
971
  writeSheet
972
972
  };
973
- //# sourceMappingURL=SheetView-KXFUAILH.js.map
973
+ //# sourceMappingURL=SheetView-SBLAFGTL.js.map
@@ -1,10 +1,25 @@
1
1
  'use client';
2
+ import {
3
+ findNote,
4
+ linkTo,
5
+ suggest
6
+ } from "./chunk-FFXAOK4A.js";
2
7
  import {
3
8
  useLoad
4
9
  } from "./chunk-QDH7EZAF.js";
5
10
  import {
6
11
  useLive
7
- } from "./chunk-XFLYD3JS.js";
12
+ } from "./chunk-ASTNK6WZ.js";
13
+ import "./chunk-A6AHJCEK.js";
14
+ import {
15
+ fromMarkdown,
16
+ toMarkdown,
17
+ track
18
+ } from "./chunk-GSIPTCQH.js";
19
+ import {
20
+ rove,
21
+ useRestore
22
+ } from "./chunk-TDP6OJET.js";
8
23
  import {
9
24
  a4,
10
25
  align,
@@ -22,18 +37,10 @@ import {
22
37
  replace,
23
38
  searching,
24
39
  spacing,
25
- suggesting
26
- } from "./chunk-E2FVJNDT.js";
27
- import {
28
- fromMarkdown,
29
- toMarkdown,
30
- track
31
- } from "./chunk-EQLBYW42.js";
32
- import {
33
- rove,
34
- useRestore
35
- } from "./chunk-TDP6OJET.js";
36
- import "./chunk-VNXZVOPN.js";
40
+ suggesting,
41
+ wikiAsk,
42
+ wikiName
43
+ } from "./chunk-B7C6NBBQ.js";
37
44
  import {
38
45
  mathml,
39
46
  readDocx,
@@ -60,6 +67,7 @@ import {
60
67
  CloudAlert,
61
68
  Code,
62
69
  FilePenLine,
70
+ FileText,
63
71
  Highlighter,
64
72
  ImagePlus,
65
73
  Italic,
@@ -283,7 +291,7 @@ var glows = ["#fef08a", "#bbf7d0", "#bfdbfe", "#fbcfe8", "#fed7aa", "#ddd6fe"];
283
291
  var faces = ["Arial", "Calibri", "Cambria", "Courier New", "Georgia", "Inter", "Roboto", "Times New Roman", "Verdana"];
284
292
  var sizes = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72];
285
293
  var uid = () => Math.random().toString(36).slice(2, 10);
286
- function TextEditor({ kind, bytes, t, language, rights, host, together, documentId, onSaved, onOutline, onReading, onPanel, slot, head, file, guard }) {
294
+ function TextEditor({ kind, bytes, t, language, rights, host, together, documentId, onSaved, onOutline, onReading, onPanel, slot, head, file, guard, wiki }) {
287
295
  const docx = kind === "docx";
288
296
  const can = { edit: !!host?.save && !!rights?.edit, comment: !!host?.comment && !!rights && (rights.comment || rights.edit) };
289
297
  const source = useLoad(async () => {
@@ -334,13 +342,23 @@ function TextEditor({ kind, bytes, t, language, rights, host, together, document
334
342
  useRestore(pop !== null);
335
343
  useRestore(editing !== null);
336
344
  useRestore(dropping !== null);
345
+ const wikiRef = useRef3(wiki);
346
+ wikiRef.current = wiki;
347
+ const wikiKeys = useRef3(null);
348
+ const [ask, setAsk] = useState3(null);
349
+ const [askAt, setAskAt] = useState3(0);
350
+ const [shut, setShut] = useState3(null);
337
351
  const editor = useEditor({
338
- extensions: kit(kind, t, shared),
352
+ extensions: kit(kind, t, shared, docx || !wiki ? void 0 : { known: (target) => !!findNote(wikiRef.current?.notes ?? [], target) }),
339
353
  content: shared ? null : source.data?.doc ?? null,
340
354
  editable: can.edit && (!live || !!shared),
341
355
  immediatelyRender: true,
342
356
  shouldRerenderOnTransaction: false,
343
- editorProps: { attributes: { class: "w100n-docs-prose w100n-text-body", "aria-label": t.documentText, spellcheck: String(spell), lang: language }, transformPastedHTML: cleanPaste },
357
+ editorProps: {
358
+ attributes: { class: "w100n-docs-prose w100n-text-body", "aria-label": t.documentText, spellcheck: String(spell), lang: language },
359
+ transformPastedHTML: cleanPaste,
360
+ handleKeyDown: (view, event) => !!wikiAsk.getState(view.state) && !!wikiKeys.current?.(event.key)
361
+ },
344
362
  onCreate: ({ editor: made }) => {
345
363
  if (source.data && !live) baseline.current = { bytes, doc: made.state.doc, base: source.data.md && track(source.data.md, made.state.doc) };
346
364
  }
@@ -440,8 +458,8 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
440
458
  useEffect(() => {
441
459
  if (!editor || !source.data) return;
442
460
  const have = new Map(notes.getState(editor.state).spots.map((s) => [s.id, s]));
443
- const fresh = open.filter((c) => !have.has(c.id));
444
- const found2 = locate(editor.state.doc, fresh.map((c) => ({ id: c.id, quote: c.quote, anchor: anchors.current.get(c.id) })));
461
+ const fresh2 = open.filter((c) => !have.has(c.id));
462
+ const found2 = locate(editor.state.doc, fresh2.map((c) => ({ id: c.id, quote: c.quote, anchor: anchors.current.get(c.id) })));
445
463
  editor.view.dispatch(editor.state.tr.setMeta(notes, { spots: [...open.flatMap((c) => have.get(c.id) ?? []), ...found2] }));
446
464
  }, [editor, source.data, openIds]);
447
465
  useEffect(() => {
@@ -561,7 +579,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
561
579
  }, [editor, pop, query]);
562
580
  useEffect(() => {
563
581
  const press = (e) => {
564
- if (!(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey || e.key.toLowerCase() !== "p") return;
582
+ if (!(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey || e.key.toLowerCase() !== "p" || !docx && wiki) return;
565
583
  e.preventDefault();
566
584
  e.stopPropagation();
567
585
  print();
@@ -586,6 +604,23 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
586
604
  window.removeEventListener("scroll", off, true);
587
605
  };
588
606
  }, [pop]);
607
+ const wikied = !!wiki;
608
+ useEffect(() => {
609
+ if (!editor || !wikied) return;
610
+ const sync = () => {
611
+ const next = wikiAsk.getState(editor.state) ?? null;
612
+ setAsk((prev) => prev?.from === next?.from && prev?.query === next?.query ? prev : next);
613
+ };
614
+ editor.on("transaction", sync);
615
+ return () => {
616
+ editor.off("transaction", sync);
617
+ };
618
+ }, [editor, wikied]);
619
+ useEffect(() => setAskAt(0), [ask?.query]);
620
+ const roster = wiki?.notes.map((n) => `${n.id}:${n.name}:${n.folder ?? ""}`).join("|");
621
+ useEffect(() => {
622
+ if (editor && !editor.isDestroyed) editor.view.dispatch(editor.state.tr.setMeta("wiki", true));
623
+ }, [editor, roster]);
589
624
  if (source.error) return docx ? /* @__PURE__ */ jsx3("div", { className: "w100n-docs-scroll", children: /* @__PURE__ */ jsx3(DocxView, { bytes, onOutline, failed: t.failed }) }) : /* @__PURE__ */ jsx3("div", { className: "w100n-docs-empty", children: t.failed });
590
625
  if (!source.data || !editor || !state || live && !live.ready && !live.late && !live.denied) return /* @__PURE__ */ jsx3("div", { className: "w100n-docs-empty", children: t.loading });
591
626
  const save = async (auto = false) => {
@@ -606,8 +641,8 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
606
641
  await host.save(documentId, out, auto ? t.autosavedNote : t.editedNote, auto);
607
642
  baseline.current = { bytes: md ? out : was.bytes, doc, base: md ? md.base : null };
608
643
  if (!md && editor.state.doc === doc) {
609
- const fresh = (await readDocx(out)).doc;
610
- if (editor.state.doc === doc && renew(fresh)) baseline.current = { bytes: out, doc: editor.state.doc, base: null };
644
+ const fresh2 = (await readDocx(out)).doc;
645
+ if (editor.state.doc === doc && renew(fresh2)) baseline.current = { bytes: out, doc: editor.state.doc, base: null };
611
646
  }
612
647
  setUnsetup(false);
613
648
  setSaving("done");
@@ -618,13 +653,13 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
618
653
  return false;
619
654
  }
620
655
  };
621
- const renew = (fresh) => {
656
+ const renew = (fresh2) => {
622
657
  const at = [];
623
658
  const refs = [];
624
659
  editor.state.doc.descendants((node, pos) => {
625
660
  if (node.isBlock) at.push(pos);
626
661
  });
627
- editor.schema.nodeFromJSON(fresh).descendants((node) => {
662
+ editor.schema.nodeFromJSON(fresh2).descendants((node) => {
628
663
  if (node.isBlock) refs.push(node.type.name, node.attrs.ref);
629
664
  });
630
665
  if (refs.length !== at.length * 2 || at.some((pos, i) => editor.state.doc.nodeAt(pos).type.name !== refs[i * 2])) return false;
@@ -852,7 +887,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
852
887
  const at = editor.state.selection.$from.before(1);
853
888
  editor.chain().focus().insertContentAt(at, { type: "toc", attrs: { entries: JSON.stringify(entries(editor.state.doc, !docx, at - 1)) } }).run();
854
889
  };
855
- const suggest = () => editor.view.dispatch(editor.state.tr.setMeta(suggesting, { on: !state.suggest, me: host?.me.name ?? "" }));
890
+ const suggest2 = () => editor.view.dispatch(editor.state.tr.setMeta(suggesting, { on: !state.suggest, me: host?.me.name ?? "" }));
856
891
  const aligns = [[AlignLeft, t.alignLeft, "left"], [AlignCenter, t.alignCenter, "center"], [AlignRight, t.alignRight, "right"], [AlignJustify, t.justify, "justify"]];
857
892
  const lines = [[1, t.single], [1.15, "1.15"], [1.5, "1.5"], [2, t.double]];
858
893
  const menus = [
@@ -929,7 +964,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
929
964
  item(t.indent, () => indent(editor, 1), { keys: `${mod}]` })
930
965
  ] : []],
931
966
  ["tools", t.menuTools, [
932
- docx && can.edit && item(t.suggest, suggest, { on: state.suggest }),
967
+ docx && can.edit && item(t.suggest, suggest2, { on: state.suggest }),
933
968
  docx && can.edit && state.revs.length > 0 && item(t.acceptAll, () => decide(editor, true)),
934
969
  docx && can.edit && state.revs.length > 0 && item(t.rejectAll, () => decide(editor, false)),
935
970
  !!host?.comments && (can.comment || open.length > 0) && item(t.comments, () => onPanel?.("comments")),
@@ -1333,7 +1368,7 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1333
1368
  tool(RemoveFormatting, t.clearFormat, () => clear(editor)),
1334
1369
  docx && /* @__PURE__ */ jsxs3(Fragment3, { children: [
1335
1370
  gap,
1336
- tool(FilePenLine, t.suggest, suggest, state.suggest)
1371
+ tool(FilePenLine, t.suggest, suggest2, state.suggest)
1337
1372
  ] })
1338
1373
  ] });
1339
1374
  const context = can.edit && (state.table ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
@@ -1372,6 +1407,39 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1372
1407
  if (e.target.closest("button")) e.preventDefault();
1373
1408
  };
1374
1409
  const sheet = docx ? { "--page-w": `${page.width}px`, "--page-h": `${page.height}px`, "--mt": `${page.margins[0]}px`, "--mr": `${page.margins[1]}px`, "--mb": `${page.margins[2]}px`, "--ml": `${page.margins[3]}px` } : void 0;
1410
+ const asking = wiki && ask && shut !== ask.from ? ask : null;
1411
+ const offers = asking ? suggest(wiki.notes, asking.query, documentId) : [];
1412
+ const fresh = asking?.query.trim() ?? "";
1413
+ const options = [
1414
+ ...offers.map((note) => ({ note })),
1415
+ ...fresh && wiki?.create && !offers.some((n) => n.name.replace(/\.(md|markdown)$/i, "").toLowerCase() === fresh.toLowerCase()) ? [{ make: fresh }] : []
1416
+ ];
1417
+ const choose = async (option) => {
1418
+ const from = asking.from;
1419
+ let target;
1420
+ if ("note" in option) target = linkTo(wiki.notes, option.note);
1421
+ else {
1422
+ if (!await wiki.create(option.make)) return;
1423
+ target = option.make;
1424
+ }
1425
+ editor.chain().focus().command(({ tr, state: now }) => {
1426
+ tr.replaceWith(from, now.selection.from, now.schema.nodes.wikilink.create({ target }));
1427
+ return true;
1428
+ }).run();
1429
+ };
1430
+ wikiKeys.current = !asking || !options.length ? null : (key) => {
1431
+ if (key === "ArrowDown" || key === "ArrowUp") setAskAt((askAt + (key === "ArrowDown" ? 1 : options.length - 1)) % options.length);
1432
+ else if (key === "Enter" || key === "Tab") void choose(options[Math.min(askAt, options.length - 1)]);
1433
+ else if (key === "Escape") setShut(asking.from);
1434
+ else return false;
1435
+ return true;
1436
+ };
1437
+ const askSpot = asking && options.length ? editor.view.coordsAtPos(asking.from) : null;
1438
+ const follow = (target) => {
1439
+ const note = findNote(wiki.notes, target);
1440
+ if (note) return wiki.open(note.id);
1441
+ if (wiki.create) void wiki.create(wikiName(target)).then((id) => id && wiki.open(id));
1442
+ };
1375
1443
  return /* @__PURE__ */ jsxs3("div", { ref: root, className: "w100n-text", "data-kind": kind, "data-docs-find": true, onKeyDown: keys, children: [
1376
1444
  head ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
1377
1445
  head.menus && createPortal(/* @__PURE__ */ jsx3("div", { className: "w100n-text-ribbon w100n-text-docbar", onKeyDown: rove, onPointerDown: keep, children: menubar }), head.menus),
@@ -1391,6 +1459,8 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1391
1459
  setSpot({ x: Math.min(e.clientX, innerWidth - 260), y: Math.min(e.clientY, innerHeight - 360) });
1392
1460
  setPop("context");
1393
1461
  }, onClick: (e) => {
1462
+ const link = wiki ? e.target.closest("[data-wiki]") : null;
1463
+ if (link) return follow(link.dataset.wiki);
1394
1464
  const atom = can.edit ? e.target.closest(".w100n-math, sup[data-footnote]") : null;
1395
1465
  if (atom) {
1396
1466
  const at = editor.view.posAtDOM(atom, 0);
@@ -1404,6 +1474,28 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1404
1474
  setActive(id);
1405
1475
  onPanel?.("comments");
1406
1476
  }, children: /* @__PURE__ */ jsx3("div", { className: "w100n-text-zoomed", style: { zoom: percent / 100 }, children: /* @__PURE__ */ jsx3("div", { className: docx ? `w100n-text-sheet${flow ? " is-flow" : ""}` : "w100n-docs-page w100n-text-column", style: sheet, children: /* @__PURE__ */ jsx3(EditorContent, { editor }) }) }) }),
1477
+ askSpot && /* @__PURE__ */ jsxs3(
1478
+ "span",
1479
+ {
1480
+ className: "w100n-text-pop w100n-text-menu w100n-wiki-ask",
1481
+ role: "listbox",
1482
+ "aria-label": t.link,
1483
+ style: { left: Math.min(askSpot.left, innerWidth - 340), top: askSpot.bottom + 6 },
1484
+ onPointerDown: (e) => e.preventDefault(),
1485
+ children: [
1486
+ options.map((option, i) => /* @__PURE__ */ jsx3("button", { type: "button", role: "option", "aria-selected": i === Math.min(askAt, options.length - 1), onClick: () => void choose(option), children: "note" in option ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
1487
+ /* @__PURE__ */ jsx3(FileText, { "aria-hidden": true }),
1488
+ /* @__PURE__ */ jsx3("b", { children: option.note.name.replace(/\.(md|markdown)$/i, "") }),
1489
+ option.note.folder && /* @__PURE__ */ jsx3("small", { children: option.note.folder })
1490
+ ] }) : /* @__PURE__ */ jsxs3(Fragment3, { children: [
1491
+ /* @__PURE__ */ jsx3(Plus, { "aria-hidden": true }),
1492
+ /* @__PURE__ */ jsx3("b", { children: t.wikiCreate.replace("{name}", option.make) }),
1493
+ /* @__PURE__ */ jsx3("small", { children: t.wikiNew })
1494
+ ] }) }, "note" in option ? option.note.id : "make")),
1495
+ /* @__PURE__ */ jsx3("small", { className: "w100n-text-hint", children: t.wikiKeys })
1496
+ ]
1497
+ }
1498
+ ),
1407
1499
  pop === "context" && /* @__PURE__ */ jsxs3("span", { className: "w100n-text-pop w100n-text-menu w100n-text-context", role: "menu", "aria-label": t.textTools, style: { left: spot.x, top: spot.y }, onPointerDown: keep, children: [
1408
1500
  rows(near),
1409
1501
  spell && /* @__PURE__ */ jsx3("small", { className: "w100n-text-hint", children: t.spellHint })
@@ -1694,4 +1786,4 @@ img { max-width: 100%; } img[data-wrap='left'] { float: left; margin: 0 12pt 6pt
1694
1786
  export {
1695
1787
  TextEditor as default
1696
1788
  };
1697
- //# sourceMappingURL=TextEditor-RNHXPYJX.js.map
1789
+ //# sourceMappingURL=TextEditor-X2GSL4QM.js.map