smoodly 0.0.45 → 0.0.46

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 (240) hide show
  1. package/README.md +3 -3
  2. package/dist/addresses.d.ts +6 -7
  3. package/dist/addresses.js +6 -4
  4. package/dist/admin/PublicSans-LICENSE.txt +93 -0
  5. package/dist/admin/auth-config.d.ts +6 -0
  6. package/dist/admin/auth-config.js +1 -0
  7. package/dist/admin/browser/fetch-op.d.ts +10 -0
  8. package/dist/admin/browser/fetch-op.js +44 -0
  9. package/dist/admin/browser/main.d.ts +1 -0
  10. package/dist/admin/browser/main.js +21 -0
  11. package/dist/admin/custom-section.d.ts +1 -1
  12. package/dist/admin/drift.d.ts +1 -1
  13. package/dist/admin/editor/EditorView.js +14 -14
  14. package/dist/admin/editor/autosave.js +1 -1
  15. package/dist/admin/editor/canvas-address.d.ts +2 -0
  16. package/dist/admin/editor/canvas-address.js +8 -0
  17. package/dist/admin/editor/overlay-geometry.d.ts +1 -1
  18. package/dist/admin/editor/protocol.d.ts +18 -4
  19. package/dist/admin/editor/protocol.js +15 -1
  20. package/dist/admin/editor/useCanvasBridge.d.ts +1 -1
  21. package/dist/admin/editor/useCanvasBridge.js +5 -6
  22. package/dist/admin/editor/useInlineSession.js +4 -2
  23. package/dist/admin/files.d.ts +11 -0
  24. package/dist/admin/files.generated.js +2 -0
  25. package/dist/admin/files.js +8 -0
  26. package/dist/admin/forms/useRefOptions.d.ts +2 -2
  27. package/dist/admin/forms/useRefOptions.js +2 -2
  28. package/dist/admin/forms/useRichtextEditor.js +4 -4
  29. package/dist/admin/handler.d.ts +40 -0
  30. package/dist/admin/handler.js +151 -0
  31. package/dist/admin/index.d.ts +1 -1
  32. package/dist/admin/ops-impl.d.ts +7 -1
  33. package/dist/admin/ops-impl.js +110 -33
  34. package/dist/admin/ops.d.ts +3 -2
  35. package/dist/admin/page-data.d.ts +21 -0
  36. package/dist/admin/page-data.js +4 -0
  37. package/dist/admin/page.d.ts +6 -0
  38. package/dist/admin/page.js +35 -0
  39. package/dist/admin/serialize.js +7 -7
  40. package/dist/admin/shell/AdminApp.js +2 -2
  41. package/dist/admin/shell/EntryForm.js +1 -1
  42. package/dist/admin/shell/router.d.ts +3 -16
  43. package/dist/admin/shell/router.js +3 -39
  44. package/dist/admin/shell/session.d.ts +2 -5
  45. package/dist/admin/supabase-auth.js +1 -1
  46. package/dist/admin/tree-ops.d.ts +1 -1
  47. package/dist/admin/ui/fonts.d.ts +12 -0
  48. package/dist/admin/ui/fonts.js +22 -0
  49. package/dist/admin/ui/theme.d.ts +13 -4
  50. package/dist/admin/ui/theme.js +28 -157
  51. package/dist/assemble.d.ts +60 -0
  52. package/dist/assemble.js +359 -0
  53. package/dist/astro/cache.d.ts +34 -0
  54. package/dist/astro/cache.js +69 -0
  55. package/dist/astro/components/Custom.astro +21 -0
  56. package/dist/astro/components/Guarded.astro +24 -0
  57. package/dist/astro/components/Head.astro +26 -0
  58. package/dist/astro/components/Image.astro +20 -0
  59. package/dist/astro/components/RichText.astro +23 -0
  60. package/dist/astro/components/Section.astro +20 -0
  61. package/dist/astro/components/Video.astro +5 -0
  62. package/dist/astro/components/Zone.astro +19 -0
  63. package/dist/astro/components.d.ts +6 -0
  64. package/dist/astro/components.js +7 -0
  65. package/dist/astro/content-loaders.d.ts +40 -0
  66. package/dist/astro/content-loaders.js +100 -0
  67. package/dist/astro/content.d.ts +9 -0
  68. package/dist/astro/content.js +17 -0
  69. package/dist/astro/custom.d.ts +1 -0
  70. package/dist/astro/custom.js +3 -0
  71. package/dist/astro/defaults.d.ts +20 -0
  72. package/dist/astro/defaults.js +21 -0
  73. package/dist/astro/env-files.d.ts +1 -0
  74. package/dist/astro/env-files.js +21 -0
  75. package/dist/astro/head.d.ts +13 -0
  76. package/dist/astro/head.js +19 -0
  77. package/dist/astro/image.d.ts +27 -0
  78. package/dist/astro/image.js +29 -0
  79. package/dist/astro/index.d.ts +43 -0
  80. package/dist/astro/index.js +111 -0
  81. package/dist/astro/locale-paths.d.ts +30 -0
  82. package/dist/astro/locale-paths.js +38 -0
  83. package/dist/astro/middleware.d.ts +1 -0
  84. package/dist/astro/middleware.js +83 -0
  85. package/dist/astro/preview-document.d.ts +1 -0
  86. package/dist/astro/preview-document.js +18 -0
  87. package/dist/astro/preview.d.ts +10 -0
  88. package/dist/astro/preview.js +72 -0
  89. package/dist/astro/richtext.d.ts +15 -0
  90. package/dist/astro/richtext.js +78 -0
  91. package/dist/astro/routes/admin.d.ts +3 -0
  92. package/dist/astro/routes/admin.js +41 -0
  93. package/dist/astro/routes/page.astro +17 -0
  94. package/dist/astro/routes/preview.astro +11 -0
  95. package/dist/astro/runtime.d.ts +32 -0
  96. package/dist/astro/runtime.js +46 -0
  97. package/dist/astro/scope.d.ts +45 -0
  98. package/dist/astro/scope.js +103 -0
  99. package/dist/astro/server.d.ts +14 -0
  100. package/dist/astro/server.js +45 -0
  101. package/dist/astro/shell.d.ts +67 -0
  102. package/dist/astro/shell.js +63 -0
  103. package/dist/astro/style.d.ts +1 -0
  104. package/dist/astro/style.js +11 -0
  105. package/dist/astro/views-check.d.ts +3 -0
  106. package/dist/astro/views-check.js +19 -0
  107. package/dist/astro/zone.d.ts +39 -0
  108. package/dist/astro/zone.js +33 -0
  109. package/dist/bind.d.ts +19 -0
  110. package/dist/bind.js +34 -0
  111. package/dist/bridge/bridge.d.ts +9 -0
  112. package/dist/bridge/bridge.js +107 -0
  113. package/dist/bridge/entry.d.ts +1 -0
  114. package/dist/bridge/entry.js +5 -0
  115. package/dist/bridge/preview-pill.d.ts +18 -0
  116. package/dist/bridge/preview-pill.js +115 -0
  117. package/dist/cli/import.d.ts +3 -0
  118. package/dist/cli/import.js +10 -1
  119. package/dist/cli/load-collections.js +4 -3
  120. package/dist/cli/load-config.d.ts +4 -0
  121. package/dist/cli/load-config.js +26 -0
  122. package/dist/cli/main.d.ts +5 -1
  123. package/dist/cli/main.js +24 -6
  124. package/dist/cli/migrate.d.ts +3 -0
  125. package/dist/cli/migrate.js +8 -1
  126. package/dist/cli/rebuild.d.ts +23 -0
  127. package/dist/cli/rebuild.js +22 -0
  128. package/dist/cli/space-io.d.ts +15 -1
  129. package/dist/cli/space-io.js +14 -0
  130. package/dist/client.js +5 -0
  131. package/dist/config.d.ts +28 -20
  132. package/dist/config.js +71 -75
  133. package/dist/content/content-api.d.ts +1 -1
  134. package/dist/content/node.d.ts +2 -3
  135. package/dist/content/node.js +2 -1
  136. package/dist/crash-message.d.ts +1 -0
  137. package/dist/crash-message.js +8 -0
  138. package/dist/css.d.ts +4 -0
  139. package/dist/css.js +5 -2
  140. package/dist/custom/CustomSection.d.ts +1 -1
  141. package/dist/custom/CustomSection.js +4 -8
  142. package/dist/custom/css.js +2 -2
  143. package/dist/custom/index.d.ts +6 -10
  144. package/dist/custom/index.js +1 -2
  145. package/dist/custom/layout.d.ts +5 -0
  146. package/dist/custom/layout.js +14 -0
  147. package/dist/entry-page.d.ts +3 -18
  148. package/dist/env.js +1 -1
  149. package/dist/global-id.js +2 -2
  150. package/dist/global.d.ts +5 -2
  151. package/dist/global.js +8 -5
  152. package/dist/image/next-config.d.ts +3 -0
  153. package/dist/image/next-config.js +12 -7
  154. package/dist/image/remote-pattern.d.ts +1 -0
  155. package/dist/image/remote-pattern.js +5 -0
  156. package/dist/index.d.ts +15 -17
  157. package/dist/index.js +10 -19
  158. package/dist/marks.d.ts +7 -0
  159. package/dist/marks.js +7 -0
  160. package/dist/next/admin-route.d.ts +7 -0
  161. package/dist/next/admin-route.js +28 -0
  162. package/dist/next/bridge.d.ts +1 -0
  163. package/dist/next/bridge.js +26 -0
  164. package/dist/next/canvas-boundary.d.ts +1 -1
  165. package/dist/next/canvas-slot.d.ts +1 -0
  166. package/dist/next/canvas-slot.js +4 -3
  167. package/dist/next/index.d.ts +2 -0
  168. package/dist/next/index.js +1 -0
  169. package/dist/next/page-renderer.d.ts +5 -1
  170. package/dist/next/page-renderer.js +19 -33
  171. package/dist/next/preview-pill-define.d.ts +1 -0
  172. package/dist/next/preview-pill-define.js +10 -0
  173. package/dist/next/preview-pill.d.ts +0 -3
  174. package/dist/next/preview-pill.js +7 -50
  175. package/dist/next/queries.d.ts +3 -28
  176. package/dist/next/queries.js +3 -90
  177. package/dist/next/reads.d.ts +2 -0
  178. package/dist/next/reads.js +18 -0
  179. package/dist/page-context.d.ts +89 -0
  180. package/dist/page-context.js +8 -0
  181. package/dist/pairing.d.ts +2 -22
  182. package/dist/project.d.ts +69 -0
  183. package/dist/project.js +210 -0
  184. package/dist/published.d.ts +96 -0
  185. package/dist/published.js +125 -0
  186. package/dist/react.d.ts +61 -0
  187. package/dist/react.js +17 -0
  188. package/dist/read-shapes.d.ts +1 -1
  189. package/dist/reads.d.ts +80 -0
  190. package/dist/reads.js +142 -0
  191. package/dist/refs.d.ts +1 -1
  192. package/dist/registration.d.ts +8 -0
  193. package/dist/registration.js +17 -0
  194. package/dist/render.d.ts +5 -83
  195. package/dist/render.js +5 -10
  196. package/dist/resolve.d.ts +1 -1
  197. package/dist/richtext/index.d.ts +6 -2
  198. package/dist/richtext/index.js +3 -2
  199. package/dist/richtext-href.d.ts +4 -0
  200. package/dist/richtext-href.js +17 -0
  201. package/dist/richtext-render.js +1 -14
  202. package/dist/schema-version.d.ts +1 -1
  203. package/dist/schema-version.js +1 -1
  204. package/dist/section-crash.d.ts +2 -2
  205. package/dist/section-crash.js +2 -7
  206. package/dist/section-wrapper.d.ts +3 -10
  207. package/dist/section-wrapper.js +3 -2
  208. package/dist/site.d.ts +38 -14
  209. package/dist/site.js +159 -286
  210. package/dist/smd-key.d.ts +9 -0
  211. package/dist/smd-key.js +1 -0
  212. package/dist/sql-space.d.ts +4 -0
  213. package/dist/sql-space.js +10 -5
  214. package/dist/sql.d.ts +2 -0
  215. package/dist/sql.js +117 -0
  216. package/dist/store.d.ts +1 -1
  217. package/dist/supabase-published-store.d.ts +35 -0
  218. package/dist/supabase-published-store.js +215 -0
  219. package/dist/supabase-store.d.ts +1 -1
  220. package/dist/toolset.d.ts +2 -4
  221. package/dist/toolset.js +6 -4
  222. package/dist/version.d.ts +1 -1
  223. package/dist/version.js +1 -1
  224. package/dist/view-props.d.ts +40 -0
  225. package/dist/view-props.js +1 -0
  226. package/dist/views.d.ts +36 -0
  227. package/dist/views.js +52 -0
  228. package/dist/zones.d.ts +7 -7
  229. package/dist/zones.js +7 -6
  230. package/migrations/20261007120000_smoodly_v8.sql +154 -0
  231. package/migrations/20261007200000_smoodly_v9.sql +30 -0
  232. package/package.json +46 -19
  233. package/dist/admin/next/bridge.d.ts +0 -2
  234. package/dist/admin/next/bridge.js +0 -129
  235. package/dist/admin/next/create-admin.d.ts +0 -19
  236. package/dist/admin/next/create-admin.js +0 -44
  237. package/dist/admin/next/index.d.ts +0 -8
  238. package/dist/admin/next/index.js +0 -8
  239. package/dist/admin/next/op-handler.d.ts +0 -18
  240. package/dist/admin/next/op-handler.js +0 -31
