@bendyline/docblocks-react 2.4.0 → 2.6.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.
@@ -0,0 +1,112 @@
1
+ import { ProofingIgnoreStore, ProofingProvider } from '@bendyline/squisq-editor-react';
2
+
3
+ /**
4
+ * The app-level proofing dictionary — words the user accepted through
5
+ * "Add to dictionary" that should stay accepted everywhere on this device.
6
+ *
7
+ * This is deliberately separate from a document's own
8
+ * `squisq-proof-dictionary` frontmatter, which travels with the file. A name
9
+ * the user writes in every document belongs here; a term specific to one
10
+ * document belongs in that document.
11
+ *
12
+ * Surfaces without durable web storage (the VS Code webview uses the host's
13
+ * state API rather than `localStorage`) pass no store, and only the per-document
14
+ * frontmatter dictionary applies.
15
+ */
16
+ /** Where accepted words are remembered between sessions. */
17
+ interface ProofingDictionaryStore {
18
+ /** Every accepted word, in no particular order. */
19
+ read(): readonly string[];
20
+ /** Remember one more accepted word. Duplicates are harmless. */
21
+ append(word: string): void;
22
+ }
23
+ /**
24
+ * Browser-local app dictionary, shared by every workspace on this device.
25
+ *
26
+ * Used by the site and by the Electron renderer, whose `app://` origin keeps
27
+ * `localStorage` stable across launches and updates.
28
+ */
29
+ declare function createLocalProofingDictionary(): ProofingDictionaryStore;
30
+
31
+ /**
32
+ * Browser-local persistence for dismissed ("Ignore") proofing findings.
33
+ *
34
+ * Squisq deliberately never writes dismissals into the document — they are
35
+ * one person's editing preference, and a file travelling through git must not
36
+ * carry them to everyone else. So the engine's state is handed to the host,
37
+ * scoped per document, and DocBlocks keeps it beside its other browser-local
38
+ * preferences.
39
+ *
40
+ * The stored payload is the engine's OPAQUE export: it holds context hashes as
41
+ * integers above 2^53, so it is only ever moved as a string and handed back
42
+ * verbatim. Nothing here parses it.
43
+ *
44
+ * Entries are keyed by workspace **and** path, matching `last-state` and
45
+ * `pinned-documents`: the same relative path means different documents in
46
+ * different workspaces, and dismissals must not leak between them.
47
+ */
48
+
49
+ interface ProofingIgnoreStorage {
50
+ getItem(key: string): string | null;
51
+ setItem(key: string, value: string): void;
52
+ }
53
+ /** Composite key for one document. `\u0000` cannot occur in either half. */
54
+ declare function proofingIgnoreKey(workspaceId: string, documentPath: string): string;
55
+ /**
56
+ * Create the store DocBlocks hands to Squisq.
57
+ *
58
+ * `resolveWorkspaceId` is read at call time rather than captured, because the
59
+ * active workspace changes underneath a mounted shell. A store created while
60
+ * no workspace is active simply does not persist: an unsaved scratch buffer
61
+ * keeping its dismissals only for the session is the documented behavior.
62
+ */
63
+ declare function createLocalProofingIgnoreStore(resolveWorkspaceId: () => string | null, storageOverride?: ProofingIgnoreStorage | null): ProofingIgnoreStore;
64
+
65
+ /**
66
+ * Host wiring for Squisq's proofing capability — grammar and spellcheck by
67
+ * [harper.js](https://github.com/Automattic/harper), Apache-2.0, running
68
+ * entirely offline in a Web Worker.
69
+ *
70
+ * Every DocBlocks surface serves the same engine from its own origin, because
71
+ * there is no CDN fallback and nothing may leave the device: the site
72
+ * publishes it beside the PWA precache, the Electron renderer inside
73
+ * `app.asar`, the VS Code webview inside the VSIX. Only two things differ per
74
+ * surface — where the WASM lives and where an accepted word is remembered —
75
+ * so those are the parameters here and everything else is shared.
76
+ *
77
+ * Nothing is downloaded by creating a provider. Squisq loads the engine
78
+ * lazily, on the first markdown document with checking effective, so the
79
+ * shell paints and the document opens whether or not the ~30 MiB binary pair
80
+ * has arrived. A failed load is retried on the next use rather than cached.
81
+ */
82
+
83
+ interface DocBlocksProofingOptions {
84
+ /**
85
+ * URL of harper's full WASM binary as this surface publishes it. May be
86
+ * root- or base-relative; the engine absolutizes it against the page before
87
+ * handing it to the worker that does the fetching.
88
+ *
89
+ * The build must publish `harper_wasm_slim_bg.wasm` in the same directory:
90
+ * the engine derives that sibling by substituting the file name and loads
91
+ * both. See `scripts/vite-harper-wasm.ts`.
92
+ */
93
+ wasmUrl: string;
94
+ /**
95
+ * Where "Add to dictionary" persists app-wide. Omit for surfaces without
96
+ * durable storage — a document's own `squisq-proof-dictionary` frontmatter
97
+ * still applies either way.
98
+ */
99
+ dictionary?: ProofingDictionaryStore | null;
100
+ }
101
+ /**
102
+ * Create the proofing provider a DocBlocks surface passes to its shell.
103
+ *
104
+ * Hold the result in module scope rather than creating one per render. The
105
+ * shell remounts the editor on every document switch, and a host-owned
106
+ * instance keeps the warm engine (a cold WASM setup costs seconds) alive
107
+ * across those remounts; a provider the editor owns would be disposed and
108
+ * rebuilt each time.
109
+ */
110
+ declare function createDocBlocksProofingProvider(options: DocBlocksProofingOptions): ProofingProvider;
111
+
112
+ export { type DocBlocksProofingOptions, type ProofingDictionaryStore, type ProofingIgnoreStorage, createDocBlocksProofingProvider, createLocalProofingDictionary, createLocalProofingIgnoreStore, proofingIgnoreKey };
@@ -0,0 +1,50 @@
1
+ import {
2
+ createLocalProofingIgnoreStore,
3
+ proofingIgnoreKey
4
+ } from "../chunk-DUKTAKB4.js";
5
+
6
+ // src/Proofing/public-api.ts
7
+ import { createHarperProofingProvider } from "@bendyline/squisq-editor-react/proofing";
8
+
9
+ // src/Proofing/proofing-dictionary.ts
10
+ var STORAGE_KEY = "docblocks:proofingDictionary";
11
+ function readWords() {
12
+ try {
13
+ const raw = localStorage.getItem(STORAGE_KEY);
14
+ if (!raw) return [];
15
+ const parsed = JSON.parse(raw);
16
+ if (!Array.isArray(parsed)) return [];
17
+ return parsed.filter((word) => typeof word === "string");
18
+ } catch {
19
+ return [];
20
+ }
21
+ }
22
+ function createLocalProofingDictionary() {
23
+ return {
24
+ read: readWords,
25
+ append(word) {
26
+ try {
27
+ const words = new Set(readWords());
28
+ words.add(word);
29
+ localStorage.setItem(STORAGE_KEY, JSON.stringify([...words]));
30
+ } catch {
31
+ }
32
+ }
33
+ };
34
+ }
35
+
36
+ // src/Proofing/public-api.ts
37
+ function createDocBlocksProofingProvider(options) {
38
+ const { wasmUrl, dictionary } = options;
39
+ return createHarperProofingProvider({
40
+ wasmUrl,
41
+ initialWords: dictionary?.read() ?? [],
42
+ onDictionaryWord: dictionary ? (word) => dictionary.append(word) : void 0
43
+ });
44
+ }
45
+ export {
46
+ createDocBlocksProofingProvider,
47
+ createLocalProofingDictionary,
48
+ createLocalProofingIgnoreStore,
49
+ proofingIgnoreKey
50
+ };
@@ -41,6 +41,31 @@ interface WriteCanvasPreferences {
41
41
  fontScheme: WriteCanvasFontScheme;
42
42
  }
