@bendyline/docblocks-react 2.6.2 → 2.7.1

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 (57) hide show
  1. package/README.md +3 -10
  2. package/THIRD_PARTY_NOTICES.txt +4284 -3651
  3. package/dist/AiDiagrams-LFV4YU6W.js +13 -0
  4. package/dist/AiEditorAssistant-GN2KXKZD.js +786 -0
  5. package/dist/AudioExportDialog-F23QXNPB.js +253 -0
  6. package/dist/DocumentConflictDialog-5LRVIGXS.js +111 -0
  7. package/dist/ExportDialog-IMBVGRYG.js +9 -0
  8. package/dist/{ExportToolbarControls-QYLBRWM7.js → ExportToolbarControls-MUM6HM3K.js} +117 -49
  9. package/dist/{GitToolbarControl-O5AXBC6T.js → GitToolbarControl-B7KG4MFP.js} +6 -6
  10. package/dist/{GitUI-L5T3XHZG.js → GitUI-RCWUZVS6.js} +6 -6
  11. package/dist/PresentationMaker-W2JIBHRN.js +9 -0
  12. package/dist/QuickOpenDialog-2KK4SEBU.js +356 -0
  13. package/dist/Settings-DuXk6baH.d.ts +144 -0
  14. package/dist/ShareDialog-XUA2OVGI.js +292 -0
  15. package/dist/SpeechToolbarControl-OSQS7NVY.js +434 -0
  16. package/dist/TextFromNarration-XYRAB6O2.js +598 -0
  17. package/dist/WorkspaceSearchPanel-BKZJRPMY.js +334 -0
  18. package/dist/chunk-2IYBBFQX.js +201 -0
  19. package/dist/{chunk-LG6HAWCK.js → chunk-56KO2LYN.js} +35 -4
  20. package/dist/chunk-6B7G33D5.js +88 -0
  21. package/dist/chunk-ARATARVJ.js +40 -0
  22. package/dist/{chunk-ODYNOPC3.js → chunk-BCQZTWE5.js} +57 -17
  23. package/dist/{chunk-FMDLZ4ZG.js → chunk-BD54Z5XP.js} +12 -3
  24. package/dist/chunk-EA4BO6E4.js +73 -0
  25. package/dist/chunk-EPOLZNFD.js +518 -0
  26. package/dist/chunk-G4MFB3IO.js +208 -0
  27. package/dist/{chunk-MRUK56JS.js → chunk-GMA4KGGO.js} +7 -3
  28. package/dist/chunk-I44HKDQX.js +314 -0
  29. package/dist/chunk-K4I3NJFL.js +49 -0
  30. package/dist/chunk-KBDZDFPU.js +61 -0
  31. package/dist/{chunk-FNSRCCBC.js → chunk-KWG6UP5O.js} +0 -10
  32. package/dist/chunk-NAH52736.js +1884 -0
  33. package/dist/chunk-RP3DVNTI.js +62 -0
  34. package/dist/chunk-SPUPWCSI.js +111 -0
  35. package/dist/chunk-TBLZBNQF.js +25 -0
  36. package/dist/{chunk-M5Y5WO7Z.js → chunk-UG4G7PJ4.js} +1 -1
  37. package/dist/chunk-UONFWKJ7.js +22 -0
  38. package/dist/chunk-VO2JYYQZ.js +40 -0
  39. package/dist/chunk-W55E6TE2.js +1714 -0
  40. package/dist/chunk-X3DDTJKR.js +574 -0
  41. package/dist/{chunk-EBWYGTN7.js → chunk-X437UAF7.js} +6 -0
  42. package/dist/editor.d.ts +36 -1
  43. package/dist/editor.js +16 -1
  44. package/dist/export/index.d.ts +27 -11
  45. package/dist/export/index.js +11 -7
  46. package/dist/index.d.ts +100 -13
  47. package/dist/index.js +3927 -1638
  48. package/dist/proofing/index.js +11 -1
  49. package/dist/{run-export-I2XOVGG4.js → run-export-47X5FTYZ.js} +3 -3
  50. package/dist/settings/index.d.ts +32 -101
  51. package/dist/settings/index.js +14 -2
  52. package/package.json +9 -9
  53. package/src/styles/docblocks.css +2344 -657
  54. package/dist/ExportDialog-Q4VWI43H.js +0 -9
  55. package/dist/ShareDialog-4OX3UPJ4.js +0 -359
  56. package/dist/chunk-JDJVRDOP.js +0 -92
  57. package/dist/chunk-Q6XNIKDG.js +0 -669
