vinojs 0.1.0 → 0.1.2

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 (115) hide show
  1. package/dist/client.mjs +1 -1
  2. package/dist/{compile-Lxl_tdxL.mjs → compile-glNMkyyx.mjs} +3 -47
  3. package/dist/compile-glNMkyyx.mjs.map +1 -0
  4. package/dist/{definePage-Ba4r-TFh.mjs → definePage--9Pz7rHs.mjs} +29 -7
  5. package/dist/definePage--9Pz7rHs.mjs.map +1 -0
  6. package/dist/defineServerFn-H-bz7xBX.mjs +47 -0
  7. package/dist/defineServerFn-H-bz7xBX.mjs.map +1 -0
  8. package/dist/factory-CVT0-OZw.d.mts +187 -0
  9. package/dist/factory-CVT0-OZw.d.mts.map +1 -0
  10. package/dist/factory.d.mts +2 -0
  11. package/dist/factory.mjs +153 -0
  12. package/dist/factory.mjs.map +1 -0
  13. package/dist/vino.d.mts +4 -103
  14. package/dist/vino.d.mts.map +1 -1
  15. package/dist/vino.mjs +8 -3
  16. package/dist/vino.mjs.map +1 -1
  17. package/dist/vite.mjs +3 -2
  18. package/dist/vite.mjs.map +1 -1
  19. package/package.json +5 -1
  20. package/dist/compile-Lxl_tdxL.mjs.map +0 -1
  21. package/dist/definePage-Ba4r-TFh.mjs.map +0 -1
  22. package/examples/basic/dist/client/.assetsignore +0 -2
  23. package/examples/basic/dist/client/about.html +0 -1
  24. package/examples/basic/dist/client/admin.html +0 -1
  25. package/examples/basic/dist/client/assets/Counter-BvqMZKON.js +0 -1
  26. package/examples/basic/dist/client/assets/_slug_-CYpOSbrn.js +0 -1
  27. package/examples/basic/dist/client/assets/about-BZXRzUyv.js +0 -1
  28. package/examples/basic/dist/client/assets/admin-DRE7uh2s.js +0 -1
  29. package/examples/basic/dist/client/assets/client-B6nFkut5.js +0 -1
  30. package/examples/basic/dist/client/assets/client-pages-Bc6cNZAm.js +0 -2
  31. package/examples/basic/dist/client/assets/components-DX9r6vHn.js +0 -1
  32. package/examples/basic/dist/client/assets/components-DsWJ6F73.js +0 -2
  33. package/examples/basic/dist/client/assets/counter-DBpvln_F.js +0 -1
  34. package/examples/basic/dist/client/assets/dom-B5sHIJ1E.js +0 -1
  35. package/examples/basic/dist/client/assets/honoto-9UtdLp4J.js +0 -33
  36. package/examples/basic/dist/client/assets/honoto-client-DEh86_WZ.css +0 -1
  37. package/examples/basic/dist/client/assets/honoto-client.js +0 -2
  38. package/examples/basic/dist/client/assets/hooks-Cz6AT21d.js +0 -1
  39. package/examples/basic/dist/client/assets/jsx-dev-runtime-92VDsVyo.js +0 -1
  40. package/examples/basic/dist/client/counter.html +0 -1
  41. package/examples/basic/dist/client/index.html +0 -1
  42. package/examples/basic/dist/client/jobs.html +0 -1
  43. package/examples/basic/dist/ssr/.vite/manifest.json +0 -140
  44. package/examples/basic/dist/ssr/assets/_slug_-CY3-kffX.js +0 -46
  45. package/examples/basic/dist/ssr/assets/about-CTDjNhkO.js +0 -15
  46. package/examples/basic/dist/ssr/assets/admin-DvS-UGJx.js +0 -26
  47. package/examples/basic/dist/ssr/assets/constants-UoriGYcX-CUecBFMT.js +0 -6
  48. package/examples/basic/dist/ssr/assets/counter-DfIbc9Sp.js +0 -30
  49. package/examples/basic/dist/ssr/assets/honoto-CA313cVy.js +0 -2129
  50. package/examples/basic/dist/ssr/assets/jobs-D9hh-UO9.js +0 -42
  51. package/examples/basic/dist/ssr/assets/jsx-CgYLQazd.js +0 -1080
  52. package/examples/basic/dist/ssr/assets/jsx-dev-runtime-BlUda7H8.js +0 -742
  53. package/examples/basic/dist/ssr/assets/jsx-renderer-CzZcZPnS.js +0 -65
  54. package/examples/basic/dist/ssr/assets/layout-DYvLwr2u.js +0 -53
  55. package/examples/basic/dist/ssr/assets/pages-DB6jeyrt.js +0 -53
  56. package/examples/basic/dist/ssr/assets/rolldown-runtime-D7D4PA-g.js +0 -13
  57. package/examples/basic/dist/ssr/assets/ssr-hooks-CBQr0cdH.js +0 -7
  58. package/examples/basic/dist/ssr/index.js +0 -22
  59. package/examples/basic/dist/ssr/wrangler.json +0 -1
  60. package/examples/full/dist/client/.assetsignore +0 -2
  61. package/examples/full/dist/client/assets/BookmarkButton-py0xGxgl.js +0 -1
  62. package/examples/full/dist/client/assets/_slug_-DZUFsE9O.js +0 -1
  63. package/examples/full/dist/client/assets/auth-client-D2Wtuobe.js +0 -1
  64. package/examples/full/dist/client/assets/bun-sqlite-dialect-C7ftEUSI-CsHdUKBY.js +0 -1
  65. package/examples/full/dist/client/assets/client-B6nFkut5.js +0 -1
  66. package/examples/full/dist/client/assets/client-pages-fshKs747.js +0 -2
  67. package/examples/full/dist/client/assets/components-DX9r6vHn.js +0 -1
  68. package/examples/full/dist/client/assets/components-S_-rWrKi.js +0 -2
  69. package/examples/full/dist/client/assets/d1-sqlite-dialect-BZmaVTp8-FPCaMZqX.js +0 -1
  70. package/examples/full/dist/client/assets/default-query-compiler-CUdqIu1h.js +0 -1
  71. package/examples/full/dist/client/assets/dist-BoGTNvkC.js +0 -1
  72. package/examples/full/dist/client/assets/dom-DCd3wYW7.js +0 -1
  73. package/examples/full/dist/client/assets/factory-Bgf4EtLx.js +0 -8
  74. package/examples/full/dist/client/assets/honoto-client-BSvNAnxN.css +0 -1
  75. package/examples/full/dist/client/assets/honoto-client.js +0 -2
  76. package/examples/full/dist/client/assets/hooks-Cz6AT21d.js +0 -1
  77. package/examples/full/dist/client/assets/jsx-dev-runtime-92VDsVyo.js +0 -1
  78. package/examples/full/dist/client/assets/kysely-adapter-BHhasAnc.js +0 -1
  79. package/examples/full/dist/client/assets/kysely-migration-tables-DFfmKhq--U5ujlMwE.js +0 -1
  80. package/examples/full/dist/client/assets/node-sqlite-dialect-DJDXH5Ot.js +0 -1
  81. package/examples/full/dist/client/assets/pages-CUQx6Eus.js +0 -1
  82. package/examples/full/dist/client/assets/saved-jIi74ncJ.js +0 -1
  83. package/examples/full/dist/client/assets/session-B-accyM3.js +0 -611
  84. package/examples/full/dist/client/assets/sign-in-BelI3gSs.js +0 -1
  85. package/examples/full/dist/client/assets/sign-up-pR94lfdu.js +0 -1
  86. package/examples/full/dist/client/index.html +0 -1
  87. package/examples/full/dist/client/saved.html +0 -1
  88. package/examples/full/dist/client/sign-in.html +0 -1
  89. package/examples/full/dist/client/sign-up.html +0 -1
  90. package/examples/full/dist/ssr/.dev.vars +0 -1
  91. package/examples/full/dist/ssr/.vite/manifest.json +0 -219
  92. package/examples/full/dist/ssr/assets/BookmarkButton-KS7z5_vi.js +0 -298
  93. package/examples/full/dist/ssr/assets/_slug_-rRStRaAN.js +0 -89
  94. package/examples/full/dist/ssr/assets/auth-DSFZ4iak.js +0 -31434
  95. package/examples/full/dist/ssr/assets/auth-client-BFSBVoML.js +0 -894
  96. package/examples/full/dist/ssr/assets/bun-sqlite-dialect-C7ftEUSI-BeXpIqKl.js +0 -162
  97. package/examples/full/dist/ssr/assets/compiled-query-DmoyCh28.js +0 -8410
  98. package/examples/full/dist/ssr/assets/d1-sqlite-dialect-BZmaVTp8-CjJdvL94.js +0 -114
  99. package/examples/full/dist/ssr/assets/default-query-compiler-D7xOzCCJ.js +0 -1727
  100. package/examples/full/dist/ssr/assets/dist-LmmDoNdk.js +0 -6832
  101. package/examples/full/dist/ssr/assets/dist-kFDN1l4Z.js +0 -342
  102. package/examples/full/dist/ssr/assets/factory-AD6s9SIW.js +0 -2079
  103. package/examples/full/dist/ssr/assets/jsx-renderer-mMLf5XLN.js +0 -1926
  104. package/examples/full/dist/ssr/assets/kysely-adapter-BCLenpM8.js +0 -2
  105. package/examples/full/dist/ssr/assets/kysely-migration-tables-DFfmKhq--BtVr6hRe.js +0 -17
  106. package/examples/full/dist/ssr/assets/layout-mVA7qP4j.js +0 -44
  107. package/examples/full/dist/ssr/assets/node-sqlite-dialect-D-wtYAD7.js +0 -162
  108. package/examples/full/dist/ssr/assets/pages-Do5kR_Ia.js +0 -147
  109. package/examples/full/dist/ssr/assets/saved-Dr4pP6B5.js +0 -111
  110. package/examples/full/dist/ssr/assets/session-BvIpX7tr.js +0 -13
  111. package/examples/full/dist/ssr/assets/sign-in-22pzTnJE.js +0 -115
  112. package/examples/full/dist/ssr/assets/sign-up-CN4j8Qg1.js +0 -117
  113. package/examples/full/dist/ssr/assets/sqlite-adapter-DVlms5wO.js +0 -79
  114. package/examples/full/dist/ssr/index.js +0 -97
  115. package/examples/full/dist/ssr/wrangler.json +0 -1