43
43
 
44
+ /**
45
+ * Inline proofing preferences — which squiggles the editor draws.
46
+ *
47
+ * Two independent switches rather than one, because they fail
48
+ * differently: spell checking is language-agnostic enough to leave on
49
+ * everywhere, while the grammar rules harper ships are English-only and
50
+ * are noise in a document written in anything else. The engine itself is
51
+ * still all-or-nothing (harper lints once and reports a category per
52
+ * finding), so these filter what surfaces; turning both off is what
53
+ * turns proofing — and the ~30 MiB engine download — off entirely.
54
+ *
55
+ * Stored per browser/profile, never in the document: a reader's tolerance
56
+ * for green underlines is not content. The per-document opt-out lives in
57
+ * `squisq-proofing` frontmatter and is separate from this.
58
+ */
59
+ interface ProofingPreferences {
60
+ /** Draw red squiggles under misspellings. */
61
+ spelling: boolean;
62
+ /** Draw green/blue squiggles under grammar and style findings. */
63
+ grammar: boolean;
64
+ }
65
+ declare const DEFAULT_PROOFING_PREFERENCES: Readonly<ProofingPreferences>;
66
+ declare function loadProofingPreferences(): ProofingPreferences;
67
+ declare function saveProofingPreferences(value: ProofingPreferences): void;
68
+
44
69
  interface SettingsDialogProps {
45
70
  title?: string;
46
71
  onClose: () => void;
@@ -59,10 +84,21 @@ interface AccentColorSettingsProps {
59
84
  name?: string;
60
85
  }
61
86
  declare function AccentColorSettings({ value, onChange, name, }: AccentColorSettingsProps): react_jsx_runtime.JSX.Element;
87
+ interface ProofingSettingsControlsProps {
88
+ value: ProofingPreferences;
89
+ onChange: (settings: ProofingPreferences) => void;
90
+ }
91
+ /**
92
+ * Spelling and grammar squiggles, as two switches. Grammar is separable
93
+ * because harper's grammar rules are English-only — a writer working in
94
+ * another language wants the spell checker and none of the green
95
+ * underlines. With both off no checking engine is ever downloaded.
96
+ */
97
+ declare function ProofingSettingsControls({ value, onChange }: ProofingSettingsControlsProps): react_jsx_runtime.JSX.Element;
62
98
  interface WriteCanvasSettingsControlsProps {
63
99
  value: WriteCanvasPreferences;
64
100
  onChange: (settings: WriteCanvasPreferences) => void;
65
101
  }
66
102
  declare function WriteCanvasSettingsControls({ value, onChange }: WriteCanvasSettingsControlsProps): react_jsx_runtime.JSX.Element;
67
103
 
68
- export { type AccentColor, AccentColorSettings, type AccentColorSettingsProps, DEFAULT_WRITE_CANVAS_FONT_SCHEME, SettingsDialog, type SettingsDialogProps, type ThemePreference, ThemeSettings, type ThemeSettingsProps, WRITE_CANVAS_FONT_SCHEMES, type WriteCanvasFontScheme, type WriteCanvasFontSchemeGroup, type WriteCanvasFontSchemeOption, type WriteCanvasPreferences, WriteCanvasSettingsControls, type WriteCanvasSettingsControlsProps, resolveWriteCanvasFonts };
104
+ export { type AccentColor, AccentColorSettings, type AccentColorSettingsProps, DEFAULT_PROOFING_PREFERENCES, DEFAULT_WRITE_CANVAS_FONT_SCHEME, type ProofingPreferences, ProofingSettingsControls, type ProofingSettingsControlsProps, SettingsDialog, type SettingsDialogProps, type ThemePreference, ThemeSettings, type ThemeSettingsProps, WRITE_CANVAS_FONT_SCHEMES, type WriteCanvasFontScheme, type WriteCanvasFontSchemeGroup, type WriteCanvasFontSchemeOption, type WriteCanvasPreferences, WriteCanvasSettingsControls, type WriteCanvasSettingsControlsProps, loadProofingPreferences, resolveWriteCanvasFonts, saveProofingPreferences };
@@ -1,19 +1,27 @@
1
1
  import {
2
2
  AccentColorSettings,
3
+ DEFAULT_PROOFING_PREFERENCES,
3
4
  DEFAULT_WRITE_CANVAS_FONT_SCHEME,
5
+ ProofingSettingsControls,
4
6
  SettingsDialog,
5
7
  ThemeSettings,
6
8
  WRITE_CANVAS_FONT_SCHEMES,
7
9
  WriteCanvasSettingsControls,
8
- resolveWriteCanvasFonts
9
- } from "../chunk-VRRL6VTD.js";
10
+ loadProofingPreferences,
11
+ resolveWriteCanvasFonts,
12
+ saveProofingPreferences
13
+ } from "../chunk-Q6XNIKDG.js";
10
14
  import "../chunk-LG6HAWCK.js";
