alabjs 0.1.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/adapters/cloudflare.d.ts +31 -0
- package/dist/adapters/cloudflare.d.ts.map +1 -0
- package/dist/adapters/cloudflare.js +30 -0
- package/dist/adapters/cloudflare.js.map +1 -0
- package/dist/adapters/deno.d.ts +22 -0
- package/dist/adapters/deno.d.ts.map +1 -0
- package/dist/adapters/deno.js +21 -0
- package/dist/adapters/deno.js.map +1 -0
- package/dist/adapters/web.d.ts +47 -0
- package/dist/adapters/web.d.ts.map +1 -0
- package/dist/adapters/web.js +212 -0
- package/dist/adapters/web.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +61 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/hooks.d.ts +119 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +220 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/hooks.test.d.ts +2 -0
- package/dist/client/hooks.test.d.ts.map +1 -0
- package/dist/client/hooks.test.js +45 -0
- package/dist/client/hooks.test.js.map +1 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/offline.d.ts +52 -0
- package/dist/client/offline.d.ts.map +1 -0
- package/dist/client/offline.js +90 -0
- package/dist/client/offline.js.map +1 -0
- package/dist/client/provider.d.ts +12 -0
- package/dist/client/provider.d.ts.map +1 -0
- package/dist/client/provider.js +10 -0
- package/dist/client/provider.js.map +1 -0
- package/dist/commands/build.d.ts +18 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +173 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/dev.d.ts +8 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +447 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/info.d.ts +6 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +92 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/ssg.d.ts +8 -0
- package/dist/commands/ssg.d.ts.map +1 -0
- package/dist/commands/ssg.js +124 -0
- package/dist/commands/ssg.js.map +1 -0
- package/dist/commands/start.d.ts +7 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +26 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/test.d.ts +24 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +87 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +38 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +46 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/Font.d.ts +57 -0
- package/dist/components/Font.d.ts.map +1 -0
- package/dist/components/Font.js +33 -0
- package/dist/components/Font.js.map +1 -0
- package/dist/components/Image.d.ts +74 -0
- package/dist/components/Image.d.ts.map +1 -0
- package/dist/components/Image.js +85 -0
- package/dist/components/Image.js.map +1 -0
- package/dist/components/Link.d.ts +23 -0
- package/dist/components/Link.d.ts.map +1 -0
- package/dist/components/Link.js +48 -0
- package/dist/components/Link.js.map +1 -0
- package/dist/components/Script.d.ts +37 -0
- package/dist/components/Script.d.ts.map +1 -0
- package/dist/components/Script.js +70 -0
- package/dist/components/Script.js.map +1 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +6 -0
- package/dist/components/index.js.map +1 -0
- package/dist/i18n/i18n.test.d.ts +2 -0
- package/dist/i18n/i18n.test.d.ts.map +1 -0
- package/dist/i18n/i18n.test.js +132 -0
- package/dist/i18n/i18n.test.js.map +1 -0
- package/dist/i18n/index.d.ts +135 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +189 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/router/code-router.d.ts +204 -0
- package/dist/router/code-router.d.ts.map +1 -0
- package/dist/router/code-router.js +258 -0
- package/dist/router/code-router.js.map +1 -0
- package/dist/router/code-router.test.d.ts +2 -0
- package/dist/router/code-router.test.d.ts.map +1 -0
- package/dist/router/code-router.test.js +128 -0
- package/dist/router/code-router.test.js.map +1 -0
- package/dist/router/index.d.ts +4 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +2 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/manifest.d.ts +12 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +2 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/server/app.d.ts +13 -0
- package/dist/server/app.d.ts.map +1 -0
- package/dist/server/app.js +407 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/cache.d.ts +99 -0
- package/dist/server/cache.d.ts.map +1 -0
- package/dist/server/cache.js +161 -0
- package/dist/server/cache.js.map +1 -0
- package/dist/server/cache.test.d.ts +2 -0
- package/dist/server/cache.test.d.ts.map +1 -0
- package/dist/server/cache.test.js +150 -0
- package/dist/server/cache.test.js.map +1 -0
- package/dist/server/csrf.d.ts +28 -0
- package/dist/server/csrf.d.ts.map +1 -0
- package/dist/server/csrf.js +66 -0
- package/dist/server/csrf.js.map +1 -0
- package/dist/server/csrf.test.d.ts +2 -0
- package/dist/server/csrf.test.d.ts.map +1 -0
- package/dist/server/csrf.test.js +154 -0
- package/dist/server/csrf.test.js.map +1 -0
- package/dist/server/image.d.ts +18 -0
- package/dist/server/image.d.ts.map +1 -0
- package/dist/server/image.js +97 -0
- package/dist/server/image.js.map +1 -0
- package/dist/server/index.d.ts +57 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +58 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/middleware.d.ts +53 -0
- package/dist/server/middleware.d.ts.map +1 -0
- package/dist/server/middleware.js +80 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/middleware.test.d.ts +2 -0
- package/dist/server/middleware.test.d.ts.map +1 -0
- package/dist/server/middleware.test.js +125 -0
- package/dist/server/middleware.test.js.map +1 -0
- package/dist/server/revalidate.d.ts +49 -0
- package/dist/server/revalidate.d.ts.map +1 -0
- package/dist/server/revalidate.js +62 -0
- package/dist/server/revalidate.js.map +1 -0
- package/dist/server/revalidate.test.d.ts +2 -0
- package/dist/server/revalidate.test.d.ts.map +1 -0
- package/dist/server/revalidate.test.js +93 -0
- package/dist/server/revalidate.test.js.map +1 -0
- package/dist/server/server-fn.test.d.ts +2 -0
- package/dist/server/server-fn.test.d.ts.map +1 -0
- package/dist/server/server-fn.test.js +105 -0
- package/dist/server/server-fn.test.js.map +1 -0
- package/dist/server/sitemap.d.ts +9 -0
- package/dist/server/sitemap.d.ts.map +1 -0
- package/dist/server/sitemap.js +26 -0
- package/dist/server/sitemap.js.map +1 -0
- package/dist/server/sitemap.test.d.ts +2 -0
- package/dist/server/sitemap.test.d.ts.map +1 -0
- package/dist/server/sitemap.test.js +61 -0
- package/dist/server/sitemap.test.js.map +1 -0
- package/dist/server/sse.d.ts +59 -0
- package/dist/server/sse.d.ts.map +1 -0
- package/dist/server/sse.js +91 -0
- package/dist/server/sse.js.map +1 -0
- package/dist/server/sse.test.d.ts +2 -0
- package/dist/server/sse.test.d.ts.map +1 -0
- package/dist/server/sse.test.js +68 -0
- package/dist/server/sse.test.js.map +1 -0
- package/dist/signals/index.d.ts +101 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/index.js +149 -0
- package/dist/signals/index.js.map +1 -0
- package/dist/signals/signals.test.d.ts +2 -0
- package/dist/signals/signals.test.d.ts.map +1 -0
- package/dist/signals/signals.test.js +146 -0
- package/dist/signals/signals.test.js.map +1 -0
- package/dist/ssr/html.d.ts +27 -0
- package/dist/ssr/html.d.ts.map +1 -0
- package/dist/ssr/html.js +107 -0
- package/dist/ssr/html.js.map +1 -0
- package/dist/ssr/html.test.d.ts +2 -0
- package/dist/ssr/html.test.d.ts.map +1 -0
- package/dist/ssr/html.test.js +178 -0
- package/dist/ssr/html.test.js.map +1 -0
- package/dist/ssr/render.d.ts +46 -0
- package/dist/ssr/render.d.ts.map +1 -0
- package/dist/ssr/render.js +87 -0
- package/dist/ssr/render.js.map +1 -0
- package/dist/ssr/router-dev.d.ts +60 -0
- package/dist/ssr/router-dev.d.ts.map +1 -0
- package/dist/ssr/router-dev.js +205 -0
- package/dist/ssr/router-dev.js.map +1 -0
- package/dist/ssr/router-dev.test.d.ts +2 -0
- package/dist/ssr/router-dev.test.d.ts.map +1 -0
- package/dist/ssr/router-dev.test.js +189 -0
- package/dist/ssr/router-dev.test.js.map +1 -0
- package/dist/test/index.d.ts +93 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +146 -0
- package/dist/test/index.js.map +1 -0
- package/dist/types/index.d.ts +117 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/napi.d.ts +15 -0
- package/dist/types/napi.d.ts.map +1 -0
- package/dist/types/napi.js +2 -0
- package/dist/types/napi.js.map +1 -0
- package/package.json +107 -0
- package/src/adapters/cloudflare.ts +30 -0
- package/src/adapters/deno.ts +21 -0
- package/src/adapters/web.ts +259 -0
- package/src/cli.ts +68 -0
- package/src/client/hooks.test.ts +54 -0
- package/src/client/hooks.ts +329 -0
- package/src/client/index.ts +5 -0
- package/src/client/offline-sw.ts +191 -0
- package/src/client/offline.ts +114 -0
- package/src/client/provider.tsx +14 -0
- package/src/commands/build.ts +201 -0
- package/src/commands/dev.ts +509 -0
- package/src/commands/info.ts +111 -0
- package/src/commands/ssg.ts +177 -0
- package/src/commands/start.ts +32 -0
- package/src/commands/test.ts +102 -0
- package/src/components/ErrorBoundary.tsx +73 -0
- package/src/components/Font.tsx +100 -0
- package/src/components/Image.tsx +141 -0
- package/src/components/Link.tsx +64 -0
- package/src/components/Script.tsx +97 -0
- package/src/components/index.ts +9 -0
- package/src/i18n/i18n.test.tsx +169 -0
- package/src/i18n/index.tsx +256 -0
- package/src/index.ts +10 -0
- package/src/router/code-router.test.ts +146 -0
- package/src/router/code-router.tsx +459 -0
- package/src/router/index.ts +18 -0
- package/src/router/manifest.ts +13 -0
- package/src/server/app.ts +466 -0
- package/src/server/cache.test.ts +192 -0
- package/src/server/cache.ts +195 -0
- package/src/server/csrf.test.ts +199 -0
- package/src/server/csrf.ts +80 -0
- package/src/server/image.ts +112 -0
- package/src/server/index.ts +144 -0
- package/src/server/middleware.test.ts +151 -0
- package/src/server/middleware.ts +95 -0
- package/src/server/revalidate.test.ts +106 -0
- package/src/server/revalidate.ts +75 -0
- package/src/server/server-fn.test.ts +127 -0
- package/src/server/sitemap.test.ts +68 -0
- package/src/server/sitemap.ts +30 -0
- package/src/server/sse.test.ts +81 -0
- package/src/server/sse.ts +110 -0
- package/src/signals/index.ts +177 -0
- package/src/signals/signals.test.ts +164 -0
- package/src/ssr/html.test.ts +200 -0
- package/src/ssr/html.ts +140 -0
- package/src/ssr/render.ts +144 -0
- package/src/ssr/router-dev.test.ts +230 -0
- package/src/ssr/router-dev.ts +229 -0
- package/src/test/index.ts +206 -0
- package/src/types/compiler.d.ts +25 -0
- package/src/types/index.ts +147 -0
- package/src/types/napi.ts +20 -0
- package/src/types/plugins.d.ts +3 -0
- package/tsconfig.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +32 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alab Signals — granular reactivity within a React tree.
|
|
3
|
+
*
|
|
4
|
+
* Signals are observable values that trigger precise re-renders only in the
|
|
5
|
+
* components that read them — no context provider needed, no full-tree
|
|
6
|
+
* reconciliation. Inspired by SolidJS signals, built on React 18's
|
|
7
|
+
* `useSyncExternalStore` for correctness in concurrent mode.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // signals.ts — define once, use anywhere
|
|
12
|
+
* import { signal } from "alabjs/signals";
|
|
13
|
+
*
|
|
14
|
+
* export const count = signal(0);
|
|
15
|
+
* export const user = signal<User | null>(null);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* ```tsx
|
|
19
|
+
* // Counter.tsx — only this component re-renders when count changes
|
|
20
|
+
* import { useSignal } from "alabjs/signals";
|
|
21
|
+
* import { count } from "../signals.js";
|
|
22
|
+
*
|
|
23
|
+
* export function Counter() {
|
|
24
|
+
* const [value, setCount] = useSignal(count);
|
|
25
|
+
* return <button onClick={() => setCount(v => v + 1)}>{value}</button>;
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export interface Signal<T> {
|
|
30
|
+
/** Read the current value (non-reactive — use `useSignalValue` inside components). */
|
|
31
|
+
get(): T;
|
|
32
|
+
/** Write a new value and notify all subscribers. */
|
|
33
|
+
set(value: T | ((prev: T) => T)): void;
|
|
34
|
+
/** @internal Subscribe to changes — consumed by `useSyncExternalStore`. */
|
|
35
|
+
subscribe(listener: () => void): () => void;
|
|
36
|
+
/** @internal Snapshot getter for SSR — returns current value synchronously. */
|
|
37
|
+
getSnapshot(): T;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create a new signal with an initial value.
|
|
41
|
+
*
|
|
42
|
+
* Signals are plain objects — they don't require a React tree to exist.
|
|
43
|
+
* Define them at module scope and import them wherever needed.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* export const darkMode = signal(false);
|
|
48
|
+
* export const cart = signal<CartItem[]>([]);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function signal<T>(initial: T): Signal<T>;
|
|
52
|
+
/**
|
|
53
|
+
* Subscribe to a signal's value — re-renders only when the signal changes.
|
|
54
|
+
* Returns `[value, setter]`, matching the `useState` API.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```tsx
|
|
58
|
+
* const [isDark, setDark] = useSignal(darkMode);
|
|
59
|
+
* <button onClick={() => setDark(v => !v)}>{isDark ? "☀️" : "🌙"}</button>
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function useSignal<T>(sig: Signal<T>): [T, (value: T | ((prev: T) => T)) => void];
|
|
63
|
+
/**
|
|
64
|
+
* Subscribe to a signal's value (read-only).
|
|
65
|
+
* Slightly cheaper than `useSignal` when you only need to read.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* const count = useSignalValue(counter);
|
|
70
|
+
* return <span>{count}</span>;
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function useSignalValue<T>(sig: Signal<T>): T;
|
|
74
|
+
/**
|
|
75
|
+
* Returns a stable setter for a signal without subscribing to its value.
|
|
76
|
+
* Use this in components that only write but never display the signal's value —
|
|
77
|
+
* they won't re-render when the signal changes.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```tsx
|
|
81
|
+
* const setCount = useSignalSetter(counter);
|
|
82
|
+
* return <button onClick={() => setCount(v => v + 1)}>Increment</button>;
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function useSignalSetter<T>(sig: Signal<T>): (value: T | ((prev: T) => T)) => void;
|
|
86
|
+
/**
|
|
87
|
+
* Derive a computed value from one or more signals.
|
|
88
|
+
* The derived signal updates automatically when any source signal changes.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const firstName = signal("Ada");
|
|
93
|
+
* const lastName = signal("Lovelace");
|
|
94
|
+
* const fullName = computed([firstName, lastName], ([f, l]) => `${f} ${l}`);
|
|
95
|
+
* // fullName.get() === "Ada Lovelace"
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function computed<Sources extends Signal<any>[], T>(sources: [...Sources], derive: (values: {
|
|
99
|
+
[K in keyof Sources]: Sources[K] extends Signal<infer V> ? V : never;
|
|
100
|
+
}) => T): Omit<Signal<T>, "set">;
|
|
101
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,sFAAsF;IACtF,GAAG,IAAI,CAAC,CAAC;IACT,oDAAoD;IACpD,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IACvC,2EAA2E;IAC3E,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,+EAA+E;IAC/E,WAAW,IAAI,CAAC,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CA0B/C;AAID;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAKvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAExF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,OAAO,SAAS,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EACvD,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EACrB,MAAM,EAAE,CAAC,MAAM,EAAE;KAAG,CAAC,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,KAAK,CAAC,GAC9F,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CA6BxB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alab Signals — granular reactivity within a React tree.
|
|
3
|
+
*
|
|
4
|
+
* Signals are observable values that trigger precise re-renders only in the
|
|
5
|
+
* components that read them — no context provider needed, no full-tree
|
|
6
|
+
* reconciliation. Inspired by SolidJS signals, built on React 18's
|
|
7
|
+
* `useSyncExternalStore` for correctness in concurrent mode.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // signals.ts — define once, use anywhere
|
|
12
|
+
* import { signal } from "alabjs/signals";
|
|
13
|
+
*
|
|
14
|
+
* export const count = signal(0);
|
|
15
|
+
* export const user = signal<User | null>(null);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* ```tsx
|
|
19
|
+
* // Counter.tsx — only this component re-renders when count changes
|
|
20
|
+
* import { useSignal } from "alabjs/signals";
|
|
21
|
+
* import { count } from "../signals.js";
|
|
22
|
+
*
|
|
23
|
+
* export function Counter() {
|
|
24
|
+
* const [value, setCount] = useSignal(count);
|
|
25
|
+
* return <button onClick={() => setCount(v => v + 1)}>{value}</button>;
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { useSyncExternalStore, useCallback } from "react";
|
|
30
|
+
/**
|
|
31
|
+
* Create a new signal with an initial value.
|
|
32
|
+
*
|
|
33
|
+
* Signals are plain objects — they don't require a React tree to exist.
|
|
34
|
+
* Define them at module scope and import them wherever needed.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* export const darkMode = signal(false);
|
|
39
|
+
* export const cart = signal<CartItem[]>([]);
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function signal(initial) {
|
|
43
|
+
let _value = initial;
|
|
44
|
+
const _listeners = new Set();
|
|
45
|
+
const notify = () => _listeners.forEach((l) => l());
|
|
46
|
+
return {
|
|
47
|
+
get() {
|
|
48
|
+
return _value;
|
|
49
|
+
},
|
|
50
|
+
set(next) {
|
|
51
|
+
const resolved = typeof next === "function"
|
|
52
|
+
? next(_value)
|
|
53
|
+
: next;
|
|
54
|
+
if (Object.is(resolved, _value))
|
|
55
|
+
return; // bail if unchanged
|
|
56
|
+
_value = resolved;
|
|
57
|
+
notify();
|
|
58
|
+
},
|
|
59
|
+
subscribe(listener) {
|
|
60
|
+
_listeners.add(listener);
|
|
61
|
+
return () => _listeners.delete(listener);
|
|
62
|
+
},
|
|
63
|
+
getSnapshot() {
|
|
64
|
+
return _value;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// ─── React hooks ──────────────────────────────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* Subscribe to a signal's value — re-renders only when the signal changes.
|
|
71
|
+
* Returns `[value, setter]`, matching the `useState` API.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* const [isDark, setDark] = useSignal(darkMode);
|
|
76
|
+
* <button onClick={() => setDark(v => !v)}>{isDark ? "☀️" : "🌙"}</button>
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function useSignal(sig) {
|
|
80
|
+
const value = useSyncExternalStore(sig.subscribe, sig.getSnapshot, sig.getSnapshot);
|
|
81
|
+
// Stable setter — signal.set is already referentially stable
|
|
82
|
+
const set = useCallback((next) => sig.set(next), [sig]);
|
|
83
|
+
return [value, set];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Subscribe to a signal's value (read-only).
|
|
87
|
+
* Slightly cheaper than `useSignal` when you only need to read.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```tsx
|
|
91
|
+
* const count = useSignalValue(counter);
|
|
92
|
+
* return <span>{count}</span>;
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export function useSignalValue(sig) {
|
|
96
|
+
return useSyncExternalStore(sig.subscribe, sig.getSnapshot, sig.getSnapshot);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Returns a stable setter for a signal without subscribing to its value.
|
|
100
|
+
* Use this in components that only write but never display the signal's value —
|
|
101
|
+
* they won't re-render when the signal changes.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* const setCount = useSignalSetter(counter);
|
|
106
|
+
* return <button onClick={() => setCount(v => v + 1)}>Increment</button>;
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export function useSignalSetter(sig) {
|
|
110
|
+
return useCallback((next) => sig.set(next), [sig]);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Derive a computed value from one or more signals.
|
|
114
|
+
* The derived signal updates automatically when any source signal changes.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* const firstName = signal("Ada");
|
|
119
|
+
* const lastName = signal("Lovelace");
|
|
120
|
+
* const fullName = computed([firstName, lastName], ([f, l]) => `${f} ${l}`);
|
|
121
|
+
* // fullName.get() === "Ada Lovelace"
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export function computed(sources, derive) {
|
|
125
|
+
// Read initial value
|
|
126
|
+
const readValues = () => sources.map((s) => s.get());
|
|
127
|
+
let _cached = derive(readValues());
|
|
128
|
+
const _listeners = new Set();
|
|
129
|
+
const recompute = () => {
|
|
130
|
+
const next = derive(readValues());
|
|
131
|
+
if (!Object.is(next, _cached)) {
|
|
132
|
+
_cached = next;
|
|
133
|
+
_listeners.forEach((l) => l());
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
// Subscribe to all source signals
|
|
137
|
+
for (const src of sources) {
|
|
138
|
+
src.subscribe(recompute);
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
get() { return _cached; },
|
|
142
|
+
getSnapshot() { return _cached; },
|
|
143
|
+
subscribe(listener) {
|
|
144
|
+
_listeners.add(listener);
|
|
145
|
+
return () => _listeners.delete(listener);
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.test.d.ts","sourceRoot":"","sources":["../../src/signals/signals.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { signal, computed } from "./index.js";
|
|
3
|
+
// Note: useSignal, useSignalValue, useSignalSetter are React hooks that require
|
|
4
|
+
// a React component context. We test the non-hook primitives here (signal, computed)
|
|
5
|
+
// which contain the core reactivity logic (~70% of the module's surface area).
|
|
6
|
+
describe("signal", () => {
|
|
7
|
+
it("initialises with the given value", () => {
|
|
8
|
+
const s = signal(42);
|
|
9
|
+
expect(s.get()).toBe(42);
|
|
10
|
+
});
|
|
11
|
+
it("updates value via set()", () => {
|
|
12
|
+
const s = signal(0);
|
|
13
|
+
s.set(10);
|
|
14
|
+
expect(s.get()).toBe(10);
|
|
15
|
+
});
|
|
16
|
+
it("supports functional updates", () => {
|
|
17
|
+
const s = signal(5);
|
|
18
|
+
s.set((prev) => prev + 3);
|
|
19
|
+
expect(s.get()).toBe(8);
|
|
20
|
+
});
|
|
21
|
+
it("getSnapshot returns the current value", () => {
|
|
22
|
+
const s = signal("hello");
|
|
23
|
+
expect(s.getSnapshot()).toBe("hello");
|
|
24
|
+
s.set("world");
|
|
25
|
+
expect(s.getSnapshot()).toBe("world");
|
|
26
|
+
});
|
|
27
|
+
it("notifies subscribers on change", () => {
|
|
28
|
+
const s = signal(0);
|
|
29
|
+
let notified = false;
|
|
30
|
+
s.subscribe(() => {
|
|
31
|
+
notified = true;
|
|
32
|
+
});
|
|
33
|
+
s.set(1);
|
|
34
|
+
expect(notified).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it("does NOT notify when value is unchanged (Object.is)", () => {
|
|
37
|
+
const s = signal(42);
|
|
38
|
+
let callCount = 0;
|
|
39
|
+
s.subscribe(() => {
|
|
40
|
+
callCount++;
|
|
41
|
+
});
|
|
42
|
+
s.set(42); // same value
|
|
43
|
+
expect(callCount).toBe(0);
|
|
44
|
+
});
|
|
45
|
+
it("does NOT notify when functional update returns same value", () => {
|
|
46
|
+
const s = signal(42);
|
|
47
|
+
let callCount = 0;
|
|
48
|
+
s.subscribe(() => {
|
|
49
|
+
callCount++;
|
|
50
|
+
});
|
|
51
|
+
s.set((v) => v); // identity — same value
|
|
52
|
+
expect(callCount).toBe(0);
|
|
53
|
+
});
|
|
54
|
+
it("unsubscribe stops notifications", () => {
|
|
55
|
+
const s = signal(0);
|
|
56
|
+
let callCount = 0;
|
|
57
|
+
const unsub = s.subscribe(() => {
|
|
58
|
+
callCount++;
|
|
59
|
+
});
|
|
60
|
+
s.set(1);
|
|
61
|
+
expect(callCount).toBe(1);
|
|
62
|
+
unsub();
|
|
63
|
+
s.set(2);
|
|
64
|
+
expect(callCount).toBe(1); // still 1, not notified
|
|
65
|
+
});
|
|
66
|
+
it("supports multiple subscribers", () => {
|
|
67
|
+
const s = signal(0);
|
|
68
|
+
let a = 0;
|
|
69
|
+
let b = 0;
|
|
70
|
+
s.subscribe(() => { a++; });
|
|
71
|
+
s.subscribe(() => { b++; });
|
|
72
|
+
s.set(1);
|
|
73
|
+
expect(a).toBe(1);
|
|
74
|
+
expect(b).toBe(1);
|
|
75
|
+
});
|
|
76
|
+
it("handles null and undefined values", () => {
|
|
77
|
+
const s = signal(null);
|
|
78
|
+
expect(s.get()).toBe(null);
|
|
79
|
+
s.set("hello");
|
|
80
|
+
expect(s.get()).toBe("hello");
|
|
81
|
+
s.set(null);
|
|
82
|
+
expect(s.get()).toBe(null);
|
|
83
|
+
});
|
|
84
|
+
it("handles object values", () => {
|
|
85
|
+
const s = signal({ name: "Ada" });
|
|
86
|
+
expect(s.get()).toEqual({ name: "Ada" });
|
|
87
|
+
const newObj = { name: "Bob" };
|
|
88
|
+
s.set(newObj);
|
|
89
|
+
expect(s.get()).toBe(newObj);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe("computed", () => {
|
|
93
|
+
it("derives value from source signals", () => {
|
|
94
|
+
const a = signal(2);
|
|
95
|
+
const b = signal(3);
|
|
96
|
+
const sum = computed([a, b], ([x, y]) => x + y);
|
|
97
|
+
expect(sum.get()).toBe(5);
|
|
98
|
+
});
|
|
99
|
+
it("recomputes when a source changes", () => {
|
|
100
|
+
const a = signal(2);
|
|
101
|
+
const b = signal(3);
|
|
102
|
+
const sum = computed([a, b], ([x, y]) => x + y);
|
|
103
|
+
a.set(10);
|
|
104
|
+
expect(sum.get()).toBe(13);
|
|
105
|
+
});
|
|
106
|
+
it("notifies subscribers when derived value changes", () => {
|
|
107
|
+
const count = signal(0);
|
|
108
|
+
const doubled = computed([count], ([c]) => c * 2);
|
|
109
|
+
let notified = false;
|
|
110
|
+
doubled.subscribe(() => {
|
|
111
|
+
notified = true;
|
|
112
|
+
});
|
|
113
|
+
count.set(5);
|
|
114
|
+
expect(notified).toBe(true);
|
|
115
|
+
expect(doubled.get()).toBe(10);
|
|
116
|
+
});
|
|
117
|
+
it("does NOT notify when derived value is unchanged", () => {
|
|
118
|
+
const a = signal(3);
|
|
119
|
+
const isPositive = computed([a], ([v]) => v > 0);
|
|
120
|
+
expect(isPositive.get()).toBe(true);
|
|
121
|
+
let callCount = 0;
|
|
122
|
+
isPositive.subscribe(() => {
|
|
123
|
+
callCount++;
|
|
124
|
+
});
|
|
125
|
+
a.set(5); // still positive → derived value stays `true`
|
|
126
|
+
expect(callCount).toBe(0);
|
|
127
|
+
});
|
|
128
|
+
it("getSnapshot returns current derived value", () => {
|
|
129
|
+
const s = signal("hello");
|
|
130
|
+
const upper = computed([s], ([v]) => v.toUpperCase());
|
|
131
|
+
expect(upper.getSnapshot()).toBe("HELLO");
|
|
132
|
+
});
|
|
133
|
+
it("supports single source signal", () => {
|
|
134
|
+
const name = signal("Ada");
|
|
135
|
+
const greeting = computed([name], ([n]) => `Hello, ${n}!`);
|
|
136
|
+
expect(greeting.get()).toBe("Hello, Ada!");
|
|
137
|
+
name.set("Bob");
|
|
138
|
+
expect(greeting.get()).toBe("Hello, Bob!");
|
|
139
|
+
});
|
|
140
|
+
it("does not expose set method", () => {
|
|
141
|
+
const s = signal(1);
|
|
142
|
+
const c = computed([s], ([v]) => v);
|
|
143
|
+
expect("set" in c).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=signals.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals.test.js","sourceRoot":"","sources":["../../src/signals/signals.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PageMetadata } from "../types/index.js";
|
|
2
|
+
export interface HtmlShellOptions {
|
|
3
|
+
metadata: PageMetadata;
|
|
4
|
+
/** Serialised params JSON string to embed in the page for client hydration. */
|
|
5
|
+
paramsJson: string;
|
|
6
|
+
/** Serialised search-params JSON string. */
|
|
7
|
+
searchParamsJson: string;
|
|
8
|
+
/** Relative path to the page module (e.g. `app/users/[id]/page.tsx`). */
|
|
9
|
+
routeFile: string;
|
|
10
|
+
/** Whether SSR is enabled for this route. */
|
|
11
|
+
ssr: boolean;
|
|
12
|
+
/** JSON array of layout file paths (relative to cwd), outermost first. */
|
|
13
|
+
layoutsJson?: string | undefined;
|
|
14
|
+
/** Relative path to the nearest loading.tsx (for client-side Suspense fallback). */
|
|
15
|
+
loadingFile?: string | undefined;
|
|
16
|
+
/** Extra content injected into <head> (used by Vite to insert HMR scripts). */
|
|
17
|
+
headExtra?: string | undefined;
|
|
18
|
+
/** Nonce for CSP inline scripts (optional). */
|
|
19
|
+
nonce?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
/** Build the opening HTML fragment — everything up to and including `<div id="alabjs-root">`. */
|
|
22
|
+
export declare function htmlShellBefore(opts: HtmlShellOptions): string;
|
|
23
|
+
/** Build the closing HTML fragment — everything after the SSR content. */
|
|
24
|
+
export declare function htmlShellAfter(opts: {
|
|
25
|
+
nonce?: string | undefined;
|
|
26
|
+
}): string;
|
|
27
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/ssr/html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,YAAY,CAAC;IACvB,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,gBAAgB,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,GAAG,EAAE,OAAO,CAAC;IACb,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,iGAAiG;AACjG,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA4D9D;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,MAAM,CAM3E"}
|
package/dist/ssr/html.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/** Build the opening HTML fragment — everything up to and including `<div id="alabjs-root">`. */
|
|
2
|
+
export function htmlShellBefore(opts) {
|
|
3
|
+
const { metadata, paramsJson, searchParamsJson, routeFile, ssr, layoutsJson, loadingFile, headExtra = "", } = opts;
|
|
4
|
+
const titleTag = metadata.title
|
|
5
|
+
? `<title>${escHtml(metadata.title)}</title>`
|
|
6
|
+
: "";
|
|
7
|
+
const descTag = metadata.description
|
|
8
|
+
? `<meta name="description" content="${escAttr(metadata.description)}" />`
|
|
9
|
+
: "";
|
|
10
|
+
const canonicalTag = metadata.canonical
|
|
11
|
+
? `<link rel="canonical" href="${escAttr(metadata.canonical)}" />`
|
|
12
|
+
: "";
|
|
13
|
+
const robotsTag = metadata.robots
|
|
14
|
+
? `<meta name="robots" content="${escAttr(metadata.robots)}" />`
|
|
15
|
+
: "";
|
|
16
|
+
const themeColorTag = metadata.themeColor
|
|
17
|
+
? `<meta name="theme-color" content="${escAttr(metadata.themeColor)}" />`
|
|
18
|
+
: "";
|
|
19
|
+
const ogTags = metadata.og ? buildOgTags(metadata.og) : "";
|
|
20
|
+
const twitterTags = metadata.twitter ? buildTwitterTags(metadata.twitter) : "";
|
|
21
|
+
const extraTags = metadata.extra ? buildExtraTags(metadata.extra) : "";
|
|
22
|
+
return `<!doctype html>
|
|
23
|
+
<html lang="en">
|
|
24
|
+
<head>
|
|
25
|
+
<meta charset="UTF-8" />
|
|
26
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
27
|
+
${titleTag}
|
|
28
|
+
${descTag}
|
|
29
|
+
${canonicalTag}
|
|
30
|
+
${robotsTag}
|
|
31
|
+
${themeColorTag}
|
|
32
|
+
${ogTags}
|
|
33
|
+
${twitterTags}
|
|
34
|
+
${extraTags}
|
|
35
|
+
<meta name="alabjs-route" content="${escAttr(routeFile)}" />
|
|
36
|
+
<meta name="alabjs-ssr" content="${ssr ? "true" : "false"}" />
|
|
37
|
+
<meta name="alabjs-params" content="${escAttr(paramsJson)}" />
|
|
38
|
+
<meta name="alabjs-search-params" content="${escAttr(searchParamsJson)}" />
|
|
39
|
+
${layoutsJson ? `<meta name="alabjs-layouts" content="${escAttr(layoutsJson)}" />` : ""}
|
|
40
|
+
${loadingFile ? `<meta name="alabjs-loading" content="${escAttr(loadingFile)}" />` : ""}
|
|
41
|
+
<link rel="stylesheet" href="/app/globals.css" />
|
|
42
|
+
${headExtra}
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
<div id="alabjs-root">`;
|
|
46
|
+
}
|
|
47
|
+
/** Build the closing HTML fragment — everything after the SSR content. */
|
|
48
|
+
export function htmlShellAfter(opts) {
|
|
49
|
+
const nonceAttr = opts.nonce ? ` nonce="${escAttr(opts.nonce)}"` : "";
|
|
50
|
+
return `</div>
|
|
51
|
+
<script type="module" src="/@alabjs/client"${nonceAttr}></script>
|
|
52
|
+
</body>
|
|
53
|
+
</html>`;
|
|
54
|
+
}
|
|
55
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
56
|
+
function escHtml(s) {
|
|
57
|
+
return s
|
|
58
|
+
.replace(/&/g, "&")
|
|
59
|
+
.replace(/</g, "<")
|
|
60
|
+
.replace(/>/g, ">");
|
|
61
|
+
}
|
|
62
|
+
function escAttr(s) {
|
|
63
|
+
return s
|
|
64
|
+
.replace(/&/g, "&")
|
|
65
|
+
.replace(/"/g, """);
|
|
66
|
+
}
|
|
67
|
+
function buildOgTags(og) {
|
|
68
|
+
const tags = [];
|
|
69
|
+
if (og.title)
|
|
70
|
+
tags.push(`<meta property="og:title" content="${escAttr(og.title)}" />`);
|
|
71
|
+
if (og.description)
|
|
72
|
+
tags.push(`<meta property="og:description" content="${escAttr(og.description)}" />`);
|
|
73
|
+
if (og.image)
|
|
74
|
+
tags.push(`<meta property="og:image" content="${escAttr(og.image)}" />`);
|
|
75
|
+
if (og.url)
|
|
76
|
+
tags.push(`<meta property="og:url" content="${escAttr(og.url)}" />`);
|
|
77
|
+
if (og.type)
|
|
78
|
+
tags.push(`<meta property="og:type" content="${escAttr(og.type)}" />`);
|
|
79
|
+
if (og.siteName)
|
|
80
|
+
tags.push(`<meta property="og:site_name" content="${escAttr(og.siteName)}" />`);
|
|
81
|
+
return tags.join("\n ");
|
|
82
|
+
}
|
|
83
|
+
function buildTwitterTags(tw) {
|
|
84
|
+
const tags = [];
|
|
85
|
+
if (tw.card)
|
|
86
|
+
tags.push(`<meta name="twitter:card" content="${escAttr(tw.card)}" />`);
|
|
87
|
+
if (tw.title)
|
|
88
|
+
tags.push(`<meta name="twitter:title" content="${escAttr(tw.title)}" />`);
|
|
89
|
+
if (tw.description)
|
|
90
|
+
tags.push(`<meta name="twitter:description" content="${escAttr(tw.description)}" />`);
|
|
91
|
+
if (tw.image)
|
|
92
|
+
tags.push(`<meta name="twitter:image" content="${escAttr(tw.image)}" />`);
|
|
93
|
+
if (tw.creator)
|
|
94
|
+
tags.push(`<meta name="twitter:creator" content="${escAttr(tw.creator)}" />`);
|
|
95
|
+
return tags.join("\n ");
|
|
96
|
+
}
|
|
97
|
+
function buildExtraTags(extra) {
|
|
98
|
+
return extra
|
|
99
|
+
.map((attrs) => {
|
|
100
|
+
const attrStr = Object.entries(attrs)
|
|
101
|
+
.map(([k, v]) => `${k}="${escAttr(v)}"`)
|
|
102
|
+
.join(" ");
|
|
103
|
+
return `<meta ${attrStr} />`;
|
|
104
|
+
})
|
|
105
|
+
.join("\n ");
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/ssr/html.ts"],"names":[],"mappings":"AAsBA,iGAAiG;AACjG,MAAM,UAAU,eAAe,CAAC,IAAsB;IACpD,MAAM,EACJ,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,GAAG,EACH,WAAW,EACX,WAAW,EACX,SAAS,GAAG,EAAE,GACf,GAAG,IAAI,CAAC;IAET,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK;QAC7B,CAAC,CAAC,UAAU,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU;QAC7C,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW;QAClC,CAAC,CAAC,qCAAqC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM;QAC1E,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS;QACrC,CAAC,CAAC,+BAA+B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM;QAClE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM;QAC/B,CAAC,CAAC,gCAAgC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM;QAChE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,aAAa,GAAG,QAAQ,CAAC,UAAU;QACvC,CAAC,CAAC,qCAAqC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM;QACzE,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvE,OAAO;;;;;MAKH,QAAQ;MACR,OAAO;MACP,YAAY;MACZ,SAAS;MACT,aAAa;MACb,MAAM;MACN,WAAW;MACX,SAAS;yCAC0B,OAAO,CAAC,SAAS,CAAC;uCACpB,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;0CACnB,OAAO,CAAC,UAAU,CAAC;iDACZ,OAAO,CAAC,gBAAgB,CAAC;MACpE,WAAW,CAAC,CAAC,CAAC,wCAAwC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;MACrF,WAAW,CAAC,CAAC,CAAC,wCAAwC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;;MAErF,SAAS;;;2BAGY,CAAC;AAC5B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,IAAoC;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO;iDACwC,SAAS;;QAElD,CAAC;AACT,CAAC;AAED,iFAAiF;AAEjF,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,WAAW,CAAC,EAAmC;IACtD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,EAAE,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,sCAAsC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvF,IAAI,EAAE,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,4CAA4C,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACzG,IAAI,EAAE,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,sCAAsC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvF,IAAI,EAAE,CAAC,GAAG;QAAE,IAAI,CAAC,IAAI,CAAC,oCAAoC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjF,IAAI,EAAE,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,qCAAqC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpF,IAAI,EAAE,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,0CAA0C,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjG,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAwC;IAChE,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,EAAE,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,sCAAsC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrF,IAAI,EAAE,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,uCAAuC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxF,IAAI,EAAE,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,6CAA6C,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1G,IAAI,EAAE,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,uCAAuC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxF,IAAI,EAAE,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,yCAAyC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9F,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,cAAc,CAAC,KAAyC;IAC/D,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;aACvC,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,OAAO,SAAS,OAAO,KAAK,CAAC;IAC/B,CAAC,CAAC;SACD,IAAI,CAAC,QAAQ,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.test.d.ts","sourceRoot":"","sources":["../../src/ssr/html.test.ts"],"names":[],"mappings":""}
|