package/dist/client.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { c as PAGE_SLOT_ID, l as PAYLOAD_SCRIPT_ID, o as NAV_HEADER, t as COMPONENT_TAG } from "./constants-BVT2bJEd.mjs";
2
- import { s as resolvePageRender } from "./definePage-Ba4r-TFh.mjs";
2
+ import { s as resolvePageRender } from "./definePage--9Pz7rHs.mjs";
3
3
  //#region src/client/create-client.ts
4
4
  const islands = /* @__PURE__ */ new Map();
5
5
  let pageRoot = null;
@@ -1,4 +1,4 @@
1
- import { o as readPageDefinition } from "./definePage-Ba4r-TFh.mjs";
1
+ import { o as readPageDefinition } from "./definePage--9Pz7rHs.mjs";
2
2
  //#region src/vino/config.ts
3
3
  function loadMergedConfig(page, pageMod) {
4
4
  const merged = { ...page.config };
@@ -12,50 +12,6 @@ async function loadMergedData(_page, c, pageMod) {
12
12
  return await fn(c);
13
13
  }
14
14
  //#endregion
15
- //#region src/vino/defineServerFn.ts
16
- const SERVER_FN_KIND = "vino:server-fn";
17
- function isServerFn(value) {
18
- return typeof value === "function" && value.kind === "vino:server-fn";
19
- }
20
- function readServerFn(value) {
21
- return isServerFn(value) ? value : void 0;
22
- }
23
- /** Call-site of `defineServerFn(...)`, not `function defineServerFn(`. */
24
- const DEFINE_SERVER_FN_CALL = /(?<!function\s)(?<![$\w])defineServerFn\s*(?:<[^>]*>\s*)?\(/g;
25
- /** True when source *calls* `defineServerFn(...)`. */
26
- function usesDefineServerFn(code) {
27
- DEFINE_SERVER_FN_CALL.lastIndex = 0;
28
- return DEFINE_SERVER_FN_CALL.test(code);
29
- }
30
- /**
31
- * Mark a function as server-only.
32
- *
33
- * Pass the result to `definePage({ data })` (or `defineServerPage`) as a
34
- * loader. The same function can later be imported and invoked
35
- *
36
- * @example
37
- * // [slug].server.ts
38
- * export default defineServerFn(c => {
39
- * const slug = c.req.param("slug") ?? ""
40
- * return { slug }
41
- * })
42
- *
43
- * @example
44
- * // [slug].tsx
45
- * import data from "./[slug].server"
46
- * export default definePage({ data, render: ({ data }) => <h1>{data.slug}</h1> })
47
- */
48
- function defineServerFn(fn) {
49
- function serverFn(c) {
50
- return fn(c);
51
- }
52
- Object.defineProperty(serverFn, "kind", {
53
- value: SERVER_FN_KIND,
54
- enumerable: true
55
- });
56
- return serverFn;
57
- }
58
- //#endregion
59
15
  //#region src/vino/compile.ts
60
16
  const GROUP_RE = /^\([^)]+\)$/;
61
17
  const CATCH_ALL_RE = /^\[\.\.\.(.+)\]$/;
@@ -150,6 +106,6 @@ function compareRoutes(a, b) {
150
106
  return b.pattern.length - a.pattern.length;
151
107
  }
152
108
  //#endregion
153
- export { pathDepth as a, SERVER_FN_KIND as c, readServerFn as d, usesDefineServerFn as f, pathCovers as i, defineServerFn as l, loadMergedData as m, compareRoutes as n, urlToHtmlFile as o, loadMergedConfig as p, compileFilePath as r, DEFINE_SERVER_FN_CALL as s, applyParams as t, isServerFn as u };
109
+ export { pathDepth as a, loadMergedData as c, pathCovers as i, compareRoutes as n, urlToHtmlFile as o, compileFilePath as r, loadMergedConfig as s, applyParams as t };
154
110
 
155
- //# sourceMappingURL=compile-Lxl_tdxL.mjs.map
111
+ //# sourceMappingURL=compile-glNMkyyx.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-glNMkyyx.mjs","names":[],"sources":["../src/vino/config.ts","../src/vino/compile.ts"],"sourcesContent":["import { readPageDefinition } from \"./definePage.ts\";\nimport type { DataLoader, ManifestPage, PageConfig, PageModule } from \"./types.ts\";\n\nexport function loadMergedConfig(page: ManifestPage, pageMod?: PageModule): PageConfig {\n const merged: PageConfig = { ...page.config };\n const inline = readPageDefinition(pageMod?.default)?.config;\n if (inline) Object.assign(merged, inline);\n return merged;\n}\n\nexport async function loadMergedData(\n _page: ManifestPage,\n c: Parameters<DataLoader>[0],\n pageMod?: PageModule,\n): Promise<unknown> {\n const fn = readPageDefinition(pageMod?.default)?.data;\n if (!fn) return undefined;\n return await fn(c);\n}\n","export interface CompiledRoute {\n /** Filesystem-derived path using `:param` (no Hono regex). `/`, `/about`, `/blog/:slug`. */\n path: string;\n /** Hono route pattern (`:slug{.+}` for catch-all). */\n pattern: string;\n isCatchAll: boolean;\n isStatic: boolean;\n paramNames: string[];\n}\n\nconst GROUP_RE = /^\\([^)]+\\)$/;\nconst CATCH_ALL_RE = /^\\[\\.\\.\\.(.+)\\]$/;\nconst PARAM_RE = /^\\[([^\\]]+)\\]$/;\n\nfunction toPosix(relativePath: string): string {\n return relativePath.replaceAll(\"\\\\\", \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction stripExt(posixPath: string): string {\n return posixPath.replace(/\\.(tsx|ts|jsx|js|mjs)$/, \"\");\n}\n\n/**\n * Compile a pages-dir-relative file path to a Hono route.\n * `(group)` dirs are omitted, `[param]` becomes `:param`, `[...slug]` becomes `:slug{.+}`,\n * trailing `index` is dropped.\n */\nexport function compileFilePath(relativePath: string): CompiledRoute {\n const posix = toPosix(relativePath);\n const withoutExt = stripExt(posix);\n\n const rawSegs = withoutExt.split(\"/\").filter(Boolean);\n const segs = rawSegs.filter((seg) => !GROUP_RE.test(seg));\n if (segs.at(-1) === \"index\") segs.pop();\n\n const out: string[] = [];\n const paramNames: string[] = [];\n let isCatchAll = false;\n\n for (const seg of segs) {\n const catchAll = CATCH_ALL_RE.exec(seg);\n if (catchAll) {\n paramNames.push(catchAll[1]);\n out.push(`:${catchAll[1]}{.+}`);\n isCatchAll = true;\n continue;\n }\n const param = PARAM_RE.exec(seg);\n if (param && !param[1].startsWith(\"...\")) {\n paramNames.push(param[1]);\n out.push(`:${param[1]}`);\n continue;\n }\n out.push(seg);\n }\n\n const pattern = out.length === 0 ? \"/\" : `/${out.join(\"/\")}`;\n const path = pattern.replaceAll(\"{.+}\", \"\");\n const isStatic = paramNames.length === 0 && !isCatchAll;\n\n return { path, pattern, isCatchAll, isStatic, paramNames };\n}\n\nexport function pathSegments(path: string): string[] {\n return path.split(\"/\").filter(Boolean);\n}\n\nexport function pathDepth(path: string): number {\n return pathSegments(path).length;\n}\n\n/**\n * True if `parent` is `/` or a prefix of `child`.\n * A `:param` segment in `parent` matches any child segment; a static parent\n * segment does not match a param child segment.\n */\nexport function pathCovers(parent: string, child: string): boolean {\n if (parent === \"/\" || parent === \"\") return true;\n const a = pathSegments(parent);\n const b = pathSegments(child);\n if (a.length > b.length) return false;\n return a.every((seg, i) => {\n const other = b[i];\n if (seg === other) return true;\n if (seg.startsWith(\":\")) return true;\n return false;\n });\n}\n\nexport function applyParams(path: string, params: Record<string, string>): string {\n let url = path;\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value);\n }\n if (!url.startsWith(\"/\")) url = `/${url}`;\n return url;\n}\n\nexport function urlToHtmlFile(url: string): string {\n const clean = url.split(\"?\")[0].split(\"#\")[0];\n if (clean === \"/\") return \"index.html\";\n const trimmed = clean.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n if (clean.endsWith(\"/\")) return `${trimmed}/index.html`;\n return `${trimmed}.html`;\n}\n\nexport function routeRank(pattern: string): number {\n if (pattern.includes(\"{.+}\")) return 2;\n if (pattern.includes(\":\")) return 1;\n return 0;\n}\n\nexport function compareRoutes(a: { pattern: string }, b: { pattern: string }): number {\n const d = routeRank(a.pattern) - routeRank(b.pattern);\n if (d !== 0) return d;\n return b.pattern.length - a.pattern.length;\n}\n"],"mappings":"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"}
@@ -39,13 +39,35 @@ function pageDefinition(page, kind, fnName) {
39
39
  config: page.config
40
40
  };
41
41
  }