@@ -0,0 +1,62 @@
1
+ // src/Export/video-export-doc.ts
2
+ import { parseMarkdown } from "@bendyline/squisq/markdown";
3
+ var DATA_PREVIEW_ROWS = 50;
4
+ var TRANSFORM_KEY = "squisq-transform";
5
+ var LEGACY_TRANSFORM_KEY = "transform-style";
6
+ function persistedTransformStyle(frontmatter, knownIds) {
7
+ if (!frontmatter) return null;
8
+ const value = Object.prototype.hasOwnProperty.call(frontmatter, TRANSFORM_KEY) ? frontmatter[TRANSFORM_KEY] : frontmatter[LEGACY_TRANSFORM_KEY];
9
+ if (typeof value !== "string") return null;
10
+ const normalized = value.trim().toLowerCase().replace(/\s+/g, "-");
11
+ const id = normalized === "datadriven" ? "data-driven" : normalized;
12
+ return knownIds.has(id) ? id : null;
13
+ }
14
+ async function withDataPreviews(doc, container, resolveDataReferences) {
15
+ try {
16
+ const { defaultDataReaders } = await import("@bendyline/squisq-formats/data");
17
+ const resolved = await resolveDataReferences(doc, container, {
18
+ readers: defaultDataReaders(),
19
+ maxPreviewRows: DATA_PREVIEW_ROWS
20
+ });
21
+ return resolved.doc;
22
+ } catch {
23
+ return doc;
24
+ }
25
+ }
26
+ async function buildVideoExportDoc(markdownSource, options = {}) {
27
+ const [
28
+ {
29
+ buildPreviewDoc,
30
+ documentTitleFromFileName,
31
+ markdownToDoc,
32
+ resolveAudioMapping,
33
+ resolveDataReferences
34
+ },
35
+ { applyTransform, getTransformStyleSummaries }
36
+ ] = await Promise.all([import("@bendyline/squisq/doc"), import("@bendyline/squisq/transform")]);
37
+ let doc = markdownToDoc(parseMarkdown(markdownSource));
38
+ const container = options.workspaceContainer;
39
+ if (container) {
40
+ doc = await resolveAudioMapping(doc, container).catch(() => doc);
41
+ doc = await withDataPreviews(doc, container, resolveDataReferences);
42
+ }
43
+ const knownIds = new Set(getTransformStyleSummaries().map((summary) => summary.id));
44
+ const transformStyle = persistedTransformStyle(doc.frontmatter, knownIds);
45
+ const contentDoc = transformStyle ? applyTransform(doc, transformStyle).doc : doc;
46
+ const narrationOwnsTimeline = (contentDoc.documentMedia ?? []).some(
47
+ (clip) => clip.anchor === "document"
48
+ );
49
+ const projected = buildPreviewDoc(contentDoc, {
50
+ documentTitle: documentTitleFromFileName(options.fileName ?? void 0),
51
+ interleaveImages: !narrationOwnsTimeline
52
+ });
53
+ const invalidPresentation = projected.diagnostics?.find(
54
+ (diagnostic) => diagnostic.code === "presentation-invalid"
55
+ );
56
+ if (invalidPresentation) throw new Error(invalidPresentation.message);
57
+ return { ...projected, audio: contentDoc.audio };
58
+ }
59
+
60
+ export {
61
+ buildVideoExportDoc
62
+ };
@@ -0,0 +1,111 @@
1
+ // src/Export/shared-document.ts
2
+ import {
3
+ SHARED_DOCUMENT_LIMITS,
4
+ createSharedDocumentUrl
5
+ } from "@bendyline/docblocks/share";
6
+ var PUBLIC_DOCBLOCKS_SHARE_URL = "https://docblocks.com/";
7
+ function resolveSharedDocumentBaseUrl(currentUrl) {
8
+ try {
9
+ const current = new URL(currentUrl);
10
+ if (current.protocol === "http:" || current.protocol === "https:") {
11
+ current.hash = "";
12
+ current.searchParams.delete("action");
13
+ return current.toString();
14
+ }
15
+ } catch {
16
+ }
17
+ return PUBLIC_DOCBLOCKS_SHARE_URL;
18
+ }
19
+ function sharedDocumentFilename(selectedFile) {
20
+ const basename = selectedFile?.replace(/\\/gu, "/").split("/").pop() ?? "shared.md";
21
+ const stem = basename.replace(/\.md$/iu, "").replace(/[^A-Za-z0-9._-]+/gu, "-");
22
+ const bounded = stem.replace(/^-+|-+$/gu, "").slice(0, 80) || "shared";
23
+ return `${bounded}.md`;
24
+ }
25
+ async function omitSharedImages(markdown) {
26
+ const { parseMarkdown, rewriteMarkdownReferences, splitFrontmatterBlock, walkMarkdownTree } = await import("@bendyline/squisq/markdown");
27
+ const { frontmatter, body } = splitFrontmatterBlock(markdown);
28
+ const imageReferences = /* @__PURE__ */ new Set();
29
+ const linkReferences = /* @__PURE__ */ new Set();
30
+ walkMarkdownTree(parseMarkdown(body, { frontmatter: false }), (node) => {
31
+ if (node.type === "imageReference") imageReferences.add(node.identifier);
32
+ if (node.type === "linkReference") linkReferences.add(node.identifier);
33
+ });
34
+ let sharedBody = rewriteMarkdownReferences(body, { images: "omit" });
35
+ let sharedDocument = parseMarkdown(sharedBody, { frontmatter: false });
36
+ let descriptionContainsImage = false;
37
+ walkMarkdownTree(sharedDocument, (node) => {
38
+ if (node.type === "image" || node.type === "imageReference") descriptionContainsImage = true;
39
+ if (node.type === "imageReference") imageReferences.add(node.identifier);
40
+ if (node.type === "linkReference") linkReferences.add(node.identifier);
41
+ });
42
+ if (descriptionContainsImage) {
43
+ sharedBody = rewriteMarkdownReferences(sharedBody, { images: "omit" });
44
+ sharedDocument = parseMarkdown(sharedBody, { frontmatter: false });
45
+ walkMarkdownTree(sharedDocument, (node) => {
46
+ if (node.type === "image" || node.type === "imageReference") {
47
+ throw new Error(
48
+ "An image description contains image markup that cannot be shared as text."
49
+ );
50
+ }
51
+ });
52
+ }
53
+ if (imageReferences.size > 0) {
54
+ const removals = [];
55
+ walkMarkdownTree(sharedDocument, (node) => {
56
+ if (node.type !== "definition" || !imageReferences.has(node.identifier) || linkReferences.has(node.identifier)) {
57
+ return;
58
+ }
59
+ const start = node.position?.start.offset;
60
+ const end = node.position?.end.offset;
61
+ if (start === void 0 || end === void 0) {
62
+ throw new Error("Cannot locate an image reference in the shared document.");
63
+ }
64
+ removals.push({ start, end });
65
+ });
66
+ for (const { start, end } of removals.sort((a, b) => b.start - a.start)) {
67
+ sharedBody = sharedBody.slice(0, start) + sharedBody.slice(end);
68
+ }
69
+ }
70
+ return (frontmatter ?? "") + sharedBody;
71
+ }
72
+ async function createSharedDocumentArchive(markdown, selectedFile) {
73
+ const sharedMarkdown = await omitSharedImages(markdown);
74
+ const encoded = new TextEncoder().encode(sharedMarkdown);
75
+ if (encoded.byteLength > SHARED_DOCUMENT_LIMITS.markdownBytes) {
76
+ throw new Error(
77
+ `This document is too large for a shared URL (maximum ${SHARED_DOCUMENT_LIMITS.markdownBytes.toLocaleString()} UTF-8 bytes).`
78
+ );
79
+ }
80
+ const [{ MemoryContentContainer }, { containerToZip }] = await Promise.all([
81
+ import("@bendyline/squisq/storage"),
82
+ import("@bendyline/squisq-formats/container")
83
+ ]);
84
+ const container = new MemoryContentContainer();
85
+ await container.writeFile(sharedDocumentFilename(selectedFile), encoded, "text/markdown");
86
+ const blob = await containerToZip(container, { compression: "DEFLATE", compressionLevel: 9 });
87
+ return new Uint8Array(await blob.arrayBuffer());
88
+ }
89
+ function buildSharedDocumentUrl(baseUrl, archive, mode) {
90
+ return createSharedDocumentUrl(resolveSharedDocumentBaseUrl(baseUrl), archive, mode);
91
+ }
92
+ function buildSharedDocumentQrUrl(archive, mode) {
93
+ const url = createSharedDocumentUrl(PUBLIC_DOCBLOCKS_SHARE_URL, archive, mode);
94
+ if (url.length > SHARED_DOCUMENT_LIMITS.qrUrlCharacters) {
95
+ throw new Error(
96
+ "This document is too large for a reliable QR code (maximum " + SHARED_DOCUMENT_LIMITS.qrUrlCharacters.toLocaleString() + " URL characters). Copy the share link instead."
97
+ );
98
+ }
99
+ return url;
100
+ }
101
+ function sharedDocumentQrFilename(selectedFile) {
102
+ return sharedDocumentFilename(selectedFile).replace(/\.md$/iu, "-qr.png");
103
+ }
104
+
105
+ export {
106
+ sharedDocumentFilename,
107
+ createSharedDocumentArchive,
108
+ buildSharedDocumentUrl,
109
+ buildSharedDocumentQrUrl,
110
+ sharedDocumentQrFilename
111
+ };
@@ -0,0 +1,25 @@
1
+ // src/components/HighlightedText.tsx
2
+ import { Fragment } from "react";
3
+ import { Fragment as Fragment2, jsx } from "react/jsx-runtime";
4
+ function HighlightedText({ text, ranges }) {
5
+ const parts = [];
6
+ let cursor = 0;
7
+ for (const [rawStart, rawEnd] of ranges) {
8
+ const start = Math.max(cursor, Math.min(rawStart, text.length));
9
+ const end = Math.min(rawEnd, text.length);
10
+ if (end <= start) continue;
11
+ if (start > cursor)
12
+ parts.push(/* @__PURE__ */ jsx(Fragment, { children: text.slice(cursor, start) }, `t${cursor}`));
13
+ parts.push(
14
+ /* @__PURE__ */ jsx("mark", { className: "db-search-match", children: text.slice(start, end) }, `m${start}`)
15
+ );
16
+ cursor = end;
17
+ }
18
+ if (cursor < text.length)
19
+ parts.push(/* @__PURE__ */ jsx(Fragment, { children: text.slice(cursor) }, `t${cursor}`));
20
+ return /* @__PURE__ */ jsx(Fragment2, { children: parts });
21
+ }
22
+
23
+ export {
24
+ HighlightedText
25
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FORMAT_EXTENSIONS
3
- } from "./chunk-EBWYGTN7.js";
3
+ } from "./chunk-X437UAF7.js";
4
4
 
