@lightspeed-js/core 0.1.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 (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/compile.js +1494 -0
  4. package/dist/index.js +3060 -0
  5. package/dist/ssg.js +3620 -0
  6. package/dist/types/build.d.ts +1 -0
  7. package/dist/types/index.d.ts +8 -0
  8. package/dist/types/src/agent/index.d.ts +175 -0
  9. package/dist/types/src/cli/commands/agent.d.ts +9 -0
  10. package/dist/types/src/cli/commands/build.d.ts +2 -0
  11. package/dist/types/src/cli/commands/create.d.ts +2 -0
  12. package/dist/types/src/cli/commands/dev.d.ts +2 -0
  13. package/dist/types/src/cli/commands/index.d.ts +3 -0
  14. package/dist/types/src/cli/index.d.ts +2 -0
  15. package/dist/types/src/cli/types/commands.d.ts +11 -0
  16. package/dist/types/src/cli/types/index.d.ts +1 -0
  17. package/dist/types/src/cli/utils/commands.d.ts +5 -0
  18. package/dist/types/src/cli/utils/index.d.ts +1 -0
  19. package/dist/types/src/compile/expressions.d.ts +76 -0
  20. package/dist/types/src/compile/index.d.ts +44 -0
  21. package/dist/types/src/compile/logic.d.ts +101 -0
  22. package/dist/types/src/manifest.d.ts +148 -0
  23. package/dist/types/src/marker.d.ts +85 -0
  24. package/dist/types/src/parser/index.d.ts +2 -0
  25. package/dist/types/src/parser/layout.d.ts +32 -0
  26. package/dist/types/src/parser/lsp.d.ts +56 -0
  27. package/dist/types/src/parser/route.d.ts +87 -0
  28. package/dist/types/src/parser/style-source-node.d.ts +19 -0
  29. package/dist/types/src/parser/style.d.ts +20 -0
  30. package/dist/types/src/parser/template.d.ts +32 -0
  31. package/dist/types/src/parser/test.d.ts +1 -0
  32. package/dist/types/src/runtime/bindings/BindingEvaluator.d.ts +174 -0
  33. package/dist/types/src/runtime/bindings/index.d.ts +2 -0
  34. package/dist/types/src/runtime/compiler/ImportTransformer.d.ts +11 -0
  35. package/dist/types/src/runtime/compiler/index.d.ts +1 -0
  36. package/dist/types/src/runtime/components/ComponentInstance.d.ts +110 -0
  37. package/dist/types/src/runtime/components/ComponentRegistry.d.ts +11 -0
  38. package/dist/types/src/runtime/components/index.d.ts +3 -0
  39. package/dist/types/src/runtime/components/types/index.d.ts +34 -0
  40. package/dist/types/src/runtime/core.d.ts +251 -0
  41. package/dist/types/src/runtime/diagnostics.d.ts +33 -0
  42. package/dist/types/src/runtime/dom/ForBlock.d.ts +127 -0
  43. package/dist/types/src/runtime/dom/Mounter.d.ts +223 -0
  44. package/dist/types/src/runtime/dom/StyleManager.d.ts +57 -0
  45. package/dist/types/src/runtime/dom/hydration.d.ts +35 -0
  46. package/dist/types/src/runtime/dom/index.d.ts +7 -0
  47. package/dist/types/src/runtime/events/EventBinder.d.ts +18 -0
  48. package/dist/types/src/runtime/events/index.d.ts +1 -0
  49. package/dist/types/src/runtime/globals/GlobalFunctions.d.ts +24 -0
  50. package/dist/types/src/runtime/globals/index.d.ts +1 -0
  51. package/dist/types/src/runtime/helpers.d.ts +141 -0
  52. package/dist/types/src/runtime/index.d.ts +16 -0
  53. package/dist/types/src/runtime/reactive/ReactiveProxy.d.ts +63 -0
  54. package/dist/types/src/runtime/reactive/UpdateScheduler.d.ts +9 -0
  55. package/dist/types/src/runtime/reactive/index.d.ts +2 -0
  56. package/dist/types/src/runtime/signals/SignalManager.d.ts +10 -0
  57. package/dist/types/src/runtime/signals/index.d.ts +3 -0
  58. package/dist/types/src/runtime/signals/signals.d.ts +16 -0
  59. package/dist/types/src/runtime/signals/types/index.d.ts +1 -0
  60. package/dist/types/src/runtime/signals/types/signals.d.ts +7 -0
  61. package/dist/types/src/runtime/state/Cell.d.ts +68 -0
  62. package/dist/types/src/runtime/state/CellManager.d.ts +101 -0
  63. package/dist/types/src/runtime/state/index.d.ts +4 -0
  64. package/dist/types/src/specifiers.d.ts +16 -0
  65. package/dist/types/src/ssg/index.d.ts +21 -0
  66. package/dist/types/src/ssg/rebuild.d.ts +49 -0
  67. package/dist/types/src/ssg/render.d.ts +104 -0
  68. package/dist/types/src/types/lsp.d.ts +22 -0
  69. package/dist/types/src/types/optional.d.ts +14 -0
  70. package/dist/types/src/types/virtual.d.ts +4 -0
  71. package/dist/types/src/vite/csp.d.ts +12 -0
  72. package/dist/types/src/vite/index.d.ts +2 -0
  73. package/dist/types/src/vite/layout.d.ts +17 -0
  74. package/dist/types/src/vite/plugin.d.ts +69 -0
  75. package/dist/types/src/vite/routes.d.ts +139 -0
  76. package/dist/types/test/adopted-styles.test.d.ts +1 -0
  77. package/dist/types/test/adoption.test.d.ts +1 -0
  78. package/dist/types/test/agent.test.d.ts +1 -0
  79. package/dist/types/test/audit.test.d.ts +1 -0
  80. package/dist/types/test/bindings.test.d.ts +1 -0
  81. package/dist/types/test/branches-in-loops.test.d.ts +1 -0
  82. package/dist/types/test/build.test.d.ts +1 -0
  83. package/dist/types/test/buildtime.test.d.ts +1 -0
  84. package/dist/types/test/built.test.d.ts +1 -0
  85. package/dist/types/test/cell-props.test.d.ts +1 -0
  86. package/dist/types/test/comments.test.d.ts +1 -0
  87. package/dist/types/test/compile-expressions.test.d.ts +1 -0
  88. package/dist/types/test/compile-logic.test.d.ts +1 -0
  89. package/dist/types/test/components.test.d.ts +1 -0
  90. package/dist/types/test/composition.test.d.ts +1 -0
  91. package/dist/types/test/declared-needs.test.d.ts +1 -0
  92. package/dist/types/test/diagnostics.test.d.ts +1 -0
  93. package/dist/types/test/dynamic.test.d.ts +1 -0
  94. package/dist/types/test/example.test.d.ts +1 -0
  95. package/dist/types/test/faq.test.d.ts +1 -0
  96. package/dist/types/test/flatten-nested.test.d.ts +1 -0
  97. package/dist/types/test/html-binding.test.d.ts +1 -0
  98. package/dist/types/test/hydration-report.test.d.ts +1 -0
  99. package/dist/types/test/hydration.test.d.ts +1 -0
  100. package/dist/types/test/layout-resolution.test.d.ts +1 -0
  101. package/dist/types/test/layout.test.d.ts +1 -0
  102. package/dist/types/test/lazy.test.d.ts +1 -0
  103. package/dist/types/test/manifest.test.d.ts +1 -0
  104. package/dist/types/test/model-props.test.d.ts +1 -0
  105. package/dist/types/test/model.test.d.ts +1 -0
  106. package/dist/types/test/mounting.test.d.ts +1 -0
  107. package/dist/types/test/needs.test.d.ts +1 -0
  108. package/dist/types/test/nested-rows.test.d.ts +1 -0
  109. package/dist/types/test/on-mounted.test.d.ts +1 -0
  110. package/dist/types/test/on-update.test.d.ts +1 -0
  111. package/dist/types/test/page-island.test.d.ts +1 -0
  112. package/dist/types/test/pages.test.d.ts +1 -0
  113. package/dist/types/test/reactivity.test.d.ts +1 -0
  114. package/dist/types/test/rebuild-keeps-logic.test.d.ts +1 -0
  115. package/dist/types/test/rebuild.test.d.ts +1 -0
  116. package/dist/types/test/reenumerate.test.d.ts +1 -0
  117. package/dist/types/test/refresh.test.d.ts +1 -0
  118. package/dist/types/test/refs.test.d.ts +1 -0
  119. package/dist/types/test/reorder.test.d.ts +1 -0
  120. package/dist/types/test/route.test.d.ts +1 -0
  121. package/dist/types/test/routes-build.test.d.ts +1 -0
  122. package/dist/types/test/routes-dev.test.d.ts +1 -0
  123. package/dist/types/test/routes-emit.test.d.ts +1 -0
  124. package/dist/types/test/routes-runtime.test.d.ts +1 -0
  125. package/dist/types/test/setup.d.ts +59 -0
  126. package/dist/types/test/show.test.d.ts +1 -0
  127. package/dist/types/test/skeleton-adoption.test.d.ts +1 -0
  128. package/dist/types/test/slots.test.d.ts +1 -0
  129. package/dist/types/test/specifiers.test.d.ts +1 -0
  130. package/dist/types/test/ssg.test.d.ts +1 -0
  131. package/dist/types/test/state.test.d.ts +1 -0
  132. package/dist/types/test/static-islands.test.d.ts +1 -0
  133. package/dist/types/test/stats.test.d.ts +1 -0
  134. package/dist/types/test/structural.test.d.ts +1 -0
  135. package/dist/types/test/style-sources.test.d.ts +1 -0
  136. package/dist/types/test/styles.test.d.ts +1 -0
  137. package/dist/types/test/surgical-rebuild.test.d.ts +1 -0
  138. package/dist/types/test/tables.test.d.ts +1 -0
  139. package/dist/types/test/unmount.test.d.ts +1 -0
  140. package/dist/types/test/verbatim.test.d.ts +1 -0
  141. package/dist/vite.js +5655 -0
  142. package/package.json +64 -0
@@ -0,0 +1,49 @@
1
+ import type { ComponentDefinition } from "../runtime/components/index.js";
2
+ /**
3
+ * Re-render built pages against fresher content, without the bundler.
4
+ *
5
+ * `fetchAt: "build"` content is exactly as stale as the last build (ADR-013),
6
+ * so publishing a corrected paragraph would otherwise mean rebuilding the whole
7
+ * site. The intended shape is a CMS webhook naming what changed, and only the
8
+ * pages that read it being re-rendered.
9
+ *
10
+ * Nothing about the JavaScript or CSS changes, so none of it is rebuilt: the
11
+ * shells recorded at build already carry the hashed asset tags, and the same
12
+ * `renderPage` runs over them again.
13
+ */
14
+ export interface RebuildOptions {
15
+ /** Build output directory - where re-rendered pages are written. */
16
+ dist: string;
17
+ /**
18
+ * The build manifest, if it is not at `.lightspeed/manifest.json`.
19
+ *
20
+ * It lives outside `dist` because it is build metadata, not site output:
21
+ * page shells alone were ~17% of a deployed build that nobody fetches. A
22
+ * build agent has the working tree, so it has this.
23
+ */
24
+ manifest?: string;
25
+ /** Component definitions, compiled from source. */
26
+ definitions: ComponentDefinition[];
27
+ /**
28
+ * Restrict to pages reading this content key - what a webhook would pass.
29
+ * Omitted, every page with build-time content is re-rendered.
30
+ */
31
+ cell?: string;
32
+ /** Restrict to named pages, e.g. `blog.html`. Wins over `cell`. */
33
+ pages?: string[];
34
+ css?: "inline" | "external";
35
+ }
36
+ export interface RebuildResult {
37
+ /** Pages written, in the order they were rendered. */
38
+ rebuilt: string[];
39
+ /** Paths that did not exist before - new entries. */
40
+ added?: string[];
41
+ /** Paths whose entry is gone; their files were deleted. */
42
+ removed?: string[];
43
+ /** Pages considered and skipped, with why. */
44
+ skipped: Array<{
45
+ page: string;
46
+ reason: string;
47
+ }>;
48
+ }
49
+ export declare function rebuildPages(options: RebuildOptions): Promise<RebuildResult>;
@@ -0,0 +1,104 @@
1
+ import type { ComponentDefinition } from "../runtime/components/index.js";
2
+ /**
3
+ * Render a page's islands to HTML at build time.
4
+ *
5
+ * Runs the **real runtime** against a DOM rather than reimplementing rendering:
6
+ * `$for`, `$if`, props, blocks and bindings all behave identically for free,
7
+ * and there is no second renderer to drift.
8
+ *
9
+ * jsdom specifically, because it parses with parse5 - the same parser browsers
10
+ * implement. A looser parser could serialise markup a browser would rearrange,
11
+ * which is precisely the class of bug that bit the old element markers.
12
+ */
13
+ export interface RenderPageOptions {
14
+ html: string;
15
+ definitions: ComponentDefinition[];
16
+ /**
17
+ * Ship inert islands as plain HTML.
18
+ *
19
+ * **On by default.** The build mounts every component and records what it
20
+ * needed the browser for; an island that needed nothing loses its markers,
21
+ * so the client never adopts it and never fetches its chunk.
22
+ *
23
+ * `$hydrate="always"` keeps one the evidence gets wrong - a listener
24
+ * attached from a promise, a library reaching for the element after mount.
25
+ * Turn the whole thing off only to compare against what hydration would have
26
+ * done.
27
+ */
28
+ flattenStatic?: boolean;
29
+ /**
30
+ * Inline this page's critical CSS, or leave it for the caller to emit as a
31
+ * cacheable file. Inline avoids a render-blocking round trip and any CLS;
32
+ * external trades that for cross-page caching.
33
+ */
34
+ css?: "inline" | "external";
35
+ /**
36
+ * Cell values seeded before rendering.
37
+ *
38
+ * How a route's params reach the page: they are an ordinary cell, so
39
+ * `shared.route` binds, `$needs` gates on it and it travels in the state
40
+ * payload like any other build-time content - no separate mechanism, and no
41
+ * routing API on the runtime.
42
+ */
43
+ seed?: Record<string, unknown>;
44
+ /**
45
+ * A pattern the *client* resolves against the URL.
46
+ *
47
+ * Only for a page whose paths could not be enumerated at build: one file
48
+ * answers many URLs, so the params cannot be baked and the pattern travels
49
+ * instead.
50
+ */
51
+ routePattern?: string;
52
+ /**
53
+ * Compiled expressions from the page's own island markers.
54
+ *
55
+ * They belong to no component, so the build renders with the same table the
56
+ * browser will get from the entry chunk.
57
+ */
58
+ pageExpressions?: {
59
+ expressions?: Record<string, any>;
60
+ writers?: Record<string, any>;
61
+ };
62
+ }
63
+ export interface RenderPageResult {
64
+ html: string;
65
+ /** Islands rendered, and islands left as a skeleton. */
66
+ rendered: number;
67
+ skipped: number;
68
+ /** Component ids this page can reach, following `uses` transitively. */
69
+ used: string[];
70
+ /** Critical CSS for those components - inlined unless css is "external". */
71
+ css: string;
72
+ /** Deferred CSS for those components. */
73
+ cssDeferred: string;
74
+ /**
75
+ * Cell keys this page fetched at build.
76
+ *
77
+ * Recorded so a rebuild can be targeted: a CMS webhook says which content
78
+ * changed, and only the pages that read it need re-rendering.
79
+ */
80
+ content: string[];
81
+ /**
82
+ * The state payload this page shipped.
83
+ *
84
+ * Returned so a caller can read build-time content back out - which is what
85
+ * lets a route enumerate its rows from the same cell the page rendered.
86
+ */
87
+ state: Record<string, unknown>;
88
+ /**
89
+ * What each island would need the browser for.
90
+ *
91
+ * Evidence gathered while it rendered, not read out of its source. An island
92
+ * with no reasons is one nothing would happen to if the client never mounted
93
+ * it - a candidate for shipping as plain HTML.
94
+ */
95
+ hydration: {
96
+ id: string;
97
+ componentId: string;
98
+ live: boolean;
99
+ reasons: string[];
100
+ }[];
101
+ /** Islands shipped as plain HTML because nothing needed them in the browser. */
102
+ flattened: number;
103
+ }
104
+ export declare function renderPage(options: RenderPageOptions): Promise<RenderPageResult>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Ambient types for consumers.
3
+ *
4
+ * A `.lsp` file becomes a JS module at build time, so TypeScript needs telling
5
+ * what that module looks like. Equivalent to the `*.vue` shim Vue ships.
6
+ */
7
+
8
+ declare module "*.lsp" {
9
+ const component: import("../runtime/index.js").ComponentDefinition
10
+ export default component
11
+
12
+ export const template: string
13
+ export const skeleton: string
14
+ export const style: string
15
+ export const logic: string
16
+ export const scopeId: string
17
+ }
18
+
19
+ interface Window {
20
+ /** Set by the app so hot reload can reach the running runtime. */
21
+ lightspeed?: import("../runtime/index.js").LightspeedRuntime
22
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Compilers the Vite plugin will use if they happen to be installed.
3
+ *
4
+ * They are loaded through a dynamic import inside a try/catch and are NOT
5
+ * dependencies - esbuild, which Vite already brings, is the default. These
6
+ * declarations keep that optional path typecheckable without pulling anything
7
+ * in.
8
+ */
9
+ declare module "@swc/core" {
10
+ export function transform(
11
+ code: string,
12
+ options?: any,
13
+ ): Promise<{ code: string }>
14
+ }
@@ -0,0 +1,4 @@
1
+ declare module "virtual:lightspeed/components" {
2
+ /** Component id to a dynamic import, generated by the Vite plugin. */
3
+ export const components: Record<string, () => Promise<unknown>>
4
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * CSP hashes for the inline `<style>` blocks in a built page.
3
+ *
4
+ * A **nonce cannot work for static output**: it must differ per response, and a
5
+ * file on disk carries one value forever, which is a nonce in name only.
6
+ * Hashes are the static equivalent - the content is fixed, so the build can
7
+ * state exactly what a host should allow via `style-src 'sha256-...'`.
8
+ *
9
+ * Build-side only. `manifest.ts` is imported by the runtime, so nothing that
10
+ * reaches for `node:crypto` can live there.
11
+ */
12
+ export declare function styleHashes(html: string): string[];
@@ -0,0 +1,2 @@
1
+ export { lightspeedPlugin } from "./plugin.js";
2
+ export type {} from "./plugin.js";
@@ -0,0 +1,17 @@
1
+ export declare const LAYOUT_PREFIX = "_";
2
+ export declare const DEFAULT_LAYOUT_FILE = "_layout.html";
3
+ /** `plain` → `_plain.html`, `layouts/admin` → `layouts/_admin.html`. */
4
+ export declare function layoutFileName(name: string): string;
5
+ export interface LayoutResult {
6
+ html: string;
7
+ /** Every layout file involved, so dev can watch them. */
8
+ sources: string[];
9
+ }
10
+ /**
11
+ * Expand a page into its layout, if it has one.
12
+ *
13
+ * Layouts may themselves declare a layout, which is how a section layout wraps
14
+ * a site one. Depth is capped so a cycle fails loudly rather than hanging the
15
+ * dev server.
16
+ */
17
+ export declare function expandLayout(html: string, filename: string, root: string): Promise<LayoutResult>;
@@ -0,0 +1,69 @@
1
+ import type { Plugin } from "vite";
2
+ interface LightspeedPluginOptions {
3
+ typescript?: boolean;
4
+ /**
5
+ * Emit every page as a directory index, so URLs carry no `.html`.
6
+ *
7
+ * Opt-in rather than default: it changes the shape of the output, and a
8
+ * project that links to `about.html` would break. Pages declaring
9
+ * `<!-- lsp:route -->` produce real files per row regardless of this.
10
+ */
11
+ routes?: boolean;
12
+ /**
13
+ * Ship islands that needed nothing from the browser as plain HTML.
14
+ *
15
+ * The build watches every component render and records what it needed the
16
+ * browser for. With this on, anything that needed nothing loses its markers:
17
+ * no adoption, no logic, and no chunk fetched.
18
+ *
19
+ * On by default. `$hydrate="always"` is the escape hatch for anything the
20
+ * evidence gets wrong, and `$hydrate="never"` is an assertion that fails the
21
+ * build when something live is inside a subtree declared static.
22
+ */
23
+ flattenStatic?: boolean;
24
+ /**
25
+ * Which host's syntax to emit rewrite rules in, for runtime-resolved routes.
26
+ *
27
+ * Only used by a route with no `from` - a baked route needs no server
28
+ * cooperation at all.
29
+ */
30
+ rewrites?: "_redirects" | "caddy" | "nginx";
31
+ compiler?: "tsc" | "esbuild" | "swc";
32
+ /**
33
+ * Where a page's critical CSS goes.
34
+ *
35
+ * "inline" (default) costs no round trip and cannot cause CLS. "external"
36
+ * emits a hashed file that caches across pages, at the cost of a
37
+ * render-blocking request - worth it for a site with heavy internal
38
+ * navigation, not for a landing page.
39
+ */
40
+ css?: "inline" | "external";
41
+ /**
42
+ * Render islands to HTML during `vite build`.
43
+ *
44
+ * Off in dev: the client mounts anyway, so rendering twice would only slow
45
+ * reloads. On in build, where it is the difference between shipping markers
46
+ * and shipping content a crawler can read.
47
+ */
48
+ render?: boolean;
49
+ /**
50
+ * Where else to look for `.lsp` components, besides the project's `src`.
51
+ *
52
+ * A component library is a package of components, and until this existed a
53
+ * package could not ship any: the scan only ever looked in the app being
54
+ * built, so a shared picker had to be copied into every app that mounted it
55
+ * - and copies drift.
56
+ *
57
+ * Paths are relative to the Vite root. Components are compiled by *this*
58
+ * build rather than shipped pre-built, so the host's styling, hydration
59
+ * policy and CSP apply to them exactly as they do to its own.
60
+ *
61
+ * Names are a flat namespace: a component is its filename, lowercased, from
62
+ * wherever it was found. The project's own `src` is searched first and wins,
63
+ * so an app can replace a package's component by giving a file the same
64
+ * name - deliberate, and announced in the build log rather than silent.
65
+ */
66
+ componentDirs?: string[];
67
+ }
68
+ export declare function lightspeedPlugin(options?: LightspeedPluginOptions): Plugin[];
69
+ export {};
@@ -0,0 +1,139 @@
1
+ import type { ComponentDefinition } from "../runtime/components/index.js";
2
+ import { type ParsedRoute, type RouteDeclaration } from "../parser/route.js";
3
+ /**
4
+ * Re-anchor relative asset URLs for a file at a different depth.
5
+ *
6
+ * With a relative `base`, Vite computes each page's `../` prefix from where
7
+ * that page sits - correct for pages it emits, and wrong for the copies a
8
+ * route makes, which sit deeper. A row whose slug contains a slash is deeper
9
+ * still, so this cannot be a constant per route.
10
+ *
11
+ * Absolute URLs need nothing, which is why an absolute `base` sidesteps all of
12
+ * this.
13
+ */
14
+ export declare function reanchorRelativeUrls(html: string, fromDepth: number, toDepth: number): string;
15
+ export interface RoutePage {
16
+ /** Page file basename, e.g. `blog.html`. */
17
+ page: string;
18
+ route: ParsedRoute;
19
+ declaration: RouteDeclaration;
20
+ /** The markup the build started from, before islands were rendered. */
21
+ shell: string;
22
+ /** Where the shell itself sits in the output, for re-anchoring. */
23
+ shellDepth: number;
24
+ }
25
+ export interface EmittedRoute {
26
+ path: string;
27
+ file: string;
28
+ params: Record<string, string>;
29
+ /**
30
+ * Build-time cells this page read.
31
+ *
32
+ * Per emitted path, not per source page: a routed page produces one output
33
+ * per row, and each row reads its *own* entry. Without this a rebuild can
34
+ * only re-render every page enumerated from a collection - a typo in one
35
+ * post rebuilding a thousand of them.
36
+ */
37
+ content?: string[];
38
+ }
39
+ /**
40
+ * Read the rows a route enumerates out of the page's own build-time content.
41
+ *
42
+ * Deliberately the *same* cell the page renders from, rather than a second
43
+ * declaration: a blog page already fetches its posts at build, and the route
44
+ * names that cell rather than re-fetching it.
45
+ */
46
+ export declare function rowsFrom(state: Record<string, unknown>, from: string, page: string): Array<Record<string, unknown>>;
47
+ /** Compute every path a route produces, failing on a collision. */
48
+ export declare function pathsFor(page: RoutePage, rows: Array<Record<string, unknown>>): EmittedRoute[];
49
+ /**
50
+ * Render one real file per row.
51
+ *
52
+ * The shell is re-rendered per row rather than string-substituted, so a routed
53
+ * page is rendered exactly the way any other page is - `$for`, `$if`, slots
54
+ * and build-time content all behave identically, because it is the same call.
55
+ */
56
+ export declare function emitRoutePages(options: {
57
+ dir: string;
58
+ page: RoutePage;
59
+ routes: EmittedRoute[];
60
+ definitions: ComponentDefinition[];
61
+ css?: "inline" | "external";
62
+ /** Ship inert islands as plain HTML - see `renderPage`. */
63
+ flattenStatic?: boolean;
64
+ }): Promise<{
65
+ written: number;
66
+ flattened: number;
67
+ }>;
68
+ /** `blog.html` + `<!-- lsp:route … -->` → a parsed, validated route page. */
69
+ export declare function toRoutePage(page: string, shell: string, declaration: RouteDeclaration & {
70
+ pattern: string;
71
+ }, shellDepth?: number): RoutePage;
72
+ /**
73
+ * Rewrite rules for a page whose URLs are resolved at runtime.
74
+ *
75
+ * The host has to map every URL matching the pattern onto the one shell that
76
+ * answers them. That is the cost of this kind of route, and the reason a baked
77
+ * route is better whenever the paths *can* be enumerated: it needs no server
78
+ * cooperation at all.
79
+ */
80
+ export interface RewriteRule {
81
+ pattern: string;
82
+ target: string;
83
+ }
84
+ /**
85
+ * Netlify / Cloudflare Pages `_redirects`. A 200 is a rewrite, not a redirect.
86
+ *
87
+ * These hosts check static files before redirect rules, so a real page always
88
+ * wins over a pattern that would also match it. The Caddy and nginx formats
89
+ * have to say so explicitly, via `try_files`.
90
+ */
91
+ export declare function formatRedirects(rules: RewriteRule[]): string;
92
+ export declare function formatCaddy(rules: RewriteRule[]): string;
93
+ export declare function formatNginx(rules: RewriteRule[]): string;
94
+ export declare const REWRITE_FORMATS: {
95
+ readonly _redirects: {
96
+ readonly file: "_redirects";
97
+ readonly format: typeof formatRedirects;
98
+ };
99
+ readonly caddy: {
100
+ readonly file: "rewrites.caddy";
101
+ readonly format: typeof formatCaddy;
102
+ };
103
+ readonly nginx: {
104
+ readonly file: "rewrites.nginx";
105
+ readonly format: typeof formatNginx;
106
+ };
107
+ };
108
+ export type RewriteFormat = keyof typeof REWRITE_FORMATS;
109
+ /**
110
+ * Warn when a routed page's content is not keyed by its own params.
111
+ *
112
+ * A routed page should read *its own* entry, so a change to one entry rebuilds
113
+ * one page. If every output reads the same collection-wide cells, a change to
114
+ * any of them fans out to all of them - O(n) work for an O(1) edit, which is
115
+ * exactly what surgical rebuilds exist to avoid.
116
+ *
117
+ * Reading a collection-wide cell is legitimate on its own: that is how paths
118
+ * are enumerated, and how a listing gets its data. The problem is reading
119
+ * *only* those, which is why this checks for the absence of a parameterised
120
+ * cell rather than the presence of a shared one.
121
+ *
122
+ * Returns null when there is nothing to say.
123
+ */
124
+ export declare function fanOutWarning(page: string, routes: EmittedRoute[]): string | null;
125
+ /**
126
+ * Whether a host has to resolve this route, or the build already did.
127
+ *
128
+ * A pattern alone does not say: a route enumerated from a cell has one too,
129
+ * and its pages are real files on disk. `from` - the cell it was enumerated
130
+ * from - is what separates them.
131
+ *
132
+ * One predicate rather than the same expression in several places: the bug it
133
+ * replaces was exactly two of them disagreeing, so a baked page was served
134
+ * from a shell that had never been emitted and 404ed.
135
+ */
136
+ export declare function resolvedByHost(entry: {
137
+ pattern?: string;
138
+ from?: string;
139
+ }): boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};