42
- function definePage(page) {
43
- return pageDefinition(page, PAGE_KIND, "definePage");
44
- }
45
- function defineServerPage(page) {
46
- return pageDefinition(page, SERVER_PAGE_KIND, "defineServerPage");
47
- }
42
+ /**
43
+ * Declare a page that SSRs with `hono/jsx`, then hydrates `#vino-page` with `hono/jsx/dom`.
44
+ *
45
+ * @example
46
+ * export default definePage(() => {
47
+ * const [n, setN] = useState(0)
48
+ * return <button onClick={() => setN(n + 1)}>{n}</button>
49
+ * })
50
+ *
51
+ * @example
52
+ * export default definePage({
53
+ * config: { prerender: 'full', clientRouting: true },
54
+ * data: async (c) => ({ title: 'Hello' }),
55
+ * render: ({ data }) => <h1>{data.title}</h1>,
56
+ * })
57
+ *
58
+ * @example
59
+ * import data from './[slug].server'
60
+ * export default definePage({ data, render: ({ data }) => <h1>{data.title}</h1> })
61
+ */
62
+ const definePage = ((page) => pageDefinition(page, PAGE_KIND, "definePage"));
63
+ /**
64
+ * Declare a page that SSRs only. The output is never hydrated.
65
+ *
66
+ * @example
67
+ * export default defineServerPage(() => <h1>About</h1>)
68
+ */
69
+ const defineServerPage = ((page) => pageDefinition(page, SERVER_PAGE_KIND, "defineServerPage"));
48
70
  //#endregion
49
71
  export { isServerPageDefinition as a, usesDefinePage as c, isPageDefinition as i, defineServerPage as n, readPageDefinition as o, isClientPageDefinition as r, resolvePageRender as s, definePage as t };
50
72
 
