@stacksjs/stx 0.2.152 → 0.2.153
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/app-shell.js +28 -1
- package/dist/browser-composables.d.ts +8 -0
- package/dist/build-id.d.ts +49 -0
- package/dist/build-id.js +20 -0
- package/dist/cli.js +886 -648
- package/dist/client-script.js +2 -2
- package/dist/color-mode-boot.d.ts +15 -10
- package/dist/color-mode-boot.js +12 -8
- package/dist/component-client-factories.js +3 -2
- package/dist/composables/index.d.ts +6 -1
- package/dist/composables/use-color-mode.d.ts +19 -4
- package/dist/composables/use-color-mode.js +37 -24
- package/dist/composables/use-storage.d.ts +14 -15
- package/dist/composables/use-storage.js +63 -2
- package/dist/craft.js +622 -384
- package/dist/dev-server/serve-app.js +9 -5
- package/dist/dev-server/types.d.ts +8 -1
- package/dist/document-shell.d.ts +55 -0
- package/dist/document-shell.js +103 -3
- package/dist/head.js +5 -1
- package/dist/includes.js +2 -2
- package/dist/index.d.ts +17 -0
- package/dist/index.js +9 -0
- package/dist/process.js +7 -3
- package/dist/production-builder.js +3 -1
- package/dist/pwa.js +581 -343
- package/dist/signals.js +280 -44
- package/dist/ssg.js +571 -333
- package/dist/stx.d.ts +14 -6
- package/dist/types/config-types.d.ts +1 -0
- package/package.json +5 -5
- package/stx.d.ts +14 -6
package/dist/app-shell.js
CHANGED
|
@@ -114,9 +114,36 @@ ${routerScript}
|
|
|
114
114
|
</body>
|
|
115
115
|
</html>`;
|
|
116
116
|
}
|
|
117
|
+
function startsDocument(html) {
|
|
118
|
+
let i = 0;
|
|
119
|
+
while (i < html.length) {
|
|
120
|
+
const rest = html.slice(i), ws = rest.match(/^\s+/);
|
|
121
|
+
if (ws) {
|
|
122
|
+
i += ws[0].length;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (rest.startsWith("<!--")) {
|
|
126
|
+
const end = html.indexOf("-->", i);
|
|
127
|
+
if (end === -1)
|
|
128
|
+
return !1;
|
|
129
|
+
i = end + 3;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const scriptOpen = rest.match(/^<script\b[^>]*>/i);
|
|
133
|
+
if (scriptOpen) {
|
|
134
|
+
const end = html.toLowerCase().indexOf("</script>", i + scriptOpen[0].length);
|
|
135
|
+
if (end === -1)
|
|
136
|
+
return !1;
|
|
137
|
+
i = end + 9;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
return /^<!DOCTYPE\b/i.test(rest) || /^<html[\s>]/i.test(rest);
|
|
141
|
+
}
|
|
142
|
+
return !1;
|
|
143
|
+
}
|
|
117
144
|
export function stripDocumentWrapper(html, options = {}) {
|
|
118
145
|
const trimmed = html.trim();
|
|
119
|
-
if (
|
|
146
|
+
if (!startsDocument(trimmed))
|
|
120
147
|
return html;
|
|
121
148
|
const headStyles = [], headMatch = trimmed.match(/<head\b[^>]*>([\s\S]*?)<\/head>/i);
|
|
122
149
|
if (headMatch) {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reactive localStorage with automatic serialization.
|
|
3
3
|
*
|
|
4
|
+
* @deprecated Returns `{ value, remove }` — a third shape for this name, and
|
|
5
|
+
* one the signals runtime cannot see. Use `useLocalStorage` from
|
|
6
|
+
* `@stacksjs/stx`, which returns a Signal (`s()` reads, `s.set(v)` writes) on
|
|
7
|
+
* every import path (stacksjs/stx#1797).
|
|
8
|
+
*
|
|
4
9
|
* @example
|
|
5
10
|
* ```typescript
|
|
6
11
|
* const theme = useLocalStorage('theme', 'dark')
|
|
@@ -12,6 +17,9 @@ export declare function useLocalStorage<T>(key: string, defaultValue: T): { valu
|
|
|
12
17
|
/**
|
|
13
18
|
* Reactive sessionStorage with automatic serialization.
|
|
14
19
|
*
|
|
20
|
+
* @deprecated See {@link useLocalStorage} above — use the Signal-returning
|
|
21
|
+
* version from `@stacksjs/stx` (stacksjs/stx#1797).
|
|
22
|
+
*
|
|
15
23
|
* @example
|
|
16
24
|
* ```typescript
|
|
17
25
|
* const token = useSessionStorage('auth_token', null)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The current process's build id.
|
|
3
|
+
*
|
|
4
|
+
* Stable for the lifetime of the process, which is the unit that matters: a
|
|
5
|
+
* `bun --watch` restart produces a new process and therefore a new id, while a
|
|
6
|
+
* production build stamps every page it renders with one value.
|
|
7
|
+
*
|
|
8
|
+
* `STX_BUILD_ID` overrides it, for deployments that render across several
|
|
9
|
+
* processes and need them to agree.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getBuildId(): string;
|
|
12
|
+
/** @internal test-only — force the id, or with `null` restore generation. */
|
|
13
|
+
export declare function __setBuildIdForTest(id: string | null): void;
|
|
14
|
+
/**
|
|
15
|
+
* Add `<meta name="stx-build">` to `<head>` if it isn't already there.
|
|
16
|
+
*
|
|
17
|
+
* Idempotent, and a no-op for output with no `<head>` — SPA fragments carry the
|
|
18
|
+
* id in a response header instead, since they have nowhere to put a meta.
|
|
19
|
+
*/
|
|
20
|
+
export declare function injectBuildId(html: string, buildId?: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Per-process build identity, used to detect runtime/fragment skew
|
|
23
|
+
* (stacksjs/stx#1772).
|
|
24
|
+
*
|
|
25
|
+
* Under `bun --watch`, a loaded page holds the client runtime from build N. A
|
|
26
|
+
* file save restarts the server, and the next SPA navigation fetches a fragment
|
|
27
|
+
* rendered by build N+1. Fragments legitimately carry preserved `{{ }}`
|
|
28
|
+
* moustaches for client-side binding, so any drift in the scoped-script or
|
|
29
|
+
* binding format between the two builds leaves the OLD runtime unable to
|
|
30
|
+
* hydrate the NEW fragment: literal moustaches on screen, dead `:show`, stale
|
|
31
|
+
* canvas. It is sporadic and never reproduces from a clean boot, which is
|
|
32
|
+
* exactly its signature.
|
|
33
|
+
*
|
|
34
|
+
* Stamping the identity on both sides lets the router notice the mismatch and
|
|
35
|
+
* fall back to a full page navigation — the same thing Next and Vite's HMR
|
|
36
|
+
* clients do on a version mismatch. It does not fix format drift; it makes the
|
|
37
|
+
* whole class of skew symptoms impossible to observe.
|
|
38
|
+
*
|
|
39
|
+
* The comparison is deliberately conservative: the router only acts when BOTH
|
|
40
|
+
* sides are known. A missing id means "no information", never "mismatch".
|
|
41
|
+
* That keeps statically hosted output (no headers to send) and any consumer on
|
|
42
|
+
* an older server working exactly as before.
|
|
43
|
+
*
|
|
44
|
+
* @module build-id
|
|
45
|
+
*/
|
|
46
|
+
/** `<meta name="stx-build">` on every rendered page. */
|
|
47
|
+
export declare const BUILD_ID_META: 'stx-build';
|
|
48
|
+
/** Response header carrying the id that rendered an SPA fragment. */
|
|
49
|
+
export declare const BUILD_ID_HEADER: 'X-STX-Build';
|
package/dist/build-id.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const BUILD_ID_META = "stx-build", BUILD_ID_HEADER = "X-STX-Build";
|
|
2
|
+
let cached = null;
|
|
3
|
+
export function getBuildId() {
|
|
4
|
+
if (cached === null)
|
|
5
|
+
cached = process.env.STX_BUILD_ID || `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
6
|
+
return cached;
|
|
7
|
+
}
|
|
8
|
+
export function __setBuildIdForTest(id) {
|
|
9
|
+
cached = id;
|
|
10
|
+
}
|
|
11
|
+
export function injectBuildId(html, buildId = getBuildId()) {
|
|
12
|
+
if (html.includes(`name="${BUILD_ID_META}"`))
|
|
13
|
+
return html;
|
|
14
|
+
const headOpen = /<head\b[^>]*>/i.exec(html);
|
|
15
|
+
if (!headOpen)
|
|
16
|
+
return html;
|
|
17
|
+
const insertAt = headOpen.index + headOpen[0].length;
|
|
18
|
+
return `${html.slice(0, insertAt)}
|
|
19
|
+
<meta name="${BUILD_ID_META}" content="${buildId}">${html.slice(insertAt)}`;
|
|
20
|
+
}
|