@brett_lamy/docstream 0.5.3 → 0.5.5

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.
package/README.md CHANGED
@@ -236,6 +236,21 @@ plugin validates the mount boundary, only edits existing files, and notifies
236
236
  Vite after a save so the preview reloads through Vite's normal module pipeline.
237
237
  Set `writable: false` on a mount when a documentation site should only render.
238
238
 
239
+ The Vite endpoints exist only during development. For a deployed static site,
240
+ bundle the referenced modules and use the read-only production client:
241
+
242
+ ```tsx
243
+ import { createBundledSourceClient } from "@brett_lamy/docstream"
244
+ import * as ButtonModule from "./components/Button"
245
+
246
+ const client = createBundledSourceClient({
247
+ "ui:Button.tsx": ButtonModule,
248
+ })
249
+ ```
250
+
251
+ Entries may also be lazy import functions. Keys can be `mount:path` (recommended)
252
+ or just `path` when names cannot collide.
253
+
239
254
  ## Assets and OpenAPI Specs
240
255
 
241
256
  Relative image and OpenAPI spec paths can be resolved against an asset base:
@@ -258,6 +273,7 @@ You can also resolve paths yourself with `resolveAsset`.
258
273
  - `OpenApiOperation`: Renders a parsed OpenAPI operation block.
259
274
  - `SourcePreview`: Imports and renders a mounted component or CSF story export.
260
275
  - `createViteSourceClient`: Reads, writes, and imports files exposed by the Vite plugin.
276
+ - `createBundledSourceClient`: Imports bundled source modules in read-only production builds.
261
277
 
262
278
  ### Parser and Serializer
263
279
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brett_lamy/docstream",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "GitBook-aware readonly markdown and AI stream renderer.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -72,6 +72,7 @@
72
72
  "@brett_lamy/viz-engine": ">=0.2.0",
73
73
  "framer-motion": "^13.1.1",
74
74
  "hast-util-to-html": "^9.0.5",
75
+ "katex": "^0.18.5",
75
76
  "lowlight": "^3.3.0",
76
77
  "lucide-react": "^1.17.0",
77
78
  "mermaid": "^11.15.0",
@@ -1,5 +1,6 @@
1
1
  import { useState, type ReactNode } from "react"
2
2
  import { LayoutGroup, motion } from "framer-motion"
3
+ import "katex/dist/katex.min.css"
3
4
  import {
4
5
  AlertTriangle,
5
6
  CheckCircle2,
@@ -18,6 +19,11 @@ import { OpenApiOperation } from "../openapi/OpenApiOperation"
18
19
  import { Mermaid } from "./Mermaid"
19
20
  import { HighlightedCode } from "./HighlightedCode"
20
21
  import { CitationSources, InlineReference } from "./reference"
22
+ import { renderMathToHtml } from "./math"
23
+
24
+ function MathBlock({ formula }: { formula: string }) {
25
+ return <div className="docs-math" dangerouslySetInnerHTML={{ __html: renderMathToHtml(formula) }} />
26
+ }
21
27
 
22
28
  export interface LivePreviewProps {
23
29
  files: Record<string, string>
@@ -327,7 +333,7 @@ function BlockView({ block, liveRenderer, sourceRenderer }: { block: Block } & R
327
333
  </table>
328
334
  )
329
335
  case "math":
330
- return <pre className="docs-math">{block.formula}</pre>
336
+ return <MathBlock formula={block.formula} />
331
337
  case "updates":
332
338
  return (
333
339
  <div className="docs-updates">
@@ -0,0 +1,9 @@
1
+ import katex from "katex"
2
+
3
+ export function renderMathToHtml(formula: string): string {
4
+ return katex.renderToString(formula, {
5
+ displayMode: true,
6
+ throwOnError: false,
7
+ output: "htmlAndMathml",
8
+ })
9
+ }
@@ -431,7 +431,6 @@ export function parseBlocks(lines: string[]): Block[] {
431
431
  const fence = trimmed.match(/^(`{3,}|~{3,})([^\s`]*)?(?:\s+(.*?))?\s*$/)
432
432
  if (fence) {
433
433
  flushParagraph()
434
- const marker = fence[1][0]
435
434
  const attrs = parseAttrs(fence[3])
436
435
  const code: string[] = []
437
436
  i++
package/src/index.ts CHANGED
@@ -36,8 +36,9 @@ export type {
36
36
  ReactDemoProps,
37
37
  } from "./playground"
38
38
  export { resolveAsset, setAssetBase } from "./assets"
39
- export { createViteSourceClient, SourcePreview } from "./source"
39
+ export { createBundledSourceClient, createViteSourceClient, SourcePreview } from "./source"
40
40
  export type {
41
+ BundledSourceModule,
41
42
  SourceFileSnapshot,
42
43
  SourceModule,
43
44
  SourcePreviewProps,
@@ -1,6 +1,8 @@
1
1
  import type { SourceRefNode } from "../gitbook/ast"
2
2
  import type { SourceFileSnapshot, SourceReferenceClient, SourceModule } from "./types"
3
3
 
4
+ export type BundledSourceModule = SourceModule | (() => SourceModule | Promise<SourceModule>)
5
+
4
6
  function params(reference: SourceRefNode): URLSearchParams {
5
7
  return new URLSearchParams({
6
8
  mount: reference.mount,
@@ -38,3 +40,20 @@ export function createViteSourceClient(apiBase = "/@docstream"): SourceReference
38
40
  },
39
41
  }
40
42
  }
43
+
44
+ /** Create a read-only source client for modules included in a production bundle. */
45
+ export function createBundledSourceClient(modules: Record<string, BundledSourceModule>): SourceReferenceClient {
46
+ return {
47
+ async read() {
48
+ throw new Error("Source text is unavailable in a bundled source client.")
49
+ },
50
+ async write() {
51
+ throw new Error("Bundled source previews are read-only.")
52
+ },
53
+ async importModule(reference) {
54
+ const entry = modules[`${reference.mount}:${reference.path}`] ?? modules[reference.path]
55
+ if (!entry) throw new Error(`No bundled source module found for ${reference.mount}:${reference.path}`)
56
+ return typeof entry === "function" ? entry() : entry
57
+ },
58
+ }
59
+ }
@@ -1,4 +1,5 @@
1
- export { createViteSourceClient } from "./client"
1
+ export { createBundledSourceClient, createViteSourceClient } from "./client"
2
+ export type { BundledSourceModule } from "./client"
2
3
  export { SourcePreview } from "./SourcePreview"
3
4
  export type { SourcePreviewProps } from "./SourcePreview"
4
5
  export type {
package/src/styles.css CHANGED
@@ -489,10 +489,12 @@
489
489
  border-radius: 12px;
490
490
  padding: 14px 16px;
491
491
  background: var(--gb-muted);
492
- font-family: ui-monospace, Menlo, monospace;
493
- font-size: 13.5px;
494
492
  text-align: center;
495
- white-space: pre-wrap;
493
+ overflow-x: auto;
494
+ }
495
+
496
+ .docs-math .katex-display {
497
+ margin: 0;
496
498
  }
497
499
 
498
500
  .docs-updates {