51
- //# sourceMappingURL=definePage-Ba4r-TFh.mjs.map
73
+ //# sourceMappingURL=definePage--9Pz7rHs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definePage--9Pz7rHs.mjs","names":[],"sources":["../src/vino/definePage.ts"],"sourcesContent":["import type { Env } from \"hono\";\nimport type { ServerFn } from \"./defineServerFn.ts\";\nimport type { DataLoader, PageConfig, PageProps, VinoHtml } from \"./types.ts\";\n\nexport const PAGE_KIND = \"vino:page\" as const;\nexport const SERVER_PAGE_KIND = \"vino:server-page\" as const;\n\nexport type PageRender<Data = unknown> = (props: PageProps<Data>) => VinoHtml;\n\nexport type PageDataFn<E extends Env = Env> = DataLoader<E> | ServerFn<unknown, E>;\n\nexport interface DefinePageOptions<Data = unknown, E extends Env = Env> {\n /** JSX page component. Alias: `page`. */\n render?: PageRender<Data>;\n page?: PageRender<Data>;\n /** Loader or `defineServerFn(...)` */\n data?: DataLoader<E> | ServerFn<Data, E>;\n config?: PageConfig;\n}\n\n/** Options object that infers `data` return type into `render` / `page`. */\nexport type InferDefinePageOptions<\n D extends (...args: never[]) => unknown,\n Data = Awaited<ReturnType<D>>,\n> = {\n data?: D;\n config?: PageConfig;\n} & (\n | { render: PageRender<Data>; page?: PageRender<Data> }\n | { page: PageRender<Data>; render?: PageRender<Data> }\n);\n\n/**\n * `definePage` / `defineServerPage` call signature, with `Env` fixed so `data(c)`\n * is typed without blocking inference of the loader return type.\n */\nexport interface DefinePageFn<E extends Env = Env> {\n <Data = unknown>(page: PageRender<Data>): PageDefinition<Data>;\n <D extends PageDataFn<E>>(\n options: InferDefinePageOptions<D>,\n ): PageDefinition<Awaited<ReturnType<D>>>;\n <Data = unknown>(options: DefinePageOptions<Data, E>): PageDefinition<Data>;\n}\n\nexport interface PageDefinition<Data = unknown> {\n readonly kind: typeof PAGE_KIND | typeof SERVER_PAGE_KIND;\n readonly client: boolean;\n readonly render: PageRender<Data>;\n readonly data?: DataLoader | ServerFn<Data>;\n readonly config?: PageConfig;\n}\n\nexport function isPageDefinition(value: unknown): value is PageDefinition {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) return false;\n const candidate = value as PageDefinition;\n return (\n (candidate.kind === PAGE_KIND || candidate.kind === SERVER_PAGE_KIND) &&\n typeof candidate.render === \"function\"\n );\n}\n\nexport function isClientPageDefinition(value: unknown): value is PageDefinition {\n return isPageDefinition(value) && value.kind === PAGE_KIND;\n}\n\nexport function isServerPageDefinition(value: unknown): value is PageDefinition {\n return isPageDefinition(value) && value.kind === SERVER_PAGE_KIND;\n}\n\nexport function readPageDefinition(value: unknown): PageDefinition | undefined {\n return isPageDefinition(value) ? value : undefined;\n}\n\nexport function resolvePageRender(value: unknown): PageRender | undefined {\n if (isPageDefinition(value)) return value.render;\n if (typeof value === \"function\") return value as PageRender;\n return undefined;\n}\n\n/** True when source calls `definePage(...)` (hydratable pages). */\nexport function usesDefinePage(code: string): boolean {\n return /(?:^|[^\\w$])definePage\\s*(?:<[^>]*>\\s*)?\\(/.test(code);\n}\n\nfunction pageDefinition<Data>(\n page: PageRender<Data> | DefinePageOptions<Data>,\n kind: typeof PAGE_KIND | typeof SERVER_PAGE_KIND,\n fnName: string,\n): PageDefinition<Data> {\n if (typeof page === \"function\") {\n return { kind, client: kind === PAGE_KIND, render: page };\n }\n const render = page.render ?? page.page;\n if (typeof render !== \"function\") {\n throw new TypeError(`[vino] ${fnName}() requires a JSX function or { render }`);\n }\n return {\n kind,\n client: kind === PAGE_KIND,\n render,\n data: page.data,\n config: page.config,\n };\n}\n\n/**\n * Declare a page that SSRs with `hono/jsx`, then hydrates `#vino-page` with `hono/jsx/dom`.\n *\n * @example\n * export default definePage(() => {\n * const [n, setN] = useState(0)\n * return <button onClick={() => setN(n + 1)}>{n}</button>\n * })\n *\n * @example\n * export default definePage({\n * config: { prerender: 'full', clientRouting: true },\n * data: async (c) => ({ title: 'Hello' }),\n * render: ({ data }) => <h1>{data.title}</h1>,\n * })\n *\n * @example\n * import data from './[slug].server'\n * export default definePage({ data, render: ({ data }) => <h1>{data.title}</h1> })\n */\nexport const definePage = ((page: PageRender | DefinePageOptions) => pageDefinition(page, PAGE_KIND, \"definePage\")) as DefinePageFn;\n\n/**\n * Declare a page that SSRs only. The output is never hydrated.\n *\n * @example\n * export default defineServerPage(() => <h1>About</h1>)\n */\nexport const defineServerPage = ((page: PageRender | DefinePageOptions) => pageDefinition(page, SERVER_PAGE_KIND, \"defineServerPage\")) as DefinePageFn;\n"],"mappings":";AAIA,MAAa,YAAY;AACzB,MAAa,mBAAmB;AA+ChC,SAAgB,iBAAiB,OAAyC;CACxE,IAAI,UAAU,QAAS,OAAO,UAAU,YAAY,OAAO,UAAU,YAAa,OAAO;CACzF,MAAM,YAAY;CAClB,QACG,UAAU,SAAA,eAAsB,UAAU,SAAA,uBAC3C,OAAO,UAAU,WAAW;AAEhC;AAEA,SAAgB,uBAAuB,OAAyC;CAC9E,OAAO,iBAAiB,KAAK,KAAK,MAAM,SAAA;AAC1C;AAEA,SAAgB,uBAAuB,OAAyC;CAC9E,OAAO,iBAAiB,KAAK,KAAK,MAAM,SAAA;AAC1C;AAEA,SAAgB,mBAAmB,OAA4C;CAC7E,OAAO,iBAAiB,KAAK,IAAI,QAAQ,KAAA;AAC3C;AAEA,SAAgB,kBAAkB,OAAwC;CACxE,IAAI,iBAAiB,KAAK,GAAG,OAAO,MAAM;CAC1C,IAAI,OAAO,UAAU,YAAY,OAAO;AAE1C;;AAGA,SAAgB,eAAe,MAAuB;CACpD,OAAO,6CAA6C,KAAK,IAAI;AAC/D;AAEA,SAAS,eACP,MACA,MACA,QACsB;CACtB,IAAI,OAAO,SAAS,YAClB,OAAO;EAAE;EAAM,QAAQ,SAAS;EAAW,QAAQ;CAAK;CAE1D,MAAM,SAAS,KAAK,UAAU,KAAK;CACnC,IAAI,OAAO,WAAW,YACpB,MAAM,IAAI,UAAU,UAAU,OAAO,yCAAyC;CAEhF,OAAO;EACL;EACA,QAAQ,SAAS;EACjB;EACA,MAAM,KAAK;EACX,QAAQ,KAAK;CACf;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,eAAe,SAAyC,eAAe,MAAM,WAAW,YAAY;;;;;;;AAQjH,MAAa,qBAAqB,SAAyC,eAAe,MAAM,kBAAkB,kBAAkB"}
@@ -0,0 +1,47 @@
1
+ //#region src/vino/defineServerFn.ts
2
+ const SERVER_FN_KIND = "vino:server-fn";
3
+ function isServerFn(value) {
4
+ return typeof value === "function" && value.kind === "vino:server-fn";
5
+ }
6
+ function readServerFn(value) {
7
+ return isServerFn(value) ? value : void 0;
8
+ }
9
+ /** Call-site of `defineServerFn(...)`, not `function defineServerFn(`. */
10
+ const DEFINE_SERVER_FN_CALL = /(?<!function\s)(?<![$\w])defineServerFn\s*(?:<[^>]*>\s*)?\(/g;
11
+ /** True when source *calls* `defineServerFn(...)`. */
12
+ function usesDefineServerFn(code) {
13
+ DEFINE_SERVER_FN_CALL.lastIndex = 0;
14
+ return DEFINE_SERVER_FN_CALL.test(code);
15
+ }
16
+ /**
17
+ * Mark a function as server-only.
18
+ *
19
+ * Pass the result to `definePage({ data })` (or `defineServerPage`) as a
20
+ * loader. The same function can later be imported and invoked
21
+ *
22
+ * @example
23
+ * // [slug].server.ts
24
+ * export default defineServerFn(c => {
25
+ * const slug = c.req.param("slug") ?? ""
26
+ * return { slug }
27
+ * })
28
+ *
29
+ * @example
30
+ * // [slug].tsx
31
+ * import data from "./[slug].server"
32
+ * export default definePage({ data, render: ({ data }) => <h1>{data.slug}</h1> })
33
+ */
34
+ function defineServerFn(fn) {
35
+ function serverFn(c) {
36
+ return fn(c);
37
+ }
38
+ Object.defineProperty(serverFn, "kind", {
39
+ value: SERVER_FN_KIND,
40
+ enumerable: true
41
+ });
42
+ return serverFn;
43
+ }
44
+ //#endregion
45
+ export { readServerFn as a, isServerFn as i, SERVER_FN_KIND as n, usesDefineServerFn as o, defineServerFn as r, DEFINE_SERVER_FN_CALL as t };
46
+
47
+ //# sourceMappingURL=defineServerFn-H-bz7xBX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineServerFn-H-bz7xBX.mjs","names":[],"sources":["../src/vino/defineServerFn.ts"],"sourcesContent":["import type { Context, Env } from \"hono\";\n\nexport const SERVER_FN_KIND = \"vino:server-fn\" as const;\n\nexport type ServerFnHandler<T = unknown, E extends Env = Env> = (\n c: Context<E, string>,\n) => T | Promise<T>;\n\n/**\n * A server-only function. Callable as a `definePage({ data })` loader\n */\nexport type ServerFn<T = unknown, E extends Env = Env> = ServerFnHandler<T, E> & {\n readonly kind: typeof SERVER_FN_KIND;\n};\n\n/**\n * `defineServerFn` call signature, with `Env` fixed so `fn(c)` is typed without\n * blocking inference of the return type.\n */\nexport type DefineServerFnFn<E extends Env = Env> = <T>(fn: ServerFnHandler<T, E>) => ServerFn<T, E>;\n\nexport function isServerFn(value: unknown): value is ServerFn {\n return typeof value === \"function\" && (value as ServerFn).kind === SERVER_FN_KIND;\n}\n\nexport function readServerFn(value: unknown): ServerFn | undefined {\n return isServerFn(value) ? value : undefined;\n}\n\n/** Call-site of `defineServerFn(...)`, not `function defineServerFn(`. */\nexport const DEFINE_SERVER_FN_CALL =\n /(?<!function\\s)(?<![$\\w])defineServerFn\\s*(?:<[^>]*>\\s*)?\\(/g;\n\n/** True when source *calls* `defineServerFn(...)`. */\nexport function usesDefineServerFn(code: string): boolean {\n DEFINE_SERVER_FN_CALL.lastIndex = 0;\n return DEFINE_SERVER_FN_CALL.test(code);\n}\n\n/**\n * Mark a function as server-only.\n *\n * Pass the result to `definePage({ data })` (or `defineServerPage`) as a\n * loader. The same function can later be imported and invoked\n *\n * @example\n * // [slug].server.ts\n * export default defineServerFn(c => {\n * const slug = c.req.param(\"slug\") ?? \"\"\n * return { slug }\n * })\n *\n * @example\n * // [slug].tsx\n * import data from \"./[slug].server\"\n * export default definePage({ data, render: ({ data }) => <h1>{data.slug}</h1> })\n */\nexport function defineServerFn<T, E extends Env = Env>(fn: ServerFnHandler<T, E>): ServerFn<T, E> {\n function serverFn(c: Context<E, string>) {\n return fn(c);\n }\n Object.defineProperty(serverFn, \"kind\", {\n value: SERVER_FN_KIND,\n enumerable: true,\n });\n return serverFn as ServerFn<T, E>;\n}\n"],"mappings":";AAEA,MAAa,iBAAiB;AAmB9B,SAAgB,WAAW,OAAmC;CAC5D,OAAO,OAAO,UAAU,cAAe,MAAmB,SAAA;AAC5D;AAEA,SAAgB,aAAa,OAAsC;CACjE,OAAO,WAAW,KAAK,IAAI,QAAQ,KAAA;AACrC;;AAGA,MAAa,wBACX;;AAGF,SAAgB,mBAAmB,MAAuB;CACxD,sBAAsB,YAAY;CAClC,OAAO,sBAAsB,KAAK,IAAI;AACxC;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,eAAuC,IAA2C;CAChG,SAAS,SAAS,GAAuB;EACvC,OAAO,GAAG,CAAC;CACb;CACA,OAAO,eAAe,UAAU,QAAQ;EACtC,OAAO;EACP,YAAY;CACd,CAAC;CACD,OAAO;AACT"}
@@ -0,0 +1,187 @@
1
+ import { a as PageConfig, c as VinoHtml, n as DataLoader, o as PageProps } from "./types-CQITdkpF.mjs";
2
+ import { Context, Env, Hono } from "hono";
3
+ //#region src/vino/defineServerFn.d.ts
4
+ declare const SERVER_FN_KIND: "vino:server-fn";
5
+ type ServerFnHandler<T = unknown, E extends Env = Env> = (c: Context<E, string>) => T | Promise<T>;
6
+ /**
7
+ * A server-only function. Callable as a `definePage({ data })` loader
8
+ */
9
+ type ServerFn<T = unknown, E extends Env = Env> = ServerFnHandler<T, E> & {
10
+ readonly kind: typeof SERVER_FN_KIND;
11
+ };
12
+ /**
13
+ * `defineServerFn` call signature, with `Env` fixed so `fn(c)` is typed without
14
+ * blocking inference of the return type.
15
+ */
16
+ type DefineServerFnFn<E extends Env = Env> = <T>(fn: ServerFnHandler<T, E>) => ServerFn<T, E>;
17
+ declare function isServerFn(value: unknown): value is ServerFn;
18
+ declare function readServerFn(value: unknown): ServerFn | undefined;
19
+ /**
20
+ * Mark a function as server-only.
21
+ *
22
+ * Pass the result to `definePage({ data })` (or `defineServerPage`) as a
23
+ * loader. The same function can later be imported and invoked
24
+ *
25
+ * @example
26
+ * // [slug].server.ts
27
+ * export default defineServerFn(c => {
28
+ * const slug = c.req.param("slug") ?? ""
29
+ * return { slug }
30
+ * })
31
+ *
32
+ * @example
33
+ * // [slug].tsx
34
+ * import data from "./[slug].server"
35
+ * export default definePage({ data, render: ({ data }) => <h1>{data.slug}</h1> })
36
+ */
37
+ declare function defineServerFn<T, E extends Env = Env>(fn: ServerFnHandler<T, E>): ServerFn<T, E>;
38
+ //#endregion
39
+ //#region src/vino/definePage.d.ts
40
+ declare const PAGE_KIND: "vino:page";
41
+ declare const SERVER_PAGE_KIND: "vino:server-page";
42
+ type PageRender<Data = unknown> = (props: PageProps<Data>) => VinoHtml;
43
+ type PageDataFn<E extends Env = Env> = DataLoader<E> | ServerFn<unknown, E>;
44
+ interface DefinePageOptions<Data = unknown, E extends Env = Env> {
45
+ /** JSX page component. Alias: `page`. */
46
+ render?: PageRender<Data>;
47
+ page?: PageRender<Data>;
48
+ /** Loader or `defineServerFn(...)` */
49
+ data?: DataLoader<E> | ServerFn<Data, E>;
50
+ config?: PageConfig;
51
+ }
52
+ /** Options object that infers `data` return type into `render` / `page`. */
53
+ type InferDefinePageOptions<D extends (...args: never[]) => unknown, Data = Awaited<ReturnType<D>>> = {
54
+ data?: D;
55
+ config?: PageConfig;
56
+ } & ({
57
+ render: PageRender<Data>;
58
+ page?: PageRender<Data>;
59
+ } | {
60
+ page: PageRender<Data>;
61
+ render?: PageRender<Data>;
62
+ });
63
+ /**
64
+ * `definePage` / `defineServerPage` call signature, with `Env` fixed so `data(c)`
65
+ * is typed without blocking inference of the loader return type.
66
+ */
67
+ interface DefinePageFn<E extends Env = Env> {
68
+ <Data = unknown>(page: PageRender<Data>): PageDefinition<Data>;
69
+ <D extends PageDataFn<E>>(options: InferDefinePageOptions<D>): PageDefinition<Awaited<ReturnType<D>>>;
70
+ <Data = unknown>(options: DefinePageOptions<Data, E>): PageDefinition<Data>;
71
+ }
72
+ interface PageDefinition<Data = unknown> {
73
+ readonly kind: typeof PAGE_KIND | typeof SERVER_PAGE_KIND;
74
+ readonly client: boolean;
75
+ readonly render: PageRender<Data>;
76
+ readonly data?: DataLoader | ServerFn<Data>;
77
+ readonly config?: PageConfig;
78
+ }
79
+ declare function isPageDefinition(value: unknown): value is PageDefinition;
80
+ declare function isClientPageDefinition(value: unknown): value is PageDefinition;
81
+ declare function isServerPageDefinition(value: unknown): value is PageDefinition;
82
+ declare function resolvePageRender(value: unknown): PageRender | undefined;
83
+ /**
84
+ * Declare a page that SSRs with `hono/jsx`, then hydrates `#vino-page` with `hono/jsx/dom`.
85
+ *
86
+ * @example
87
+ * export default definePage(() => {
88
+ * const [n, setN] = useState(0)
89
+ * return <button onClick={() => setN(n + 1)}>{n}</button>
90
+ * })
91
+ *
92
+ * @example
93
+ * export default definePage({
94
+ * config: { prerender: 'full', clientRouting: true },
95
+ * data: async (c) => ({ title: 'Hello' }),
96
+ * render: ({ data }) => <h1>{data.title}</h1>,
97
+ * })
98
+ *
99
+ * @example
100
+ * import data from './[slug].server'
101
+ * export default definePage({ data, render: ({ data }) => <h1>{data.title}</h1> })
102
+ */
103
+ declare const definePage: DefinePageFn;
104
+ /**
105
+ * Declare a page that SSRs only. The output is never hydrated.
106
+ *
107
+ * @example
108
+ * export default defineServerPage(() => <h1>About</h1>)
109
+ */
110
+ declare const defineServerPage: DefinePageFn;
111
+ //#endregion
112
+ //#region src/vino/factory.d.ts
113
+ /** Initialize every app created by `factory.createApp()`, and pages from `definePage`. */
114
+ type InitApp<E extends Env = Env> = (app: Hono<E>) => void;
115
+ type HonoCtorOptions = NonNullable<ConstructorParameters<typeof Hono>[0]>;
116
+ interface FactoryOptions<E extends Env = Env> {
117
+ initApp?: InitApp<E>;
118
+ defaultAppOptions?: HonoCtorOptions;
119
+ }
120
+ /** `initApp` stamped onto a `definePage` / `defineServerFn` result. */
121
+ declare function readBoundInitApp(value: unknown): InitApp | undefined;
122
+ declare function readPageModuleInitApp(pageDefault: unknown, data?: unknown): InitApp | undefined;
123
+ /**
124
+ * Run a factory `initApp`'s `app.use()` middleware on the current context.
125
+ * Skips if this `initApp` already ran on `c` (e.g. via `createApp()`).
126
+ * Params and `c.set` stay on the same context so page loaders still see them.
127
+ */
128
+ declare function applyInitApp(initApp: InitApp | undefined, c: Context, next: () => Promise<Response>): Promise<Response>;
129
+ declare class Factory<E extends Env = Env> {
130
+ private initApp?;
131
+ private defaultAppOptions?;
132
+ constructor(init?: FactoryOptions<E>);
133
+ /**
134
+ * Create a Hono app typed with this factory's `Env`.
135
+ * Runs `initApp` (if provided) before returning, so middleware is registered
136
+ * before you call `mountVino(app)`.
137
+ */
138
+ createApp: (options?: HonoCtorOptions) => Hono<E>;
139
+ /** Same as `definePage`, with `c` typed as `Context<E>` and this factory's `initApp`. */
140
+ definePage: DefinePageFn<E>;
141
+ /** Same as `defineServerPage`, with `c` typed as `Context<E>` and this factory's `initApp`. */
142
+ defineServerPage: DefinePageFn<E>;
143
+ /** Same as `defineServerFn`, with `c` typed as `Context<E>` and this factory's `initApp`. */
144
+ defineServerFn: DefineServerFnFn<E>;
145
+ }
146
+ /**
147
+ * Create a factory that binds `Env` onto page helpers and `createApp()`.
148
+ *
149
+ * Pages keep the `initApp` of the factory that defined them, so a blog factory
150
+ * can set `c.var.db` only for `blogFactory.definePage` routes while the root
151
+ * app still uses the global factory.
152
+ *
153
+ * @example
154
+ * // src/factory.ts
155
+ * export const factory = createFactory<Env>({
156
+ * initApp: (app) => {
157
+ * app.use(async (c, next) => {
158
+ * c.set("db", drizzle(c.env.DB))
159
+ * await next()
160
+ * })
161
+ * },
162
+ * })
163
+ * export const blogFactory = createFactory<BlogEnv>({
164
+ * initApp: (app) => {
165
+ * app.use(async (c, next) => {
166
+ * c.set("posts", createPosts(c.env.BLOG_DB))
167
+ * await next()
168
+ * })
169
+ * },
170
+ * })
171
+ *
172
+ * @example
173
+ * // src/server.ts
174
+ * const app = factory.createApp()
175
+ * mountVino(app)
176
+ *
177
+ * @example
178
+ * // src/pages/blog/[slug].tsx
179
+ * export default blogFactory.definePage({
180
+ * data: (c) => c.var.posts.get(c.req.param("slug")),
181
+ * render: ({ data }) => <h1>{data.title}</h1>,
182
+ * })
183
+ */
184
+ declare function createFactory<E extends Env = Env>(options?: FactoryOptions<E>): Factory<E>;
185
+ //#endregion
186
+ export { defineServerFn as C, ServerFnHandler as S, readServerFn as T, isPageDefinition as _, createFactory as a, DefineServerFnFn as b, DefinePageFn as c, PageDataFn as d, PageDefinition as f, isClientPageDefinition as g, defineServerPage as h, applyInitApp as i, DefinePageOptions as l, definePage as m, FactoryOptions as n, readBoundInitApp as o, PageRender as p, InitApp as r, readPageModuleInitApp as s, Factory as t, InferDefinePageOptions as u, isServerPageDefinition as v, isServerFn as w, ServerFn as x, resolvePageRender as y };
187
+ //# sourceMappingURL=factory-CVT0-OZw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory-CVT0-OZw.d.mts","names":[],"sources":["../src/vino/defineServerFn.ts","../src/vino/definePage.ts","../src/vino/factory.ts"],"mappings":";;;cAEa;KAED,gBAAgB,aAAa,UAAU,MAAM,QACvD,GAAG,QAAQ,eACR,IAAI,QAAQ;;;;KAKL,SAAS,aAAa,UAAU,MAAM,OAAO,gBAAgB,GAAG;WACjE,aAAa;;;;;;KAOZ,iBAAiB,UAAU,MAAM,QAAQ,GAAG,IAAI,gBAAgB,GAAG,OAAO,SAAS,GAAG;iBAElF,WAAW,iBAAiB,SAAS;iBAIrC,aAAa,iBAAiB;;;;;;;;;;;;;;;;;;;iBAgC9B,eAAe,GAAG,UAAU,MAAM,KAAK,IAAI,gBAAgB,GAAG,KAAK,SAAS,GAAG;;;cCrDlF;cACA;KAED,WAAW,mBAAmB,OAAO,UAAU,UAAU;KAEzD,WAAW,UAAU,MAAM,OAAO,WAAW,KAAK,kBAAkB;UAE/D,kBAAkB,gBAAgB,UAAU,MAAM;;EAEjE,SAAS,WAAW;EACpB,OAAO,WAAW;;EAElB,OAAO,WAAW,KAAK,SAAS,MAAM;EACtC,SAAS;;;KAIC,uBACV,cAAc,2BACd,OAAO,QAAQ,WAAW;EAE1B,OAAO;EACP,SAAS;;EAEL,QAAQ,WAAW;EAAO,OAAO,WAAW;;EAC5C,MAAM,WAAW;EAAO,SAAS,WAAW;;;;;;UAOjC,aAAa,UAAU,MAAM;GAC3C,gBAAgB,MAAM,WAAW,QAAQ,eAAe;GACxD,UAAU,WAAW,IACpB,SAAS,uBAAuB,KAC/B,eAAe,QAAQ,WAAW;GACpC,gBAAgB,SAAS,kBAAkB,MAAM,KAAK,eAAe;;UAGvD,eAAe;WACrB,aAAa,mBAAmB;WAChC;WACA,QAAQ,WAAW;WACnB,OAAO,aAAa,SAAS;WAC7B,SAAS;;iBAGJ,iBAAiB,iBAAiB,SAAS;iBAS3C,uBAAuB,iBAAiB,SAAS;iBAIjD,uBAAuB,iBAAiB,SAAS;iBAQjD,kBAAkB,iBAAiB;;;;;;;;;;;;;;;;;;;;;cAoDtC,YAA0G;;;;;;;cAQ1G,kBAA6H;;;;KC7G9H,QAAQ,UAAU,MAAM,QAAQ,KAAK,KAAK;KAEjD,kBAAkB,YAAY,6BAA6B;UAG/C,eAAe,UAAU,MAAM;EAC9C,UAAU,QAAQ;EAClB,oBAAoB;;;iBAiBN,iBAAiB,iBAAiB;iBAKlC,sBAAsB,sBAAsB,iBAAiB;;;;;;iBAiCvD,aACpB,SAAS,qBACT,GAAG,SACH,YAAY,QAAQ,YACnB,QAAQ;cAoBE,QAAQ,UAAU,MAAM;UAC3B;UACA;EAEI,YAAA,OAAO,eAAe;;;;;;EAUlC,YAAa,UAAU,oBAAkB,KAAK;;EAkB9C,YAAY,aAAa;;EAIzB,kBAAkB,aAAa;;EAI/B,gBAAgB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0CnB,cAAc,UAAU,MAAM,KAAK,UAAU,eAAe,KAAK,QAAQ"}
@@ -0,0 +1,2 @@
1
+ import { a as createFactory, i as applyInitApp, n as FactoryOptions, o as readBoundInitApp, r as InitApp, s as readPageModuleInitApp, t as Factory } from "./factory-CVT0-OZw.mjs";
2
+ export { Factory, FactoryOptions, InitApp, applyInitApp, createFactory, readBoundInitApp, readPageModuleInitApp };
@@ -0,0 +1,153 @@
1
+ import { n as defineServerPage, o as readPageDefinition, t as definePage } from "./definePage--9Pz7rHs.mjs";
2
+ import { r as defineServerFn } from "./defineServerFn-H-bz7xBX.mjs";
3
+ import { Hono } from "hono";
4
+ //#region src/vino/factory.ts
5
+ /**
6
+ * Factory helper for Vino, analogous to `hono/factory`.
7
+ *
8
+ * Bind `Env` once so `definePage` / `defineServerPage` / `defineServerFn` type
9
+ * `c` without blocking inference of loader return data. `createApp()` builds a
10
+ * Hono instance with that `Env`. Each factory's `initApp` also runs for pages
11
+ * defined with that factory, so multiple Envs can share one mounted app.
12
+ */
13
+ const boundInit = /* @__PURE__ */ new WeakMap();
14
+ const appliedInit = /* @__PURE__ */ new WeakMap();
15
+ const middlewareCache = /* @__PURE__ */ new WeakMap();
16
+ function storedInitApp(initApp) {
17
+ return initApp;
18
+ }
19
+ function bindInitApp(value, initApp) {
20
+ if (initApp) boundInit.set(value, initApp);
21
+ return value;
22
+ }
23
+ /** `initApp` stamped onto a `definePage` / `defineServerFn` result. */
24
+ function readBoundInitApp(value) {
25
+ if (value === null || typeof value !== "object" && typeof value !== "function") return void 0;
26
+ return boundInit.get(value);
27
+ }
28
+ function readPageModuleInitApp(pageDefault, data) {
29
+ return readBoundInitApp(pageDefault) ?? readBoundInitApp(data ?? readPageDefinition(pageDefault)?.data);
30
+ }
31
+ function markInitApplied(c, initApp) {
32
+ let set = appliedInit.get(c);
33
+ if (!set) {
34
+ set = /* @__PURE__ */ new Set();
35
+ appliedInit.set(c, set);
36
+ }
37
+ set.add(initApp);
38
+ }
39
+ function isInitApplied(c, initApp) {
40
+ return appliedInit.get(c)?.has(initApp) ?? false;
41
+ }
42
+ function middlewareFromInitApp(initApp) {
43
+ let list = middlewareCache.get(initApp);
44
+ if (!list) {
45
+ const app = new Hono();
46
+ initApp(app);
47
+ list = app.routes.filter((route) => route.method === "ALL").map((route) => route.handler);
48
+ middlewareCache.set(initApp, list);
49
+ }
50
+ return list;
51
+ }
52
+ /**
53
+ * Run a factory `initApp`'s `app.use()` middleware on the current context.
54
+ * Skips if this `initApp` already ran on `c` (e.g. via `createApp()`).
55
+ * Params and `c.set` stay on the same context so page loaders still see them.
56
+ */
57
+ async function applyInitApp(initApp, c, next) {
58
+ if (!initApp || isInitApplied(c, initApp)) return next();
59
+ markInitApplied(c, initApp);
60
+ const handlers = middlewareFromInitApp(initApp);
61
+ if (handlers.length === 0) return next();
62
+ let response;
63
+ const run = async (i) => {
64
+ const handler = handlers[i];
65
+ if (!handler) {
66
+ response = await next();
67
+ return;
68
+ }
69
+ const out = await handler(c, () => run(i + 1));
70
+ if (out instanceof Response) response = out;
71
+ };
72
+ await run(0);
73
+ return response ?? c.res;
74
+ }
75
+ var Factory = class {
76
+ initApp;
77
+ defaultAppOptions;
78
+ constructor(init) {
79
+ this.initApp = init?.initApp;
80
+ this.defaultAppOptions = init?.defaultAppOptions;
81
+ }
82
+ /**
83
+ * Create a Hono app typed with this factory's `Env`.
84
+ * Runs `initApp` (if provided) before returning, so middleware is registered
85
+ * before you call `mountVino(app)`.
86
+ */
87
+ createApp = (options) => {
88
+ const app = new Hono(options && this.defaultAppOptions ? {
89
+ ...this.defaultAppOptions,
90
+ ...options
91
+ } : options ?? this.defaultAppOptions);
92
+ if (this.initApp) {
93
+ const initApp = this.initApp;
94
+ app.use(async (c, next) => {
95
+ markInitApplied(c, initApp);
96
+ await next();
97
+ });
98
+ initApp(app);
99
+ }
100
+ return app;
101
+ };
102
+ /** Same as `definePage`, with `c` typed as `Context<E>` and this factory's `initApp`. */
103
+ definePage = ((page) => bindInitApp(definePage(page), storedInitApp(this.initApp)));
104
+ /** Same as `defineServerPage`, with `c` typed as `Context<E>` and this factory's `initApp`. */
105
+ defineServerPage = ((page) => bindInitApp(defineServerPage(page), storedInitApp(this.initApp)));
106
+ /** Same as `defineServerFn`, with `c` typed as `Context<E>` and this factory's `initApp`. */
107
+ defineServerFn = ((fn) => bindInitApp(defineServerFn(fn), storedInitApp(this.initApp)));
108
+ };
109
+ /**
110
+ * Create a factory that binds `Env` onto page helpers and `createApp()`.
111
+ *
112
+ * Pages keep the `initApp` of the factory that defined them, so a blog factory
113
+ * can set `c.var.db` only for `blogFactory.definePage` routes while the root
114
+ * app still uses the global factory.
115
+ *
116
+ * @example
117
+ * // src/factory.ts
118
+ * export const factory = createFactory<Env>({
119
+ * initApp: (app) => {
120
+ * app.use(async (c, next) => {
121
+ * c.set("db", drizzle(c.env.DB))
122
+ * await next()
123
+ * })
124
+ * },
125
+ * })
126
+ * export const blogFactory = createFactory<BlogEnv>({
127
+ * initApp: (app) => {
128
+ * app.use(async (c, next) => {
129
+ * c.set("posts", createPosts(c.env.BLOG_DB))
130
+ * await next()
131
+ * })
132
+ * },
133
+ * })
134
+ *
135
+ * @example
136
+ * // src/server.ts
137
+ * const app = factory.createApp()
138
+ * mountVino(app)
139
+ *
140
+ * @example
141
+ * // src/pages/blog/[slug].tsx
142
+ * export default blogFactory.definePage({
143
+ * data: (c) => c.var.posts.get(c.req.param("slug")),
144
+ * render: ({ data }) => <h1>{data.title}</h1>,
145
+ * })
146
+ */
147
+ function createFactory(options) {
148
+ return new Factory(options);
149
+ }
150
+ //#endregion
151
+ export { Factory, applyInitApp, createFactory, readBoundInitApp, readPageModuleInitApp };
152
+
153
+ //# sourceMappingURL=factory.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.mjs","names":["definePageImpl","defineServerPageImpl","defineServerFnImpl"],"sources":["../src/vino/factory.ts"],"sourcesContent":["/**\n * Factory helper for Vino, analogous to `hono/factory`.\n *\n * Bind `Env` once so `definePage` / `defineServerPage` / `defineServerFn` type\n * `c` without blocking inference of loader return data. `createApp()` builds a\n * Hono instance with that `Env`. Each factory's `initApp` also runs for pages\n * defined with that factory, so multiple Envs can share one mounted app.\n */\n\nimport { Hono } from \"hono\";\nimport type { Context, Env } from \"hono\";\nimport {\n definePage as definePageImpl,\n defineServerPage as defineServerPageImpl,\n readPageDefinition,\n type DefinePageFn,\n} from \"./definePage.ts\";\nimport {\n defineServerFn as defineServerFnImpl,\n type DefineServerFnFn,\n type ServerFnHandler,\n} from \"./defineServerFn.ts\";\n\n/** Initialize every app created by `factory.createApp()`, and pages from `definePage`. */\nexport type InitApp<E extends Env = Env> = (app: Hono<E>) => void;\n\ntype HonoCtorOptions = NonNullable<ConstructorParameters<typeof Hono>[0]>;\ntype InitMiddleware = (c: Context, next: () => Promise<void>) => Promise<unknown>;\n\nexport interface FactoryOptions<E extends Env = Env> {\n initApp?: InitApp<E>;\n defaultAppOptions?: HonoCtorOptions;\n}\n\nconst boundInit = new WeakMap<object, InitApp>();\nconst appliedInit = new WeakMap<Context, Set<InitApp>>();\nconst middlewareCache = new WeakMap<InitApp, InitMiddleware[]>();\n\nfunction storedInitApp<E extends Env>(initApp: InitApp<E> | undefined): InitApp | undefined {\n return initApp as unknown as InitApp | undefined;\n}\n\nfunction bindInitApp<T extends object>(value: T, initApp?: InitApp): T {\n if (initApp) boundInit.set(value, initApp);\n return value;\n}\n\n/** `initApp` stamped onto a `definePage` / `defineServerFn` result. */\nexport function readBoundInitApp(value: unknown): InitApp | undefined {\n if (value === null || (typeof value !== \"object\" && typeof value !== \"function\")) return undefined;\n return boundInit.get(value);\n}\n\nexport function readPageModuleInitApp(pageDefault: unknown, data?: unknown): InitApp | undefined {\n return readBoundInitApp(pageDefault) ?? readBoundInitApp(data ?? readPageDefinition(pageDefault)?.data);\n}\n\nfunction markInitApplied(c: Context, initApp: InitApp): void {\n let set = appliedInit.get(c);\n if (!set) {\n set = new Set();\n appliedInit.set(c, set);\n }\n set.add(initApp);\n}\n\nfunction isInitApplied(c: Context, initApp: InitApp): boolean {\n return appliedInit.get(c)?.has(initApp) ?? false;\n}\n\nfunction middlewareFromInitApp(initApp: InitApp): InitMiddleware[] {\n let list = middlewareCache.get(initApp);\n if (!list) {\n const app = new Hono();\n initApp(app);\n list = app.routes.filter((route) => route.method === \"ALL\").map((route) => route.handler as InitMiddleware);\n middlewareCache.set(initApp, list);\n }\n return list;\n}\n\n/**\n * Run a factory `initApp`'s `app.use()` middleware on the current context.\n * Skips if this `initApp` already ran on `c` (e.g. via `createApp()`).\n * Params and `c.set` stay on the same context so page loaders still see them.\n */\nexport async function applyInitApp(\n initApp: InitApp | undefined,\n c: Context,\n next: () => Promise<Response>,\n): Promise<Response> {\n if (!initApp || isInitApplied(c, initApp)) return next();\n markInitApplied(c, initApp);\n const handlers = middlewareFromInitApp(initApp);\n if (handlers.length === 0) return next();\n\n let response: Response | undefined;\n const run = async (i: number): Promise<void> => {\n const handler = handlers[i];\n if (!handler) {\n response = await next();\n return;\n }\n const out = await handler(c, () => run(i + 1));\n if (out instanceof Response) response = out;\n };\n await run(0);\n return response ?? c.res;\n}\n\nexport class Factory<E extends Env = Env> {\n private initApp?: InitApp<E>;\n private defaultAppOptions?: HonoCtorOptions;\n\n constructor(init?: FactoryOptions<E>) {\n this.initApp = init?.initApp;\n this.defaultAppOptions = init?.defaultAppOptions;\n }\n\n /**\n * Create a Hono app typed with this factory's `Env`.\n * Runs `initApp` (if provided) before returning, so middleware is registered\n * before you call `mountVino(app)`.\n */\n createApp = (options?: HonoCtorOptions): Hono<E> => {\n const app = new Hono<E>(\n options && this.defaultAppOptions\n ? { ...this.defaultAppOptions, ...options }\n : (options ?? this.defaultAppOptions),\n );\n if (this.initApp) {\n const initApp = this.initApp;\n app.use(async (c, next) => {\n markInitApplied(c, initApp as unknown as InitApp);\n await next();\n });\n initApp(app);\n }\n return app;\n };\n\n /** Same as `definePage`, with `c` typed as `Context<E>` and this factory's `initApp`. */\n definePage: DefinePageFn<E> = ((page: never) =>\n bindInitApp(definePageImpl(page), storedInitApp(this.initApp))) as DefinePageFn<E>;\n\n /** Same as `defineServerPage`, with `c` typed as `Context<E>` and this factory's `initApp`. */\n defineServerPage: DefinePageFn<E> = ((page: never) =>\n bindInitApp(defineServerPageImpl(page), storedInitApp(this.initApp))) as DefinePageFn<E>;\n\n /** Same as `defineServerFn`, with `c` typed as `Context<E>` and this factory's `initApp`. */\n defineServerFn: DefineServerFnFn<E> = ((fn: ServerFnHandler<never, E>) =>\n bindInitApp(defineServerFnImpl(fn), storedInitApp(this.initApp))) as DefineServerFnFn<E>;\n}\n\n/**\n * Create a factory that binds `Env` onto page helpers and `createApp()`.\n *\n * Pages keep the `initApp` of the factory that defined them, so a blog factory\n * can set `c.var.db` only for `blogFactory.definePage` routes while the root\n * app still uses the global factory.\n *\n * @example\n * // src/factory.ts\n * export const factory = createFactory<Env>({\n * initApp: (app) => {\n * app.use(async (c, next) => {\n * c.set(\"db\", drizzle(c.env.DB))\n * await next()\n * })\n * },\n * })\n * export const blogFactory = createFactory<BlogEnv>({\n * initApp: (app) => {\n * app.use(async (c, next) => {\n * c.set(\"posts\", createPosts(c.env.BLOG_DB))\n * await next()\n * })\n * },\n * })\n *\n * @example\n * // src/server.ts\n * const app = factory.createApp()\n * mountVino(app)\n *\n * @example\n * // src/pages/blog/[slug].tsx\n * export default blogFactory.definePage({\n * data: (c) => c.var.posts.get(c.req.param(\"slug\")),\n * render: ({ data }) => <h1>{data.title}</h1>,\n * })\n */\nexport function createFactory<E extends Env = Env>(options?: FactoryOptions<E>): Factory<E> {\n return new Factory<E>(options);\n}\n"],"mappings":";;;;;;;;;;;;AAkCA,MAAM,4BAAY,IAAI,QAAyB;AAC/C,MAAM,8BAAc,IAAI,QAA+B;AACvD,MAAM,kCAAkB,IAAI,QAAmC;AAE/D,SAAS,cAA6B,SAAsD;CAC1F,OAAO;AACT;AAEA,SAAS,YAA8B,OAAU,SAAsB;CACrE,IAAI,SAAS,UAAU,IAAI,OAAO,OAAO;CACzC,OAAO;AACT;;AAGA,SAAgB,iBAAiB,OAAqC;CACpE,IAAI,UAAU,QAAS,OAAO,UAAU,YAAY,OAAO,UAAU,YAAa,OAAO,KAAA;CACzF,OAAO,UAAU,IAAI,KAAK;AAC5B;AAEA,SAAgB,sBAAsB,aAAsB,MAAqC;CAC/F,OAAO,iBAAiB,WAAW,KAAK,iBAAiB,QAAQ,mBAAmB,WAAW,CAAC,EAAE,IAAI;AACxG;AAEA,SAAS,gBAAgB,GAAY,SAAwB;CAC3D,IAAI,MAAM,YAAY,IAAI,CAAC;CAC3B,IAAI,CAAC,KAAK;EACR,sBAAM,IAAI,IAAI;EACd,YAAY,IAAI,GAAG,GAAG;CACxB;CACA,IAAI,IAAI,OAAO;AACjB;AAEA,SAAS,cAAc,GAAY,SAA2B;CAC5D,OAAO,YAAY,IAAI,CAAC,CAAC,EAAE,IAAI,OAAO,KAAK;AAC7C;AAEA,SAAS,sBAAsB,SAAoC;CACjE,IAAI,OAAO,gBAAgB,IAAI,OAAO;CACtC,IAAI,CAAC,MAAM;EACT,MAAM,MAAM,IAAI,KAAK;EACrB,QAAQ,GAAG;EACX,OAAO,IAAI,OAAO,QAAQ,UAAU,MAAM,WAAW,KAAK,CAAC,CAAC,KAAK,UAAU,MAAM,OAAyB;EAC1G,gBAAgB,IAAI,SAAS,IAAI;CACnC;CACA,OAAO;AACT;;;;;;AAOA,eAAsB,aACpB,SACA,GACA,MACmB;CACnB,IAAI,CAAC,WAAW,cAAc,GAAG,OAAO,GAAG,OAAO,KAAK;CACvD,gBAAgB,GAAG,OAAO;CAC1B,MAAM,WAAW,sBAAsB,OAAO;CAC9C,IAAI,SAAS,WAAW,GAAG,OAAO,KAAK;CAEvC,IAAI;CACJ,MAAM,MAAM,OAAO,MAA6B;EAC9C,MAAM,UAAU,SAAS;EACzB,IAAI,CAAC,SAAS;GACZ,WAAW,MAAM,KAAK;GACtB;EACF;EACA,MAAM,MAAM,MAAM,QAAQ,SAAS,IAAI,IAAI,CAAC,CAAC;EAC7C,IAAI,eAAe,UAAU,WAAW;CAC1C;CACA,MAAM,IAAI,CAAC;CACX,OAAO,YAAY,EAAE;AACvB;AAEA,IAAa,UAAb,MAA0C;CACxC;CACA;CAEA,YAAY,MAA0B;EACpC,KAAK,UAAU,MAAM;EACrB,KAAK,oBAAoB,MAAM;CACjC;;;;;;CAOA,aAAa,YAAuC;EAClD,MAAM,MAAM,IAAI,KACd,WAAW,KAAK,oBACZ;GAAE,GAAG,KAAK;GAAmB,GAAG;EAAQ,IACvC,WAAW,KAAK,iBACvB;EACA,IAAI,KAAK,SAAS;GAChB,MAAM,UAAU,KAAK;GACrB,IAAI,IAAI,OAAO,GAAG,SAAS;IACzB,gBAAgB,GAAG,OAA6B;IAChD,MAAM,KAAK;GACb,CAAC;GACD,QAAQ,GAAG;EACb;EACA,OAAO;CACT;;CAGA,eAAgC,SAC9B,YAAYA,WAAe,IAAI,GAAG,cAAc,KAAK,OAAO,CAAC;;CAG/D,qBAAsC,SACpC,YAAYC,iBAAqB,IAAI,GAAG,cAAc,KAAK,OAAO,CAAC;;CAGrE,mBAAwC,OACtC,YAAYC,eAAmB,EAAE,GAAG,cAAc,KAAK,OAAO,CAAC;AACnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,cAAmC,SAAyC;CAC1F,OAAO,IAAI,QAAW,OAAO;AAC/B"}