@stacksjs/stx 0.2.321 → 0.2.322
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/builtins/image-delivery.d.ts +33 -1
- package/dist/builtins/image-delivery.js +51 -3
- package/dist/builtins/image-placeholder.d.ts +9 -0
- package/dist/builtins/image-placeholder.js +14 -1
- package/dist/builtins/image-warmup-worker.d.ts +1 -0
- package/dist/builtins/image-warmup-worker.js +18 -0
- package/dist/builtins/image-worker.d.ts +40 -0
- package/dist/builtins/image-worker.js +82 -0
- package/dist/chunk-0050wktp.js +2 -0
- package/dist/{chunk-qz462c22.js → chunk-02hjbe0p.js} +1 -1
- package/dist/{chunk-g38wktfx.js → chunk-0aqtbma7.js} +1 -1
- package/dist/{chunk-fs5gwtd9.js → chunk-0fkvezw3.js} +1 -1
- package/dist/{chunk-1yv1v7hh.js → chunk-0xw3atfx.js} +1 -1
- package/dist/chunk-1yxtx5y2.js +2 -0
- package/dist/{chunk-8q3a8g7m.js → chunk-24r2ctta.js} +1 -1
- package/dist/{chunk-7kk2jb1j.js → chunk-2astj1fq.js} +173 -173
- package/dist/{chunk-2925bmqr.js → chunk-2dk3ym1g.js} +1 -1
- package/dist/{chunk-zeqktcby.js → chunk-2hyxkzpc.js} +1 -1
- package/dist/chunk-2k9qqkx2.js +2 -0
- package/dist/chunk-2qk3qwmp.js +2 -0
- package/dist/{chunk-526rr83q.js → chunk-308r399e.js} +1 -1
- package/dist/{chunk-wr011j4b.js → chunk-3vydymb5.js} +1 -1
- package/dist/{chunk-rpnjwpw3.js → chunk-3yn8ghtz.js} +1 -1
- package/dist/{chunk-4kp87md5.js → chunk-54mnf7n2.js} +1 -1
- package/dist/chunk-59fcj7ym.js +2 -0
- package/dist/{chunk-w913decg.js → chunk-5az2jb8y.js} +2 -2
- package/dist/chunk-5n2ps25k.js +2 -0
- package/dist/{chunk-4zz9edh0.js → chunk-5zqec01h.js} +1 -1
- package/dist/chunk-62s55rv0.js +2 -0
- package/dist/{chunk-n3qsg135.js → chunk-69knrrh9.js} +1 -1
- package/dist/{chunk-x2j5b308.js → chunk-7bmqjfft.js} +1 -1
- package/dist/chunk-7dd808wv.js +2 -0
- package/dist/{chunk-mjbrbnv2.js → chunk-7jqh58k9.js} +1 -1
- package/dist/{chunk-3ntb5zkk.js → chunk-88kr475r.js} +1 -1
- package/dist/{chunk-xaeamzng.js → chunk-8cwenbw3.js} +1 -1
- package/dist/{chunk-sr042pkc.js → chunk-8n0mjaf6.js} +1 -1
- package/dist/{chunk-9qxv7emz.js → chunk-8r0yf1q7.js} +1 -1
- package/dist/{chunk-nn17da2e.js → chunk-90ma145g.js} +1 -1
- package/dist/{chunk-2btrq8sz.js → chunk-9e6pyjwz.js} +1 -1
- package/dist/{chunk-3x0b8j25.js → chunk-9q9z1027.js} +1 -1
- package/dist/{chunk-0eydszkp.js → chunk-akrxtrh1.js} +1 -1
- package/dist/chunk-asf7qyyc.js +2 -0
- package/dist/{chunk-gnk0xd8n.js → chunk-avpsqyaq.js} +1 -1
- package/dist/{chunk-q5hwa8dn.js → chunk-b0wm1c6x.js} +1 -1
- package/dist/{chunk-ymfh9wan.js → chunk-b1h7pyhs.js} +1 -1
- package/dist/{chunk-tk459ykz.js → chunk-bdr8dz57.js} +2 -2
- package/dist/chunk-bgwcrkg8.js +2 -0
- package/dist/{chunk-gyrf55m1.js → chunk-brb3g571.js} +1 -1
- package/dist/chunk-bw0488z7.js +2 -0
- package/dist/chunk-c3pg3yx4.js +2 -0
- package/dist/chunk-cevmy9cn.js +2 -0
- package/dist/chunk-df5wrw50.js +3 -0
- package/dist/{chunk-5mdvkpt8.js → chunk-dgrayagx.js} +1 -1
- package/dist/{chunk-mnhwgk4x.js → chunk-dsqcfv2k.js} +1 -1
- package/dist/chunk-dvszm8ay.js +2 -0
- package/dist/{chunk-krvreaxb.js → chunk-e0369ngw.js} +1 -1
- package/dist/{chunk-sb2g9f73.js → chunk-e10pfrds.js} +1 -1
- package/dist/{chunk-xnj5h0bq.js → chunk-e9dtt2cw.js} +2 -2
- package/dist/{chunk-1r3ydhkx.js → chunk-ecbqmesm.js} +1 -1
- package/dist/chunk-eqsqs6yj.js +2 -0
- package/dist/{chunk-9fjhmyje.js → chunk-exrnsgtc.js} +1 -1
- package/dist/{chunk-rwq2qzpx.js → chunk-ez93xc1z.js} +1 -1
- package/dist/{chunk-wtdkz7wz.js → chunk-f75yj981.js} +1 -1
- package/dist/chunk-fps56kyx.js +2 -0
- package/dist/{chunk-twdvqqft.js → chunk-g2pjef44.js} +1 -1
- package/dist/{chunk-373fc0m2.js → chunk-gctdc94b.js} +1 -1
- package/dist/chunk-gg74g03k.js +2 -0
- package/dist/chunk-gyprd56b.js +2 -0
- package/dist/{chunk-vmjktkm9.js → chunk-hrs2pepp.js} +1 -1
- package/dist/{chunk-hmrv7qv5.js → chunk-k0ht65ts.js} +1 -1
- package/dist/{chunk-jgfkmkpb.js → chunk-k3w1ctbb.js} +1 -1
- package/dist/{chunk-qqvwfhd5.js → chunk-kb040j0d.js} +1 -1
- package/dist/{chunk-hrd56xw7.js → chunk-kwrj745h.js} +2 -2
- package/dist/{chunk-1q1qmmfn.js → chunk-m4wwqznv.js} +1 -1
- package/dist/{chunk-cjf5h08r.js → chunk-mczfzq2y.js} +1 -1
- package/dist/{chunk-hrrynmne.js → chunk-mp8nekfh.js} +1 -1
- package/dist/chunk-mr33j493.js +2 -0
- package/dist/{chunk-3qt3cxh0.js → chunk-mz9twa1f.js} +1 -1
- package/dist/{chunk-j8bwgnz5.js → chunk-namj6apv.js} +2 -2
- package/dist/{chunk-1b2wksq3.js → chunk-nh2ze1a7.js} +1 -1
- package/dist/chunk-nkpww053.js +2 -0
- package/dist/{chunk-esq6ydx5.js → chunk-nksce8wc.js} +1 -1
- package/dist/{chunk-mmhdgz5x.js → chunk-nq0ec0w1.js} +1 -1
- package/dist/{chunk-mgd0vre2.js → chunk-nq19m0ja.js} +1 -1
- package/dist/{chunk-3erkb524.js → chunk-nytw8ek5.js} +1 -1
- package/dist/{chunk-tv2qdq7h.js → chunk-pc70paa2.js} +1 -1
- package/dist/chunk-pgafdv9x.js +2 -0
- package/dist/{chunk-8mspafdh.js → chunk-pty8ywaj.js} +1 -1
- package/dist/chunk-pwwhcdh3.js +2 -0
- package/dist/{chunk-6r72pp2t.js → chunk-qhzvf0nf.js} +1 -1
- package/dist/{chunk-cey6rhqw.js → chunk-qrkxyb5p.js} +1 -1
- package/dist/{chunk-8q9qfy2v.js → chunk-qsxtjtvv.js} +2 -2
- package/dist/{chunk-33gkb5pr.js → chunk-r05ekvht.js} +1 -1
- package/dist/{chunk-jtaxnnq3.js → chunk-r1g0bnpv.js} +1 -1
- package/dist/chunk-r8scz4g7.js +2 -0
- package/dist/{chunk-sqkz8tf3.js → chunk-rcvnh2p7.js} +1 -1
- package/dist/chunk-rw93qdw8.js +2 -0
- package/dist/{chunk-kncbae57.js → chunk-sn1edmp8.js} +1 -1
- package/dist/{chunk-9whbqxsv.js → chunk-tpvs4bzw.js} +1 -1
- package/dist/{chunk-tbw7qn8b.js → chunk-v1jcfb07.js} +1 -1
- package/dist/{chunk-dr2rpkb4.js → chunk-v3taty7e.js} +1 -1
- package/dist/{chunk-7b09hmk4.js → chunk-vtn57jw8.js} +10 -10
- package/dist/{chunk-akefvpqr.js → chunk-vy2nvpbw.js} +2 -2
- package/dist/{chunk-yhebk7kd.js → chunk-wf3pcr37.js} +1 -1
- package/dist/{chunk-0en7mkpa.js → chunk-ws4kh6et.js} +1 -1
- package/dist/{chunk-a6q5dmq7.js → chunk-x5xee26w.js} +1 -1
- package/dist/{chunk-rypa8b99.js → chunk-xgrh0461.js} +1 -1
- package/dist/{chunk-x7eb8e98.js → chunk-xsrb2heb.js} +1 -1
- package/dist/{chunk-222swfwr.js → chunk-y1zwvdn5.js} +1 -1
- package/dist/chunk-y3egkbc2.js +2 -0
- package/dist/{chunk-cfj7y2tp.js → chunk-yc7fptr2.js} +2 -2
- package/dist/chunk-ycjjd5js.js +2 -0
- package/dist/{chunk-pavfpmwj.js → chunk-yms0xgy0.js} +1 -1
- package/dist/{chunk-hgc3n1xq.js → chunk-yyq7rpw2.js} +1 -1
- package/dist/chunk-zcea9z8j.js +2 -0
- package/dist/{chunk-ycmsckjw.js → chunk-zgbwr604.js} +1 -1
- package/dist/{chunk-eh66m9ar.js → chunk-zwkzwymf.js} +1 -1
- package/dist/cli.js +14 -14
- package/dist/craft-entry.js +1 -1
- package/dist/craft.js +1 -1
- package/dist/database.js +1 -1
- package/dist/pwa.js +2 -2
- package/dist/ssg.js +2 -2
- package/dist/visual-testing.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-129fa2d9.js +0 -2
- package/dist/chunk-1rdcew9t.js +0 -2
- package/dist/chunk-25m79xdw.js +0 -2
- package/dist/chunk-2rkq7pd1.js +0 -2
- package/dist/chunk-2tcn2rw4.js +0 -2
- package/dist/chunk-48w09pf7.js +0 -2
- package/dist/chunk-4a2wcz8h.js +0 -2
- package/dist/chunk-4dtjqc90.js +0 -2
- package/dist/chunk-5sz2tmw3.js +0 -2
- package/dist/chunk-7je3fd68.js +0 -2
- package/dist/chunk-7v72zj7x.js +0 -2
- package/dist/chunk-8x78ed8t.js +0 -2
- package/dist/chunk-99yynes4.js +0 -2
- package/dist/chunk-9zrmwtgh.js +0 -2
- package/dist/chunk-bdwe7er9.js +0 -2
- package/dist/chunk-c5zfgpgx.js +0 -2
- package/dist/chunk-ced1qbdw.js +0 -2
- package/dist/chunk-cpa76anv.js +0 -2
- package/dist/chunk-fh33afkv.js +0 -2
- package/dist/chunk-g5v7gw13.js +0 -2
- package/dist/chunk-hg77c5m2.js +0 -2
- package/dist/chunk-hhjrtjc9.js +0 -3
- package/dist/chunk-jxx9apw6.js +0 -2
- package/dist/chunk-m1n5a725.js +0 -2
- package/dist/chunk-pn1syk7x.js +0 -2
- package/dist/chunk-ssdzdsm1.js +0 -2
- package/dist/chunk-wn9z19wm.js +0 -2
- package/dist/chunk-xc5swjjg.js +0 -2
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { ImageDeliveryManifest } from 'ts-images/delivery';
|
|
2
2
|
import { webpHeaderHasAlpha } from './image-alpha';
|
|
3
3
|
export { webpHeaderHasAlpha };
|
|
4
|
+
/**
|
|
5
|
+
* Which encoders this process writes variants with, e.g.
|
|
6
|
+
* `ts-webp@0.1.6+ts-avif@0.1.4`. Resolved the way ts-images resolves them,
|
|
7
|
+
* so a vendored or hoisted copy reports the copy that actually runs. An
|
|
8
|
+
* encoder that cannot be identified reads as `unknown`, which is still a
|
|
9
|
+
* namespace no older release wrote into.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Override {@link imageEncoderIdentity}, or with no argument go back to
|
|
13
|
+
* resolving it. For tests that need a variant cache written by another
|
|
14
|
+
* encoder than the one installed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function setImageEncoderIdentity(identity?: string): void;
|
|
17
|
+
export declare function imageEncoderIdentity(): string;
|
|
4
18
|
/** Return build-time delivery metadata for one public image URL. */
|
|
5
19
|
export declare function getImageDelivery(src: string): ImageDeliveryManifest | undefined;
|
|
6
20
|
/**
|
|
@@ -12,6 +26,24 @@ export declare function getImageDelivery(src: string): ImageDeliveryManifest | u
|
|
|
12
26
|
export declare function isTransparentImage(src: string): boolean;
|
|
13
27
|
/** Clear process-global delivery state between builds and tests. */
|
|
14
28
|
export declare function clearImageDeliveryCatalog(): void;
|
|
29
|
+
/** The catalog as plain data, for a worker to post back to the thread that serves. */
|
|
30
|
+
export interface ImageDeliverySnapshot {
|
|
31
|
+
entries: Array<[string, ImageDeliveryManifest]>;
|
|
32
|
+
transparent: string[];
|
|
33
|
+
}
|
|
34
|
+
/** What this thread's catalog holds, in a form `postMessage` can carry. */
|
|
35
|
+
export declare function snapshotImageDelivery(): ImageDeliverySnapshot;
|
|
36
|
+
/** Swap in a catalog built elsewhere, whole, as the in-thread pass does. */
|
|
37
|
+
export declare function installImageDelivery(snapshot: ImageDeliverySnapshot): void;
|
|
38
|
+
export interface PrepareImageDeliveryOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Decode and encode on a worker thread, and install the finished catalog
|
|
41
|
+
* here. For a long-lived server, whose event loop has requests to answer
|
|
42
|
+
* while a cold cache re-encodes every raster. Same files, same names, same
|
|
43
|
+
* catalog; falls back to running in-thread where no worker can start.
|
|
44
|
+
*/
|
|
45
|
+
offThread?: boolean;
|
|
46
|
+
}
|
|
15
47
|
/**
|
|
16
48
|
* Optimize every raster in the public directory before templates render.
|
|
17
49
|
*
|
|
@@ -19,7 +51,7 @@ export declare function clearImageDeliveryCatalog(): void;
|
|
|
19
51
|
* catalog. Its content fingerprint is folded into the SSG cache key to ensure
|
|
20
52
|
* changing image bytes can never reuse HTML pointing at an older asset hash.
|
|
21
53
|
*/
|
|
22
|
-
export declare function prepareImageDelivery(publicDir: string, outputDir: string): Promise<{
|
|
54
|
+
export declare function prepareImageDelivery(publicDir: string, outputDir: string, options?: PrepareImageDeliveryOptions): Promise<{
|
|
23
55
|
count: number;
|
|
24
56
|
fingerprint: string;
|
|
25
57
|
}>;
|
|
@@ -4,9 +4,43 @@ import path from "node:path";
|
|
|
4
4
|
import { decode, generateThumbHash } from "ts-images";
|
|
5
5
|
import { createImageDeliveryCatalog } from "ts-images/delivery";
|
|
6
6
|
import { readAt, sourceAlpha, webpHeaderHasAlpha } from "./image-alpha.js";
|
|
7
|
+
import { runImageTask, WORKER_UNAVAILABLE } from "./image-worker.js";
|
|
7
8
|
|
|
8
9
|
export { webpHeaderHasAlpha };
|
|
9
|
-
const RASTER_EXTENSIONS = new Set([".avif", ".jpeg", ".jpg", ".png", ".webp"]), DEFAULT_WIDTHS = [320, 640, 960, 1280, 1920], DELIVERY_URL = "/_stx/images", ALPHA_NAMESPACE = `stx:${DELIVERY_URL}:alpha-1
|
|
10
|
+
const RASTER_EXTENSIONS = new Set([".avif", ".jpeg", ".jpg", ".png", ".webp"]), DEFAULT_WIDTHS = [320, 640, 960, 1280, 1920], DELIVERY_URL = "/_stx/images", ALPHA_NAMESPACE = `stx:${DELIVERY_URL}:alpha-1`, ENCODER_PACKAGES = ["@stacksjs/ts-webp", "@stacksjs/ts-avif"];
|
|
11
|
+
let encoderIdentity;
|
|
12
|
+
function packageVersion(specifier, fromDir) {
|
|
13
|
+
let dir = path.dirname(Bun.resolveSync(specifier, fromDir));
|
|
14
|
+
while (dir !== path.dirname(dir)) {
|
|
15
|
+
const manifest = path.join(dir, "package.json");
|
|
16
|
+
if (fs.existsSync(manifest)) {
|
|
17
|
+
const pkg = JSON.parse(fs.readFileSync(manifest, "utf8"));
|
|
18
|
+
if (pkg.name === specifier)
|
|
19
|
+
return pkg.version;
|
|
20
|
+
}
|
|
21
|
+
dir = path.dirname(dir);
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
export function setImageEncoderIdentity(identity) {
|
|
26
|
+
encoderIdentity = identity;
|
|
27
|
+
}
|
|
28
|
+
export function imageEncoderIdentity() {
|
|
29
|
+
if (encoderIdentity !== void 0)
|
|
30
|
+
return encoderIdentity;
|
|
31
|
+
let from;
|
|
32
|
+
try {
|
|
33
|
+
from = path.dirname(Bun.resolveSync("ts-images", import.meta.dir));
|
|
34
|
+
} catch {}
|
|
35
|
+
encoderIdentity = ENCODER_PACKAGES.map((specifier) => {
|
|
36
|
+
let version;
|
|
37
|
+
try {
|
|
38
|
+
version = from ? packageVersion(specifier, from) : void 0;
|
|
39
|
+
} catch {}
|
|
40
|
+
return `${specifier.replace("@stacksjs/", "")}@${version ?? "unknown"}`;
|
|
41
|
+
}).join("+");
|
|
42
|
+
return encoderIdentity;
|
|
43
|
+
}
|
|
10
44
|
let deliveryCatalog = new Map, transparentSources = new Set;
|
|
11
45
|
const warnedOpaqueWebp = new Set;
|
|
12
46
|
function publicUrl(relativePath) {
|
|
@@ -182,11 +216,25 @@ export function clearImageDeliveryCatalog() {
|
|
|
182
216
|
deliveryCatalog = new Map;
|
|
183
217
|
transparentSources = new Set;
|
|
184
218
|
}
|
|
185
|
-
export
|
|
219
|
+
export function snapshotImageDelivery() {
|
|
220
|
+
return { entries: [...deliveryCatalog], transparent: [...transparentSources] };
|
|
221
|
+
}
|
|
222
|
+
export function installImageDelivery(snapshot) {
|
|
223
|
+
deliveryCatalog = new Map(snapshot.entries);
|
|
224
|
+
transparentSources = new Set(snapshot.transparent);
|
|
225
|
+
}
|
|
226
|
+
export async function prepareImageDelivery(publicDir, outputDir, options = {}) {
|
|
186
227
|
if (!publicDir || !fs.existsSync(publicDir)) {
|
|
187
228
|
clearImageDeliveryCatalog();
|
|
188
229
|
return { count: 0, fingerprint: "" };
|
|
189
230
|
}
|
|
231
|
+
if (options.offThread) {
|
|
232
|
+
const reply = await runImageTask("delivery", { publicDir, outputDir });
|
|
233
|
+
if (reply !== WORKER_UNAVAILABLE) {
|
|
234
|
+
installImageDelivery(reply.state);
|
|
235
|
+
return reply.result;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
190
238
|
const allFiles = await collectRasterImages(publicDir);
|
|
191
239
|
if (allFiles.length === 0) {
|
|
192
240
|
clearImageDeliveryCatalog();
|
|
@@ -203,7 +251,7 @@ export async function prepareImageDelivery(publicDir, outputDir) {
|
|
|
203
251
|
clearImageDeliveryCatalog();
|
|
204
252
|
return { count: 0, fingerprint: "" };
|
|
205
253
|
}
|
|
206
|
-
const alphaStorage = deliveryStorage(path.join(outputDir, "_stx", "images"), ALPHA_NAMESPACE), catalogOptions = {
|
|
254
|
+
const alphaStorage = deliveryStorage(path.join(outputDir, "_stx", "images"), `${ALPHA_NAMESPACE}:${imageEncoderIdentity()}`), catalogOptions = {
|
|
207
255
|
outDir: path.join(outputDir, "_stx", "images"),
|
|
208
256
|
storage: deliveryStorage(path.join(outputDir, "_stx", "images")),
|
|
209
257
|
baseUrl: DELIVERY_URL,
|
|
@@ -46,6 +46,8 @@ export declare function getImagePlaceholder(src: string): ImagePlaceholder | und
|
|
|
46
46
|
export declare function placeholdersWarmed(): boolean;
|
|
47
47
|
/** Drop everything, for tests and for a watch-mode rebuild. */
|
|
48
48
|
export declare function clearImagePlaceholders(): void;
|
|
49
|
+
/** Every placeholder this thread holds, in a form `postMessage` can carry. */
|
|
50
|
+
export declare function snapshotImagePlaceholders(): Array<[string, ImagePlaceholder]>;
|
|
49
51
|
/**
|
|
50
52
|
* Register a placeholder directly. Used by the warm below, and by tests that
|
|
51
53
|
* would rather not decode a real JPEG to check the markup.
|
|
@@ -69,6 +71,13 @@ export interface WarmOptions {
|
|
|
69
71
|
maxBytes?: number;
|
|
70
72
|
/** Stop after this many images, so an enormous asset tree cannot stall a build. */
|
|
71
73
|
limit?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Decode on a worker thread and merge the results here. For a long-lived
|
|
76
|
+
* server, whose event loop has requests to answer while a cold cache
|
|
77
|
+
* decodes every image. Same placeholders, same cache file; falls back to
|
|
78
|
+
* running in-thread where no worker can start.
|
|
79
|
+
*/
|
|
80
|
+
offThread?: boolean;
|
|
72
81
|
}
|
|
73
82
|
/**
|
|
74
83
|
* Derive placeholders for every image under `publicDir` and hold them for
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { sourceAlpha } from "./image-alpha.js";
|
|
4
|
+
import { runImageTask, WORKER_UNAVAILABLE } from "./image-worker.js";
|
|
4
5
|
const IMAGE_EXTENSIONS = new Set([".jpg", ".jpeg", ".png", ".webp", ".avif"]), placeholders = new Map;
|
|
5
6
|
let warmed = !1;
|
|
6
7
|
export function getImagePlaceholder(src) {
|
|
@@ -16,6 +17,9 @@ export function clearImagePlaceholders() {
|
|
|
16
17
|
placeholders.clear();
|
|
17
18
|
warmed = !1;
|
|
18
19
|
}
|
|
20
|
+
export function snapshotImagePlaceholders() {
|
|
21
|
+
return [...placeholders];
|
|
22
|
+
}
|
|
19
23
|
export function setImagePlaceholder(urlPath, placeholder) {
|
|
20
24
|
placeholders.set(urlPath, placeholder);
|
|
21
25
|
warmed = !0;
|
|
@@ -94,11 +98,20 @@ function collectImages(dir, baseUrl, out = []) {
|
|
|
94
98
|
return out;
|
|
95
99
|
}
|
|
96
100
|
export async function warmImagePlaceholders(publicDir, options = {}) {
|
|
97
|
-
const { cachePath, maxBytes = 33554432, limit = 2000 } = options;
|
|
101
|
+
const { cachePath, maxBytes = 33554432, limit = 2000, offThread } = options;
|
|
98
102
|
if (!publicDir || !fs.existsSync(publicDir)) {
|
|
99
103
|
warmed = !0;
|
|
100
104
|
return placeholders.size;
|
|
101
105
|
}
|
|
106
|
+
if (offThread) {
|
|
107
|
+
const reply = await runImageTask("placeholders", { publicDir, options: { cachePath, maxBytes, limit } });
|
|
108
|
+
if (reply !== WORKER_UNAVAILABLE) {
|
|
109
|
+
for (const [urlPath, placeholder] of reply.placeholders)
|
|
110
|
+
placeholders.set(urlPath, placeholder);
|
|
111
|
+
warmed = !0;
|
|
112
|
+
return placeholders.size;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
102
115
|
let tsImages;
|
|
103
116
|
try {
|
|
104
117
|
tsImages = await import("ts-images");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { prepareImageDelivery, snapshotImageDelivery } from "./image-delivery.js";
|
|
2
|
+
import { snapshotImagePlaceholders, warmImagePlaceholders } from "./image-placeholder.js";
|
|
3
|
+
self.addEventListener("message", async (event) => {
|
|
4
|
+
const { task, args } = event.data;
|
|
5
|
+
try {
|
|
6
|
+
if (task === "delivery") {
|
|
7
|
+
const result = await prepareImageDelivery(args.publicDir, args.outputDir);
|
|
8
|
+
self.postMessage({ type: "result", value: { result, state: snapshotImageDelivery() } });
|
|
9
|
+
} else {
|
|
10
|
+
await warmImagePlaceholders(args.publicDir, args.options);
|
|
11
|
+
self.postMessage({ type: "result", value: { placeholders: snapshotImagePlaceholders() } });
|
|
12
|
+
}
|
|
13
|
+
} catch (error) {
|
|
14
|
+
const err = error instanceof Error ? error : Error(String(error));
|
|
15
|
+
self.postMessage({ type: "error", error: { name: err.name, message: err.message, stack: err.stack } });
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
self.postMessage({ type: "ready" });
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the image pass on a worker thread.
|
|
3
|
+
*
|
|
4
|
+
* Decoding and encoding (AVIF, WebP, thumbhash) is pure TypeScript and fully
|
|
5
|
+
* synchronous per image. On the thread that also answers requests, a cold pass
|
|
6
|
+
* over a photo-heavy `public/` held the event loop for most of its minutes:
|
|
7
|
+
* every `await` a render made queued behind the next encode, so a first page
|
|
8
|
+
* took 14-18s and a proxy in front of the server saw empty responses. On a
|
|
9
|
+
* worker the same code runs to the same results, and the serving thread only
|
|
10
|
+
* receives the finished catalog.
|
|
11
|
+
*
|
|
12
|
+
* The worker is the mechanism, not a requirement. Where one cannot start (no
|
|
13
|
+
* `Worker` in the runtime, or the entry file missing because stx was bundled
|
|
14
|
+
* into something else), {@link runImageTask} reports that and the caller runs
|
|
15
|
+
* the pass in-thread exactly as before.
|
|
16
|
+
*
|
|
17
|
+
* @module builtins/image-worker
|
|
18
|
+
*/
|
|
19
|
+
/** Tasks the worker entry knows how to run. */
|
|
20
|
+
export type ImageTask = 'delivery' | 'placeholders';
|
|
21
|
+
/** Returned instead of a result when no worker could be started. */
|
|
22
|
+
export declare const WORKER_UNAVAILABLE: unique symbol;
|
|
23
|
+
/**
|
|
24
|
+
* How many image workers may run at once.
|
|
25
|
+
*
|
|
26
|
+
* Serving needs a core of its own, so on a two-core box the placeholder and
|
|
27
|
+
* delivery passes take turns in one worker instead of claiming both cores.
|
|
28
|
+
* Two at most: the passes are the only callers, and a third would have
|
|
29
|
+
* nothing to do.
|
|
30
|
+
*/
|
|
31
|
+
export declare function imageWorkerSlots(cores?: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Run `task` with `args` on a worker thread and resolve with what it posts
|
|
34
|
+
* back, or with {@link WORKER_UNAVAILABLE} when no worker could be started.
|
|
35
|
+
*
|
|
36
|
+
* A failure inside the task rejects, as the in-thread call would have thrown.
|
|
37
|
+
* Only a worker that never became ready counts as unavailable, so a crash
|
|
38
|
+
* mid-pass is never silently re-run on the serving thread.
|
|
39
|
+
*/
|
|
40
|
+
export declare function runImageTask<T>(task: ImageTask, args: unknown): Promise<T | typeof WORKER_UNAVAILABLE>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
export const WORKER_UNAVAILABLE = Symbol("stx.image-worker.unavailable");
|
|
5
|
+
export function imageWorkerSlots(cores = typeof os.availableParallelism === "function" ? os.availableParallelism() : os.cpus().length) {
|
|
6
|
+
return Math.max(1, Math.min(2, cores - 1));
|
|
7
|
+
}
|
|
8
|
+
let active = 0;
|
|
9
|
+
const waiting = [];
|
|
10
|
+
async function acquire() {
|
|
11
|
+
if (active < imageWorkerSlots()) {
|
|
12
|
+
active++;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
await new Promise((resolve) => waiting.push(resolve));
|
|
16
|
+
active++;
|
|
17
|
+
}
|
|
18
|
+
function release() {
|
|
19
|
+
active--;
|
|
20
|
+
waiting.shift()?.();
|
|
21
|
+
}
|
|
22
|
+
function workerEntry() {
|
|
23
|
+
const extension = import.meta.url.endsWith(".ts") ? "ts" : "js", url = new URL(`./image-warmup-worker.${extension}`, import.meta.url);
|
|
24
|
+
try {
|
|
25
|
+
return url.protocol === "file:" && fs.existsSync(fileURLToPath(url)) ? url : void 0;
|
|
26
|
+
} catch {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function runImageTask(task, args) {
|
|
31
|
+
if (typeof Worker > "u")
|
|
32
|
+
return WORKER_UNAVAILABLE;
|
|
33
|
+
const entry = workerEntry();
|
|
34
|
+
if (!entry)
|
|
35
|
+
return WORKER_UNAVAILABLE;
|
|
36
|
+
await acquire();
|
|
37
|
+
try {
|
|
38
|
+
return await new Promise((resolve, reject) => {
|
|
39
|
+
let worker;
|
|
40
|
+
try {
|
|
41
|
+
worker = new Worker(entry);
|
|
42
|
+
} catch {
|
|
43
|
+
resolve(WORKER_UNAVAILABLE);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let ready = !1, settled = !1;
|
|
47
|
+
const finish = (settle) => {
|
|
48
|
+
if (settled)
|
|
49
|
+
return;
|
|
50
|
+
settled = !0;
|
|
51
|
+
settle();
|
|
52
|
+
worker.terminate();
|
|
53
|
+
};
|
|
54
|
+
worker.addEventListener("message", (event) => {
|
|
55
|
+
const reply = event.data;
|
|
56
|
+
if (reply.type === "ready") {
|
|
57
|
+
ready = !0;
|
|
58
|
+
worker.postMessage({ task, args });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (reply.type === "result") {
|
|
62
|
+
finish(() => resolve(reply.value));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const error = Error(reply.error?.message ?? "image worker failed");
|
|
66
|
+
if (reply.error?.name)
|
|
67
|
+
error.name = reply.error.name;
|
|
68
|
+
if (reply.error?.stack)
|
|
69
|
+
error.stack = reply.error.stack;
|
|
70
|
+
finish(() => reject(error));
|
|
71
|
+
});
|
|
72
|
+
worker.addEventListener("error", (event) => {
|
|
73
|
+
finish(() => ready ? reject(event.error instanceof Error ? event.error : Error(event.message || "image worker crashed")) : resolve(WORKER_UNAVAILABLE));
|
|
74
|
+
});
|
|
75
|
+
worker.addEventListener("close", () => {
|
|
76
|
+
finish(() => ready ? reject(Error("image worker exited before it finished")) : resolve(WORKER_UNAVAILABLE));
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
} finally {
|
|
80
|
+
release();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{tk as a,uk as b,vk as c,wk as d}from"./chunk-k3w1ctbb.js";import"./chunk-vy2nvpbw.js";import"./chunk-2astj1fq.js";import"./chunk-9e6pyjwz.js";import"./chunk-z698hwht.js";import"./chunk-70zb3560.js";import"./chunk-zsapb653.js";import"./chunk-kwrj745h.js";import"./chunk-df5wrw50.js";import"./chunk-e10pfrds.js";import"./chunk-ecbqmesm.js";import"./chunk-namj6apv.js";import"./chunk-dgrayagx.js";import"./chunk-2hyxkzpc.js";import"./chunk-r1g0bnpv.js";import"./chunk-2dk3ym1g.js";import"./chunk-8n0mjaf6.js";import"./chunk-5az2jb8y.js";import"./chunk-rcvnh2p7.js";import"./chunk-qrkxyb5p.js";export{b as getAvailableTargets,c as getAvailableFormats,d as default,a as buildNative};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Nf as T}from"./chunk-
|
|
2
|
+
import{Nf as T}from"./chunk-zgbwr604.js";import{pw as I}from"./chunk-qrkxyb5p.js";import E from"fs";import X from"path";import U from"crypto";var _=new Set(["webp","avif","jpeg","png"]),F=new Set(["cover","contain","fill","inside","outside"]),A=new Set([".jpg",".jpeg",".png",".webp",".avif",".gif"]),S=4096,y=80,D="cover";async function g(k,G){let J=G.routePath??"/_stx/img",B=new URL(k.url);if(B.pathname!==J)return null;let $=q(B,G);if(!$.ok)return new Response($.error,{status:$.status,headers:{"Content-Type":"text/plain"}});let{srcFsPath:j,srcUrl:K,width:H,height:v,format:Z,quality:Y,fit:z}=$,C;try{C=E.statSync(j)}catch{return new Response(`Source image not found: ${K}`,{status:404,headers:{"Content-Type":"text/plain"}})}if(!C.isFile())return new Response("Not a file",{status:404,headers:{"Content-Type":"text/plain"}});let N=G.cacheDir??".stx/cache/img";await E.promises.mkdir(N,{recursive:!0});let V=`${j}:${C.mtimeMs}:${C.size}`,O=`${H}x${v}:${Z}:${Y}:${z}`,b=U.createHash("sha256").update(`${V}|${O}`).digest("hex").slice(0,16),Q=X.join(N,`${b}.${Z}`),W={"Content-Type":T(Z),"Cache-Control":"public, max-age=31536000, immutable",ETag:`"${b}"`,"X-Stx-Image-Cache":"HIT"};if(k.headers.get("if-none-match")===`"${b}"`)return new Response(null,{status:304,headers:W});let L=Bun.file(Q);if(await L.exists())return new Response(L,{headers:W});try{let R=Buffer.from(await Bun.file(j).arrayBuffer()),{resizeAndConvert:M}=await P(),w=await M(R,{width:H,height:v,format:Z,quality:Y,fit:z});return await Bun.write(Q,w),W["X-Stx-Image-Cache"]="MISS",new Response(new Uint8Array(w),{headers:W})}catch(R){let M=R.message;return new Response(`Image processing failed: ${M}`,{status:500,headers:{"Content-Type":"text/plain"}})}}function l(k){return async(G)=>{return await g(G,k)??new Response("Not Found",{status:404,headers:{"Content-Type":"text/plain"}})}}function q(k,G){let J=k.searchParams.get("src");if(!J)return{ok:!1,error:"Missing required param: src",status:400};if(!J.startsWith("/"))return{ok:!1,error:"src must be an absolute URL path (start with /)",status:400};if(J.startsWith("//"))return{ok:!1,error:"src must be a local path",status:400};let B=X.extname(J).toLowerCase();if(!A.has(B))return{ok:!1,error:`Unsupported source extension: ${B}`,status:400};let $=X.resolve(G.publicDir),j=X.resolve($,J.slice(1));if(!j.startsWith(`${$}${X.sep}`)&&j!==$)return{ok:!1,error:"src is outside publicDir",status:400};let K=G.maxWidth??S,H=G.maxHeight??S,v=k.searchParams.get("w"),Z=k.searchParams.get("h"),Y=v?Number.parseInt(v,10):0,z=Z?Number.parseInt(Z,10):0;if(v&&(!Number.isFinite(Y)||Y<=0))return{ok:!1,error:"Invalid w (must be positive integer)",status:400};if(Z&&(!Number.isFinite(z)||z<=0))return{ok:!1,error:"Invalid h (must be positive integer)",status:400};if(!v&&!Z)return{ok:!1,error:"At least one of w or h is required",status:400};let C=Math.min(Y||K,K),N=Math.min(z||H,H),V=k.searchParams.get("f")||"webp";if(!_.has(V))return{ok:!1,error:`Invalid f (must be one of: ${[..._].join(", ")})`,status:400};let O=V,b=k.searchParams.get("q"),Q=b?Number.parseInt(b,10):G.defaultQuality??y;if(!Number.isFinite(Q)||Q<1||Q>100)return{ok:!1,error:"Invalid q (must be 1-100)",status:400};let x=k.searchParams.get("fit")||G.defaultFit||D;if(!F.has(x))return{ok:!1,error:`Invalid fit (must be one of: ${[...F].join(", ")})`,status:400};return{ok:!0,srcFsPath:j,srcUrl:J,width:C,height:N,format:O,quality:Q,fit:x}}async function P(){return await import("./chunk-3yn8ghtz.js")}
|
|
3
3
|
export{g as yf,l as zf};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{a as N,c as R,e as W,g as j,i as H,k as J}from"./chunk-0y46fbkx.js";import{l as k,m as w,n as B}from"./chunk-q9n5swx7.js";import"./chunk-
|
|
2
|
+
import{a as N,c as R,e as W,g as j,i as H,k as J}from"./chunk-0y46fbkx.js";import{l as k,m as w,n as B}from"./chunk-q9n5swx7.js";import"./chunk-qrkxyb5p.js";import E from"fs";import K from"path";var V=[];function _(U){V=[];for(let A of U.storyFiles)if(V.push({text:A.fileName.toLowerCase(),original:A.fileName,type:"story",storyId:A.id}),V.push({text:A.relativePath.toLowerCase(),original:A.relativePath,type:"story",storyId:A.id}),A.story)for(let z of A.story.variants)V.push({text:z.title.toLowerCase(),original:z.title,type:"story",storyId:A.id,variantId:z.id})}function $(){return JSON.stringify(V)}async function O(U={}){let A=Date.now();N();let z=await k({mode:"build"});if(!z.config.enabled){W("Story feature is disabled in config.");return}let P=await H(z);w(z,P);let Y=J(z.config,P);B(z,Y),R(P.length);let X=U.outDir??z.config.outDir,Q=K.resolve(z.root,X);await E.promises.mkdir(Q,{recursive:!0}),console.log(` Building to ${X}...`);let M=F(z);await E.promises.writeFile(K.join(Q,"index.html"),M);let v={files:P.map((G)=>({id:G.id,fileName:G.fileName,relativePath:G.relativePath,treePath:G.treePath})),tree:Y};await E.promises.writeFile(K.join(Q,"stories.json"),JSON.stringify(v,null,2));let L={theme:z.config.theme,responsivePresets:z.config.responsivePresets,backgroundPresets:z.config.backgroundPresets};await E.promises.writeFile(K.join(Q,"config.json"),JSON.stringify(L,null,2));let Z=K.join(Q,"stories");await E.promises.mkdir(Z,{recursive:!0});for(let G of P){let g=await E.promises.readFile(G.path,"utf-8");await E.promises.writeFile(K.join(Z,`${G.id}.stx`),g)}_(z);let T=$();await E.promises.writeFile(K.join(Q,"search-index.json"),T);let C=Date.now()-A;j(P.length,X,C)}function F(U){let{theme:A}=U.config,z=A.title||"STX Story";return`<!DOCTYPE html>
|
|
3
3
|
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{$s as Q}from"./chunk-
|
|
2
|
+
import{$s as Q}from"./chunk-9e6pyjwz.js";import"./chunk-z698hwht.js";import{zu as R}from"./chunk-ecbqmesm.js";import"./chunk-qrkxyb5p.js";import O from"fs";import U from"path";async function W(j,b={}){let q=Date.now(),z={total:0,passed:0,failed:0,new:0,failures:[],duration:0},K=b.snapshotDir||R(j.root,"story","snapshots");await O.promises.mkdir(K,{recursive:!0});let B=j.storyFiles;if(b.filter&&b.filter.length>0)B=B.filter((J)=>b.filter.some((G)=>J.fileName.toLowerCase().includes(G.toLowerCase())));for(let J of B)await X(J,K,b,z);return z.duration=Date.now()-q,z}async function X(j,b,q,z){let K=j.story;if(!K)return;for(let B of K.variants){z.total++;let J=U.join(b,`${j.id}-${B.id}.snap`),G=Y(B.source||""),L=await _(J);if(q.update||!L){let M={storyId:j.id,variantId:B.id,component:j.fileName,timestamp:Date.now(),hash:G};if(await O.promises.writeFile(J,JSON.stringify(M,null,2)),!L)z.new++;z.passed++}else try{let M=await O.promises.readFile(J,"utf-8"),N=JSON.parse(M);if(N.hash===G)z.passed++;else z.failed++,z.failures.push({storyId:j.id,variantId:B.id,component:j.fileName,message:"Snapshot mismatch",difference:Z(N.hash,G)})}catch(M){z.failed++,z.failures.push({storyId:j.id,variantId:B.id,component:j.fileName,message:`Error reading snapshot: ${M}`})}}}async function A(j,b={}){return(await W(j,{...b,update:!0})).total}function Y(j){let b=0;for(let q=0;q<j.length;q++){let z=j.charCodeAt(q);b=(b<<5)-b+z,b=b&b}return b.toString(16)}function Z(j,b){if(j===b)return 0;let q=Math.abs(Number.parseInt(j,16)-Number.parseInt(b,16));return Math.min(q/1e6,1)}async function _(j){try{return await O.promises.access(j),!0}catch{return!1}}function I(j){let b=[];if(b.push(""),b.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),b.push(" STX Story Visual Regression Tests"),b.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),b.push(""),j.failures.length>0){b.push(" \u274C Failures:"),b.push("");for(let q of j.failures){if(b.push(` \u2022 ${q.component} / ${q.variantId}`),b.push(` ${q.message}`),q.difference!==void 0)b.push(` Difference: ${(q.difference*100).toFixed(2)}%`);b.push("")}}if(b.push(" Summary:"),b.push(` Total: ${j.total}`),b.push(` Passed: ${j.passed} \u2713`),b.push(` Failed: ${j.failed} \u2717`),j.new>0)b.push(` New: ${j.new} \u26A1`);return b.push(` Time: ${j.duration}ms`),b.push(""),b.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),b.push(""),b.join(`
|
|
3
3
|
`)}async function S(j,b={}){let q=performance.now(),z=[],K=0,B=0;for(let G of j.storyFiles)try{let L=await Bun.file(G.path).text(),M=await Q(L,G.path);if(M.length>0){for(let N of M)z.push({storyId:G.id,variantId:"default",component:G.component,message:`A11y: ${N.message}`,expected:"No accessibility violations",actual:`${N.type}: ${N.message} (impact: ${N.impact})`});B++}else K++}catch(L){z.push({storyId:G.id,variantId:"default",component:G.component,message:`Failed to check a11y: ${L instanceof Error?L.message:String(L)}`,expected:"File readable for a11y check",actual:"File read error"}),B++}let J=performance.now()-q;return{total:j.storyFiles.length,passed:K,failed:B,new:0,failures:z,duration:J}}export{A as updateSnapshots,W as runVisualTests,S as runA11yTests,I as formatTestResults};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Ku as a,Lu as b,Mu as c,Nu as d,Ou as e,Pu as f,Qu as g,Ru as h,Su as i,Tu as j,Uu as k,Vu as l,Wu as m,Xu as n,Yu as o,Zu as p}from"./chunk-2hyxkzpc.js";import"./chunk-qrkxyb5p.js";export{i as useTitle,f as useSeoMeta,i as usePageTitle,d as useHead,g as seoMetaToHeadConfig,c as resetHead,k as renderHtmlAttrs,j as renderHead,l as renderBodyAttrs,o as processTitleDirective,p as processMetaDirective,n as processHeadDirective,e as mergeHeadConfigs,b as getPageMeta,a as getHead,h as definePageMeta,m as applyHead};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Ue as a}from"./chunk-mz9twa1f.js";import"./chunk-dvvx1wny.js";import"./chunk-2astj1fq.js";import"./chunk-9e6pyjwz.js";import"./chunk-z698hwht.js";import"./chunk-70zb3560.js";import"./chunk-zsapb653.js";import"./chunk-kwrj745h.js";import"./chunk-df5wrw50.js";import"./chunk-e10pfrds.js";import"./chunk-ecbqmesm.js";import"./chunk-namj6apv.js";import"./chunk-dgrayagx.js";import"./chunk-2hyxkzpc.js";import"./chunk-r1g0bnpv.js";import"./chunk-2dk3ym1g.js";import"./chunk-8n0mjaf6.js";import"./chunk-5az2jb8y.js";import"./chunk-rcvnh2p7.js";import"./chunk-qrkxyb5p.js";export{a as buildApp};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Qh as a,Rh as b,Sh as c,Th as d,Uh as e,Vh as f,Wh as g,Xh as h,Yh as i,Zh as j,_h as k}from"./chunk-9368t9jm.js";import"./chunk-
|
|
2
|
+
import{Qh as a,Rh as b,Sh as c,Th as d,Uh as e,Vh as f,Wh as g,Xh as h,Yh as i,Zh as j,_h as k}from"./chunk-9368t9jm.js";import"./chunk-qrkxyb5p.js";export{i as processStaticDirectives,b as processPartialHydrationDirectives,h as onHydrated,g as isHydrated,d as hydrateIsland,e as hydrateByStrategy,f as hydrateAll,c as generatePartialHydrationCSS,j as generateIslandManifest,k as default,a as createIslandRegistry};
|