5
5
  // src/Export/export-filename.ts
6
6
  function buildExportFilename(selectedFile, options) {
@@ -0,0 +1,22 @@
1
+ // src/Export/host-error.ts
2
+ function hostErrorDetail(caught) {
3
+ return caught instanceof Error ? caught.message.replace(/^Error invoking remote method '[^']+': Error:\s*/, "").trim() : "";
4
+ }
5
+
6
+ // src/Export/image-save.ts
7
+ function createImageSaveOutput(adapter) {
8
+ return async (blob, filename) => {
9
+ try {
10
+ const target = await adapter.pickTarget(filename, null);
11
+ if (!target) return false;
12
+ return await adapter.saveBlob(blob, filename, target) !== null;
13
+ } catch (caught) {
14
+ throw new Error(hostErrorDetail(caught) || `Couldn't save "${filename}".`);
15
+ }
16
+ };
17
+ }
18
+
19
+ export {
20
+ hostErrorDetail,
21
+ createImageSaveOutput
22
+ };
@@ -0,0 +1,40 @@
1
+ // src/Speech/useSpeechStatus.ts
2
+ import { useEffect, useState } from "react";
3
+ function useSpeechStatus(speech) {
4
+ const [status, setStatus] = useState(null);
5
+ useEffect(() => {
6
+ let live = true;
7
+ const unsubscribe = speech.onStatus((next) => {
8
+ if (live) setStatus(next);
9
+ });
10
+ void speech.status().then(
11
+ (initial) => {
12
+ if (live) setStatus((current) => current ?? initial);
13
+ },
14
+ () => {
15
+ if (live)
16
+ setStatus(
17
+ (current) => current ?? {
18
+ stt: {
19
+ state: "unavailable",
20
+ reason: "Speech status is unavailable. Try opening Settings."
21
+ },
22
+ tts: {
23
+ state: "unavailable",
24
+ reason: "Speech status is unavailable. Try opening Settings."
25
+ }
26
+ }
27
+ );
28
+ }
29
+ );
30
+ return () => {
31
+ live = false;
32
+ unsubscribe();
33
+ };
34
+ }, [speech]);
35
+ return status;
36
+ }
37
+
38
+ export {
39
+ useSpeechStatus
40
+ };