fibrae 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/build.d.ts +34 -0
- package/dist/cli/build.js +92 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/cli.d.ts +10 -0
- package/dist/cli/cli.js +43 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/config.d.ts +19 -0
- package/dist/cli/config.js +5 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/html.d.ts +13 -0
- package/dist/cli/html.js +101 -0
- package/dist/cli/html.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/vite-plugin.d.ts +9 -0
- package/dist/cli/vite-plugin.js +143 -0
- package/dist/cli/vite-plugin.js.map +1 -0
- package/dist/components.d.ts +27 -29
- package/dist/components.js +32 -52
- package/dist/components.js.map +1 -1
- package/dist/core.js +7 -10
- package/dist/core.js.map +1 -1
- package/dist/dom.d.ts +13 -4
- package/dist/dom.js +91 -26
- package/dist/dom.js.map +1 -1
- package/dist/fiber-boundary.d.ts +39 -0
- package/dist/fiber-boundary.js +151 -0
- package/dist/fiber-boundary.js.map +1 -0
- package/dist/fiber-commit.d.ts +27 -0
- package/dist/fiber-commit.js +243 -0
- package/dist/fiber-commit.js.map +1 -0
- package/dist/fiber-render.d.ts +9 -9
- package/dist/fiber-render.js +165 -958
- package/dist/fiber-render.js.map +1 -1
- package/dist/fiber-tree.d.ts +77 -0
- package/dist/fiber-tree.js +152 -0
- package/dist/fiber-tree.js.map +1 -0
- package/dist/fiber-update.d.ts +46 -0
- package/dist/fiber-update.js +515 -0
- package/dist/fiber-update.js.map +1 -0
- package/dist/h.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime/index.d.ts +253 -2
- package/dist/live/atom.d.ts +31 -0
- package/dist/live/atom.js +33 -0
- package/dist/live/atom.js.map +1 -0
- package/dist/live/client.d.ts +50 -0
- package/dist/live/client.js +90 -0
- package/dist/live/client.js.map +1 -0
- package/dist/live/codec.d.ts +39 -0
- package/dist/live/codec.js +41 -0
- package/dist/live/codec.js.map +1 -0
- package/dist/live/config.d.ts +13 -0
- package/dist/live/config.js +11 -0
- package/dist/live/config.js.map +1 -0
- package/dist/live/index.d.ts +25 -0
- package/dist/live/index.js +19 -0
- package/dist/live/index.js.map +1 -0
- package/dist/live/server.d.ts +83 -0
- package/dist/live/server.js +106 -0
- package/dist/live/server.js.map +1 -0
- package/dist/live/sse-stream.d.ts +14 -0
- package/dist/live/sse-stream.js +30 -0
- package/dist/live/sse-stream.js.map +1 -0
- package/dist/live/types.d.ts +40 -0
- package/dist/live/types.js +20 -0
- package/dist/live/types.js.map +1 -0
- package/dist/router/History.d.ts +2 -7
- package/dist/router/History.js +0 -8
- package/dist/router/History.js.map +1 -1
- package/dist/router/Link.d.ts +8 -4
- package/dist/router/Link.js +13 -34
- package/dist/router/Link.js.map +1 -1
- package/dist/router/Navigator.d.ts +12 -1
- package/dist/router/Navigator.js +31 -68
- package/dist/router/Navigator.js.map +1 -1
- package/dist/router/Route.d.ts +16 -3
- package/dist/router/Route.js +32 -25
- package/dist/router/Route.js.map +1 -1
- package/dist/router/Router.d.ts +27 -19
- package/dist/router/Router.js +78 -101
- package/dist/router/Router.js.map +1 -1
- package/dist/router/RouterBuilder.d.ts +106 -34
- package/dist/router/RouterBuilder.js +78 -39
- package/dist/router/RouterBuilder.js.map +1 -1
- package/dist/router/RouterOutlet.d.ts +1 -18
- package/dist/router/RouterOutlet.js +25 -8
- package/dist/router/RouterOutlet.js.map +1 -1
- package/dist/router/RouterState.d.ts +1 -1
- package/dist/router/index.d.ts +5 -5
- package/dist/router/index.js +5 -3
- package/dist/router/index.js.map +1 -1
- package/dist/router/utils.d.ts +36 -0
- package/dist/router/utils.js +48 -0
- package/dist/router/utils.js.map +1 -0
- package/dist/runtime.d.ts +10 -7
- package/dist/runtime.js +20 -2
- package/dist/runtime.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +15 -29
- package/dist/server.js.map +1 -1
- package/dist/shared.d.ts +58 -59
- package/dist/shared.js +51 -13
- package/dist/shared.js.map +1 -1
- package/dist/tracking.d.ts +4 -3
- package/dist/tracking.js +6 -1
- package/dist/tracking.js.map +1 -1
- package/package.json +32 -7
- package/dist/hydration.d.ts +0 -30
- package/dist/hydration.js +0 -355
- package/dist/hydration.js.map +0 -1
- package/dist/render.d.ts +0 -19
- package/dist/render.js +0 -285
- package/dist/render.js.map +0 -1
- package/dist/scope-utils.d.ts +0 -14
- package/dist/scope-utils.js +0 -29
- package/dist/scope-utils.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSG build pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates: Vite client build → route discovery → pre-render → write HTML.
|
|
5
|
+
*/
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as Layer from "effect/Layer";
|
|
8
|
+
import { FileSystem } from "@effect/platform";
|
|
9
|
+
import { Path } from "@effect/platform";
|
|
10
|
+
import { Router, RouterHandlers } from "../router/index.js";
|
|
11
|
+
import type { HeadData } from "../router/index.js";
|
|
12
|
+
import type { VElement } from "../shared.js";
|
|
13
|
+
export interface BuildOptions {
|
|
14
|
+
/** The fibrae router instance */
|
|
15
|
+
readonly router: Router.Router;
|
|
16
|
+
/** Layer providing RouterHandlers */
|
|
17
|
+
readonly handlersLayer: Layer.Layer<RouterHandlers>;
|
|
18
|
+
/** Wraps each route's rendered element in the app shell */
|
|
19
|
+
readonly appShell: (element: VElement) => VElement;
|
|
20
|
+
/** Output directory */
|
|
21
|
+
readonly outDir: string;
|
|
22
|
+
/** Base path prefix for routes (e.g. "/app") */
|
|
23
|
+
readonly basePath?: string;
|
|
24
|
+
/** Path to client JS bundle (relative to site root) */
|
|
25
|
+
readonly clientScript?: string;
|
|
26
|
+
/** Default page title */
|
|
27
|
+
readonly title?: string;
|
|
28
|
+
/** Global head tags injected into every page */
|
|
29
|
+
readonly headTags?: HeadData;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Pre-render all routes marked with `prerender: true` to static HTML files.
|
|
33
|
+
*/
|
|
34
|
+
export declare const build: (options: BuildOptions) => Effect.Effect<void, unknown, FileSystem.FileSystem | Path.Path>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSG build pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates: Vite client build → route discovery → pre-render → write HTML.
|
|
5
|
+
*/
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as Layer from "effect/Layer";
|
|
8
|
+
import { FileSystem } from "@effect/platform";
|
|
9
|
+
import { Path } from "@effect/platform";
|
|
10
|
+
import { renderToStringWith, SSRAtomRegistryLayer } from "../server.js";
|
|
11
|
+
import { Router, RouterHandlers, getPrerenderRoutes } from "../router/index.js";
|
|
12
|
+
import { buildPage } from "./html.js";
|
|
13
|
+
/**
|
|
14
|
+
* Render a single route to an HTML string.
|
|
15
|
+
*/
|
|
16
|
+
const renderRoute = (config) => Effect.gen(function* () {
|
|
17
|
+
const serverLayer = Router.serverLayer({
|
|
18
|
+
router: config.router,
|
|
19
|
+
pathname: config.pathname,
|
|
20
|
+
search: "",
|
|
21
|
+
basePath: config.basePath,
|
|
22
|
+
});
|
|
23
|
+
const fullLayer = Layer.provideMerge(serverLayer, Layer.merge(config.handlersLayer, SSRAtomRegistryLayer));
|
|
24
|
+
const { html, dehydratedState, head } = yield* Effect.gen(function* () {
|
|
25
|
+
const { element, head } = yield* Router.CurrentRouteElement;
|
|
26
|
+
const renderResult = yield* renderToStringWith(config.appShell(element));
|
|
27
|
+
return { ...renderResult, head };
|
|
28
|
+
}).pipe(Effect.provide(fullLayer));
|
|
29
|
+
return yield* buildPage({
|
|
30
|
+
html,
|
|
31
|
+
dehydratedState: dehydratedState,
|
|
32
|
+
clientScript: config.clientScript,
|
|
33
|
+
title: config.title,
|
|
34
|
+
head,
|
|
35
|
+
headTags: config.headTags,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Compute all (pathname, handler) pairs from prerender routes.
|
|
40
|
+
*/
|
|
41
|
+
const expandRoutes = (prerenderRoutes, basePath) => Effect.all(prerenderRoutes.flatMap(({ handler, paramSets }) => paramSets.map((params) => handler.route
|
|
42
|
+
.interpolate(params)
|
|
43
|
+
.pipe(Effect.map((pathname) => ({ pathname: basePath + pathname, handler }))))));
|
|
44
|
+
/**
|
|
45
|
+
* Write an HTML string to the appropriate file path under outDir.
|
|
46
|
+
* Creates directories as needed.
|
|
47
|
+
*
|
|
48
|
+
* / → outDir/index.html
|
|
49
|
+
* /about → outDir/about/index.html
|
|
50
|
+
* /posts/1 → outDir/posts/1/index.html
|
|
51
|
+
*/
|
|
52
|
+
const writePageFile = (outDir, pathname, html) => Effect.gen(function* () {
|
|
53
|
+
const fs = yield* FileSystem.FileSystem;
|
|
54
|
+
const path = yield* Path.Path;
|
|
55
|
+
const filePath = pathname === "/" || pathname === ""
|
|
56
|
+
? path.join(outDir, "index.html")
|
|
57
|
+
: path.join(outDir, pathname, "index.html");
|
|
58
|
+
yield* fs.makeDirectory(path.dirname(filePath), { recursive: true });
|
|
59
|
+
yield* fs.writeFileString(filePath, html);
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Pre-render all routes marked with `prerender: true` to static HTML files.
|
|
63
|
+
*/
|
|
64
|
+
export const build = (options) => Effect.gen(function* () {
|
|
65
|
+
const { router, handlersLayer, appShell, outDir, basePath = "", clientScript, title, headTags, } = options;
|
|
66
|
+
// Resolve handlers to get prerender routes
|
|
67
|
+
const handlers = yield* Effect.provide(Effect.flatMap(RouterHandlers, (h) => getPrerenderRoutes(h)), handlersLayer);
|
|
68
|
+
const routes = yield* expandRoutes(handlers, basePath);
|
|
69
|
+
if (routes.length === 0) {
|
|
70
|
+
yield* Effect.log("No prerender routes found.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
yield* Effect.log(`Pre-rendering ${routes.length} page(s)...`);
|
|
74
|
+
// Render all routes
|
|
75
|
+
const pages = yield* Effect.all(routes.map(({ pathname }) => renderRoute({
|
|
76
|
+
router,
|
|
77
|
+
handlersLayer,
|
|
78
|
+
appShell,
|
|
79
|
+
pathname,
|
|
80
|
+
basePath,
|
|
81
|
+
clientScript,
|
|
82
|
+
title,
|
|
83
|
+
headTags,
|
|
84
|
+
}).pipe(Effect.map((html) => ({ pathname, html })))));
|
|
85
|
+
// Write all pages to disk
|
|
86
|
+
yield* Effect.forEach(pages, ({ pathname, html }) => Effect.gen(function* () {
|
|
87
|
+
yield* writePageFile(outDir, pathname, html);
|
|
88
|
+
yield* Effect.log(` ${pathname} → ${outDir}${pathname === "/" ? "/index.html" : `${pathname}/index.html`}`);
|
|
89
|
+
}), { discard: true });
|
|
90
|
+
yield* Effect.log(`Done. ${pages.length} page(s) written to ${outDir}/`);
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* fibrae CLI — static site generation for fibrae apps.
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* fibrae build Pre-render routes and build client bundle
|
|
7
|
+
* fibrae dev Start Vite dev server with on-demand SSR
|
|
8
|
+
* fibrae preview Serve the built output
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
package/dist/cli/cli.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* fibrae CLI — static site generation for fibrae apps.
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* fibrae build Pre-render routes and build client bundle
|
|
7
|
+
* fibrae dev Start Vite dev server with on-demand SSR
|
|
8
|
+
* fibrae preview Serve the built output
|
|
9
|
+
*/
|
|
10
|
+
const [command] = process.argv.slice(2);
|
|
11
|
+
const commands = {
|
|
12
|
+
async build() {
|
|
13
|
+
const { build } = await import("vite");
|
|
14
|
+
await build();
|
|
15
|
+
},
|
|
16
|
+
async dev() {
|
|
17
|
+
const { createServer } = await import("vite");
|
|
18
|
+
const server = await createServer({ server: { open: true } });
|
|
19
|
+
await server.listen();
|
|
20
|
+
server.printUrls();
|
|
21
|
+
},
|
|
22
|
+
async preview() {
|
|
23
|
+
const { preview } = await import("vite");
|
|
24
|
+
const server = await preview();
|
|
25
|
+
server.printUrls();
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
const run = commands[command ?? ""];
|
|
29
|
+
if (!run) {
|
|
30
|
+
console.log(`Usage: fibrae <command>
|
|
31
|
+
|
|
32
|
+
Commands:
|
|
33
|
+
build Pre-render routes and build client bundle
|
|
34
|
+
dev Start Vite dev server with on-demand SSR
|
|
35
|
+
preview Serve the built output`);
|
|
36
|
+
process.exit(command ? 1 : 0);
|
|
37
|
+
}
|
|
38
|
+
run().catch((err) => {
|
|
39
|
+
console.error(err);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAExC,MAAM,QAAQ,GAAwC;IACpD,KAAK,CAAC,KAAK;QACT,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,KAAK,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;QAC/B,MAAM,CAAC,SAAS,EAAE,CAAC;IACrB,CAAC;CACF,CAAC;AAEF,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAEpC,IAAI,CAAC,GAAG,EAAE,CAAC;IACT,OAAO,CAAC,GAAG,CAAC;;;;;kCAKoB,CAAC,CAAC;IAClC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAClB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration types for fibrae-cli.
|
|
3
|
+
*/
|
|
4
|
+
import type { HeadData } from "../router/RouterBuilder.js";
|
|
5
|
+
export interface FibraeConfig {
|
|
6
|
+
/** Module path that exports { router, handlers, App } */
|
|
7
|
+
readonly entry: string;
|
|
8
|
+
/** Client hydration entry point */
|
|
9
|
+
readonly client: string;
|
|
10
|
+
/** Output directory (default: "dist") */
|
|
11
|
+
readonly outDir?: string;
|
|
12
|
+
/** Base path prefix for routes */
|
|
13
|
+
readonly basePath?: string;
|
|
14
|
+
/** Default page title */
|
|
15
|
+
readonly title?: string;
|
|
16
|
+
/** Global head tags injected into every page (fonts, analytics, meta, etc.) */
|
|
17
|
+
readonly headTags?: HeadData;
|
|
18
|
+
}
|
|
19
|
+
export declare const defineConfig: (config: FibraeConfig) => FibraeConfig;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAoB,EAAgB,EAAE,CAAC,MAAM,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HeadData } from "../router/RouterBuilder.js";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Option from "effect/Option";
|
|
4
|
+
export interface PageOptions {
|
|
5
|
+
readonly html: string;
|
|
6
|
+
readonly dehydratedState: ReadonlyArray<unknown>;
|
|
7
|
+
readonly clientScript?: string;
|
|
8
|
+
readonly title?: string;
|
|
9
|
+
readonly head: Option.Option<HeadData>;
|
|
10
|
+
/** Global head tags from config, merged with per-route head */
|
|
11
|
+
readonly headTags?: HeadData;
|
|
12
|
+
}
|
|
13
|
+
export declare const buildPage: (options: PageOptions) => Effect.Effect<string, unknown, never>;
|
package/dist/cli/html.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML page template for static site generation.
|
|
3
|
+
*
|
|
4
|
+
* Uses fibrae JSX to generate full HTML documents wrapping
|
|
5
|
+
* pre-rendered content with dehydrated state and client scripts.
|
|
6
|
+
*/
|
|
7
|
+
import { h } from "../h.js";
|
|
8
|
+
import { renderToString } from "../server.js";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import * as Option from "effect/Option";
|
|
11
|
+
import * as Array from "effect/Array";
|
|
12
|
+
const metaToElement = (meta) => {
|
|
13
|
+
if ("title" in meta)
|
|
14
|
+
return Option.none();
|
|
15
|
+
if ("charset" in meta)
|
|
16
|
+
return Option.some(h("meta", { charset: meta.charset }));
|
|
17
|
+
if ("script:ld+json" in meta)
|
|
18
|
+
return Option.some(h("script", {
|
|
19
|
+
type: "application/ld+json",
|
|
20
|
+
dangerouslySetInnerHTML: JSON.stringify(meta["script:ld+json"]),
|
|
21
|
+
}));
|
|
22
|
+
if ("name" in meta)
|
|
23
|
+
return Option.some(h("meta", { name: meta.name, content: meta.content }));
|
|
24
|
+
if ("property" in meta)
|
|
25
|
+
return Option.some(h("meta", { property: meta.property, content: meta.content }));
|
|
26
|
+
if ("httpEquiv" in meta)
|
|
27
|
+
return Option.some(h("meta", { "http-equiv": meta.httpEquiv, content: meta.content }));
|
|
28
|
+
if ("tagName" in meta) {
|
|
29
|
+
const { tagName, ...attrs } = meta;
|
|
30
|
+
return Option.some(h(tagName, attrs));
|
|
31
|
+
}
|
|
32
|
+
return Option.none();
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Get the dedup key for a meta descriptor.
|
|
36
|
+
* Per TanStack Router pattern: meta tags with the same name/property are
|
|
37
|
+
* deduplicated, with per-route tags winning over global tags.
|
|
38
|
+
*/
|
|
39
|
+
const metaKey = (meta) => {
|
|
40
|
+
if ("name" in meta)
|
|
41
|
+
return `name:${meta.name}`;
|
|
42
|
+
if ("property" in meta)
|
|
43
|
+
return `property:${meta.property}`;
|
|
44
|
+
if ("httpEquiv" in meta)
|
|
45
|
+
return `httpEquiv:${meta.httpEquiv}`;
|
|
46
|
+
if ("charset" in meta)
|
|
47
|
+
return "charset";
|
|
48
|
+
return undefined;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Merge meta arrays with deduplication. Per-route entries override globals
|
|
52
|
+
* when they share the same name/property/httpEquiv key.
|
|
53
|
+
*/
|
|
54
|
+
const dedupMeta = (global, perRoute) => {
|
|
55
|
+
const routeKeys = new Set(perRoute.map(metaKey).filter(Boolean));
|
|
56
|
+
const filtered = global.filter((m) => {
|
|
57
|
+
const key = metaKey(m);
|
|
58
|
+
return key === undefined || !routeKeys.has(key);
|
|
59
|
+
});
|
|
60
|
+
return [...filtered, ...perRoute];
|
|
61
|
+
};
|
|
62
|
+
const buildHeadChildren = (title, head, headTags) => {
|
|
63
|
+
const headData = Option.getOrUndefined(head);
|
|
64
|
+
// Per-route title wins, then global headTags title, then config title
|
|
65
|
+
const pageTitle = headData?.title ?? headTags?.title ?? title;
|
|
66
|
+
// Merge global headTags with per-route head.
|
|
67
|
+
// Meta tags are deduplicated by name/property (per-route wins).
|
|
68
|
+
// Links and scripts are concatenated (global first, then per-route).
|
|
69
|
+
const allMeta = dedupMeta(headTags?.meta ?? [], headData?.meta ?? []);
|
|
70
|
+
const allLinks = [...(headTags?.links ?? []), ...(headData?.links ?? [])];
|
|
71
|
+
const allScripts = [...(headTags?.scripts ?? []), ...(headData?.scripts ?? [])];
|
|
72
|
+
return [
|
|
73
|
+
h("meta", { charset: "UTF-8" }),
|
|
74
|
+
h("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }),
|
|
75
|
+
...Option.match(Option.fromNullable(pageTitle), {
|
|
76
|
+
onNone: () => [],
|
|
77
|
+
onSome: (t) => [h("title", {}, [t])],
|
|
78
|
+
}),
|
|
79
|
+
...Array.filterMap(allMeta, metaToElement),
|
|
80
|
+
...allLinks.map((attrs) => h("link", attrs)),
|
|
81
|
+
...allScripts.flatMap((script) => script.src
|
|
82
|
+
? [h("script", { type: script.type, src: script.src })]
|
|
83
|
+
: script.content
|
|
84
|
+
? [h("script", { type: script.type, dangerouslySetInnerHTML: script.content })]
|
|
85
|
+
: []),
|
|
86
|
+
];
|
|
87
|
+
};
|
|
88
|
+
const PageShell = (props) => h("html", { lang: "en" }, [
|
|
89
|
+
h("head", {}, buildHeadChildren(props.title, props.head, props.headTags)),
|
|
90
|
+
h("body", {}, [
|
|
91
|
+
h("div", { id: "root", dangerouslySetInnerHTML: props.html }),
|
|
92
|
+
h("script", {
|
|
93
|
+
type: "application/json",
|
|
94
|
+
id: "__fibrae-state__",
|
|
95
|
+
dangerouslySetInnerHTML: JSON.stringify(props.dehydratedState),
|
|
96
|
+
}),
|
|
97
|
+
...(props.clientScript ? [h("script", { type: "module", src: props.clientScript })] : []),
|
|
98
|
+
]),
|
|
99
|
+
]);
|
|
100
|
+
export const buildPage = (options) => renderToString(PageShell(options)).pipe(Effect.map(({ html }) => `<!DOCTYPE html>\n${html}`));
|
|
101
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/cli/html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { buildPage } from "./html.js";
|
|
2
|
+
export type { PageOptions } from "./html.js";
|
|
3
|
+
export { build } from "./build.js";
|
|
4
|
+
export type { BuildOptions } from "./build.js";
|
|
5
|
+
export { defineConfig } from "./config.js";
|
|
6
|
+
export type { FibraeConfig } from "./config.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite plugin for fibrae static site generation.
|
|
3
|
+
*
|
|
4
|
+
* Hooks into Vite's build pipeline to pre-render routes after the client build.
|
|
5
|
+
* In dev mode, provides on-demand SSR middleware.
|
|
6
|
+
*/
|
|
7
|
+
import type { Plugin } from "vite";
|
|
8
|
+
import type { FibraeConfig } from "./config.js";
|
|
9
|
+
export declare const fibrae: (config: FibraeConfig) => Plugin<any>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import * as Layer from "effect/Layer";
|
|
4
|
+
import { NodeContext } from "@effect/platform-node";
|
|
5
|
+
import { Router, RouterHandlers } from "../router/index.js";
|
|
6
|
+
import { renderToStringWith, SSRAtomRegistryLayer } from "../server.js";
|
|
7
|
+
import { buildPage } from "./html.js";
|
|
8
|
+
/**
|
|
9
|
+
* Render a single page for the dev server.
|
|
10
|
+
*/
|
|
11
|
+
const renderDevPage = (opts) => Effect.gen(function* () {
|
|
12
|
+
const serverLayer = Router.serverLayer({
|
|
13
|
+
router: opts.router,
|
|
14
|
+
pathname: opts.pathname,
|
|
15
|
+
search: "",
|
|
16
|
+
basePath: opts.basePath,
|
|
17
|
+
});
|
|
18
|
+
const fullLayer = Layer.provideMerge(serverLayer, Layer.merge(opts.handlersLayer, SSRAtomRegistryLayer));
|
|
19
|
+
const { html, dehydratedState, head } = yield* Effect.gen(function* () {
|
|
20
|
+
const { head } = yield* Router.CurrentRouteElement;
|
|
21
|
+
const renderResult = opts.App
|
|
22
|
+
? yield* renderToStringWith(opts.App())
|
|
23
|
+
: yield* Effect.gen(function* () {
|
|
24
|
+
const { element } = yield* Router.CurrentRouteElement;
|
|
25
|
+
const app = opts.appShell ? opts.appShell(element) : element;
|
|
26
|
+
return yield* renderToStringWith(app);
|
|
27
|
+
});
|
|
28
|
+
return { ...renderResult, head };
|
|
29
|
+
}).pipe(Effect.provide(fullLayer));
|
|
30
|
+
return yield* buildPage({
|
|
31
|
+
html,
|
|
32
|
+
dehydratedState: dehydratedState,
|
|
33
|
+
clientScript: opts.clientScript,
|
|
34
|
+
title: opts.title,
|
|
35
|
+
head,
|
|
36
|
+
headTags: opts.headTags,
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Walk the Vite module graph from an entry and collect CSS module URLs.
|
|
41
|
+
* Injects these as <style> tags in the SSR HTML to prevent FOUC.
|
|
42
|
+
*/
|
|
43
|
+
const collectCss = async (server, entryUrl) => {
|
|
44
|
+
// Warm the module graph so CSS deps are discovered
|
|
45
|
+
await server.transformRequest(entryUrl);
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
const cssUrls = [];
|
|
48
|
+
const walk = (mod) => {
|
|
49
|
+
if (!mod?.id || seen.has(mod.id))
|
|
50
|
+
return;
|
|
51
|
+
seen.add(mod.id);
|
|
52
|
+
if (mod.id.endsWith(".css")) {
|
|
53
|
+
cssUrls.push(mod.url);
|
|
54
|
+
}
|
|
55
|
+
for (const dep of mod.importedModules) {
|
|
56
|
+
walk(dep);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
walk(await server.moduleGraph.getModuleByUrl(entryUrl));
|
|
60
|
+
return cssUrls;
|
|
61
|
+
};
|
|
62
|
+
export const fibrae = (config) => {
|
|
63
|
+
let _resolvedConfig;
|
|
64
|
+
return {
|
|
65
|
+
name: "fibrae-ssg",
|
|
66
|
+
configResolved(resolved) {
|
|
67
|
+
_resolvedConfig = resolved;
|
|
68
|
+
},
|
|
69
|
+
configureServer(server) {
|
|
70
|
+
server.middlewares.use(async (req, res, next) => {
|
|
71
|
+
const url = req.url;
|
|
72
|
+
if (!url || url.startsWith("/@") || url.includes(".")) {
|
|
73
|
+
return next();
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const appModule = await server.ssrLoadModule(config.entry);
|
|
77
|
+
const { router, handlersLayer, appShell, App } = appModule;
|
|
78
|
+
if (!router || !handlersLayer) {
|
|
79
|
+
return next();
|
|
80
|
+
}
|
|
81
|
+
// Only SSR routes the router knows about; pass everything else through
|
|
82
|
+
if (Option.isNone(router.matchRoute(url))) {
|
|
83
|
+
return next();
|
|
84
|
+
}
|
|
85
|
+
const rawHtml = await Effect.runPromise(renderDevPage({
|
|
86
|
+
router,
|
|
87
|
+
handlersLayer,
|
|
88
|
+
App,
|
|
89
|
+
appShell,
|
|
90
|
+
pathname: url,
|
|
91
|
+
basePath: config.basePath ?? "",
|
|
92
|
+
clientScript: config.client,
|
|
93
|
+
title: config.title,
|
|
94
|
+
headTags: config.headTags,
|
|
95
|
+
}));
|
|
96
|
+
// Collect CSS from client entry's module graph and inject into <head>
|
|
97
|
+
const cssUrls = await collectCss(server, config.client);
|
|
98
|
+
const cssTags = cssUrls.map((u) => `<link rel="stylesheet" href="${u}">`).join("\n");
|
|
99
|
+
const withCss = cssTags ? rawHtml.replace("</head>", `${cssTags}\n</head>`) : rawHtml;
|
|
100
|
+
// Let Vite inject HMR client
|
|
101
|
+
const result = await server.transformIndexHtml(url, withCss);
|
|
102
|
+
res.setHeader("Content-Type", "text/html");
|
|
103
|
+
res.end(result);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
next();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
async closeBundle() {
|
|
111
|
+
if (_resolvedConfig.command !== "build")
|
|
112
|
+
return;
|
|
113
|
+
const outDir = config.outDir ?? _resolvedConfig.build.outDir ?? "dist";
|
|
114
|
+
try {
|
|
115
|
+
const entryPath = new URL(config.entry, `file://${process.cwd()}/`).pathname;
|
|
116
|
+
const appModule = await import(entryPath);
|
|
117
|
+
const { router, handlersLayer, appShell } = appModule;
|
|
118
|
+
if (!router || !handlersLayer) {
|
|
119
|
+
console.warn("[fibrae-ssg] Entry module missing router or handlersLayer exports. Skipping SSG.");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const { build: ssgBuild } = await import("./build.js");
|
|
123
|
+
const clientScript = config.client
|
|
124
|
+
? `/${config.client.replace(/\.tsx?$/, ".js")}`
|
|
125
|
+
: undefined;
|
|
126
|
+
await Effect.runPromise(ssgBuild({
|
|
127
|
+
router,
|
|
128
|
+
handlersLayer,
|
|
129
|
+
appShell: appShell ?? ((el) => el),
|
|
130
|
+
outDir,
|
|
131
|
+
basePath: config.basePath ?? "",
|
|
132
|
+
clientScript,
|
|
133
|
+
title: config.title,
|
|
134
|
+
headTags: config.headTags,
|
|
135
|
+
}).pipe(Effect.provide(NodeContext.layer)));
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
console.error("[fibrae-ssg] Pre-render failed:", e);
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=vite-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../../src/cli/vite-plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/components.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import * as Context from "effect/Context";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Stream from "effect/Stream";
|
|
4
3
|
import { type ComponentError, type VElement } from "./shared.js";
|
|
5
4
|
declare const ErrorBoundaryChannel_base: Context.TagClass<ErrorBoundaryChannel, "ErrorBoundaryChannel", {
|
|
6
5
|
/** Report an error to this boundary. Used by event handlers and stream subscriptions. */
|
|
7
6
|
readonly reportError: (error: unknown) => Effect.Effect<void, never, never>;
|
|
8
7
|
/** Optional unique identifier for this boundary (for debugging/logging) */
|
|
9
|
-
readonly boundaryId?: string;
|
|
8
|
+
readonly boundaryId?: string | undefined;
|
|
10
9
|
}>;
|
|
11
10
|
/**
|
|
12
11
|
* Error boundary channel - used by ErrorBoundary for async error reporting.
|
|
@@ -33,42 +32,41 @@ export declare class ErrorBoundaryChannel extends ErrorBoundaryChannel_base {
|
|
|
33
32
|
*/
|
|
34
33
|
export declare const Suspense: (props: {
|
|
35
34
|
fallback: VElement;
|
|
36
|
-
threshold?: number;
|
|
37
|
-
children?: VElement | VElement
|
|
35
|
+
threshold?: number | undefined;
|
|
36
|
+
children?: VElement[] | VElement | undefined;
|
|
38
37
|
}) => VElement;
|
|
39
38
|
/**
|
|
40
|
-
*
|
|
39
|
+
* Error boundary component — catches errors in its subtree and shows a fallback.
|
|
41
40
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* Supports recovery: when children re-emit (e.g. route change), the boundary
|
|
42
|
+
* resets and shows the new content. Children are "parked" during error state
|
|
43
|
+
* (subscriptions stay alive), similar to how Suspense works.
|
|
44
44
|
*
|
|
45
45
|
* @example
|
|
46
46
|
* ```tsx
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* RenderError: (e) => Stream.succeed(<div>Render failed: {e.componentName}</div>),
|
|
51
|
-
* StreamError: (e) => Stream.succeed(<div>Stream failed: {e.phase}</div>),
|
|
52
|
-
* EventHandlerError: (e) => Stream.succeed(<div>Event {e.eventType} failed</div>),
|
|
53
|
-
* })
|
|
54
|
-
* );
|
|
55
|
-
*
|
|
56
|
-
* // Use it like any other component
|
|
57
|
-
* <SafeApp />
|
|
47
|
+
* <ErrorBoundary fallback={(error) => <div>Error: {error._tag}</div>}>
|
|
48
|
+
* <RouterOutlet />
|
|
49
|
+
* </ErrorBoundary>
|
|
58
50
|
* ```
|
|
59
51
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* 2. The renderer detects this marker and sets up error handling
|
|
63
|
-
* 3. If any error occurs in the subtree, the Stream fails with that ComponentError
|
|
64
|
-
* 4. `Stream.catchTags` catches the error and produces a fallback Stream
|
|
65
|
-
* 5. The fallback VElement is rendered in place of the failed content
|
|
52
|
+
* The `error` parameter is a `ComponentError` union — match on `_tag` for
|
|
53
|
+
* per-type handling:
|
|
66
54
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
55
|
+
* ```tsx
|
|
56
|
+
* const fallback = (error: ComponentError) => {
|
|
57
|
+
* switch (error._tag) {
|
|
58
|
+
* case "RenderError": return <div>Render failed: {error.componentName}</div>
|
|
59
|
+
* case "StreamError": return <div>Stream failed in {error.phase}</div>
|
|
60
|
+
* case "EventHandlerError": return <div>Event {error.eventType} failed</div>
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
69
64
|
*
|
|
70
|
-
* @param
|
|
71
|
-
* @
|
|
65
|
+
* @param props.fallback - Function that receives the error and returns fallback UI
|
|
66
|
+
* @param props.children - Child components to wrap in the error boundary
|
|
72
67
|
*/
|
|
73
|
-
export declare const ErrorBoundary: (
|
|
68
|
+
export declare const ErrorBoundary: (props: {
|
|
69
|
+
fallback: (error: ComponentError) => VElement;
|
|
70
|
+
children?: VElement[] | VElement | undefined;
|
|
71
|
+
}) => VElement;
|
|
74
72
|
export {};
|