alabjs 0.2.5 → 0.3.0-alpha.1
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/analytics/handler.d.ts +5 -1
- package/dist/analytics/handler.d.ts.map +1 -1
- package/dist/analytics/handler.js +14 -10
- package/dist/analytics/handler.js.map +1 -1
- package/dist/cli.js +7 -2
- package/dist/cli.js.map +1 -1
- package/dist/client/federation.d.ts +41 -0
- package/dist/client/federation.d.ts.map +1 -0
- package/dist/client/federation.js +48 -0
- package/dist/client/federation.js.map +1 -0
- package/dist/client/hooks.d.ts +9 -1
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/hooks.js +37 -4
- package/dist/client/hooks.js.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/offline-sw.js +142 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +279 -40
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +78 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.js +1 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/components/Image.d.ts +0 -12
- package/dist/components/Image.d.ts.map +1 -1
- package/dist/components/Image.js +2 -29
- package/dist/components/Image.js.map +1 -1
- package/dist/components/ImageServer.d.ts +20 -0
- package/dist/components/ImageServer.d.ts.map +1 -0
- package/dist/components/ImageServer.js +37 -0
- package/dist/components/ImageServer.js.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/config.d.ts +66 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +251 -41
- package/dist/server/app.js.map +1 -1
- package/dist/server/cache.d.ts.map +1 -1
- package/dist/server/cache.js +26 -4
- package/dist/server/cache.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +5 -0
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/revalidate.d.ts.map +1 -1
- package/dist/server/revalidate.js +10 -3
- package/dist/server/revalidate.js.map +1 -1
- package/dist/ssr/html.d.ts +7 -0
- package/dist/ssr/html.d.ts.map +1 -1
- package/dist/ssr/html.js +24 -4
- package/dist/ssr/html.js.map +1 -1
- package/dist/ssr/ppr.d.ts.map +1 -1
- package/dist/ssr/ppr.js +2 -1
- package/dist/ssr/ppr.js.map +1 -1
- package/dist/ssr/render.d.ts +5 -0
- package/dist/ssr/render.d.ts.map +1 -1
- package/dist/ssr/render.js +2 -1
- package/dist/ssr/render.js.map +1 -1
- package/package.json +9 -4
- package/src/analytics/handler.ts +15 -10
- package/src/cli.ts +9 -2
- package/src/client/federation.ts +55 -0
- package/src/client/hooks.ts +42 -4
- package/src/client/index.ts +1 -0
- package/src/client/offline-sw.ts +7 -2
- package/src/commands/build.ts +335 -44
- package/src/commands/dev.ts +84 -2
- package/src/commands/start.ts +1 -1
- package/src/components/Image.tsx +2 -35
- package/src/components/ImageServer.ts +43 -0
- package/src/components/index.ts +1 -1
- package/src/config.ts +143 -0
- package/src/index.ts +2 -0
- package/src/server/app.ts +289 -35
- package/src/server/cache.ts +28 -4
- package/src/server/csrf.ts +5 -0
- package/src/server/revalidate.ts +14 -2
- package/src/ssr/html.ts +31 -3
- package/src/ssr/ppr.ts +2 -1
- package/src/ssr/render.ts +7 -0
- package/tsconfig.sw.json +18 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -17,8 +17,12 @@ export declare function handleVitalsBeacon(req: IncomingMessage, res: ServerResp
|
|
|
17
17
|
* GET /_alabjs/analytics
|
|
18
18
|
*
|
|
19
19
|
* Returns a JSON snapshot of all collected metrics.
|
|
20
|
-
*
|
|
20
|
+
* Always requires Authorization: Bearer <ALAB_ANALYTICS_SECRET>.
|
|
21
21
|
* Falls back to ALAB_REVALIDATE_SECRET if ALAB_ANALYTICS_SECRET is unset.
|
|
22
|
+
*
|
|
23
|
+
* If neither env var is set the endpoint returns 401 — the endpoint is
|
|
24
|
+
* intentionally closed by default to prevent information leaks in production
|
|
25
|
+
* deployments that forget to set an analytics secret.
|
|
22
26
|
*/
|
|
23
27
|
export declare function handleAnalyticsDashboard(req: IncomingMessage, res: ServerResponse): void;
|
|
24
28
|
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/analytics/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAejE;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/analytics/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAejE;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,CA6Cf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,IAAI,CAqBN"}
|
|
@@ -63,21 +63,25 @@ export async function handleVitalsBeacon(req, res) {
|
|
|
63
63
|
* GET /_alabjs/analytics
|
|
64
64
|
*
|
|
65
65
|
* Returns a JSON snapshot of all collected metrics.
|
|
66
|
-
*
|
|
66
|
+
* Always requires Authorization: Bearer <ALAB_ANALYTICS_SECRET>.
|
|
67
67
|
* Falls back to ALAB_REVALIDATE_SECRET if ALAB_ANALYTICS_SECRET is unset.
|
|
68
|
+
*
|
|
69
|
+
* If neither env var is set the endpoint returns 401 — the endpoint is
|
|
70
|
+
* intentionally closed by default to prevent information leaks in production
|
|
71
|
+
* deployments that forget to set an analytics secret.
|
|
68
72
|
*/
|
|
69
73
|
export function handleAnalyticsDashboard(req, res) {
|
|
70
74
|
const secret = process.env["ALAB_ANALYTICS_SECRET"] ??
|
|
71
75
|
process.env["ALAB_REVALIDATE_SECRET"];
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
const auth = req.headers["authorization"] ?? "";
|
|
77
|
+
const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
|
|
78
|
+
if (!secret || token !== secret) {
|
|
79
|
+
res.statusCode = 401;
|
|
80
|
+
res.setHeader("content-type", "application/json");
|
|
81
|
+
res.end(JSON.stringify({
|
|
82
|
+
error: "Unauthorized. Set ALAB_ANALYTICS_SECRET and pass Authorization: Bearer <secret>.",
|
|
83
|
+
}));
|
|
84
|
+
return;
|
|
81
85
|
}
|
|
82
86
|
res.statusCode = 200;
|
|
83
87
|
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/analytics/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAmB,MAAM,YAAY,CAAC;AAExE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAE3E,mDAAmD;AACnD,SAAS,QAAQ,CAAC,GAAoB;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAoB,EACpB,GAAmB;IAEnB,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAElD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,eAAe,CAAC,CAAC;QAC/D,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAC;QAC9D,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACrB,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACrB,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChC,yEAAyE;QACzE,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAEzD,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,IACE,EAAE,KAAK,IAAI;gBACX,OAAO,EAAE,KAAK,QAAQ;gBACtB,MAAM,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ;gBAC3C,OAAO,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ;gBAC7C,OAAO,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ;gBAC7C,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EACzB,CAAC;gBACD,YAAY,CACV,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAS,wBAAwB;gBACvD,EAAE,CAAC,IAAkB,EACrB,EAAE,CAAC,KAAK,CACT,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;IAC3D,CAAC;IAED,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;IACrB,GAAG,CAAC,GAAG,EAAE,CAAC;AACZ,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/analytics/handler.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* alab info — print the route manifest and compiler info
|
|
9
9
|
*/
|
|
10
10
|
import { parseArgs } from "node:util";
|
|
11
|
+
import { resolve } from "node:path";
|
|
11
12
|
const { positionals, values } = parseArgs({
|
|
12
13
|
allowPositionals: true,
|
|
13
14
|
options: {
|
|
@@ -18,10 +19,14 @@ const { positionals, values } = parseArgs({
|
|
|
18
19
|
analyze: { type: "boolean", default: false },
|
|
19
20
|
watch: { type: "boolean", default: false },
|
|
20
21
|
ui: { type: "boolean", default: false },
|
|
22
|
+
/** Target a specific app directory — useful in monorepos. e.g. `--cwd apps/marketing` */
|
|
23
|
+
cwd: { type: "string", short: "C" },
|
|
21
24
|
},
|
|
22
25
|
});
|
|
23
26
|
const [command = "dev"] = positionals;
|
|
24
|
-
|
|
27
|
+
// Resolve --cwd relative to wherever the CLI was invoked.
|
|
28
|
+
// Falls back to process.cwd() when omitted (standard single-app behaviour).
|
|
29
|
+
const cwd = values["cwd"] ? resolve(process.cwd(), values["cwd"]) : process.cwd();
|
|
25
30
|
switch (command) {
|
|
26
31
|
case "dev":
|
|
27
32
|
await import("./commands/dev.js").then((m) => m.dev({ cwd }));
|
|
@@ -37,7 +42,7 @@ switch (command) {
|
|
|
37
42
|
break;
|
|
38
43
|
}
|
|
39
44
|
case "start":
|
|
40
|
-
await import("./commands/start.js").then((m) => m.start({ cwd }));
|
|
45
|
+
await import("./commands/start.js").then((m) => m.start({ cwd, port: Number(values["port"]) }));
|
|
41
46
|
break;
|
|
42
47
|
case "info":
|
|
43
48
|
await import("./commands/info.js").then((m) => m.info({ cwd }));
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ComponentType, type LazyExoticComponent } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Load a component from a federated remote application using native browser ESM.
|
|
4
|
+
*
|
|
5
|
+
* The specifier is resolved at runtime via the `<script type="importmap">` that
|
|
6
|
+
* AlabJS injects into every page when `federation.remotes` is set in
|
|
7
|
+
* `alabjs.config.ts`. No bundler runtime shim is required.
|
|
8
|
+
*
|
|
9
|
+
* The returned component is a `React.lazy` wrapper — wrap it in a `<Suspense>`
|
|
10
|
+
* boundary to handle the async load:
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // alabjs.config.ts
|
|
15
|
+
* export default defineConfig({
|
|
16
|
+
* federation: {
|
|
17
|
+
* name: "host",
|
|
18
|
+
* remotes: { "RemoteApp": "https://remote.example.com" },
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // app/page.tsx
|
|
23
|
+
* import { useFederatedComponent } from "alabjs/client";
|
|
24
|
+
* import { Suspense } from "react";
|
|
25
|
+
*
|
|
26
|
+
* const RemoteButton = useFederatedComponent("RemoteApp/Button");
|
|
27
|
+
*
|
|
28
|
+
* export default function Page() {
|
|
29
|
+
* return (
|
|
30
|
+
* <Suspense fallback={<span>Loading…</span>}>
|
|
31
|
+
* <RemoteButton variant="primary">Click me</RemoteButton>
|
|
32
|
+
* </Suspense>
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @param specifier - Module specifier in `"RemoteName/ExposedName"` format.
|
|
38
|
+
* Must match a key in the remote's `federation.exposes` config.
|
|
39
|
+
*/
|
|
40
|
+
export declare function useFederatedComponent<T extends ComponentType<any> = ComponentType<Record<string, unknown>>>(specifier: string): LazyExoticComponent<T>;
|
|
41
|
+
//# sourceMappingURL=federation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federation.d.ts","sourceRoot":"","sources":["../../src/client/federation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,qBAAqB,CAEnC,CAAC,SAAS,aAAa,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACrE,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAW3C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { lazy } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Load a component from a federated remote application using native browser ESM.
|
|
4
|
+
*
|
|
5
|
+
* The specifier is resolved at runtime via the `<script type="importmap">` that
|
|
6
|
+
* AlabJS injects into every page when `federation.remotes` is set in
|
|
7
|
+
* `alabjs.config.ts`. No bundler runtime shim is required.
|
|
8
|
+
*
|
|
9
|
+
* The returned component is a `React.lazy` wrapper — wrap it in a `<Suspense>`
|
|
10
|
+
* boundary to handle the async load:
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // alabjs.config.ts
|
|
15
|
+
* export default defineConfig({
|
|
16
|
+
* federation: {
|
|
17
|
+
* name: "host",
|
|
18
|
+
* remotes: { "RemoteApp": "https://remote.example.com" },
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // app/page.tsx
|
|
23
|
+
* import { useFederatedComponent } from "alabjs/client";
|
|
24
|
+
* import { Suspense } from "react";
|
|
25
|
+
*
|
|
26
|
+
* const RemoteButton = useFederatedComponent("RemoteApp/Button");
|
|
27
|
+
*
|
|
28
|
+
* export default function Page() {
|
|
29
|
+
* return (
|
|
30
|
+
* <Suspense fallback={<span>Loading…</span>}>
|
|
31
|
+
* <RemoteButton variant="primary">Click me</RemoteButton>
|
|
32
|
+
* </Suspense>
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @param specifier - Module specifier in `"RemoteName/ExposedName"` format.
|
|
38
|
+
* Must match a key in the remote's `federation.exposes` config.
|
|
39
|
+
*/
|
|
40
|
+
export function useFederatedComponent(specifier) {
|
|
41
|
+
return lazy(() =>
|
|
42
|
+
// @vite-ignore: resolved at runtime via the host page's import map —
|
|
43
|
+
// Vite must not try to statically analyse or bundle this specifier.
|
|
44
|
+
import(/* @vite-ignore */ specifier).then((mod) => ({
|
|
45
|
+
default: (mod.default ?? mod),
|
|
46
|
+
})));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=federation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federation.js","sourceRoot":"","sources":["../../src/client/federation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgD,MAAM,OAAO,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,qBAAqB,CAGnC,SAAiB;IACjB,OAAO,IAAI,CACT,GAAG,EAAE;IACH,qEAAqE;IACrE,oEAAoE;IACpE,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,IAAI,CACvC,CAAC,GAA8C,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAM;KACnC,CAAC,CACwB,CAC/B,CAAC;AACJ,CAAC"}
|
package/dist/client/hooks.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { ServerFn, InferServerOutput, RouteParams, InferServerPath } from "../types/index.js";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Clear the server-side promise cache between SSR renders.
|
|
4
|
+
*
|
|
5
|
+
* @internal — Called by Alab's dev and production SSR entry points before each
|
|
6
|
+
* `renderToPipeableStream` call. If you build a custom SSR integration, you
|
|
7
|
+
* MUST call this before rendering each page; failing to do so causes stale
|
|
8
|
+
* promises from a previous request to be returned by `useServerData`, resulting
|
|
9
|
+
* in wrong data being served to subsequent visitors.
|
|
10
|
+
*/
|
|
3
11
|
export declare function _clearALabSSRCache(): void;
|
|
4
12
|
/**
|
|
5
13
|
* Fetch server data with full type inference from a `ServerFn`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAoBnG;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC7D,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GACvC,iBAAiB,CAAC,CAAC,CAAC,CAkCtB;AAiCD,MAAM,WAAW,kBAAkB,CAAC,MAAM,EAAE,KAAK;IAC/C;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC3D,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;6CAG/D,CAAC,4BAkBI,IAAI;UAyDzB,uBAAS,SAAS;IACtC,4EAA4E;;;WAGtD,KAAK,GAAG,SAAS;IACvC,mFAAmF;;;;;;EAOtF;AAID,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,oDAAoD;IACpD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,sFAAsF;IACtF,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC;IACpB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,gDAAgD;IAChD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,OAAO,EAChC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAAC,CAAC,CAAC,CA4DjB"}
|
package/dist/client/hooks.js
CHANGED
|
@@ -4,9 +4,26 @@ import { use, useReducer, useTransition, useCallback, useState, useEffect, useRe
|
|
|
4
4
|
// re-renders after Suspense resolution return the same promise object, which
|
|
5
5
|
// is required for renderToPipeableStream to correctly resolve Suspense.
|
|
6
6
|
// • On the CLIENT: intentionally persists for the session to avoid redundant
|
|
7
|
-
// network round-trips on subsequent re-renders.
|
|
7
|
+
// network round-trips on subsequent re-renders. Capped at 256 entries (LRU)
|
|
8
|
+
// to prevent unbounded growth in long-lived SPAs.
|
|
9
|
+
const _CACHE_MAX = 256;
|
|
8
10
|
const _promiseCache = new Map();
|
|
9
|
-
|
|
11
|
+
function _cacheSet(key, value) {
|
|
12
|
+
if (_promiseCache.size >= _CACHE_MAX) {
|
|
13
|
+
// Map preserves insertion order — delete the oldest entry.
|
|
14
|
+
_promiseCache.delete(_promiseCache.keys().next().value);
|
|
15
|
+
}
|
|
16
|
+
_promiseCache.set(key, value);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Clear the server-side promise cache between SSR renders.
|
|
20
|
+
*
|
|
21
|
+
* @internal — Called by Alab's dev and production SSR entry points before each
|
|
22
|
+
* `renderToPipeableStream` call. If you build a custom SSR integration, you
|
|
23
|
+
* MUST call this before rendering each page; failing to do so causes stale
|
|
24
|
+
* promises from a previous request to be returned by `useServerData`, resulting
|
|
25
|
+
* in wrong data being served to subsequent visitors.
|
|
26
|
+
*/
|
|
10
27
|
export function _clearALabSSRCache() {
|
|
11
28
|
_promiseCache.clear();
|
|
12
29
|
}
|
|
@@ -31,6 +48,14 @@ export function _clearALabSSRCache() {
|
|
|
31
48
|
* ```
|
|
32
49
|
*/
|
|
33
50
|
export function useServerData(fnName, params) {
|
|
51
|
+
// During PPR build-time pre-rendering there is no server running, so we
|
|
52
|
+
// must not make network calls. Return an empty array so the component can
|
|
53
|
+
// render its static shell; data-dependent children should be inside
|
|
54
|
+
// <Dynamic> which renders a placeholder hole in PPR mode anyway.
|
|
55
|
+
if (typeof process !== "undefined" &&
|
|
56
|
+
process.env["ALAB_PPR_PRERENDER"] === "1") {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
34
59
|
const searchParams = params
|
|
35
60
|
? new URLSearchParams(params).toString()
|
|
36
61
|
: "";
|
|
@@ -47,7 +72,7 @@ export function useServerData(fnName, params) {
|
|
|
47
72
|
throw new Error(`[alabjs] server data fetch failed: ${r.status} ${r.statusText} — ${url}`);
|
|
48
73
|
return r.json();
|
|
49
74
|
});
|
|
50
|
-
|
|
75
|
+
_cacheSet(url, promise);
|
|
51
76
|
}
|
|
52
77
|
return use(promise);
|
|
53
78
|
}
|
|
@@ -97,9 +122,17 @@ export function useMutation(fnName, options) {
|
|
|
97
122
|
startTransition(() => {
|
|
98
123
|
void (async () => {
|
|
99
124
|
try {
|
|
125
|
+
// Read the CSRF token from the cookie (set by the server on any SSR
|
|
126
|
+
// page response) and echo it as x-csrf-token for double-submit protection.
|
|
127
|
+
const csrfToken = typeof document !== "undefined"
|
|
128
|
+
? document.cookie.match(/alab-csrf=([^;]+)/)?.[1] ?? ""
|
|
129
|
+
: "";
|
|
100
130
|
const r = await fetch(`/_alabjs/fn/${fnName}`, {
|
|
101
131
|
method: "POST",
|
|
102
|
-
headers: {
|
|
132
|
+
headers: {
|
|
133
|
+
"content-type": "application/json",
|
|
134
|
+
...(csrfToken ? { "x-csrf-token": csrfToken } : {}),
|
|
135
|
+
},
|
|
103
136
|
body: JSON.stringify(input),
|
|
104
137
|
});
|
|
105
138
|
// Zod validation error from server
|
package/dist/client/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAGjG,8BAA8B;AAC9B,+EAA+E;AAC/E,+EAA+E;AAC/E,0EAA0E;AAC1E,6EAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export type { UseSSEOptions, UseSSEResult, SSEReadyState } from "./hooks.js";
|
|
|
3
3
|
export { useOfflineMutations } from "./offline.js";
|
|
4
4
|
export type { UseOfflineMutationsResult, OfflineMutationResult } from "./offline.js";
|
|
5
5
|
export { AlabProvider } from "./provider.js";
|
|
6
|
+
export { useFederatedComponent } from "./federation.js";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACpF,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACpF,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/client/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { useServerData, useMutation, useSSE, _clearALabSSRCache } from "./hooks.js";
|
|
2
2
|
export { useOfflineMutations } from "./offline.js";
|
|
3
3
|
export { AlabProvider } from "./provider.js";
|
|
4
|
+
export { useFederatedComponent } from "./federation.js";
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alab offline service worker — queue-and-replay for mutations.
|
|
3
|
+
*
|
|
4
|
+
* This module is compiled to a separate SW entry point by `alab build`.
|
|
5
|
+
* It intercepts failed `/_alabjs/fn/*` POST requests when the network is
|
|
6
|
+
* unavailable, stores them in IndexedDB, and replays them when connectivity
|
|
7
|
+
* is restored.
|
|
8
|
+
*
|
|
9
|
+
* The SW communicates with the page via `postMessage`:
|
|
10
|
+
* page → SW: { type: "ALAB_REPLAY" } — manual replay trigger
|
|
11
|
+
* SW → page: { type: "ALAB_QUEUED", count: number }
|
|
12
|
+
* SW → page: { type: "ALAB_REPLAYED", fn: string, ok: boolean }
|
|
13
|
+
* SW → page: { type: "ALAB_QUEUE_EMPTY" }
|
|
14
|
+
*/
|
|
15
|
+
// ─── IndexedDB helpers ────────────────────────────────────────────────────────
|
|
16
|
+
const DB_NAME = "alab-offline";
|
|
17
|
+
const STORE = "mutations";
|
|
18
|
+
const DB_VERSION = 1;
|
|
19
|
+
function openDb() {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const req = indexedDB.open(DB_NAME, DB_VERSION);
|
|
22
|
+
req.onupgradeneeded = () => {
|
|
23
|
+
req.result.createObjectStore(STORE, { keyPath: "id" });
|
|
24
|
+
};
|
|
25
|
+
req.onsuccess = () => resolve(req.result);
|
|
26
|
+
req.onerror = () => reject(req.error);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function enqueue(item) {
|
|
30
|
+
const db = await openDb();
|
|
31
|
+
await new Promise((resolve, reject) => {
|
|
32
|
+
const tx = db.transaction(STORE, "readwrite");
|
|
33
|
+
tx.objectStore(STORE).put(item);
|
|
34
|
+
tx.oncomplete = () => resolve();
|
|
35
|
+
tx.onerror = () => reject(tx.error);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async function dequeue(id) {
|
|
39
|
+
const db = await openDb();
|
|
40
|
+
await new Promise((resolve, reject) => {
|
|
41
|
+
const tx = db.transaction(STORE, "readwrite");
|
|
42
|
+
tx.objectStore(STORE).delete(id);
|
|
43
|
+
tx.oncomplete = () => resolve();
|
|
44
|
+
tx.onerror = () => reject(tx.error);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async function getAllQueued() {
|
|
48
|
+
const db = await openDb();
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const tx = db.transaction(STORE, "readonly");
|
|
51
|
+
const req = tx.objectStore(STORE).getAll();
|
|
52
|
+
req.onsuccess = () => resolve(req.result);
|
|
53
|
+
req.onerror = () => reject(req.error);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// ─── Broadcast to all controlled pages ───────────────────────────────────────
|
|
57
|
+
function broadcast(msg) {
|
|
58
|
+
self.clients.matchAll({ includeUncontrolled: true }).then((clients) => {
|
|
59
|
+
clients.forEach((c) => c.postMessage(msg));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// ─── Replay queued mutations ──────────────────────────────────────────────────
|
|
63
|
+
async function replay() {
|
|
64
|
+
const queued = await getAllQueued();
|
|
65
|
+
if (queued.length === 0) {
|
|
66
|
+
broadcast({ type: "ALAB_QUEUE_EMPTY" });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
for (const item of queued) {
|
|
70
|
+
try {
|
|
71
|
+
const res = await fetch(`/_alabjs/fn/${item.fn}`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: { "content-type": "application/json" },
|
|
74
|
+
body: item.body,
|
|
75
|
+
});
|
|
76
|
+
if (res.ok || res.status === 422) {
|
|
77
|
+
// 422 = Zod error — not a network failure; dequeue and notify
|
|
78
|
+
await dequeue(item.id);
|
|
79
|
+
broadcast({ type: "ALAB_REPLAYED", fn: item.fn, ok: res.ok });
|
|
80
|
+
}
|
|
81
|
+
// 5xx: leave in queue and try again next time
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Still offline — leave in queue
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// If all items were processed, notify pages the queue is empty.
|
|
88
|
+
const remaining = await getAllQueued();
|
|
89
|
+
if (remaining.length === 0) {
|
|
90
|
+
broadcast({ type: "ALAB_QUEUE_EMPTY" });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ─── SW event listeners ───────────────────────────────────────────────────────
|
|
94
|
+
self.addEventListener("install", () => {
|
|
95
|
+
self.skipWaiting();
|
|
96
|
+
});
|
|
97
|
+
self.addEventListener("activate", (event) => {
|
|
98
|
+
event.waitUntil(self.clients.claim());
|
|
99
|
+
});
|
|
100
|
+
self.addEventListener("fetch", (event) => {
|
|
101
|
+
const { request } = event;
|
|
102
|
+
// Only intercept mutation POSTs to /_alabjs/fn/*
|
|
103
|
+
if (request.method !== "POST" ||
|
|
104
|
+
!new URL(request.url).pathname.startsWith("/_alabjs/fn/")) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
event.respondWith((async () => {
|
|
108
|
+
try {
|
|
109
|
+
return await fetch(request.clone());
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Network failure — queue the mutation
|
|
113
|
+
const fn = new URL(request.url).pathname.replace("/_alabjs/fn/", "");
|
|
114
|
+
const body = await request.text();
|
|
115
|
+
const item = {
|
|
116
|
+
id: `${fn}-${crypto.randomUUID()}`,
|
|
117
|
+
fn,
|
|
118
|
+
body,
|
|
119
|
+
timestamp: Date.now(),
|
|
120
|
+
};
|
|
121
|
+
await enqueue(item);
|
|
122
|
+
const queued = await getAllQueued();
|
|
123
|
+
broadcast({ type: "ALAB_QUEUED", count: queued.length });
|
|
124
|
+
// Return a synthetic "queued" response so the caller isn't left hanging
|
|
125
|
+
return new Response(JSON.stringify({ __queued: true, id: item.id }), {
|
|
126
|
+
status: 202,
|
|
127
|
+
headers: { "content-type": "application/json" },
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
})());
|
|
131
|
+
});
|
|
132
|
+
self.addEventListener("sync", (event) => {
|
|
133
|
+
if (event.tag === "alab-mutation-replay") {
|
|
134
|
+
event.waitUntil(replay());
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
self.addEventListener("message", (event) => {
|
|
138
|
+
if (event.data?.["type"] === "ALAB_REPLAY") {
|
|
139
|
+
event.waitUntil(replay());
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAUA,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAsED,wBAAsB,KAAK,CAAC,EAAE,GAAG,EAAE,aAAqB,EAAE,IAAY,EAAE,OAAe,EAAE,EAAE,YAAY,iBA4GtG"}
|