@@ -0,0 +1,17 @@
1
+ /** Only schemes an editor's link may carry reach the page: http(s), mailto, tel, and site-relative targets.
2
+ * Anything else (javascript:, data:, an empty href, a protocol-relative `//host` or a backslash form
3
+ * `/\host` that a browser treats the same way) renders the text without an anchor. */
4
+ const SAFE_HREF = /^(https?:|mailto:|tel:|\/(?![/\\])|#|\?|\.)/i;
5
+ export function safeHref(raw) {
6
+ if (typeof raw !== "string")
7
+ return null;
8
+ // URL parsers drop tab, LF and CR, so normalise before testing to see what the parser sees.
9
+ const href = raw.replace(/[\t\n\r]/g, "").trim();
10
+ return href !== "" && SAFE_HREF.test(href) ? href : null;
11
+ }
12
+ const ESCAPES = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#x27;" };
13
+ export function escapeHtml(text) {
14
+ return text.replace(/[&<>"']/g, (c) => ESCAPES[c]);
15
+ }
16
+ export const isResolvedImage = (v) => typeof v === "object" && v !== null && typeof v.url === "string"
17
+ && typeof v.width === "number" && typeof v.height === "number";
@@ -9,26 +9,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
9
9
  // (default: a figure over a plain <img>); an `element` node renders the
10
10
  // paired component named in `elements`, nothing when unknown.
11
11
  import { Fragment, createElement } from "react";
12
+ import { isResolvedImage, safeHref } from "./richtext-href.js";
12
13
  import { ELEMENT_NODE, IMAGE_NODE } from "./richtext-walk.js";
13
- /** Only schemes an editor's link may carry reach the page: http(s), mailto, tel,
14
- * and site-relative targets. Anything else (javascript:, data:, an empty href,
15
- * a protocol-relative `//host` or a backslash form `/\host` that a browser
16
- * treats the same way) renders the text without an anchor. */
17
- const SAFE_HREF = /^(https?:|mailto:|tel:|\/(?![/\\])|#|\?|\.)/i;
18
- function safeHref(raw) {
19
- if (typeof raw !== "string")
20
- return null;
21
- // URL parsers drop tab, LF and CR, so normalise before testing to see what the parser sees.
22
- const href = raw.replace(/[\t\n\r]/g, "").trim();
23
- return href !== "" && SAFE_HREF.test(href) ? href : null;
24
- }
25
14
  /** Lazy by default: body images sit below the fold, and a lazy <img> is
26
15
  * the one React does not hoist a preload hint for on the server. */
27
16
  export function defaultRichTextImage({ image, caption }) {
28
17
  return (_jsxs("figure", { children: [_jsx("img", { src: image.url, width: image.width, height: image.height, alt: image.alt, loading: "lazy" }), caption !== "" && _jsx("figcaption", { children: caption })] }));
29
18
  }
30
- const isResolvedImage = (v) => typeof v === "object" && v !== null && typeof v.url === "string"
31
- && typeof v.width === "number" && typeof v.height === "number";
32
19
  export function RichText({ doc, elements = [], image = defaultRichTextImage }) {
33
20
  const d = doc;
34
21
  if (!d || typeof d !== "object" || d.type !== "doc" || !Array.isArray(d.content))
@@ -1,7 +1,7 @@
1
1
  /** The minimum schema version the package needs. Moves ONLY in a release
2
2
  * that adds a table, column, function or policy the package reads; a
3
3
  * unit test holds it equal to the highest file in `migrations/`. */
4
- export declare const SCHEMA_VERSION = 7;
4
+ export declare const SCHEMA_VERSION = 9;
5
5
  export declare const SCHEMA_VERSION_KEY = "schema_version";
6
6
  export declare const CORE_FILE_RE: RegExp;
7
7
  export declare const VIEWS_FILE_RE: RegExp;
@@ -7,7 +7,7 @@
7
7
  /** The minimum schema version the package needs. Moves ONLY in a release
8
8
  * that adds a table, column, function or policy the package reads; a
9
9
  * unit test holds it equal to the highest file in `migrations/`. */
10
- export const SCHEMA_VERSION = 7;
10
+ export const SCHEMA_VERSION = 9;
11
11
  export const SCHEMA_VERSION_KEY = "schema_version";
12
12
  export const CORE_FILE_RE = /^(\d{14})_smoodly_v(\d+)\.sql$/;
13
13
  export const VIEWS_FILE_RE = /^(\d{14})_smoodly_views\.sql$/;
@@ -1,8 +1,8 @@
1
1
  import type { CSSProperties } from "react";
2
+ import { crashMessage } from "./crash-message.ts";
3
+ export { crashMessage };
2
4
  /** The canvas placeholders' look — the unknown section's too (spec 2026-09-27 editor safety §5). */
3
5
  export declare const PLACEHOLDER_STYLE: CSSProperties;
4
- /** Why it crashed, for the placeholder: the message, or the digest when a production build stripped the message. */
5
- export declare function crashMessage(error: unknown): string;
6
6
  export declare function CrashPlaceholder({ id, title, error, live }: {
7
7
  id: string;
8
8
  title: string;
@@ -1,16 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { crashMessage } from "./crash-message.js";
2
3
  import { CRASHED_ATTR, NODE_ATTR } from "./marks.js";
4
+ export { crashMessage };
3
5
  /** The canvas placeholders' look — the unknown section's too (spec 2026-09-27 editor safety §5). */
4
6
  export const PLACEHOLDER_STYLE = {
5
7
  padding: "24px 16px", border: "1px dashed #b54708", color: "#b54708", font: "500 14px/1.4 system-ui, sans-serif", textAlign: "center",
6
8
  };
7
- /** Why it crashed, for the placeholder: the message, or the digest when a production build stripped the message. */
8
- export function crashMessage(error) {
9
- const digest = typeof error === "object" && error !== null ? error.digest : undefined;
10
- if (typeof digest === "string")
11
- return `the server log has the error (digest ${digest})`;
12
- return error instanceof Error ? error.message : String(error);
13
- }
14
9
  export function CrashPlaceholder({ id, title, error, live }) {
15
10
  return (_jsx("div", { [NODE_ATTR]: id, [CRASHED_ATTR]: live, style: PLACEHOLDER_STYLE, children: `Section “${title}” failed to render — ${crashMessage(error)}` }));
16
11
  }
@@ -1,14 +1,7 @@
1
1
  import type { CSSProperties, ReactNode } from "react";
2
- import { type StyleProps, type StyleValues } from "./styles.ts";
3
- /** The reserved key `<Zone>` and `getGlobal` ride on the styles object. */
4
- export declare const SMD_KEY = "__smd";
5
- export type SmdInternal = {
6
- node?: string;
7
- css?: string;
8
- values?: StyleValues;
9
- /** Pre-scoped layout CSS (the custom section, spec 2026-09-14 §6), emitted before the editor's css so the box wins. */
10
- layoutCss?: string;
11
- };
2
+ import { type StyleProps } from "./styles.ts";
3
+ import { SMD_KEY, type SmdInternal } from "./smd-key.ts";
4
+ export { SMD_KEY, type SmdInternal };
12
5
  export declare function Section({ as, styles, className, style, children, ...rest }: {
13
6
  as?: keyof React.JSX.IntrinsicElements;
14
7
  styles: StyleProps & {
@@ -2,6 +2,7 @@ import { createElement } from "react";
2
2
  import { NODE_ATTR } from "./marks.js";
3
3
  import { DEFAULT_STYLE_VALUES, inlineStyles } from "./styles.js";
4
4
  import { safeCss, scopedCss } from "./css.js";
5
+ import { SMD_KEY } from "./smd-key.js";
5
6
  // The root wrapper every section renders through (spec 2026-09-14 §2, §4).
6
7
  // Owns the real root element, no extra div: element choice via `as`,
7
8
  // Smoodly's styles set rendered INLINE (an editor's step beats the
@@ -9,8 +10,8 @@ import { safeCss, scopedCss } from "./css.js";
9
10
  // node id as data-smd-node always (the custom-CSS scope needs it on the
10
11
  // live site), the scoped <style> child, and every other prop spread onto
11
12
  // the root — settings never become attributes; the view writes its own.
12
- /** The reserved key `<Zone>` and `getGlobal` ride on the styles object. */
13
- export const SMD_KEY = "__smd";
13
+ // The reserved key lives in smd-key.ts (pure), re-exported here.
14
+ export { SMD_KEY };
14
15
  export function Section({ as = "section", styles, className, style, children, ...rest }) {
15
16
  const { [SMD_KEY]: smd, ...steps } = (styles ?? {});
16
17
  const inline = inlineStyles(steps, smd?.values ?? DEFAULT_STYLE_VALUES);
package/dist/site.d.ts CHANGED
@@ -4,18 +4,31 @@ import type { Descriptor } from "./fields.ts";
4
4
  import { type EntryRecord, type EntryStore, type Where } from "./entry-store.ts";
5
5
  import { type LocaleAlternate, type LocaleSet, type PageAlternate, type PathTarget } from "./paths.ts";
6
6
  import type { SectionLike } from "./refs.ts";
7
- import type { PageContext, PageLink, PageTree } from "./render.tsx";
8
- import { type GlobalSchema } from "./global.ts";
9
- import { type StyleValues, type StyleValuesInput } from "./styles.ts";
10
- import { type CustomConfigInput, type ResolvedCustom } from "./custom/index.ts";
7
+ import type { PageContext, PageLink, PageTree } from "./page-context.ts";
8
+ import type { GlobalSchema } from "./global.ts";
9
+ import type { StyleValues, StyleValuesInput } from "./styles.ts";
10
+ import type { CustomConfigInput, ResolvedCustom } from "./custom/index.ts";
11
11
  import type { PageRecord, PageStore } from "./store.ts";
12
12
  import type { PathHit } from "./path-index.ts";
13
13
  import { type EntryItem, type PageItem, type Seo } from "./read-shapes.ts";
14
+ import type { SchemaOr } from "./registration.ts";
15
+ /** An address read with its layout's globals: the hit as `lookup` answers it, and each item's value by name. */
16
+ export type AddressWithGlobals = {
17
+ hit: SiteHit | {
18
+ kind: "redirect";
19
+ target: PathTarget;
20
+ } | null;
21
+ globals: Map<string, unknown>;
22
+ };
23
+ import type { PublishedStore } from "./published.ts";
24
+ import { type Projector } from "./project.ts";
14
25
  export type SiteOptions = {
26
+ /** `published`: the delivery documents outside draft mode read (spec 2026-10-07 delivery model §3). */
15
27
  stores: () => {
16
28
  pages: PageStore;
17
29
  entries: EntryStore;
18
30
  assets?: AssetStore;
31
+ published: PublishedStore;
19
32
  };
20
33
  collections: CollectionSchema<any>[];
21
34
  sections: SectionLike[];
@@ -31,18 +44,16 @@ export type SiteOptions = {
31
44
  /** Page shapes (entry pages are ignored): the source of each template's page-field descriptors (spec 2026-09-10 page fields §3)
32
45
  * and of the fixed pages' addresses (spec 2026-09-29 nested paths §3) — `config.registry.pages`. Required: a site that
33
46
  * missed one would take its code-owned record for an orphan and drop its URLs at the first lookup. */
34
- pages: ReadonlyArray<SitePageSchema>;
47
+ pages: ReadonlyArray<SchemaOr<SitePageSchema>>;
35
48
  };
36
- /** A page registration as the site needs it: the template's page fields, and a fixed page's address. */
49
+ /** A page type as the site needs it: its page fields, and a fixed page's address. */
37
50
  export type SitePageSchema = {
38
- schema: {
39
- kind: string;
40
- name: string;
41
- title?: string;
42
- slug?: string | Record<string, string>;
43
- fields?: Record<string, Descriptor>;
44
- seo?: true;
45
- };
51
+ kind: string;
52
+ name: string;
53
+ title?: string;
54
+ slug?: string | Record<string, string>;
55
+ fields?: Record<string, Descriptor>;
56
+ seo?: true;
46
57
  };
47
58
  export type SitePage = {
48
59
  kind: "page";
@@ -122,6 +133,17 @@ export interface SmoodlySite {
122
133
  /** Everything the renderer needs for one target: null when it is a folder, unpublished (outside draft), or gone. */
123
134
  load(target: PathTarget, locale: string, path: string, options?: LoadOptions): Promise<SiteHit | null>;
124
135
  resolve(locale: string, path: string, options?: LoadOptions): Promise<SiteHit | null>;
136
+ /** The published read of an address (spec 2026-10-07 delivery model §3): one lookup of the stored document; on a miss
137
+ * the code-owned page, then one locate that tells a redirect row from a record to assemble and from a 404. */
138
+ lookup(locale: string, path: string): Promise<SiteHit | {
139
+ kind: "redirect";
140
+ target: PathTarget;
141
+ } | null>;
142
+ /** The same lookup with the layout's global items riding along (schema v9): one store call answers the page and
143
+ * each item's value by name, a row behind the model healed as `getGlobal` heals it. A miss brings no globals. */
144
+ lookupWithGlobals(locale: string, path: string, items: readonly GlobalSchema<any>[]): Promise<AddressWithGlobals>;
145
+ /** Writes delivery rows from the editing tables: Publish calls it, and heal on read goes through it. */
146
+ readonly projector: Projector;
125
147
  /** A fixed page type (or a collection's index page) as code alone describes it, when `path` is its address in
126
148
  * `locale`: an empty tree, the page fields' defaults, the registration's title. The renderer serves it where
127
149
  * the index has no row — a page type added after install, a locale added to the config — until the admin
@@ -152,5 +174,7 @@ export interface SmoodlySite {
152
174
  draft?: boolean;
153
175
  }): Promise<V | null>;
154
176
  }
177
+ /** The `page` prop for a loaded page. `href` is the app's seam from a
178
+ * locale-relative path to a site URL; the default keeps CMS paths as URLs. */
155
179
  export declare function pageContextOf(hit: SitePage, href?: (path: string, locale: string) => string): PageContext;
156
180
  export declare function createSmoodlySite(options: SiteOptions): SmoodlySite;