11
15
  export {
12
16
  AccentColorSettings,
17
+ DEFAULT_PROOFING_PREFERENCES,
13
18
  DEFAULT_WRITE_CANVAS_FONT_SCHEME,
19
+ ProofingSettingsControls,
14
20
  SettingsDialog,
15
21
  ThemeSettings,
16
22
  WRITE_CANVAS_FONT_SCHEMES,
17
23
  WriteCanvasSettingsControls,
18
- resolveWriteCanvasFonts
24
+ loadProofingPreferences,
25
+ resolveWriteCanvasFonts,
26
+ saveProofingPreferences
19
27
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/docblocks-react",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "React components for DocBlocks — file explorer, workspace picker, and editor shell",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -21,7 +21,7 @@
21
21
  "access": "public"
22
22
  },
23
23
  "engines": {
24
- "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
24
+ "node": "^24.18.0 || >=26.0.0"
25
25
  },
26
26
  "type": "module",
27
27
  "main": "./dist/index.js",
@@ -47,6 +47,16 @@
47
47
  "import": "./dist/export/index.js",
48
48
  "default": "./dist/export/index.js"
49
49
  },
50
+ "./calculation": {
51
+ "types": "./dist/calculation/index.d.ts",
52
+ "import": "./dist/calculation/index.js",
53
+ "default": "./dist/calculation/index.js"
54
+ },
55
+ "./proofing": {
56
+ "types": "./dist/proofing/index.d.ts",
57
+ "import": "./dist/proofing/index.js",
58
+ "default": "./dist/proofing/index.js"
59
+ },
50
60
  "./settings": {
51
61
  "types": "./dist/settings/index.d.ts",
52
62
  "import": "./dist/settings/index.js",
@@ -75,16 +85,19 @@
75
85
  }
