@takazudo/zfb 0.1.0-next.80 → 0.1.0-next.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/plugins.d.ts +13 -12
- package/dist/plugins.js.map +1 -1
- package/dist/wasm.d.ts +4 -0
- package/dist/wasm.js +2 -0
- package/dist/wasm.js.map +1 -0
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "./wasm.js";
|
|
1
2
|
export { ANONYMOUS_COMPONENT_NAME, HYDRATE_MARKER_ATTR, Island, SKIP_SSR_MARKER_ATTR, resolveWhen, type IslandElement, type IslandProps, } from "./island.js";
|
|
2
3
|
export { scheduleHydrate, mountIslands, mountNewIslands, cancelPendingIslands, unmountIslands, } from "./runtime.js";
|
|
3
4
|
export type { IslandManifest, IslandManifestValue } from "./runtime.js";
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
// The hydration runtime (Sub 3) reaches the helper via
|
|
5
5
|
// `import { scheduleHydrate } from "@takazudo/zfb/runtime"` (or by inlining the
|
|
6
6
|
// same logic; coordinated separately).
|
|
7
|
+
// Keep the global Wasm declaration reachable from this package's emitted
|
|
8
|
+
// root declaration. The compiled module is intentionally empty at runtime.
|
|
9
|
+
import "./wasm.js";
|
|
7
10
|
export { ANONYMOUS_COMPONENT_NAME, HYDRATE_MARKER_ATTR, Island, SKIP_SSR_MARKER_ATTR, resolveWhen, } from "./island.js";
|
|
8
11
|
export { scheduleHydrate, mountIslands, mountNewIslands, cancelPendingIslands, unmountIslands, } from "./runtime.js";
|
|
9
12
|
export { DEFAULT_WHEN, isWhen, WHEN_VALUES } from "./types.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,iFAAiF;AACjF,uDAAuD;AACvD,gFAAgF;AAChF,uCAAuC;AAEvC,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,MAAM,EACN,oBAAoB,EACpB,WAAW,GAGZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAa,MAAM,YAAY,CAAC;AAE1E,yEAAyE;AACzE,iFAAiF;AACjF,oEAAoE;AACpE,+FAA+F;AAC/F,qCAAqC;AACrC,kEAAkE;AAClE,sEAAsE;AACtE,wEAAwE;AACxE,YAAY;AACZ,OAAO,EACL,YAAY,GAUb,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,kBAAkB,GAInB,MAAM,cAAc,CAAC","sourcesContent":["// Public entry point for the \"@takazudo/zfb\" package.\n//\n// User TSX pages reach this module via `import { Island } from \"@takazudo/zfb\"`.\n// The hydration runtime (Sub 3) reaches the helper via\n// `import { scheduleHydrate } from \"@takazudo/zfb/runtime\"` (or by inlining the\n// same logic; coordinated separately).\n\nexport {\n ANONYMOUS_COMPONENT_NAME,\n HYDRATE_MARKER_ATTR,\n Island,\n SKIP_SSR_MARKER_ATTR,\n resolveWhen,\n type IslandElement,\n type IslandProps,\n} from \"./island.js\";\nexport {\n scheduleHydrate,\n mountIslands,\n mountNewIslands,\n cancelPendingIslands,\n unmountIslands,\n} from \"./runtime.js\";\nexport type { IslandManifest, IslandManifestValue } from \"./runtime.js\";\nexport type { VNode, VNodeArray, VNodeObject } from \"./jsx-types.js\";\nexport { DEFAULT_WHEN, isWhen, WHEN_VALUES, type When } from \"./types.js\";\n\n// `defaultComponents` (htmlOverrides convention) is re-exported from the\n// root entry point so `import { defaultComponents } from \"@takazudo/zfb\"` is the\n// canonical access path. Each named override is also re-exported so\n// consumers can tree-shake-import a single one (`import { ContentLink } from \"@takazudo/zfb\"`)\n// without dragging in the whole map.\n// Plugin lifecycle types + `definePlugin` identity helper. Plugin\n// authors typically import these from \"@takazudo/zfb/plugins\" but the\n// root entry re-exports them so simple plugins can pull everything from\n// one path.\nexport {\n definePlugin,\n type ZfbBuildHookContext,\n type ZfbDevMiddlewareContext,\n type ZfbDevMiddlewareHandler,\n type ZfbDevMiddlewareRequest,\n type ZfbDevMiddlewareResponse,\n type ZfbPlugin,\n type ZfbPluginLogger,\n type ZfbPreviewMiddlewareContext,\n type ZfbPreviewMiddlewareHandler,\n} from \"./plugins.js\";\n\nexport { slugify, SlugAllocator } from \"./slugify.js\";\n\nexport { clientScript } from \"./client-script.js\";\n\nexport {\n ContentBlockquote,\n ContentCode,\n ContentH2,\n ContentH3,\n ContentH4,\n ContentLink,\n ContentOl,\n ContentParagraph,\n ContentStrong,\n ContentTable,\n ContentUl,\n defaultComponents,\n mergeMdxComponents,\n type ContentComponentElement,\n type ContentComponentProps,\n type MdxComponents,\n} from \"./content.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,iFAAiF;AACjF,uDAAuD;AACvD,gFAAgF;AAChF,uCAAuC;AAEvC,yEAAyE;AACzE,2EAA2E;AAC3E,OAAO,WAAW,CAAC;AAEnB,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,MAAM,EACN,oBAAoB,EACpB,WAAW,GAGZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAa,MAAM,YAAY,CAAC;AAE1E,yEAAyE;AACzE,iFAAiF;AACjF,oEAAoE;AACpE,+FAA+F;AAC/F,qCAAqC;AACrC,kEAAkE;AAClE,sEAAsE;AACtE,wEAAwE;AACxE,YAAY;AACZ,OAAO,EACL,YAAY,GAUb,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,kBAAkB,GAInB,MAAM,cAAc,CAAC","sourcesContent":["// Public entry point for the \"@takazudo/zfb\" package.\n//\n// User TSX pages reach this module via `import { Island } from \"@takazudo/zfb\"`.\n// The hydration runtime (Sub 3) reaches the helper via\n// `import { scheduleHydrate } from \"@takazudo/zfb/runtime\"` (or by inlining the\n// same logic; coordinated separately).\n\n// Keep the global Wasm declaration reachable from this package's emitted\n// root declaration. The compiled module is intentionally empty at runtime.\nimport \"./wasm.js\";\n\nexport {\n ANONYMOUS_COMPONENT_NAME,\n HYDRATE_MARKER_ATTR,\n Island,\n SKIP_SSR_MARKER_ATTR,\n resolveWhen,\n type IslandElement,\n type IslandProps,\n} from \"./island.js\";\nexport {\n scheduleHydrate,\n mountIslands,\n mountNewIslands,\n cancelPendingIslands,\n unmountIslands,\n} from \"./runtime.js\";\nexport type { IslandManifest, IslandManifestValue } from \"./runtime.js\";\nexport type { VNode, VNodeArray, VNodeObject } from \"./jsx-types.js\";\nexport { DEFAULT_WHEN, isWhen, WHEN_VALUES, type When } from \"./types.js\";\n\n// `defaultComponents` (htmlOverrides convention) is re-exported from the\n// root entry point so `import { defaultComponents } from \"@takazudo/zfb\"` is the\n// canonical access path. Each named override is also re-exported so\n// consumers can tree-shake-import a single one (`import { ContentLink } from \"@takazudo/zfb\"`)\n// without dragging in the whole map.\n// Plugin lifecycle types + `definePlugin` identity helper. Plugin\n// authors typically import these from \"@takazudo/zfb/plugins\" but the\n// root entry re-exports them so simple plugins can pull everything from\n// one path.\nexport {\n definePlugin,\n type ZfbBuildHookContext,\n type ZfbDevMiddlewareContext,\n type ZfbDevMiddlewareHandler,\n type ZfbDevMiddlewareRequest,\n type ZfbDevMiddlewareResponse,\n type ZfbPlugin,\n type ZfbPluginLogger,\n type ZfbPreviewMiddlewareContext,\n type ZfbPreviewMiddlewareHandler,\n} from \"./plugins.js\";\n\nexport { slugify, SlugAllocator } from \"./slugify.js\";\n\nexport { clientScript } from \"./client-script.js\";\n\nexport {\n ContentBlockquote,\n ContentCode,\n ContentH2,\n ContentH3,\n ContentH4,\n ContentLink,\n ContentOl,\n ContentParagraph,\n ContentStrong,\n ContentTable,\n ContentUl,\n defaultComponents,\n mergeMdxComponents,\n type ContentComponentElement,\n type ContentComponentProps,\n type MdxComponents,\n} from \"./content.js\";\n"]}
|
package/dist/plugins.d.ts
CHANGED
|
@@ -181,8 +181,7 @@ export type ZfbVirtualModuleLoader = () => string | Promise<string>;
|
|
|
181
181
|
*
|
|
182
182
|
* ```ts
|
|
183
183
|
* setup({ command, injectRoute }) {
|
|
184
|
-
* // package-owned page route (
|
|
185
|
-
* // the dev caveat)
|
|
184
|
+
* // package-owned page route (rendered in build and dev)
|
|
186
185
|
* injectRoute("/preset-page", "./pages/preset-page.tsx");
|
|
187
186
|
* // dev-only mock endpoint
|
|
188
187
|
* if (command === "dev") {
|
|
@@ -199,10 +198,11 @@ export type ZfbVirtualModuleLoader = () => string | Promise<string>;
|
|
|
199
198
|
export type ZfbSetupContext = {
|
|
200
199
|
/**
|
|
201
200
|
* Active zfb command. `"build"` during `zfb build`; `"dev"` during
|
|
202
|
-
* `zfb dev`; `"preview"` during `zfb preview` (#1542).
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
201
|
+
* `zfb dev`; `"preview"` during `zfb preview` (#1542). It can guide
|
|
202
|
+
* lifecycle-specific plugin behavior. `injectRoute` registrations are
|
|
203
|
+
* accepted in both `"dev"` and `"build"`; user `pages/` routes retain
|
|
204
|
+
* precedence over matching injected routes (see
|
|
205
|
+
* [`injectRoute`](#injectRoute)).
|
|
206
206
|
*
|
|
207
207
|
* Under `"preview"`, `setup` still fires (Rust-side via the minimal
|
|
208
208
|
* non-V8 `run_preview_setup` path) so plugin-side state
|
|
@@ -255,10 +255,10 @@ export type ZfbSetupContext = {
|
|
|
255
255
|
* into a per-build overlay pages root and **prerendered** through
|
|
256
256
|
* the normal scan → bundle → render pipeline, so a preset can own a
|
|
257
257
|
* route without the project shipping a `pages/` stub file. A `"/"`
|
|
258
|
-
* package route
|
|
259
|
-
* enabling a truly empty/absent user `pages
|
|
260
|
-
* whose URL shape collides with a user `pages/` route
|
|
261
|
-
* (user `pages/` wins). This is the supported, complete path.
|
|
258
|
+
* package route becomes the project's root page when no user
|
|
259
|
+
* `pages/index` exists, enabling a truly empty/absent user `pages/`.
|
|
260
|
+
* A package route whose URL shape collides with a user `pages/` route
|
|
261
|
+
* is dropped (user `pages/` wins). This is the supported, complete path.
|
|
262
262
|
* - In **dev**, both static and dynamic injected routes are rendered
|
|
263
263
|
* by `zfb dev`. Static routes (where the URL equals the pattern,
|
|
264
264
|
* e.g. `/preset-about`) are seeded into the dev route universe at
|
|
@@ -266,8 +266,9 @@ export type ZfbSetupContext = {
|
|
|
266
266
|
* on first request via a request-time synthetic entry — params are
|
|
267
267
|
* extracted from the URL by the Hono router inside the live bundle.
|
|
268
268
|
* User `pages/` files take precedence over any injected route of
|
|
269
|
-
* the same shape
|
|
270
|
-
*
|
|
269
|
+
* the same shape, including `pages/index` over an injected `"/"`.
|
|
270
|
+
* Without a user index, an injected root is staged, seeded, and served
|
|
271
|
+
* like any other static injected route. **HMR:** content the
|
|
271
272
|
* route reads from watched collections live-refreshes normally.
|
|
272
273
|
* Editing the package's **compiled entrypoint under `node_modules`**
|
|
273
274
|
* is NOT watched and requires a `zfb dev` restart (restart-only
|
package/dist/plugins.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,wEAAwE;AACxE,oEAAoE;AACpE,oEAAoE;AACpE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,qEAAqE;AACrE,sEAAsE;AACtE,sEAAsE;AACtE,6CAA6C;AAC7C,EAAE;AACF,wCAAwC;AACxC,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,oEAAoE;AACpE,oEAAoE;AACpE,+BAA+B;AA4X/B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["// `zfb/plugins` — TypeScript helper for the zfb plugin lifecycle.\n//\n// A plugin is a JS module whose default export is a [`ZfbPlugin`] object.\n// `zfb.config.ts` references plugins by `name` (npm bare specifier or a\n// `./`-relative path); the zfb config loader resolves each `name` to an\n// absolute module specifier and the Rust-side plugin host loads the\n// module via dynamic `import()` and dispatches the lifecycle hooks.\n//\n// Sub 3 / issue #108 — initial drop. Three optional hooks: `preBuild`,\n// `postBuild`, `devMiddleware`. Astro-migration epic #253 / sub-issue\n// #255 adds a fourth: `setup`, which runs once before `preBuild` and\n// lets plugins register virtual modules, import aliases, and dev-only\n// injected routes. None of the hooks see real Node IPC objects across\n// the boundary; everything is JSON-friendly.\n//\n// ## Inline functions are NOT supported\n//\n// `PluginConfig` (in `./config.ts`) carries only data. A user cannot\n// inline a function in `zfb.config.ts` — the config goes through a\n// JSON round-trip and any function value would be silently dropped.\n// Plugins must live in their own module (npm package or local file)\n// and be referenced by `name`.\n\n/**\n * Logger handed to every plugin hook. The Rust side wraps `tracing` so\n * the same lines show up alongside the rest of the build's structured\n * logs. Hooks should prefer this over `console.log`.\n */\nexport type ZfbPluginLogger = {\n info(msg: string): void;\n warn(msg: string): void;\n error(msg: string): void;\n};\n\n/**\n * One emitted route in the `postBuild` route manifest (#262).\n * Present on `ctx.routes.routes` so a `postBuild` plugin can iterate\n * every URL the build produced (e.g. to write a `sitemap.xml`).\n */\nexport type ZfbRouteEntry = {\n /** Emitted URL path, e.g. `/`, `/blog/hello/`, `/sitemap.xml`. */\n url: string;\n /** Path under `outDir`, e.g. `index.html`, `blog/hello/index.html`, `sitemap.xml`. */\n output: string;\n /** File extension: `html`, `xml`, `rss`, `txt`, `json`, … */\n extension: string;\n /** Source page module relative to the project root, e.g. `pages/blog/[slug].tsx`. */\n source: string;\n /**\n * `true` when the page is prerendered to disk (default / SSG); `false`\n * when the page exports `prerender = false` and is served by the\n * runtime adapter (SSR — no on-disk artifact under `outDir`).\n *\n * Indexes that enumerate on-disk URLs (sitemap.xml, search-index.json,\n * etc.) should filter `r.prerender !== false` to avoid surfacing SSR\n * routes that have no static output.\n */\n prerender: boolean;\n /**\n * Bound route parameters. Absent for static routes.\n * Dynamic (`[slug]`) params are string scalars; catchall (`[...rest]`)\n * params are string arrays.\n */\n params?: Record<string, string | string[]>;\n};\n\n/**\n * The route manifest exposed on `ctx.routes` during a `postBuild` callback\n * (#262). Sorted by `url` for byte-stable output across runs.\n */\nexport type ZfbRouteManifest = {\n routes: ZfbRouteEntry[];\n};\n\n/**\n * Context passed to `preBuild` and `postBuild`. `outDir` is the\n * resolved absolute path of the configured `outDir` (default\n * `<projectRoot>/dist`). `projectRoot` is the directory containing\n * `zfb.config.ts`.\n *\n * `routes` is **only present on `postBuild`** calls; it is `undefined`\n * on `preBuild`. This is intentional: the route manifest is not\n * available until the build finishes writing `dist/` (#262).\n */\nexport type ZfbBuildHookContext = {\n /** Project root — the directory containing `zfb.config.ts`. */\n projectRoot: string;\n /** Resolved absolute path of the build output directory. */\n outDir: string;\n /** The full loaded `ZfbConfig` (data-only view). */\n config: import(\"./config.js\").ZfbConfig;\n /** Plugin-specific options block, copied verbatim from the matching `PluginConfig.options`. */\n options: Record<string, unknown>;\n /** Logger that wraps the Rust-side `tracing` subscriber. */\n logger: ZfbPluginLogger;\n /**\n * All routes emitted by this build, sorted by URL (#262).\n * Present only on `postBuild` calls; `undefined` on `preBuild`.\n */\n routes?: ZfbRouteManifest;\n};\n\n/**\n * A request handed to a `devMiddleware` handler. Subset of the Node\n * `http.IncomingMessage` surface intentionally — the dev server is\n * Rust-side `axum`, not Node, so we expose only what survives a JSON\n * envelope hop.\n */\nexport type ZfbDevMiddlewareRequest = {\n method: string;\n url: string;\n /** Lower-cased header names → first value. */\n headers: Record<string, string>;\n /** Raw request body; absent for GET/HEAD. UTF-8 only — binary is out of scope for v1 dev plugins. */\n body?: string;\n};\n\n/**\n * Response returned by a `devMiddleware` handler. All fields optional\n * except `status`. `body` may be a string (UTF-8) or a base64-encoded\n * binary payload (set `bodyEncoding` to `\"base64\"` in that case).\n */\nexport type ZfbDevMiddlewareResponse = {\n status: number;\n headers?: Record<string, string>;\n body?: string;\n bodyEncoding?: \"utf8\" | \"base64\";\n};\n\n/**\n * Handler signature for a `devMiddleware` registration. The `next` callback\n * is reserved for future composition; v1 plugins should produce a response\n * directly. Returning `undefined` from the handler signals \"I did not handle\n * this request\" — the dev server then falls through to its built-in routes\n * (the page cache, /__zfb/livereload.js, etc.).\n */\nexport type ZfbDevMiddlewareHandler = (\n req: ZfbDevMiddlewareRequest,\n) => Promise<ZfbDevMiddlewareResponse | undefined> | ZfbDevMiddlewareResponse | undefined;\n\n/**\n * Context passed to `devMiddleware`. The `register` callback installs\n * one handler per URL path prefix. `path` is matched as an exact prefix\n * — a registration on `/doc-history` matches `/doc-history` and\n * `/doc-history/foo`, but NOT `/doc-historyx`.\n */\nexport type ZfbDevMiddlewareContext = {\n projectRoot: string;\n config: import(\"./config.js\").ZfbConfig;\n options: Record<string, unknown>;\n logger: ZfbPluginLogger;\n /** Register an HTTP handler at `path`. Calling twice on the same path overwrites. */\n register(path: string, handler: ZfbDevMiddlewareHandler): void;\n};\n\n/**\n * Handler signature for a `previewMiddleware` registration (#1542).\n * Deliberately reuses [`ZfbDevMiddlewareRequest`] /\n * [`ZfbDevMiddlewareResponse`] verbatim — the wire shape crossing the\n * Rust↔JS boundary is genuinely the SAME for dev and preview (mirrors\n * the Rust side, which shares `DevRequest`/`DevResponse` between both\n * hooks too), so there is nothing preview-specific to say about the\n * request/response contract itself. `next` is likewise reserved for\n * future composition; returning `undefined` signals \"I did not handle\n * this request\" and the preview server falls through to its built-in\n * routes (static-file serving, or the wrangler-backed adapter in\n * adapter mode).\n */\nexport type ZfbPreviewMiddlewareHandler = (\n req: ZfbDevMiddlewareRequest,\n) => Promise<ZfbDevMiddlewareResponse | undefined> | ZfbDevMiddlewareResponse | undefined;\n\n/**\n * Context passed to `previewMiddleware` (#1542). Structurally identical\n * to [`ZfbDevMiddlewareContext`] today — one handler per URL path\n * prefix, matched the same way — but declared as its own named type\n * (unlike the request/response types above, which are reused verbatim)\n * because the *context* is where a hook-specific capability would land\n * first if one were ever added (e.g. something preview-only that\n * `devMiddleware` has no equivalent for). Keeping it a separate\n * declaration costs nothing today and avoids a breaking rename later.\n */\nexport type ZfbPreviewMiddlewareContext = {\n projectRoot: string;\n config: import(\"./config.js\").ZfbConfig;\n options: Record<string, unknown>;\n logger: ZfbPluginLogger;\n /** Register an HTTP handler at `path`. Calling twice on the same path overwrites. */\n register(path: string, handler: ZfbPreviewMiddlewareHandler): void;\n};\n\n/**\n * Loader signature for a virtual-module registration. Must return the\n * **complete ESM module source text** as a string — the bundler /\n * embedded V8 host feeds the returned string in as the module's\n * source verbatim. The loader is invoked **exactly once per build**\n * (and once per `zfb dev` host boot) the first time any consumer\n * imports the registered specifier; subsequent imports of the same\n * specifier re-use the memoised result.\n *\n * Example:\n *\n * ```ts\n * addVirtualModule(\"virtual:my-data\", () =>\n * `export default ${JSON.stringify(myJson)}`,\n * );\n * ```\n */\nexport type ZfbVirtualModuleLoader = () => string | Promise<string>;\n\n/**\n * Context passed to the new `setup` hook (#255). Runs once per host\n * boot, in `Config.plugins` declaration order, **before** `preBuild`.\n *\n * `ctx.command` tells the plugin which lifecycle is active so it can\n * gate per-lifecycle registrations. A dev-only mock route stays gated\n * to `\"dev\"`; a package-owned page route is registered unconditionally\n * (it is prerendered during a build and dev-routed during dev):\n *\n * ```ts\n * setup({ command, injectRoute }) {\n * // package-owned page route (prerendered at BUILD; see injectRoute for\n * // the dev caveat)\n * injectRoute(\"/preset-page\", \"./pages/preset-page.tsx\");\n * // dev-only mock endpoint\n * if (command === \"dev\") {\n * injectRoute(\"/api/dev/x\", \"./scripts/dev-x.ts\");\n * }\n * }\n * ```\n *\n * The hook's surface is intentionally **closed**: only `injectRoute`,\n * `addVirtualModule`, `addAlias`, and `addClientEntry`. There is no\n * `addRemarkPlugin` / `addRehypePlugin` / `addMarkdownVisitor` — by\n * design (see the concept doc for the rationale).\n */\nexport type ZfbSetupContext = {\n /**\n * Active zfb command. `\"build\"` during `zfb build`; `\"dev\"` during\n * `zfb dev`; `\"preview\"` during `zfb preview` (#1542). Affects\n * `injectRoute`: in `\"dev\"`, `\"/\"` is reserved for the devMiddleware\n * catch-all and is rejected; in `\"build\"`, a `\"/\"` package route is\n * allowed (see [`injectRoute`](#injectRoute)).\n *\n * Under `\"preview\"`, `setup` still fires (Rust-side via the minimal\n * non-V8 `run_preview_setup` path) so plugin-side state\n * initialisation runs, but `zfb preview` serves an ALREADY-BUILT\n * `dist/` verbatim and never re-enters the scan → bundle → render\n * pipeline. Consequently `injectRoute` / `addVirtualModule` /\n * `addAlias` / `addClientEntry` calls made under `\"preview\"` are\n * accepted (for shape-consistency with `\"build\"`/`\"dev\"`) but are\n * **inert** — nothing downstream ever reads them. Only the hook's\n * side effects and a subsequent `previewMiddleware` registration do\n * anything meaningful under `\"preview\"`.\n */\n command: \"build\" | \"dev\" | \"preview\";\n /** Project root — the directory containing `zfb.config.ts`. */\n projectRoot: string;\n /** The full loaded `ZfbConfig` (data-only view). */\n config: import(\"./config.js\").ZfbConfig;\n /** Plugin-specific options block, copied verbatim from `PluginConfig.options`. */\n options: Record<string, unknown>;\n /** Logger that wraps the Rust-side `tracing` subscriber. */\n logger: ZfbPluginLogger;\n\n /**\n * Register an import alias. **Exact-match-only in v1**:\n * `addAlias(\"@/foo\", \"./src/foo.tsx\")` rewrites `import \"@/foo\"`\n * but does NOT match `import \"@/foo/bar\"`. Prefix-matching is\n * explicitly deferred to v2 — switch to one bare alias per file\n * until then.\n *\n * `to` is resolved relative to the project root. Two plugins\n * registering the same `from` with different `to` raises\n * `AliasConflict` and aborts the build.\n */\n addAlias(from: string, to: string): void;\n\n /**\n * Register a virtual module. `specifier` is a bare import\n * specifier (recommended `virtual:` prefix, not enforced).\n * `loader` returns the complete ESM source text as a string and\n * runs **exactly once per build** at first import.\n *\n * Two plugins registering the same `specifier` raises\n * `VirtualModuleConflict` and aborts the build.\n */\n addVirtualModule(specifier: string, loader: ZfbVirtualModuleLoader): void;\n\n /**\n * Register a synthetic / package-owned page route. `pattern` uses the\n * same grammar as `pages/` filenames (`/blog/[slug]`, `/api/dev/x`,\n * `/docs/[...rest]`).\n *\n * - In **build** (package-owned routes), the route is materialised\n * into a per-build overlay pages root and **prerendered** through\n * the normal scan → bundle → render pipeline, so a preset can own a\n * route without the project shipping a `pages/` stub file. A `\"/\"`\n * package route is allowed (it becomes the project's root page,\n * enabling a truly empty/absent user `pages/`). A package route\n * whose URL shape collides with a user `pages/` route is dropped\n * (user `pages/` wins). This is the supported, complete path.\n * - In **dev**, both static and dynamic injected routes are rendered\n * by `zfb dev`. Static routes (where the URL equals the pattern,\n * e.g. `/preset-about`) are seeded into the dev route universe at\n * boot; dynamic routes (e.g. `/preset-docs/[slug]`) are rendered\n * on first request via a request-time synthetic entry — params are\n * extracted from the URL by the Hono router inside the live bundle.\n * User `pages/` files take precedence over any injected route of\n * the same shape (including the dev-only `\"/\"` reservation, which\n * is still rejected at registration in dev). **HMR:** content the\n * route reads from watched collections live-refreshes normally.\n * Editing the package's **compiled entrypoint under `node_modules`**\n * is NOT watched and requires a `zfb dev` restart (restart-only\n * contract — a published package is not project source). **Per-route\n * data:** an injected route loads per-route data via a **dynamic\n * route's `paths()` export** (which returns `{ params, props }`);\n * `getStaticProps` on a package page is not forwarded by the overlay\n * (only `default` + the `prerender` hint are forwarded — same as\n * `zfb build`). A route that needs per-route data should be a\n * dynamic route whose `paths()` reads the data.\n *\n * `opts.prerender` controls the route's prerender shape during a\n * build: omit it (or `true`) for the SSG default; `false` marks an\n * SSR-shaped route, which `output: 'static'` rejects. It is build-only\n * metadata and ignored in dev.\n *\n * Two plugins registering the same `pattern` (or one plugin\n * re-registering it with a different entrypoint) raises\n * `InjectRouteConflict`.\n */\n injectRoute(pattern: string, entrypoint: string, opts?: { prerender?: boolean }): void;\n\n /**\n * Register a package-owned client-side side-effect entry (#1196).\n *\n * `entrypoint` **must** point to a `*.client.{ts,tsx,js,jsx}` file —\n * this is enforced (#1191 review [9]): a path missing the `.client.`\n * infix, or a bare `.client.ts` with an empty stem, throws an error\n * (`addClientEntry` JS-host validation + Rust `InvalidClientEntry`)\n * rather than being silently accepted under an invented name. The entry\n * name is derived from the filename stem minus `.client`\n * (e.g. `my-lib.client.ts` → `my-lib`), via the same canonical helper\n * as user-authored `*.client.*` discovery.\n *\n * The entry is bundled and shipped as\n * `/assets/client/<name>.js` (stable URL) / `/assets/client/<name>-<hash>.js`\n * (production, hashed). User-authored files win on name collision —\n * the registered entry is silently dropped when a user-authored file of\n * the same name exists in the discovery roots.\n *\n * Two plugins registering the same entry name with different entrypoints\n * raises `ClientEntryConflict` and aborts the build.\n *\n * `entrypoint` is resolved relative to the project root if given as a\n * relative path (same rule as `injectRoute`).\n */\n addClientEntry(entrypoint: string): void;\n};\n\n/**\n * The plugin-module shape. `name` is informational (the resolved module\n * specifier wins for identification on the Rust side) and helps the\n * plugin self-identify in logs.\n *\n * Five optional hooks; declaration-order matters when multiple plugins\n * touch the same surface. Each hook is independent — a plugin may\n * declare any subset:\n *\n * - `setup` (#255) — register virtual modules, aliases, injected\n * routes. Runs once at host boot, before `preBuild`. Also runs under\n * `zfb preview` (#1542) via the minimal non-V8 `run_preview_setup`\n * path — see [`ZfbSetupContext.command`](#command) for what is and\n * isn't meaningful there.\n * - `preBuild` — file-generation work that downstream stages will\n * see. Runs once per `zfb build` and once per `zfb dev` boot. Does\n * **NOT** fire under `zfb preview` (#1542) — preview serves an\n * already-built `dist/` and never re-triggers file generation.\n * - `postBuild` — finalisation work that runs after `dist/` has been\n * written. Does not fire under `zfb preview` either, for the same\n * reason as `preBuild`.\n * - `devMiddleware` — register HTTP handlers for ad-hoc dev-only\n * URLs. Per-request dispatch, distinct from `injectRoute` (which\n * goes through the page renderer). Fires only during `zfb dev`.\n * - `previewMiddleware` (#1542) — register HTTP handlers for ad-hoc\n * preview-only URLs. Same register-context shape as `devMiddleware`,\n * fires only during `zfb preview`. A plugin wanting coverage in both\n * modes registers the same handler under both hooks — `zfb` does\n * NOT reuse a `devMiddleware` registration for preview automatically\n * (explicit per-mode opt-in, by design).\n */\nexport type ZfbPlugin = {\n /** Plugin display name; surfaces in error / log lines. */\n name: string;\n setup?(ctx: ZfbSetupContext): Promise<void> | void;\n preBuild?(ctx: ZfbBuildHookContext): Promise<void> | void;\n postBuild?(ctx: ZfbBuildHookContext): Promise<void> | void;\n devMiddleware?(ctx: ZfbDevMiddlewareContext): Promise<void> | void;\n previewMiddleware?(ctx: ZfbPreviewMiddlewareContext): Promise<void> | void;\n};\n\n/**\n * Identity helper that types the supplied object as a [`ZfbPlugin`].\n * Use as the default export of a plugin module so editors surface\n * field-level types and typos surface at compile time.\n *\n * ```ts\n * import { definePlugin } from \"@takazudo/zfb/plugins\";\n *\n * export default definePlugin({\n * name: \"my-plugin\",\n * async preBuild({ outDir, logger }) {\n * logger.info(`generating index into ${outDir}`);\n * },\n * });\n * ```\n */\nexport function definePlugin(plugin: ZfbPlugin): ZfbPlugin {\n return plugin;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,wEAAwE;AACxE,oEAAoE;AACpE,oEAAoE;AACpE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,qEAAqE;AACrE,sEAAsE;AACtE,sEAAsE;AACtE,6CAA6C;AAC7C,EAAE;AACF,wCAAwC;AACxC,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,oEAAoE;AACpE,oEAAoE;AACpE,+BAA+B;AA6X/B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["// `zfb/plugins` — TypeScript helper for the zfb plugin lifecycle.\n//\n// A plugin is a JS module whose default export is a [`ZfbPlugin`] object.\n// `zfb.config.ts` references plugins by `name` (npm bare specifier or a\n// `./`-relative path); the zfb config loader resolves each `name` to an\n// absolute module specifier and the Rust-side plugin host loads the\n// module via dynamic `import()` and dispatches the lifecycle hooks.\n//\n// Sub 3 / issue #108 — initial drop. Three optional hooks: `preBuild`,\n// `postBuild`, `devMiddleware`. Astro-migration epic #253 / sub-issue\n// #255 adds a fourth: `setup`, which runs once before `preBuild` and\n// lets plugins register virtual modules, import aliases, and dev-only\n// injected routes. None of the hooks see real Node IPC objects across\n// the boundary; everything is JSON-friendly.\n//\n// ## Inline functions are NOT supported\n//\n// `PluginConfig` (in `./config.ts`) carries only data. A user cannot\n// inline a function in `zfb.config.ts` — the config goes through a\n// JSON round-trip and any function value would be silently dropped.\n// Plugins must live in their own module (npm package or local file)\n// and be referenced by `name`.\n\n/**\n * Logger handed to every plugin hook. The Rust side wraps `tracing` so\n * the same lines show up alongside the rest of the build's structured\n * logs. Hooks should prefer this over `console.log`.\n */\nexport type ZfbPluginLogger = {\n info(msg: string): void;\n warn(msg: string): void;\n error(msg: string): void;\n};\n\n/**\n * One emitted route in the `postBuild` route manifest (#262).\n * Present on `ctx.routes.routes` so a `postBuild` plugin can iterate\n * every URL the build produced (e.g. to write a `sitemap.xml`).\n */\nexport type ZfbRouteEntry = {\n /** Emitted URL path, e.g. `/`, `/blog/hello/`, `/sitemap.xml`. */\n url: string;\n /** Path under `outDir`, e.g. `index.html`, `blog/hello/index.html`, `sitemap.xml`. */\n output: string;\n /** File extension: `html`, `xml`, `rss`, `txt`, `json`, … */\n extension: string;\n /** Source page module relative to the project root, e.g. `pages/blog/[slug].tsx`. */\n source: string;\n /**\n * `true` when the page is prerendered to disk (default / SSG); `false`\n * when the page exports `prerender = false` and is served by the\n * runtime adapter (SSR — no on-disk artifact under `outDir`).\n *\n * Indexes that enumerate on-disk URLs (sitemap.xml, search-index.json,\n * etc.) should filter `r.prerender !== false` to avoid surfacing SSR\n * routes that have no static output.\n */\n prerender: boolean;\n /**\n * Bound route parameters. Absent for static routes.\n * Dynamic (`[slug]`) params are string scalars; catchall (`[...rest]`)\n * params are string arrays.\n */\n params?: Record<string, string | string[]>;\n};\n\n/**\n * The route manifest exposed on `ctx.routes` during a `postBuild` callback\n * (#262). Sorted by `url` for byte-stable output across runs.\n */\nexport type ZfbRouteManifest = {\n routes: ZfbRouteEntry[];\n};\n\n/**\n * Context passed to `preBuild` and `postBuild`. `outDir` is the\n * resolved absolute path of the configured `outDir` (default\n * `<projectRoot>/dist`). `projectRoot` is the directory containing\n * `zfb.config.ts`.\n *\n * `routes` is **only present on `postBuild`** calls; it is `undefined`\n * on `preBuild`. This is intentional: the route manifest is not\n * available until the build finishes writing `dist/` (#262).\n */\nexport type ZfbBuildHookContext = {\n /** Project root — the directory containing `zfb.config.ts`. */\n projectRoot: string;\n /** Resolved absolute path of the build output directory. */\n outDir: string;\n /** The full loaded `ZfbConfig` (data-only view). */\n config: import(\"./config.js\").ZfbConfig;\n /** Plugin-specific options block, copied verbatim from the matching `PluginConfig.options`. */\n options: Record<string, unknown>;\n /** Logger that wraps the Rust-side `tracing` subscriber. */\n logger: ZfbPluginLogger;\n /**\n * All routes emitted by this build, sorted by URL (#262).\n * Present only on `postBuild` calls; `undefined` on `preBuild`.\n */\n routes?: ZfbRouteManifest;\n};\n\n/**\n * A request handed to a `devMiddleware` handler. Subset of the Node\n * `http.IncomingMessage` surface intentionally — the dev server is\n * Rust-side `axum`, not Node, so we expose only what survives a JSON\n * envelope hop.\n */\nexport type ZfbDevMiddlewareRequest = {\n method: string;\n url: string;\n /** Lower-cased header names → first value. */\n headers: Record<string, string>;\n /** Raw request body; absent for GET/HEAD. UTF-8 only — binary is out of scope for v1 dev plugins. */\n body?: string;\n};\n\n/**\n * Response returned by a `devMiddleware` handler. All fields optional\n * except `status`. `body` may be a string (UTF-8) or a base64-encoded\n * binary payload (set `bodyEncoding` to `\"base64\"` in that case).\n */\nexport type ZfbDevMiddlewareResponse = {\n status: number;\n headers?: Record<string, string>;\n body?: string;\n bodyEncoding?: \"utf8\" | \"base64\";\n};\n\n/**\n * Handler signature for a `devMiddleware` registration. The `next` callback\n * is reserved for future composition; v1 plugins should produce a response\n * directly. Returning `undefined` from the handler signals \"I did not handle\n * this request\" — the dev server then falls through to its built-in routes\n * (the page cache, /__zfb/livereload.js, etc.).\n */\nexport type ZfbDevMiddlewareHandler = (\n req: ZfbDevMiddlewareRequest,\n) => Promise<ZfbDevMiddlewareResponse | undefined> | ZfbDevMiddlewareResponse | undefined;\n\n/**\n * Context passed to `devMiddleware`. The `register` callback installs\n * one handler per URL path prefix. `path` is matched as an exact prefix\n * — a registration on `/doc-history` matches `/doc-history` and\n * `/doc-history/foo`, but NOT `/doc-historyx`.\n */\nexport type ZfbDevMiddlewareContext = {\n projectRoot: string;\n config: import(\"./config.js\").ZfbConfig;\n options: Record<string, unknown>;\n logger: ZfbPluginLogger;\n /** Register an HTTP handler at `path`. Calling twice on the same path overwrites. */\n register(path: string, handler: ZfbDevMiddlewareHandler): void;\n};\n\n/**\n * Handler signature for a `previewMiddleware` registration (#1542).\n * Deliberately reuses [`ZfbDevMiddlewareRequest`] /\n * [`ZfbDevMiddlewareResponse`] verbatim — the wire shape crossing the\n * Rust↔JS boundary is genuinely the SAME for dev and preview (mirrors\n * the Rust side, which shares `DevRequest`/`DevResponse` between both\n * hooks too), so there is nothing preview-specific to say about the\n * request/response contract itself. `next` is likewise reserved for\n * future composition; returning `undefined` signals \"I did not handle\n * this request\" and the preview server falls through to its built-in\n * routes (static-file serving, or the wrangler-backed adapter in\n * adapter mode).\n */\nexport type ZfbPreviewMiddlewareHandler = (\n req: ZfbDevMiddlewareRequest,\n) => Promise<ZfbDevMiddlewareResponse | undefined> | ZfbDevMiddlewareResponse | undefined;\n\n/**\n * Context passed to `previewMiddleware` (#1542). Structurally identical\n * to [`ZfbDevMiddlewareContext`] today — one handler per URL path\n * prefix, matched the same way — but declared as its own named type\n * (unlike the request/response types above, which are reused verbatim)\n * because the *context* is where a hook-specific capability would land\n * first if one were ever added (e.g. something preview-only that\n * `devMiddleware` has no equivalent for). Keeping it a separate\n * declaration costs nothing today and avoids a breaking rename later.\n */\nexport type ZfbPreviewMiddlewareContext = {\n projectRoot: string;\n config: import(\"./config.js\").ZfbConfig;\n options: Record<string, unknown>;\n logger: ZfbPluginLogger;\n /** Register an HTTP handler at `path`. Calling twice on the same path overwrites. */\n register(path: string, handler: ZfbPreviewMiddlewareHandler): void;\n};\n\n/**\n * Loader signature for a virtual-module registration. Must return the\n * **complete ESM module source text** as a string — the bundler /\n * embedded V8 host feeds the returned string in as the module's\n * source verbatim. The loader is invoked **exactly once per build**\n * (and once per `zfb dev` host boot) the first time any consumer\n * imports the registered specifier; subsequent imports of the same\n * specifier re-use the memoised result.\n *\n * Example:\n *\n * ```ts\n * addVirtualModule(\"virtual:my-data\", () =>\n * `export default ${JSON.stringify(myJson)}`,\n * );\n * ```\n */\nexport type ZfbVirtualModuleLoader = () => string | Promise<string>;\n\n/**\n * Context passed to the new `setup` hook (#255). Runs once per host\n * boot, in `Config.plugins` declaration order, **before** `preBuild`.\n *\n * `ctx.command` tells the plugin which lifecycle is active so it can\n * gate per-lifecycle registrations. A dev-only mock route stays gated\n * to `\"dev\"`; a package-owned page route is registered unconditionally\n * (it is prerendered during a build and dev-routed during dev):\n *\n * ```ts\n * setup({ command, injectRoute }) {\n * // package-owned page route (rendered in build and dev)\n * injectRoute(\"/preset-page\", \"./pages/preset-page.tsx\");\n * // dev-only mock endpoint\n * if (command === \"dev\") {\n * injectRoute(\"/api/dev/x\", \"./scripts/dev-x.ts\");\n * }\n * }\n * ```\n *\n * The hook's surface is intentionally **closed**: only `injectRoute`,\n * `addVirtualModule`, `addAlias`, and `addClientEntry`. There is no\n * `addRemarkPlugin` / `addRehypePlugin` / `addMarkdownVisitor` — by\n * design (see the concept doc for the rationale).\n */\nexport type ZfbSetupContext = {\n /**\n * Active zfb command. `\"build\"` during `zfb build`; `\"dev\"` during\n * `zfb dev`; `\"preview\"` during `zfb preview` (#1542). It can guide\n * lifecycle-specific plugin behavior. `injectRoute` registrations are\n * accepted in both `\"dev\"` and `\"build\"`; user `pages/` routes retain\n * precedence over matching injected routes (see\n * [`injectRoute`](#injectRoute)).\n *\n * Under `\"preview\"`, `setup` still fires (Rust-side via the minimal\n * non-V8 `run_preview_setup` path) so plugin-side state\n * initialisation runs, but `zfb preview` serves an ALREADY-BUILT\n * `dist/` verbatim and never re-enters the scan → bundle → render\n * pipeline. Consequently `injectRoute` / `addVirtualModule` /\n * `addAlias` / `addClientEntry` calls made under `\"preview\"` are\n * accepted (for shape-consistency with `\"build\"`/`\"dev\"`) but are\n * **inert** — nothing downstream ever reads them. Only the hook's\n * side effects and a subsequent `previewMiddleware` registration do\n * anything meaningful under `\"preview\"`.\n */\n command: \"build\" | \"dev\" | \"preview\";\n /** Project root — the directory containing `zfb.config.ts`. */\n projectRoot: string;\n /** The full loaded `ZfbConfig` (data-only view). */\n config: import(\"./config.js\").ZfbConfig;\n /** Plugin-specific options block, copied verbatim from `PluginConfig.options`. */\n options: Record<string, unknown>;\n /** Logger that wraps the Rust-side `tracing` subscriber. */\n logger: ZfbPluginLogger;\n\n /**\n * Register an import alias. **Exact-match-only in v1**:\n * `addAlias(\"@/foo\", \"./src/foo.tsx\")` rewrites `import \"@/foo\"`\n * but does NOT match `import \"@/foo/bar\"`. Prefix-matching is\n * explicitly deferred to v2 — switch to one bare alias per file\n * until then.\n *\n * `to` is resolved relative to the project root. Two plugins\n * registering the same `from` with different `to` raises\n * `AliasConflict` and aborts the build.\n */\n addAlias(from: string, to: string): void;\n\n /**\n * Register a virtual module. `specifier` is a bare import\n * specifier (recommended `virtual:` prefix, not enforced).\n * `loader` returns the complete ESM source text as a string and\n * runs **exactly once per build** at first import.\n *\n * Two plugins registering the same `specifier` raises\n * `VirtualModuleConflict` and aborts the build.\n */\n addVirtualModule(specifier: string, loader: ZfbVirtualModuleLoader): void;\n\n /**\n * Register a synthetic / package-owned page route. `pattern` uses the\n * same grammar as `pages/` filenames (`/blog/[slug]`, `/api/dev/x`,\n * `/docs/[...rest]`).\n *\n * - In **build** (package-owned routes), the route is materialised\n * into a per-build overlay pages root and **prerendered** through\n * the normal scan → bundle → render pipeline, so a preset can own a\n * route without the project shipping a `pages/` stub file. A `\"/\"`\n * package route becomes the project's root page when no user\n * `pages/index` exists, enabling a truly empty/absent user `pages/`.\n * A package route whose URL shape collides with a user `pages/` route\n * is dropped (user `pages/` wins). This is the supported, complete path.\n * - In **dev**, both static and dynamic injected routes are rendered\n * by `zfb dev`. Static routes (where the URL equals the pattern,\n * e.g. `/preset-about`) are seeded into the dev route universe at\n * boot; dynamic routes (e.g. `/preset-docs/[slug]`) are rendered\n * on first request via a request-time synthetic entry — params are\n * extracted from the URL by the Hono router inside the live bundle.\n * User `pages/` files take precedence over any injected route of\n * the same shape, including `pages/index` over an injected `\"/\"`.\n * Without a user index, an injected root is staged, seeded, and served\n * like any other static injected route. **HMR:** content the\n * route reads from watched collections live-refreshes normally.\n * Editing the package's **compiled entrypoint under `node_modules`**\n * is NOT watched and requires a `zfb dev` restart (restart-only\n * contract — a published package is not project source). **Per-route\n * data:** an injected route loads per-route data via a **dynamic\n * route's `paths()` export** (which returns `{ params, props }`);\n * `getStaticProps` on a package page is not forwarded by the overlay\n * (only `default` + the `prerender` hint are forwarded — same as\n * `zfb build`). A route that needs per-route data should be a\n * dynamic route whose `paths()` reads the data.\n *\n * `opts.prerender` controls the route's prerender shape during a\n * build: omit it (or `true`) for the SSG default; `false` marks an\n * SSR-shaped route, which `output: 'static'` rejects. It is build-only\n * metadata and ignored in dev.\n *\n * Two plugins registering the same `pattern` (or one plugin\n * re-registering it with a different entrypoint) raises\n * `InjectRouteConflict`.\n */\n injectRoute(pattern: string, entrypoint: string, opts?: { prerender?: boolean }): void;\n\n /**\n * Register a package-owned client-side side-effect entry (#1196).\n *\n * `entrypoint` **must** point to a `*.client.{ts,tsx,js,jsx}` file —\n * this is enforced (#1191 review [9]): a path missing the `.client.`\n * infix, or a bare `.client.ts` with an empty stem, throws an error\n * (`addClientEntry` JS-host validation + Rust `InvalidClientEntry`)\n * rather than being silently accepted under an invented name. The entry\n * name is derived from the filename stem minus `.client`\n * (e.g. `my-lib.client.ts` → `my-lib`), via the same canonical helper\n * as user-authored `*.client.*` discovery.\n *\n * The entry is bundled and shipped as\n * `/assets/client/<name>.js` (stable URL) / `/assets/client/<name>-<hash>.js`\n * (production, hashed). User-authored files win on name collision —\n * the registered entry is silently dropped when a user-authored file of\n * the same name exists in the discovery roots.\n *\n * Two plugins registering the same entry name with different entrypoints\n * raises `ClientEntryConflict` and aborts the build.\n *\n * `entrypoint` is resolved relative to the project root if given as a\n * relative path (same rule as `injectRoute`).\n */\n addClientEntry(entrypoint: string): void;\n};\n\n/**\n * The plugin-module shape. `name` is informational (the resolved module\n * specifier wins for identification on the Rust side) and helps the\n * plugin self-identify in logs.\n *\n * Five optional hooks; declaration-order matters when multiple plugins\n * touch the same surface. Each hook is independent — a plugin may\n * declare any subset:\n *\n * - `setup` (#255) — register virtual modules, aliases, injected\n * routes. Runs once at host boot, before `preBuild`. Also runs under\n * `zfb preview` (#1542) via the minimal non-V8 `run_preview_setup`\n * path — see [`ZfbSetupContext.command`](#command) for what is and\n * isn't meaningful there.\n * - `preBuild` — file-generation work that downstream stages will\n * see. Runs once per `zfb build` and once per `zfb dev` boot. Does\n * **NOT** fire under `zfb preview` (#1542) — preview serves an\n * already-built `dist/` and never re-triggers file generation.\n * - `postBuild` — finalisation work that runs after `dist/` has been\n * written. Does not fire under `zfb preview` either, for the same\n * reason as `preBuild`.\n * - `devMiddleware` — register HTTP handlers for ad-hoc dev-only\n * URLs. Per-request dispatch, distinct from `injectRoute` (which\n * goes through the page renderer). Fires only during `zfb dev`.\n * - `previewMiddleware` (#1542) — register HTTP handlers for ad-hoc\n * preview-only URLs. Same register-context shape as `devMiddleware`,\n * fires only during `zfb preview`. A plugin wanting coverage in both\n * modes registers the same handler under both hooks — `zfb` does\n * NOT reuse a `devMiddleware` registration for preview automatically\n * (explicit per-mode opt-in, by design).\n */\nexport type ZfbPlugin = {\n /** Plugin display name; surfaces in error / log lines. */\n name: string;\n setup?(ctx: ZfbSetupContext): Promise<void> | void;\n preBuild?(ctx: ZfbBuildHookContext): Promise<void> | void;\n postBuild?(ctx: ZfbBuildHookContext): Promise<void> | void;\n devMiddleware?(ctx: ZfbDevMiddlewareContext): Promise<void> | void;\n previewMiddleware?(ctx: ZfbPreviewMiddlewareContext): Promise<void> | void;\n};\n\n/**\n * Identity helper that types the supplied object as a [`ZfbPlugin`].\n * Use as the default export of a plugin module so editors surface\n * field-level types and typos surface at compile time.\n *\n * ```ts\n * import { definePlugin } from \"@takazudo/zfb/plugins\";\n *\n * export default definePlugin({\n * name: \"my-plugin\",\n * async preBuild({ outDir, logger }) {\n * logger.info(`generating index into ${outDir}`);\n * },\n * });\n * ```\n */\nexport function definePlugin(plugin: ZfbPlugin): ZfbPlugin {\n return plugin;\n}\n"]}
|
package/dist/wasm.d.ts
ADDED
package/dist/wasm.js
ADDED
package/dist/wasm.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm.js","sourceRoot":"","sources":["../src/wasm.ts"],"names":[],"mappings":"","sourcesContent":["// Ambient module typing for Wasm files bundled by zfb.\n//\n// This source file intentionally has no imports or exports: the declaration\n// must remain global rather than becoming a module augmentation.\ndeclare module \"*.wasm\" {\n const wasmModule: WebAssembly.Module;\n export default wasmModule;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takazudo/zfb",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.82",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Rust-built static-site engine for Astro and Next.js users — millisecond rebuilds, single binary. SDK with islands, content collections, pagination, and config helpers.",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"LICENSE"
|
|
75
75
|
],
|
|
76
76
|
"optionalDependencies": {
|
|
77
|
-
"@takazudo/zfb-darwin-arm64": "0.1.0-next.
|
|
78
|
-
"@takazudo/zfb-darwin-x64": "0.1.0-next.
|
|
79
|
-
"@takazudo/zfb-linux-arm64-gnu": "0.1.0-next.
|
|
80
|
-
"@takazudo/zfb-linux-x64-gnu": "0.1.0-next.
|
|
81
|
-
"@takazudo/zfb-win32-x64-msvc": "0.1.0-next.
|
|
77
|
+
"@takazudo/zfb-darwin-arm64": "0.1.0-next.82",
|
|
78
|
+
"@takazudo/zfb-darwin-x64": "0.1.0-next.82",
|
|
79
|
+
"@takazudo/zfb-linux-arm64-gnu": "0.1.0-next.82",
|
|
80
|
+
"@takazudo/zfb-linux-x64-gnu": "0.1.0-next.82",
|
|
81
|
+
"@takazudo/zfb-win32-x64-msvc": "0.1.0-next.82"
|
|
82
82
|
},
|
|
83
83
|
"publishConfig": {
|
|
84
84
|
"access": "public"
|