@zvndev/darkmown 2.2.0 → 2.3.1-next.1.g3a4a8dc

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 (105) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +34 -2
  3. package/docs/spec-alignment.md +10 -0
  4. package/package.json +16 -11
  5. package/site/pages/docs/index.wd +14 -0
  6. package/site/pages/playground/index.js +47 -46
  7. package/src/catalog.js +16 -1
  8. package/src/compiler/actions.js +42 -22
  9. package/src/compiler/body.js +36 -14
  10. package/src/compiler/collections.js +16 -10
  11. package/src/compiler/context.js +39 -10
  12. package/src/compiler/fetch.js +39 -15
  13. package/src/compiler/format.js +5 -2
  14. package/src/compiler/forms.js +91 -26
  15. package/src/compiler/frontmatter.js +11 -2
  16. package/src/compiler/fs-reader.js +2 -1
  17. package/src/compiler/image-size.js +340 -0
  18. package/src/compiler/includes.js +8 -4
  19. package/src/compiler/interpolation.js +15 -7
  20. package/src/compiler/loops.js +63 -35
  21. package/src/compiler/markdown.js +4 -3
  22. package/src/compiler/media.js +17 -3
  23. package/src/compiler/page.js +8 -6
  24. package/src/compiler/predicates.js +49 -24
  25. package/src/compiler/reader.js +12 -2
  26. package/src/compiler/state.js +16 -2
  27. package/src/compiler/structure.js +24 -14
  28. package/src/deploy.js +8 -4
  29. package/src/errors.js +1156 -0
  30. package/src/router.js +7 -4
  31. package/src/scaffold.js +4 -2
  32. package/src/skin.js +17 -6
  33. package/types/api-runner.d.ts +94 -0
  34. package/types/builder.d.ts +141 -10
  35. package/types/catalog.d.ts +97 -0
  36. package/types/compiler/actions.d.ts +41 -0
  37. package/types/compiler/body.d.ts +11 -0
  38. package/types/compiler/collections.d.ts +76 -0
  39. package/types/compiler/context.d.ts +647 -0
  40. package/types/compiler/directives.d.ts +6 -0
  41. package/types/compiler/expr-ast.d.ts +20 -0
  42. package/types/compiler/fetch.d.ts +29 -0
  43. package/types/compiler/format.d.ts +49 -0
  44. package/types/compiler/forms.d.ts +94 -0
  45. package/types/compiler/frontmatter.d.ts +33 -0
  46. package/types/compiler/fs-reader.d.ts +7 -0
  47. package/types/compiler/image-size.d.ts +14 -0
  48. package/types/compiler/includes.d.ts +100 -0
  49. package/types/compiler/index.d.ts +5 -0
  50. package/types/compiler/interpolation.d.ts +115 -0
  51. package/types/compiler/loops.d.ts +36 -0
  52. package/types/compiler/markdown.d.ts +34 -0
  53. package/types/compiler/media.d.ts +32 -0
  54. package/types/compiler/page.d.ts +109 -0
  55. package/types/compiler/predicates.d.ts +50 -0
  56. package/types/compiler/reader.d.ts +48 -0
  57. package/types/compiler/state.d.ts +68 -0
  58. package/types/compiler/structure.d.ts +56 -0
  59. package/types/compiler.d.ts +35 -223
  60. package/types/dev.d.ts +47 -2
  61. package/types/errors.d.ts +100 -0
  62. package/types/feeds.d.ts +150 -0
  63. package/types/headers.d.ts +44 -0
  64. package/types/highlight.d.ts +24 -0
  65. package/types/router.d.ts +42 -3
  66. package/types/scaffold.d.ts +15 -3
  67. package/types/skin.d.ts +28 -1
  68. package/types/src/api-runner.d.ts +94 -0
  69. package/types/src/builder.d.ts +170 -0
  70. package/types/src/catalog.d.ts +97 -0
  71. package/types/src/compiler/actions.d.ts +41 -0
  72. package/types/src/compiler/body.d.ts +11 -0
  73. package/types/src/compiler/collections.d.ts +76 -0
  74. package/types/src/compiler/context.d.ts +647 -0
  75. package/types/src/compiler/directives.d.ts +6 -0
  76. package/types/src/compiler/expr-ast.d.ts +20 -0
  77. package/types/src/compiler/fetch.d.ts +29 -0
  78. package/types/src/compiler/format.d.ts +49 -0
  79. package/types/src/compiler/forms.d.ts +94 -0
  80. package/types/src/compiler/frontmatter.d.ts +33 -0
  81. package/types/src/compiler/fs-reader.d.ts +7 -0
  82. package/types/src/compiler/image-size.d.ts +14 -0
  83. package/types/src/compiler/includes.d.ts +100 -0
  84. package/types/src/compiler/index.d.ts +5 -0
  85. package/types/src/compiler/interpolation.d.ts +115 -0
  86. package/types/src/compiler/loops.d.ts +36 -0
  87. package/types/src/compiler/markdown.d.ts +34 -0
  88. package/types/src/compiler/media.d.ts +32 -0
  89. package/types/src/compiler/page.d.ts +109 -0
  90. package/types/src/compiler/predicates.d.ts +50 -0
  91. package/types/src/compiler/reader.d.ts +48 -0
  92. package/types/src/compiler/state.d.ts +68 -0
  93. package/types/src/compiler/structure.d.ts +56 -0
  94. package/types/src/compiler.d.ts +48 -0
  95. package/types/src/config.d.ts +45 -0
  96. package/types/src/dev.d.ts +58 -0
  97. package/types/src/errors.d.ts +100 -0
  98. package/types/src/feeds.d.ts +150 -0
  99. package/types/src/headers.d.ts +44 -0
  100. package/types/src/highlight.d.ts +24 -0
  101. package/types/src/router.d.ts +78 -0
  102. package/types/src/scaffold.d.ts +20 -0
  103. package/types/src/skin.d.ts +48 -0
  104. package/types/src/statics.d.ts +24 -0
  105. package/types/statics.d.ts +2 -1
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Compile a page source file into a full HTML document plus its assets.
3
+ * @param {string} file Absolute path to the source `.md`/`.wd` file.
4
+ * @param {Paths} context Resolved project paths.
5
+ * @param {{ feed?: { href: string, title: string }, collections?: Map<string, import("./collections.js").CollectionRow[]>, vars?: Record<string, unknown>, reader?: import("./reader.js").Reader }} [options]
6
+ * When a site-wide RSS feed is emitted (the home page set `site_url` and the
7
+ * site has dated posts), `feed` carries its absolute href + title so every page
8
+ * links it. `collections` is the build-time collection index a bare-name
9
+ * `@loop` resolves against; `vars` seeds the document scope (the pager `page`
10
+ * object on a paginated route). `reader` is the source reader (fs-backed by
11
+ * default via `src/compiler.js`; in-memory for `compileFromMemory`).
12
+ * @returns {CompiledPage}
13
+ */
14
+ export function compilePage(file: string, context: Paths, options?: {
15
+ feed?: {
16
+ href: string;
17
+ title: string;
18
+ };
19
+ collections?: Map<string, import("./collections.js").CollectionRow[]>;
20
+ vars?: Record<string, unknown>;
21
+ reader?: import("./reader.js").Reader;
22
+ }): CompiledPage;
23
+ /**
24
+ * Harden every `<img>` in the assembled page body — compile-time only, zero
25
+ * runtime JS. Bare markdown images reflow the page as they decode (cumulative
26
+ * layout shift — the literal "jump" on navigation) and load eagerly. This
27
+ * stamps intrinsic `width`/`height` (read from the file on disk so the browser
28
+ * reserves space), `decoding="async"` on all, and a load-priority split: the
29
+ * first image is the LCP candidate (eager + `fetchpriority="high"`), the rest
30
+ * lazy-load. Author-set attributes are never overwritten.
31
+ * @param {string} html Assembled page body HTML.
32
+ * @param {Paths} paths Resolved project paths.
33
+ * @param {import("./reader.js").Reader} reader Source reader for the image bytes.
34
+ * @returns {string}
35
+ */
36
+ export function enhanceImages(html: string, paths: Paths, reader: import("./reader.js").Reader): string;
37
+ /**
38
+ * Compile a source file into its body HTML, frontmatter, and assets (no page shell).
39
+ * @param {string} file Absolute path to the source file.
40
+ * @param {Paths} context Resolved project paths.
41
+ * @param {string[]} [stack] Include stack for cycle detection.
42
+ * @param {Record<string, unknown>} [vars] Initial static scope variables.
43
+ * @param {Map<string, import("./collections.js").CollectionRow[]>} [collections]
44
+ * Build-time collection index a bare-name `@loop` resolves against.
45
+ * @param {import("./reader.js").Reader} [reader] Source reader (fs-backed when
46
+ * omitted via `src/compiler.js`; in-memory for `compileFromMemory`).
47
+ * @returns {CompiledDocument}
48
+ */
49
+ export function compileDocument(file: string, context: Paths, stack?: string[], vars?: Record<string, unknown>, collections?: Map<string, import("./collections.js").CollectionRow[]>, reader?: import("./reader.js").Reader): CompiledDocument;
50
+ /**
51
+ * Compile a single file: parse frontmatter, collect assets, render body.
52
+ * @param {string} file
53
+ * @param {Paths} context
54
+ * @param {string[]} stack
55
+ * @param {Scope} scope
56
+ * @param {Compilation} comp
57
+ * @param {string[]} sections
58
+ * @param {string | null} loopItem
59
+ * @param {number} [reactiveDepth] Enclosing REACTIVE `@loop` levels, threaded in
60
+ * from the including page so an include's body can't bypass the two-level
61
+ * reactive-nesting limit at the `@include` boundary.
62
+ * @param {{ at: string, line: string } | null} [loopOpener] The enclosing `@loop`
63
+ * opener, threaded in so a depth error inside the include names the right opener.
64
+ * @returns {{ meta: Meta, html: string }}
65
+ */
66
+ export function compileFile(file: string, context: Paths, stack: string[], scope: Scope, comp: Compilation, sections: string[], loopItem: string | null, reactiveDepth?: number, loopOpener?: {
67
+ at: string;
68
+ line: string;
69
+ } | null): {
70
+ meta: Meta;
71
+ html: string;
72
+ };
73
+ /**
74
+ * Compile a page entirely from an in-memory file map — no filesystem, no
75
+ * `node:fs`. `files` maps PROJECT-RELATIVE POSIX paths (`site/pages/index.wd`,
76
+ * `site/_/nav.wd`) to their source strings; `entryPath` is the project-relative
77
+ * path of the page to compile. Includes, colocated `.skin`/`.js` detection, and
78
+ * `@loop` JSON-data reads all resolve against the same map (anything not in it
79
+ * is simply "absent"), so `@include`s work as long as their targets are present.
80
+ *
81
+ * This is the strategic fs-free entry point the browser playground and a planned
82
+ * mobile host use: the entire module graph reachable from here is free of
83
+ * `node:fs`, so it bundles for the browser. It returns the same
84
+ * {@link CompiledPage} shape as {@link compilePage} and throws the same
85
+ * `file:line` compile errors, so the error DX is identical in-browser.
86
+ * @param {Record<string, string> | Map<string, string>} files Project-relative
87
+ * path → source content.
88
+ * @param {string} entryPath Project-relative path of the page to compile.
89
+ * @param {{ feed?: { href: string, title: string }, collections?: Map<string, import("./collections.js").CollectionRow[]>, vars?: Record<string, unknown>, cwd?: string }} [options]
90
+ * Same shell options as {@link compilePage}; `cwd` overrides the virtual
91
+ * project root the relative keys resolve against (defaults to `/`).
92
+ * @returns {CompiledPage}
93
+ */
94
+ export function compileFromMemory(files: Record<string, string> | Map<string, string>, entryPath: string, options?: {
95
+ feed?: {
96
+ href: string;
97
+ title: string;
98
+ };
99
+ collections?: Map<string, import("./collections.js").CollectionRow[]>;
100
+ vars?: Record<string, unknown>;
101
+ cwd?: string;
102
+ }): CompiledPage;
103
+ export type Paths = import("./context.js").Paths;
104
+ export type Meta = import("./context.js").Meta;
105
+ export type Scope = import("./context.js").Scope;
106
+ export type Compilation = import("./context.js").Compilation;
107
+ export type Ctx = import("./context.js").Ctx;
108
+ export type CompiledDocument = import("./context.js").CompiledDocument;
109
+ export type CompiledPage = import("./context.js").CompiledPage;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @param {string} raw
3
+ * @param {string} itemName
4
+ * @param {Ctx} ctx
5
+ * @returns {Predicate}
6
+ */
7
+ export function compilePredicate(raw: string, itemName: string, ctx: Ctx): Predicate;
8
+ /**
9
+ * Evaluate a compiled predicate against a row at build time by walking its AST —
10
+ * the same closed evaluator the runtime uses, so the fold matches. No eval.
11
+ * @param {string} body
12
+ * @param {unknown} item
13
+ * @param {Ctx} ctx
14
+ * @returns {boolean}
15
+ */
16
+ export function evalPredicate(body: string, item: unknown, ctx: Ctx): boolean;
17
+ /**
18
+ * Compile a `::: … .class when <predicate>`. Allows `:if`-style bare truthy
19
+ * paths and `where`-style `left <op> right` conditions joined by `and`/`or`.
20
+ * Folds to a static verdict when every operand is build-known, else returns a
21
+ * runtime body over I()/S()/C() plus whether it reads the reactive loop item
22
+ * (which decides data-wd-each-class vs the global data-wd-class).
23
+ * @param {string} raw
24
+ * @param {Ctx} ctx
25
+ * @param {string} [what] Directive label for error messages.
26
+ * @returns {{ static: true, value: boolean } | { static: false, body: string, item: boolean }}
27
+ */
28
+ export function compileWhen(raw: string, ctx: Ctx, what?: string): {
29
+ static: true;
30
+ value: boolean;
31
+ } | {
32
+ static: false;
33
+ body: string;
34
+ item: boolean;
35
+ };
36
+ /**
37
+ * Compile a `:computed` expression into safe JS over the `S(key, path)` reader.
38
+ * @param {string} raw
39
+ * @param {Ctx} ctx
40
+ * @returns {string}
41
+ */
42
+ export function compileComputedExpr(raw: string, ctx: Ctx): string;
43
+ /**
44
+ * @typedef {import("./context.js").Ctx} Ctx
45
+ * @typedef {import("./context.js").Predicate} Predicate
46
+ */
47
+ export const PREDICATE_OPS: string[];
48
+ export const PREDICATE_JOINERS: string[];
49
+ export type Ctx = import("./context.js").Ctx;
50
+ export type Predicate = import("./context.js").Predicate;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The narrow filesystem surface the compiler needs. Every method takes an
3
+ * ABSOLUTE path (the compiler resolves includes/assets to absolute paths before
4
+ * reading), so a reader only has to map absolute paths to bytes/existence.
5
+ * @typedef {object} Reader
6
+ * @property {(absPath: string) => string} readText Read a UTF-8 text file.
7
+ * @property {(absPath: string) => Uint8Array} readBinary Read raw bytes (images).
8
+ * @property {(absPath: string) => boolean} exists Whether the path exists.
9
+ * @property {(absPath: string) => string} realpath Canonical path (symlinks
10
+ * resolved on a real fs; a no-op normalize in memory) — used for cycle keys.
11
+ */
12
+ /**
13
+ * A reader backed by an in-memory map of PROJECT-RELATIVE path → content. Keys
14
+ * are POSIX, project-relative (e.g. `site/pages/index.wd`, `site/_/nav.wd`);
15
+ * lookups translate an absolute compile path back to its key via `cwd`. There
16
+ * are no symlinks in memory, so `realpath` just normalizes. Binary reads are
17
+ * unsupported (the playground has no image files, and image measuring degrades
18
+ * to "no dimensions" on a throw), so `readBinary` throws — callers already
19
+ * try/catch it.
20
+ * @param {Record<string, string> | Map<string, string>} files
21
+ * @param {string} [cwd] Virtual project root the keys are relative to.
22
+ * @returns {Reader}
23
+ */
24
+ export function memoryReader(files: Record<string, string> | Map<string, string>, cwd?: string): Reader;
25
+ /**
26
+ * The narrow filesystem surface the compiler needs. Every method takes an
27
+ * ABSOLUTE path (the compiler resolves includes/assets to absolute paths before
28
+ * reading), so a reader only has to map absolute paths to bytes/existence.
29
+ */
30
+ export type Reader = {
31
+ /**
32
+ * Read a UTF-8 text file.
33
+ */
34
+ readText: (absPath: string) => string;
35
+ /**
36
+ * Read raw bytes (images).
37
+ */
38
+ readBinary: (absPath: string) => Uint8Array;
39
+ /**
40
+ * Whether the path exists.
41
+ */
42
+ exists: (absPath: string) => boolean;
43
+ /**
44
+ * Canonical path (symlinks
45
+ * resolved on a real fs; a no-op normalize in memory) — used for cycle keys.
46
+ */
47
+ realpath: (absPath: string) => string;
48
+ };
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @param {string} line
3
+ * @param {Ctx} ctx
4
+ * @param {number} index 0-based line index for `file:line` errors.
5
+ * @returns {string}
6
+ */
7
+ export function handleState(line: string, ctx: Ctx, index: number): string;
8
+ /**
9
+ * Register a state key in the current section scope, enabling the runtime.
10
+ * @param {string} name
11
+ * @param {unknown} value
12
+ * @param {Ctx} ctx
13
+ * @returns {string} The fully-qualified state key.
14
+ */
15
+ export function declareState(name: string, value: unknown, ctx: Ctx): string;
16
+ /**
17
+ * @param {string} line
18
+ * @param {Ctx} ctx
19
+ * @param {number} index 0-based line index for `file:line` errors.
20
+ * @returns {string}
21
+ */
22
+ export function handleStore(line: string, ctx: Ctx, index: number): string;
23
+ /**
24
+ * Register a page-global store. The bare name is added to `comp.state` so every
25
+ * resolver (interpolation, :if, @loop, :computed, actions) sees it, and tracked
26
+ * in `comp.stores` for collision checks. Never section-scoped.
27
+ * @param {string} name
28
+ * @param {unknown} value
29
+ * @param {Ctx} ctx
30
+ * @returns {string} The store name (also its bare state key).
31
+ */
32
+ export function declareStore(name: string, value: unknown, ctx: Ctx): string;
33
+ /**
34
+ * Seed a `<name>_error` state key (null) if absent. Shared by :fetch and the
35
+ * round-trip :form so error fallbacks have a key to bind.
36
+ * @param {string} key
37
+ * @param {Ctx} ctx
38
+ * @returns {void}
39
+ */
40
+ export function declareErrorState(key: string, ctx: Ctx): void;
41
+ /**
42
+ * @param {string} line
43
+ * @param {Ctx} ctx
44
+ * @param {number} index 0-based line index for `file:line` errors.
45
+ * @returns {string}
46
+ */
47
+ export function handleComputed(line: string, ctx: Ctx, index: number): string;
48
+ /**
49
+ * `:theme [name] [= "auto"]` declares a durable `:store` (default name `theme`,
50
+ * seed `"auto"`) and reflects its value onto `<html data-theme>`. This layers a
51
+ * manual light/dark switch over the OS preference: `"auto"` follows the skin's
52
+ * `tokens dark` media query, while `"light"`/`"dark"` force the matching
53
+ * `:root[data-theme]` scope. Wire a switch with ordinary store actions —
54
+ * `:button "Dark" -> theme = "dark"`. Durable, so the choice survives reloads.
55
+ * @param {string} line
56
+ * @param {Ctx} ctx
57
+ * @param {number} index 0-based line index for `file:line` errors.
58
+ * @returns {string}
59
+ */
60
+ export function handleTheme(line: string, ctx: Ctx, index: number): string;
61
+ /**
62
+ * @typedef {import("./context.js").Ctx} Ctx
63
+ */
64
+ export const STATE_EXAMPLE: ":state count = 0";
65
+ export const STORE_EXAMPLE: ":store cart = []";
66
+ export const COMPUTED_EXAMPLE: ":computed total = items.length * 4";
67
+ export const THEME_EXAMPLE: ":theme";
68
+ export type Ctx = import("./context.js").Ctx;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @param {string} line
3
+ * @param {Ctx} ctx
4
+ * @param {number} index 0-based line index for `file:line` errors.
5
+ * @returns {string}
6
+ */
7
+ export function handleInclude(line: string, ctx: Ctx, index: number): string;
8
+ /**
9
+ * @param {string} header
10
+ * @param {string[]} bodyLines
11
+ * @param {Ctx} ctx
12
+ * @param {number} index 0-based line index for `file:line` errors.
13
+ * @returns {string}
14
+ */
15
+ export function handleContainer(header: string, bodyLines: string[], ctx: Ctx, index: number): string;
16
+ /**
17
+ * `:carousel [autoplay=N]` … `:endcarousel` — a horizontally scroll-snapping
18
+ * carousel. Contract: each DIRECT child element of the track is one slide, so put
19
+ * each slide in its own block (e.g. a `::: slide` container) and give that block
20
+ * the slide sizing in your skin — loose prose lines would each count as a slide.
21
+ * Registers the `carousel` behavior (prev/next, dot nav, optional autoplay, mouse
22
+ * drag); native CSS scroll-snap + the page skin handle layout and touch swipe.
23
+ * `autoplay` is suppressed under `prefers-reduced-motion`. No runtime required.
24
+ * @param {string} line
25
+ * @param {string[]} bodyLines
26
+ * @param {Ctx} ctx
27
+ * @param {number} index 0-based line index for `file:line` errors.
28
+ * @returns {string}
29
+ */
30
+ export function handleCarousel(line: string, bodyLines: string[], ctx: Ctx, index: number): string;
31
+ /**
32
+ * @param {string} line
33
+ * @param {string[]} truthyLines
34
+ * @param {string[]} falsyLines
35
+ * @param {Ctx} ctx
36
+ * @param {number} index 0-based line index for `file:line` errors.
37
+ * @param {number} [falsyStart] 0-based index the falsy body starts at in the
38
+ * current slice, so nested errors in that branch report the true file line.
39
+ * @returns {string}
40
+ */
41
+ export function handleIf(line: string, truthyLines: string[], falsyLines: string[], ctx: Ctx, index: number, falsyStart?: number): string;
42
+ /**
43
+ * Render the documentation-demo directives (`:try`, `:note`, `:sprint`).
44
+ * @param {string} line
45
+ * @param {Ctx} ctx
46
+ * @returns {string}
47
+ */
48
+ export function renderDemoDirective(line: string, ctx: Ctx): string;
49
+ /**
50
+ * @typedef {import("./context.js").Ctx} Ctx
51
+ */
52
+ export const INCLUDE_EXAMPLE: "@include /header.wd";
53
+ export const CONTAINER_EXAMPLE: "::: card .featured";
54
+ export const IF_EXAMPLE: ":if count > 0";
55
+ export const CAROUSEL_EXAMPLE: ":carousel autoplay=3000";
56
+ export type Ctx = import("./context.js").Ctx;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Compile a page source file into a full HTML document plus its assets, reading
3
+ * from the real filesystem by default. Pass `options.reader` to compile against
4
+ * a different source (see `compileFromMemory`).
5
+ * @param {string} file Absolute path to the source `.md`/`.wd` file.
6
+ * @param {import("./config.js").Paths} context Resolved project paths.
7
+ * @param {{ feed?: { href: string, title: string }, collections?: Map<string, import("./compiler/collections.js").CollectionRow[]>, vars?: Record<string, unknown>, reader?: import("./compiler/reader.js").Reader }} [options]
8
+ * @returns {CompiledPage}
9
+ */
10
+ export function compilePage(file: string, context: import("./config.js").Paths, options?: {
11
+ feed?: {
12
+ href: string;
13
+ title: string;
14
+ };
15
+ collections?: Map<string, import("./compiler/collections.js").CollectionRow[]>;
16
+ vars?: Record<string, unknown>;
17
+ reader?: import("./compiler/reader.js").Reader;
18
+ }): CompiledPage;
19
+ /**
20
+ * Compile a source file into its body HTML, frontmatter, and assets (no page
21
+ * shell), reading from the real filesystem by default.
22
+ * @param {string} file Absolute path to the source file.
23
+ * @param {import("./config.js").Paths} context Resolved project paths.
24
+ * @param {string[]} [stack] Include stack for cycle detection.
25
+ * @param {Record<string, unknown>} [vars] Initial static scope variables.
26
+ * @param {Map<string, import("./compiler/collections.js").CollectionRow[]>} [collections]
27
+ * @param {import("./compiler/reader.js").Reader} [reader] Source reader.
28
+ * @returns {CompiledDocument}
29
+ */
30
+ export function compileDocument(file: string, context: import("./config.js").Paths, stack?: string[], vars?: Record<string, unknown>, collections?: Map<string, import("./compiler/collections.js").CollectionRow[]>, reader?: import("./compiler/reader.js").Reader): CompiledDocument;
31
+ /**
32
+ * Harden every `<img>` in an assembled page body, reading intrinsic dimensions
33
+ * from the real filesystem by default.
34
+ * @param {string} html Assembled page body HTML.
35
+ * @param {import("./config.js").Paths} paths Resolved project paths.
36
+ * @param {import("./compiler/reader.js").Reader} [reader] Source reader for image bytes.
37
+ * @returns {string}
38
+ */
39
+ export function enhanceImages(html: string, paths: import("./config.js").Paths, reader?: import("./compiler/reader.js").Reader): string;
40
+ export type Meta = import("./compiler/context.js").Meta;
41
+ export type FrontmatterValue = import("./compiler/context.js").FrontmatterValue;
42
+ export type Assets = import("./compiler/context.js").Assets;
43
+ export type Compilation = import("./compiler/context.js").Compilation;
44
+ export type Scope = import("./compiler/context.js").Scope;
45
+ export type Ctx = import("./compiler/context.js").Ctx;
46
+ export type CompiledDocument = import("./compiler/context.js").CompiledDocument;
47
+ export type CompiledPage = import("./compiler/context.js").CompiledPage;
48
+ export { compileFromMemory, escapeHtml, loopKeyOf, parseFrontmatter, stampScope } from "./compiler/index.js";
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Resolved project paths used across the build pipeline.
3
+ * @typedef {object} Paths
4
+ * @property {string} cwd Project working directory.
5
+ * @property {string} routesRoot Absolute path to `site/pages`.
6
+ * @property {string} shelfRoot Absolute path to the include shelf `site/_`.
7
+ * @property {string} distRoot Absolute path to the build output `dist`.
8
+ */
9
+ /**
10
+ * Build the absolute project paths for a given working directory.
11
+ * @param {string} [cwd] Project working directory (defaults to `process.cwd()`).
12
+ * @returns {Paths}
13
+ */
14
+ export function createPaths(cwd?: string): Paths;
15
+ /**
16
+ * Whether a file or directory name is hidden from routing (starts with `.`, `-`, or `_`).
17
+ * @param {string} name
18
+ * @returns {boolean}
19
+ */
20
+ export function isHiddenName(name: string): boolean;
21
+ export const routesDir: "site/pages";
22
+ export const shelfDir: "site/_";
23
+ export const distDir: "dist";
24
+ export const pageExtensions: Set<string>;
25
+ /**
26
+ * Resolved project paths used across the build pipeline.
27
+ */
28
+ export type Paths = {
29
+ /**
30
+ * Project working directory.
31
+ */
32
+ cwd: string;
33
+ /**
34
+ * Absolute path to `site/pages`.
35
+ */
36
+ routesRoot: string;
37
+ /**
38
+ * Absolute path to the include shelf `site/_`.
39
+ */
40
+ shelfRoot: string;
41
+ /**
42
+ * Absolute path to the build output `dist`.
43
+ */
44
+ distRoot: string;
45
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Serialize the dev server's rebuilds: at most ONE child build runs at a time.
3
+ * Every build read-modify-writes the dependency map (`dist/.wd-dev-deps.json`),
4
+ * so overlapping children could persist a stale map missing deps a concurrent
5
+ * build just recorded — after which the affected routes silently stop
6
+ * rebuilding. Changes debounce into a batch; changes arriving MID-build
7
+ * accumulate into the next batch (duplicate paths coalesce via the Set, and a
8
+ * `null` — a `src/` change or an unattributable event, forcing a full rebuild —
9
+ * swallows the whole batch into one full build).
10
+ * @param {(changed: string[]) => Promise<void> | void} runBuild Runs one child
11
+ * build over the changed `site/` paths (`[]` = full rebuild). Build failures
12
+ * are its own concern (report + resolve); a rejection still frees the queue.
13
+ * @param {number} [debounceMs] Debounce window for batching change events.
14
+ * @returns {{ change: (path: string | null) => void, close: () => void }}
15
+ */
16
+ export function createRebuildQueue(runBuild: (changed: string[]) => Promise<void> | void, debounceMs?: number): {
17
+ change: (path: string | null) => void;
18
+ close: () => void;
19
+ };
20
+ /**
21
+ * Inject the dev-client `<script>` before `</body>` (or append it if absent),
22
+ * plus — for a `draft: true` page — an inline draft-banner script. Both are
23
+ * injected at dev-SERVE time only, so neither ever touches the shipped HTML on
24
+ * disk (a production build excludes drafts entirely; a `build --drafts` staging
25
+ * build emits clean HTML with no banner).
26
+ * @param {string} html Page HTML to augment.
27
+ * @param {{ draft?: boolean }} [options] `draft: true` adds the visible banner.
28
+ * @returns {string}
29
+ */
30
+ export function injectDevClient(html: string, options?: {
31
+ draft?: boolean;
32
+ }): string;
33
+ /**
34
+ * The inline dev-only draft banner: a fixed bar marking the page as an unpublished
35
+ * draft, so it's unmistakable in `darkmown dev` that this content is excluded from
36
+ * a production build. Inert (`pointer-events:none`) and high-z so it never blocks
37
+ * the page; dev-serve-injected, so it's never in shipped output.
38
+ * @returns {string}
39
+ */
40
+ export function draftBannerScript(): string;
41
+ /**
42
+ * The page the dev server serves for a route with no dist output while the last
43
+ * build is FAILED — the honest alternative to the production 404 copy, which
44
+ * would claim the route "is hidden or has not been created" when the real cause
45
+ * is a compile error. The message renders inline (works without JS) and the
46
+ * injected dev client replays the `builderror` overlay on connect, then reloads
47
+ * the real page on the next successful build.
48
+ * @param {string} message The recorded build failure.
49
+ * @returns {string}
50
+ */
51
+ export function buildFailedPage(message: string): string;
52
+ /**
53
+ * The dev-client browser script that opens the SSE channel for live reload.
54
+ * @returns {string}
55
+ */
56
+ export function devClientScript(): string;
57
+ export const devClientPath: "/__wd/dev-client.js";
58
+ export const devEventsPath: "/__wd/dev-events";
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The full error-code registry, in code order. Each entry carries the stable
3
+ * code, its subsystem, a short title, what causes it, and how to fix it.
4
+ * @returns {ErrorEntry[]}
5
+ */
6
+ export function errorCatalog(): ErrorEntry[];
7
+ /**
8
+ * Look up one code, or undefined when it is not registered.
9
+ * @param {string} code
10
+ * @returns {ErrorEntry | undefined}
11
+ */
12
+ export function errorForCode(code: string): ErrorEntry | undefined;
13
+ /**
14
+ * Render `docs/errors.md` from the registry. Generated, never hand-edited, so
15
+ * the reference page cannot drift from the codes the compiler actually throws
16
+ * (`scripts/gen-errors.mjs` writes it; tests/error-codes.test.js re-checks it).
17
+ * @returns {string}
18
+ */
19
+ export function errorsMarkdown(): string;
20
+ /**
21
+ * One subsystem block of the numbering scheme.
22
+ * @typedef {object} ErrorArea
23
+ * @property {number} block The hundreds digit (0-9).
24
+ * @property {string} range Human label for the block, e.g. `WD1xx`.
25
+ * @property {string} name Short machine name, e.g. `loops`.
26
+ * @property {string} title One-line description of what the block covers.
27
+ */
28
+ /**
29
+ * A registered error code.
30
+ * @typedef {object} ErrorEntry
31
+ * @property {string} code The stable `WDxxx` identifier.
32
+ * @property {string} area The subsystem name (derived from the hundreds digit).
33
+ * @property {string} title Short name for the mistake.
34
+ * @property {string} cause What the author wrote that triggers it.
35
+ * @property {string} fix The corrective action, in one line.
36
+ * @property {string} [example] A concrete, compilable line, sourced from the
37
+ * compiler's own `*_EXAMPLE` constants.
38
+ */
39
+ /** The subsystem blocks, in code order. */
40
+ /** @type {ErrorArea[]} */
41
+ export const ERROR_AREAS: ErrorArea[];
42
+ /**
43
+ * Codes that were withdrawn. They are NEVER reused: a retired number stays
44
+ * listed here so the next free number in its block is always genuinely free,
45
+ * and so an old error message found in a log or an issue still resolves to a
46
+ * meaningful (if historical) entry. Empty today.
47
+ * @type {string[]}
48
+ */
49
+ export const RETIRED_CODES: string[];
50
+ /**
51
+ * One subsystem block of the numbering scheme.
52
+ */
53
+ export type ErrorArea = {
54
+ /**
55
+ * The hundreds digit (0-9).
56
+ */
57
+ block: number;
58
+ /**
59
+ * Human label for the block, e.g. `WD1xx`.
60
+ */
61
+ range: string;
62
+ /**
63
+ * Short machine name, e.g. `loops`.
64
+ */
65
+ name: string;
66
+ /**
67
+ * One-line description of what the block covers.
68
+ */
69
+ title: string;
70
+ };
71
+ /**
72
+ * A registered error code.
73
+ */
74
+ export type ErrorEntry = {
75
+ /**
76
+ * The stable `WDxxx` identifier.
77
+ */
78
+ code: string;
79
+ /**
80
+ * The subsystem name (derived from the hundreds digit).
81
+ */
82
+ area: string;
83
+ /**
84
+ * Short name for the mistake.
85
+ */
86
+ title: string;
87
+ /**
88
+ * What the author wrote that triggers it.
89
+ */
90
+ cause: string;
91
+ /**
92
+ * The corrective action, in one line.
93
+ */
94
+ fix: string;
95
+ /**
96
+ * A concrete, compilable line, sourced from the
97
+ * compiler's own `*_EXAMPLE` constants.
98
+ */
99
+ example?: string | undefined;
100
+ };