76
86
  },
77
87
  "dependencies": {
78
- "@bendyline/docblocks": "2.4.0",
79
- "@bendyline/squisq": "2.8.0",
80
- "@bendyline/squisq-editor-react": "2.8.0",
81
- "@bendyline/squisq-formats": "2.4.5",
82
- "@bendyline/squisq-react": "2.8.0",
83
- "@bendyline/squisq-video": "2.3.0",
84
- "@bendyline/squisq-video-react": "2.4.0"
88
+ "@bendyline/docblocks": "2.6.0",
89
+ "@bendyline/squisq": "2.11.1",
90
+ "@bendyline/squisq-calc": "2.11.0",
91
+ "@bendyline/squisq-editor-react": "2.11.1",
92
+ "@bendyline/squisq-formats": "2.6.1",
93
+ "@bendyline/squisq-react": "2.11.1",
94
+ "@bendyline/squisq-video": "2.3.4",
95
+ "@bendyline/squisq-video-react": "2.4.5",
96
+ "qrcode": "1.5.4"
85
97
  },
86
98
  "devDependencies": {
87
99
  "@happy-dom/global-registrator": "20.9.0",
100
+ "@types/qrcode": "1.5.6",
88
101
  "@types/react": "18.3.28",
89
102
  "@types/react-dom": "18.3.7",
90
103
  "happy-dom": "20.9.0",