alabjs 0.2.6 → 0.4.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/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 +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client/hooks.d.ts +9 -1
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/hooks.js +26 -2
- package/dist/client/hooks.js.map +1 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +279 -65
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +225 -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/Link.d.ts +16 -0
- package/dist/components/Link.d.ts.map +1 -1
- package/dist/components/Link.js +10 -0
- package/dist/components/Link.js.map +1 -1
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/index.js.map +1 -1
- package/dist/live/broadcaster.d.ts +64 -0
- package/dist/live/broadcaster.d.ts.map +1 -0
- package/dist/live/broadcaster.js +78 -0
- package/dist/live/broadcaster.js.map +1 -0
- package/dist/live/registry.d.ts +34 -0
- package/dist/live/registry.d.ts.map +1 -0
- package/dist/live/registry.js +33 -0
- package/dist/live/registry.js.map +1 -0
- package/dist/live/renderer.d.ts +22 -0
- package/dist/live/renderer.d.ts.map +1 -0
- package/dist/live/renderer.js +45 -0
- package/dist/live/renderer.js.map +1 -0
- package/dist/router/manifest.d.ts +1 -1
- package/dist/router/manifest.d.ts.map +1 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +339 -43
- package/dist/server/app.js.map +1 -1
- package/dist/server/cache.d.ts.map +1 -1
- package/dist/server/cache.js +23 -1
- 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/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/revalidate.d.ts.map +1 -1
- package/dist/server/revalidate.js +3 -0
- package/dist/server/revalidate.js.map +1 -1
- package/dist/ssr/html.d.ts.map +1 -1
- package/dist/ssr/html.js +15 -0
- 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/package.json +8 -3
- package/src/analytics/handler.ts +15 -10
- package/src/cli.ts +3 -1
- package/src/client/hooks.ts +30 -2
- package/src/commands/build.ts +316 -69
- package/src/commands/dev.ts +246 -3
- package/src/commands/start.ts +1 -1
- package/src/components/Image.tsx +2 -35
- package/src/components/ImageServer.ts +43 -0
- package/src/components/Link.tsx +20 -0
- package/src/components/index.ts +3 -3
- package/src/live/broadcaster.ts +83 -0
- package/src/live/registry.ts +56 -0
- package/src/live/renderer.ts +54 -0
- package/src/router/manifest.ts +1 -1
- package/src/server/app.ts +369 -44
- package/src/server/cache.ts +23 -1
- package/src/server/csrf.ts +5 -0
- package/src/server/index.ts +1 -0
- package/src/server/revalidate.ts +3 -0
- package/src/ssr/html.ts +15 -0
- package/src/ssr/ppr.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-only image utilities.
|
|
3
|
+
*
|
|
4
|
+
* Import from "alabjs/components/server" — do NOT import from "alabjs/components"
|
|
5
|
+
* because this file uses Node.js built-ins (fs, path) and must never be bundled
|
|
6
|
+
* for the browser.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Base64 blur-up placeholder for an image in `public/`.
|
|
10
|
+
*
|
|
11
|
+
* Calls the Rust napi binding to resize the image to 8px wide and encode it
|
|
12
|
+
* as a tiny WebP, then Base64-encodes it into a data URL ready for `blurDataURL`.
|
|
13
|
+
*
|
|
14
|
+
* Run this in a server function — it reads from disk and must not run in the browser.
|
|
15
|
+
*
|
|
16
|
+
* @param src - Path relative to `public/` (e.g. `"/hero.jpg"`)
|
|
17
|
+
* @param publicDir - Absolute path to the `public/` directory
|
|
18
|
+
*/
|
|
19
|
+
export async function generateBlurPlaceholder(src, publicDir) {
|
|
20
|
+
const { readFile } = await import("node:fs/promises");
|
|
21
|
+
const { resolve } = await import("node:path");
|
|
22
|
+
const safeSrc = src.replace(/\.\./g, "").replace(/^\/+/, "");
|
|
23
|
+
const filePath = resolve(publicDir, safeSrc);
|
|
24
|
+
const input = await readFile(filePath);
|
|
25
|
+
let napi;
|
|
26
|
+
try {
|
|
27
|
+
napi = (await import("@alabjs/compiler"));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// napi not built — return empty string (image still loads, just no blur effect)
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
const tiny = await napi.optimizeImage(input, 40, 8, null, "webp");
|
|
34
|
+
const b64 = Buffer.from(tiny).toString("base64");
|
|
35
|
+
return `data:image/webp;base64,${b64}`;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=ImageServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageServer.js","sourceRoot":"","sources":["../../src/components/ImageServer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,GAAW,EACX,SAAiB;IAEjB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACtD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEvC,IAAI,IAAiH,CAAC;IACtH,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAgB,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,gFAAgF;QAChF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,0BAA0B,GAAG,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -4,6 +4,14 @@ export interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
|
4
4
|
/** Prefetch the target page on hover (default: true). */
|
|
5
5
|
prefetch?: boolean;
|
|
6
6
|
}
|
|
7
|
+
export interface RouteLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href"> {
|
|
8
|
+
/** The destination path. Narrows to AlabRoutes when routes.d.ts is included. */
|
|
9
|
+
to: string;
|
|
10
|
+
/** Replace the current history entry instead of pushing a new one. */
|
|
11
|
+
replace?: boolean;
|
|
12
|
+
/** Prefetch the target page on hover (default: true). */
|
|
13
|
+
prefetch?: boolean;
|
|
14
|
+
}
|
|
7
15
|
declare global {
|
|
8
16
|
interface Window {
|
|
9
17
|
__alabjs_navigate?: (href: string) => Promise<void>;
|
|
@@ -20,4 +28,12 @@ declare global {
|
|
|
20
28
|
* background so the browser caches it before the user clicks.
|
|
21
29
|
*/
|
|
22
30
|
export declare function Link({ href, children, prefetch, onClick, ...rest }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* Type-safe navigation link.
|
|
33
|
+
*
|
|
34
|
+
* Identical to `<Link>` but uses a `to` prop instead of `href`.
|
|
35
|
+
* When `.alabjs/routes.d.ts` is included in your tsconfig, the `to` prop
|
|
36
|
+
* is narrowed to the `AlabRoutes` union so typos become build errors.
|
|
37
|
+
*/
|
|
38
|
+
export declare function RouteLink({ to, replace: _replace, ...rest }: RouteLinkProps): import("react/jsx-runtime").JSX.Element;
|
|
23
39
|
//# sourceMappingURL=Link.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAc,MAAM,OAAO,CAAC;AAE9D,MAAM,WAAW,SAAU,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrD;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAe,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,2CAuCpF"}
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAc,MAAM,OAAO,CAAC;AAE9D,MAAM,WAAW,SAAU,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3F,gFAAgF;IAChF,EAAE,EAAE,MAAM,CAAC;IACX,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrD;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAe,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,2CAuCpF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,2CAE3E"}
|
package/dist/components/Link.js
CHANGED
|
@@ -45,4 +45,14 @@ export function Link({ href, children, prefetch = true, onClick, ...rest }) {
|
|
|
45
45
|
: undefined;
|
|
46
46
|
return (_jsx("a", { href: href, onClick: handleClick, onMouseEnter: handleMouseEnter, ...rest, children: children }));
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Type-safe navigation link.
|
|
50
|
+
*
|
|
51
|
+
* Identical to `<Link>` but uses a `to` prop instead of `href`.
|
|
52
|
+
* When `.alabjs/routes.d.ts` is included in your tsconfig, the `to` prop
|
|
53
|
+
* is narrowed to the `AlabRoutes` union so typos become build errors.
|
|
54
|
+
*/
|
|
55
|
+
export function RouteLink({ to, replace: _replace, ...rest }) {
|
|
56
|
+
return _jsx(Link, { href: to, ...rest });
|
|
57
|
+
}
|
|
48
58
|
//# sourceMappingURL=Link.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/components/Link.tsx"],"names":[],"mappings":";AAuBA;;;;;;;;;GASG;AACH,MAAM,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAa;IACnF,MAAM,YAAY,GAAG,CAAC,GAAW,EAAW,EAAE;QAC5C,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,EAAE,CAAgC,EAAE,EAAE;QAC7D,oEAAoE;QACpE,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO;QAC7D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO;QAEhC,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAEb,IAAI,OAAO,MAAM,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;YACnD,MAAM,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,QAAQ;QAC/B,CAAC,CAAC,GAAG,EAAE;YACH,IAAI,OAAO,MAAM,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;gBACnD,8DAA8D;gBAC9D,KAAK,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAiB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QACH,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,CACL,YAAG,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,KAAM,IAAI,YAC1E,QAAQ,GACP,CACL,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAkB;IAC1E,OAAO,KAAC,IAAI,IAAC,IAAI,EAAE,EAAE,KAAM,IAAI,GAAI,CAAC;AACtC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { Image
|
|
1
|
+
export { Image } from "./Image.js";
|
|
2
2
|
export type { ImageProps } from "./Image.js";
|
|
3
|
-
export { Link } from "./Link.js";
|
|
4
|
-
export type { LinkProps } from "./Link.js";
|
|
3
|
+
export { Link, RouteLink } from "./Link.js";
|
|
4
|
+
export type { LinkProps, RouteLinkProps } from "./Link.js";
|
|
5
5
|
export { ErrorBoundary } from "./ErrorBoundary.js";
|
|
6
6
|
export { Script } from "./Script.js";
|
|
7
7
|
export type { ScriptProps } from "./Script.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { Image
|
|
2
|
-
export { Link } from "./Link.js";
|
|
1
|
+
export { Image } from "./Image.js";
|
|
2
|
+
export { Link, RouteLink } from "./Link.js";
|
|
3
3
|
export { ErrorBoundary } from "./ErrorBoundary.js";
|
|
4
4
|
export { Script } from "./Script.js";
|
|
5
5
|
export { Font } from "./Font.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process tag-based pub/sub broadcaster for live components.
|
|
3
|
+
*
|
|
4
|
+
* Each SSE connection subscribes to the tags returned by its component's
|
|
5
|
+
* `liveTags(props)` export. When `invalidateLive({ tags })` is called from
|
|
6
|
+
* anywhere on the server (route handler, webhook, cron job), every matching
|
|
7
|
+
* subscriber is notified and re-renders its HTML fragment over SSE.
|
|
8
|
+
*
|
|
9
|
+
* Current implementation: plain Node.js `EventEmitter` — zero dependencies,
|
|
10
|
+
* zero config, works for any single-process deployment (Railway, Fly.io,
|
|
11
|
+
* Render, Heroku — single dyno/instance covers the vast majority of use cases).
|
|
12
|
+
*
|
|
13
|
+
* ─── Redis adapter (ON HOLD) ──────────────────────────────────────────────────
|
|
14
|
+
* Multi-instance deployments (PM2 cluster, multiple replicas behind a load
|
|
15
|
+
* balancer) need cross-process pub/sub: `invalidateLive` called on instance A
|
|
16
|
+
* must wake SSE connections on instances B and C.
|
|
17
|
+
*
|
|
18
|
+
* A Redis adapter is planned but intentionally deferred:
|
|
19
|
+
* - Most alab apps run single-instance and would pay Redis cost for no benefit
|
|
20
|
+
* - Vertical scaling (bigger machine) handles serious load before needing replicas
|
|
21
|
+
* - The interface here (`subscribeToTag` / `broadcastTag`) is already the right
|
|
22
|
+
* abstraction; swapping the backend is a ~20-line change when needed
|
|
23
|
+
*
|
|
24
|
+
* When it ships it will be an optional package:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* // alabjs.config.ts
|
|
28
|
+
* import { redisBroadcaster } from "@alabjs/broadcaster-redis";
|
|
29
|
+
*
|
|
30
|
+
* export default defineConfig({
|
|
31
|
+
* live: { broadcaster: redisBroadcaster({ url: process.env.REDIS_URL }) },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Tracking issue: https://github.com/alab-framework/alab/issues — search
|
|
36
|
+
* "broadcaster-redis" to follow progress or upvote.
|
|
37
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Subscribe a callback to a specific tag.
|
|
41
|
+
*
|
|
42
|
+
* @returns An unsubscribe function — call it on SSE client disconnect.
|
|
43
|
+
*/
|
|
44
|
+
export declare function subscribeToTag(tag: string, callback: () => void): () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Broadcast a tag change to all live SSE connections subscribed to it.
|
|
47
|
+
*/
|
|
48
|
+
export declare function broadcastTag(tag: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Invalidate live components by tag.
|
|
51
|
+
*
|
|
52
|
+
* Triggers an immediate re-render push for every SSE connection subscribed
|
|
53
|
+
* to any of the given tags. Called from route handlers, webhooks, cron jobs,
|
|
54
|
+
* or the existing `/_alabjs/revalidate` endpoint.
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { invalidateLive } from "alabjs/server";
|
|
58
|
+
* await invalidateLive({ tags: ["stock:AAPL", "stock:GOOG"] });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function invalidateLive(opts: {
|
|
62
|
+
tags: string[];
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
//# sourceMappingURL=broadcaster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcaster.d.ts","sourceRoot":"","sources":["../../src/live/broadcaster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAWH;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAI5E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI5E"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process tag-based pub/sub broadcaster for live components.
|
|
3
|
+
*
|
|
4
|
+
* Each SSE connection subscribes to the tags returned by its component's
|
|
5
|
+
* `liveTags(props)` export. When `invalidateLive({ tags })` is called from
|
|
6
|
+
* anywhere on the server (route handler, webhook, cron job), every matching
|
|
7
|
+
* subscriber is notified and re-renders its HTML fragment over SSE.
|
|
8
|
+
*
|
|
9
|
+
* Current implementation: plain Node.js `EventEmitter` — zero dependencies,
|
|
10
|
+
* zero config, works for any single-process deployment (Railway, Fly.io,
|
|
11
|
+
* Render, Heroku — single dyno/instance covers the vast majority of use cases).
|
|
12
|
+
*
|
|
13
|
+
* ─── Redis adapter (ON HOLD) ──────────────────────────────────────────────────
|
|
14
|
+
* Multi-instance deployments (PM2 cluster, multiple replicas behind a load
|
|
15
|
+
* balancer) need cross-process pub/sub: `invalidateLive` called on instance A
|
|
16
|
+
* must wake SSE connections on instances B and C.
|
|
17
|
+
*
|
|
18
|
+
* A Redis adapter is planned but intentionally deferred:
|
|
19
|
+
* - Most alab apps run single-instance and would pay Redis cost for no benefit
|
|
20
|
+
* - Vertical scaling (bigger machine) handles serious load before needing replicas
|
|
21
|
+
* - The interface here (`subscribeToTag` / `broadcastTag`) is already the right
|
|
22
|
+
* abstraction; swapping the backend is a ~20-line change when needed
|
|
23
|
+
*
|
|
24
|
+
* When it ships it will be an optional package:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* // alabjs.config.ts
|
|
28
|
+
* import { redisBroadcaster } from "@alabjs/broadcaster-redis";
|
|
29
|
+
*
|
|
30
|
+
* export default defineConfig({
|
|
31
|
+
* live: { broadcaster: redisBroadcaster({ url: process.env.REDIS_URL }) },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Tracking issue: https://github.com/alab-framework/alab/issues — search
|
|
36
|
+
* "broadcaster-redis" to follow progress or upvote.
|
|
37
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
*/
|
|
39
|
+
import { EventEmitter } from "node:events";
|
|
40
|
+
// One emitter per process — all SSE handlers share it.
|
|
41
|
+
const _emitter = new EventEmitter();
|
|
42
|
+
// Prevent Node.js MaxListenersExceededWarning on pages with many live components.
|
|
43
|
+
_emitter.setMaxListeners(0);
|
|
44
|
+
const TAG_EVENT_PREFIX = "live:tag:";
|
|
45
|
+
/**
|
|
46
|
+
* Subscribe a callback to a specific tag.
|
|
47
|
+
*
|
|
48
|
+
* @returns An unsubscribe function — call it on SSE client disconnect.
|
|
49
|
+
*/
|
|
50
|
+
export function subscribeToTag(tag, callback) {
|
|
51
|
+
const event = TAG_EVENT_PREFIX + tag;
|
|
52
|
+
_emitter.on(event, callback);
|
|
53
|
+
return () => _emitter.off(event, callback);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Broadcast a tag change to all live SSE connections subscribed to it.
|
|
57
|
+
*/
|
|
58
|
+
export function broadcastTag(tag) {
|
|
59
|
+
_emitter.emit(TAG_EVENT_PREFIX + tag);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Invalidate live components by tag.
|
|
63
|
+
*
|
|
64
|
+
* Triggers an immediate re-render push for every SSE connection subscribed
|
|
65
|
+
* to any of the given tags. Called from route handlers, webhooks, cron jobs,
|
|
66
|
+
* or the existing `/_alabjs/revalidate` endpoint.
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { invalidateLive } from "alabjs/server";
|
|
70
|
+
* await invalidateLive({ tags: ["stock:AAPL", "stock:GOOG"] });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export async function invalidateLive(opts) {
|
|
74
|
+
for (const tag of opts.tags) {
|
|
75
|
+
broadcastTag(tag);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=broadcaster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcaster.js","sourceRoot":"","sources":["../../src/live/broadcaster.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,uDAAuD;AACvD,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;AACpC,kFAAkF;AAClF,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAE5B,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,QAAoB;IAC9D,MAAM,KAAK,GAAG,gBAAgB,GAAG,GAAG,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC7B,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAwB;IAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,YAAY,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live component registry.
|
|
3
|
+
*
|
|
4
|
+
* At server startup, `createApp` scans `dist/server/**\/*.live.js`, imports
|
|
5
|
+
* each module, reads the `liveInterval` and `liveTags` exports, and calls
|
|
6
|
+
* `registerLiveComponent()`. The SSE endpoint then looks up entries here.
|
|
7
|
+
*/
|
|
8
|
+
export interface LiveComponentEntry {
|
|
9
|
+
/** Stable FNV-1a hash of the original source module path (16 hex chars). */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Absolute path to the compiled `.live.js` file in dist/server. */
|
|
12
|
+
modulePath: string;
|
|
13
|
+
/**
|
|
14
|
+
* Re-render interval in milliseconds.
|
|
15
|
+
* Set via `export const liveInterval = 5000` in the live component file.
|
|
16
|
+
* When undefined, the component only updates on tag invalidation.
|
|
17
|
+
*/
|
|
18
|
+
liveInterval?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Function that returns cache tags for a given props object.
|
|
21
|
+
* Set via `export const liveTags = (props) => [\`stock:\${props.ticker}\`]`.
|
|
22
|
+
* When undefined, the component is not subscribed to tag broadcasts.
|
|
23
|
+
*/
|
|
24
|
+
liveTags?: (props: unknown) => string[];
|
|
25
|
+
}
|
|
26
|
+
export declare function registerLiveComponent(entry: LiveComponentEntry): void;
|
|
27
|
+
export declare function getLiveComponent(id: string): LiveComponentEntry | undefined;
|
|
28
|
+
/** Return all entries whose `liveTags(props)` includes the given tag. */
|
|
29
|
+
export declare function getLiveComponentsByTag(tag: string): Array<{
|
|
30
|
+
entry: LiveComponentEntry;
|
|
31
|
+
props: unknown;
|
|
32
|
+
}>;
|
|
33
|
+
export declare function registrySize(): number;
|
|
34
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/live/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,EAAE,CAAC;CACzC;AAID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAErE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE3E;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAaxG;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live component registry.
|
|
3
|
+
*
|
|
4
|
+
* At server startup, `createApp` scans `dist/server/**\/*.live.js`, imports
|
|
5
|
+
* each module, reads the `liveInterval` and `liveTags` exports, and calls
|
|
6
|
+
* `registerLiveComponent()`. The SSE endpoint then looks up entries here.
|
|
7
|
+
*/
|
|
8
|
+
const _registry = new Map();
|
|
9
|
+
export function registerLiveComponent(entry) {
|
|
10
|
+
_registry.set(entry.id, entry);
|
|
11
|
+
}
|
|
12
|
+
export function getLiveComponent(id) {
|
|
13
|
+
return _registry.get(id);
|
|
14
|
+
}
|
|
15
|
+
/** Return all entries whose `liveTags(props)` includes the given tag. */
|
|
16
|
+
export function getLiveComponentsByTag(tag) {
|
|
17
|
+
// This is called by the broadcaster when a tag is invalidated.
|
|
18
|
+
// Each SSE connection registers itself with the tag broadcaster directly,
|
|
19
|
+
// so this function is used only for discovery — not for fan-out.
|
|
20
|
+
const results = [];
|
|
21
|
+
for (const entry of _registry.values()) {
|
|
22
|
+
if (entry.liveTags) {
|
|
23
|
+
// We don't know props here — tag matching is handled per-connection
|
|
24
|
+
// in the SSE handler via subscribeToTag.
|
|
25
|
+
results.push({ entry, props: undefined });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return results;
|
|
29
|
+
}
|
|
30
|
+
export function registrySize() {
|
|
31
|
+
return _registry.size;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/live/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,MAAM,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;AAExD,MAAM,UAAU,qBAAqB,CAAC,KAAyB;IAC7D,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,OAAO,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,+DAA+D;IAC/D,0EAA0E;IAC1E,iEAAiE;IACjE,MAAM,OAAO,GAAyD,EAAE,CAAC;IACzE,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,oEAAoE;YACpE,yCAAyC;YACzC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,SAAS,CAAC,IAAI,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side HTML fragment renderer for live components.
|
|
3
|
+
*
|
|
4
|
+
* Uses `renderToStaticMarkup` (not `renderToPipeableStream`) because:
|
|
5
|
+
* - The SSE update path does a raw DOM swap — no React hydration needed.
|
|
6
|
+
* - Synchronous output fits the push model.
|
|
7
|
+
* - No `data-reactroot` attributes in the fragment (smaller payload).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Render a live component to an HTML fragment string.
|
|
11
|
+
*
|
|
12
|
+
* @param modulePath - Absolute path to the compiled `.live.js` module.
|
|
13
|
+
* @param props - Props to pass to the component (from the SSE query string).
|
|
14
|
+
* @returns - Raw HTML string (no wrapping element).
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderLiveFragment(modulePath: string, props: unknown): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* FNV-1a 64-bit content hash of an HTML string.
|
|
19
|
+
* Used to suppress no-op SSE pushes when the rendered output hasn't changed.
|
|
20
|
+
*/
|
|
21
|
+
export declare function hashFragment(html: string): string;
|
|
22
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/live/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASjD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side HTML fragment renderer for live components.
|
|
3
|
+
*
|
|
4
|
+
* Uses `renderToStaticMarkup` (not `renderToPipeableStream`) because:
|
|
5
|
+
* - The SSE update path does a raw DOM swap — no React hydration needed.
|
|
6
|
+
* - Synchronous output fits the push model.
|
|
7
|
+
* - No `data-reactroot` attributes in the fragment (smaller payload).
|
|
8
|
+
*/
|
|
9
|
+
import { createElement } from "react";
|
|
10
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
11
|
+
/**
|
|
12
|
+
* Render a live component to an HTML fragment string.
|
|
13
|
+
*
|
|
14
|
+
* @param modulePath - Absolute path to the compiled `.live.js` module.
|
|
15
|
+
* @param props - Props to pass to the component (from the SSE query string).
|
|
16
|
+
* @returns - Raw HTML string (no wrapping element).
|
|
17
|
+
*/
|
|
18
|
+
export async function renderLiveFragment(modulePath, props) {
|
|
19
|
+
// Dynamic import — Node's module cache means repeated calls for the same
|
|
20
|
+
// module path are effectively free after the first load.
|
|
21
|
+
const mod = await import(modulePath);
|
|
22
|
+
const Component = mod.default;
|
|
23
|
+
if (typeof Component !== "function") {
|
|
24
|
+
throw new Error(`[alabjs] live component at ${modulePath} has no default export`);
|
|
25
|
+
}
|
|
26
|
+
// renderToStaticMarkup handles async components (React 19+).
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
const html = renderToStaticMarkup(createElement(Component, props));
|
|
29
|
+
return html;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* FNV-1a 64-bit content hash of an HTML string.
|
|
33
|
+
* Used to suppress no-op SSE pushes when the rendered output hasn't changed.
|
|
34
|
+
*/
|
|
35
|
+
export function hashFragment(html) {
|
|
36
|
+
const FNV_OFFSET = 14695981039346656037n;
|
|
37
|
+
const FNV_PRIME = 1099511628211n;
|
|
38
|
+
let hash = FNV_OFFSET;
|
|
39
|
+
for (let i = 0; i < html.length; i++) {
|
|
40
|
+
hash ^= BigInt(html.charCodeAt(i));
|
|
41
|
+
hash = BigInt.asUintN(64, hash * FNV_PRIME);
|
|
42
|
+
}
|
|
43
|
+
return hash.toString(16).padStart(16, "0");
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/live/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB,EAClB,KAAc;IAEd,yEAAyE;IACzE,yDAAyD;IACzD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAA0B,CAAC;IAC9D,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC;IAE9B,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACb,8BAA8B,UAAU,wBAAwB,CACjE,CAAC;IACJ,CAAC;IAED,6DAA6D;IAC7D,8DAA8D;IAC9D,MAAM,IAAI,GAAG,oBAAoB,CAAC,aAAa,CAAC,SAAgB,EAAE,KAAY,CAAC,CAAC,CAAC;IACjF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,UAAU,GAAG,qBAA2B,CAAC;IAC/C,MAAM,SAAS,GAAG,cAAkB,CAAC;IACrC,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/router/manifest.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/router/manifest.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5F,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB"}
|
package/dist/server/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAqI3D,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAiyB3E"}
|