gemi 0.119.1 → 0.120.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/ai/index.js +2 -2
- package/dist/ai/index.js.map +1 -1
- package/dist/app/index.js +2 -2
- package/dist/app/index.js.map +1 -1
- package/dist/auth/routes.d.ts.map +1 -1
- package/dist/bin/gemi.js +32 -5
- package/dist/bin/gemi.js.map +6 -5
- package/dist/bun/plugin.js +1 -1
- package/dist/bun/preload.js +1 -1
- package/dist/{chunk-xfw8zyvn.js → chunk-0ejjgzwc.js} +2 -2
- package/dist/{chunk-xfw8zyvn.js.map → chunk-0ejjgzwc.js.map} +1 -1
- package/dist/{chunk-33s2xqv1.js → chunk-0k02tza1.js} +1 -1
- package/dist/{chunk-a1qt8aky.js → chunk-0yj0s1pn.js} +2 -2
- package/dist/{chunk-a1qt8aky.js.map → chunk-0yj0s1pn.js.map} +1 -1
- package/dist/{chunk-y09r0wsw.js → chunk-19dpzp4y.js} +3 -3
- package/dist/{chunk-y09r0wsw.js.map → chunk-19dpzp4y.js.map} +1 -1
- package/dist/{chunk-cvfg88cx.js → chunk-1wnnkde0.js} +3 -3
- package/dist/{chunk-cvfg88cx.js.map → chunk-1wnnkde0.js.map} +1 -1
- package/dist/{chunk-xx7necqt.js → chunk-1xdrs2hx.js} +3 -3
- package/dist/{chunk-xx7necqt.js.map → chunk-1xdrs2hx.js.map} +1 -1
- package/dist/{chunk-mdp2dsbb.js → chunk-231a9920.js} +3 -3
- package/dist/{chunk-mdp2dsbb.js.map → chunk-231a9920.js.map} +3 -3
- package/dist/{chunk-scc0j5k9.js → chunk-2c0s0561.js} +2 -2
- package/dist/{chunk-scc0j5k9.js.map → chunk-2c0s0561.js.map} +1 -1
- package/dist/{chunk-8wcpxm41.js → chunk-2n3pgfnb.js} +2 -2
- package/dist/{chunk-8wcpxm41.js.map → chunk-2n3pgfnb.js.map} +1 -1
- package/dist/{chunk-q290tgza.js → chunk-32n8t8x6.js} +2 -2
- package/dist/{chunk-q290tgza.js.map → chunk-32n8t8x6.js.map} +1 -1
- package/dist/{chunk-pvz90a49.js → chunk-3gsv1vv1.js} +2 -2
- package/dist/{chunk-hm9cjxy2.js.map → chunk-3gsv1vv1.js.map} +1 -1
- package/dist/{chunk-sce5jes2.js → chunk-3wnghdsx.js} +2 -2
- package/dist/{chunk-sce5jes2.js.map → chunk-3wnghdsx.js.map} +1 -1
- package/dist/{chunk-01ehxca0.js → chunk-471htqmz.js} +2 -2
- package/dist/{chunk-01ehxca0.js.map → chunk-471htqmz.js.map} +1 -1
- package/dist/{chunk-dwpn6fze.js → chunk-48gmyaxc.js} +2 -2
- package/dist/{chunk-dwpn6fze.js.map → chunk-48gmyaxc.js.map} +1 -1
- package/dist/{chunk-3zxfd7pn.js → chunk-4acpw92g.js} +3 -3
- package/dist/{chunk-3zxfd7pn.js.map → chunk-4acpw92g.js.map} +1 -1
- package/dist/{chunk-d806cy7p.js → chunk-4fx8p02c.js} +2 -2
- package/dist/{chunk-d806cy7p.js.map → chunk-4fx8p02c.js.map} +1 -1
- package/dist/{chunk-xtzn0qfh.js → chunk-51w5ktv2.js} +3 -3
- package/dist/{chunk-xtzn0qfh.js.map → chunk-51w5ktv2.js.map} +1 -1
- package/dist/{chunk-cte6ysqd.js → chunk-5nj94s66.js} +4 -4
- package/dist/{chunk-cte6ysqd.js.map → chunk-5nj94s66.js.map} +1 -1
- package/dist/{chunk-bgwtdbfw.js → chunk-5tdxbwzg.js} +3 -3
- package/dist/{chunk-bgwtdbfw.js.map → chunk-5tdxbwzg.js.map} +1 -1
- package/dist/{chunk-hkf2k2eq.js → chunk-65beps2q.js} +3 -3
- package/dist/{chunk-hkf2k2eq.js.map → chunk-65beps2q.js.map} +1 -1
- package/dist/{chunk-1z1rj2zq.js → chunk-6yhpprzs.js} +3 -3
- package/dist/{chunk-1z1rj2zq.js.map → chunk-6yhpprzs.js.map} +1 -1
- package/dist/{chunk-j5858bz7.js → chunk-7ftj43vp.js} +2 -2
- package/dist/{chunk-j5858bz7.js.map → chunk-7ftj43vp.js.map} +1 -1
- package/dist/{chunk-qf4bmee9.js → chunk-7g649j8h.js} +2 -2
- package/dist/{chunk-qf4bmee9.js.map → chunk-7g649j8h.js.map} +1 -1
- package/dist/{chunk-675kzd7z.js → chunk-7mmw0jr2.js} +2 -2
- package/dist/{chunk-675kzd7z.js.map → chunk-7mmw0jr2.js.map} +1 -1
- package/dist/{chunk-pkr5dsbk.js → chunk-9d2d08qm.js} +2 -2
- package/dist/{chunk-pkr5dsbk.js.map → chunk-9d2d08qm.js.map} +1 -1
- package/dist/{chunk-r1favzz4.js → chunk-9rr5h818.js} +3 -3
- package/dist/{chunk-r1favzz4.js.map → chunk-9rr5h818.js.map} +1 -1
- package/dist/{chunk-30xxc6r7.js → chunk-9xyxbxgk.js} +2 -2
- package/dist/{chunk-30xxc6r7.js.map → chunk-9xyxbxgk.js.map} +1 -1
- package/dist/{chunk-6ggmk2eg.js → chunk-c0v61fp5.js} +2 -2
- package/dist/{chunk-6ggmk2eg.js.map → chunk-c0v61fp5.js.map} +1 -1
- package/dist/{chunk-hzepfrzy.js → chunk-c7qs1xp3.js} +2 -2
- package/dist/{chunk-hzepfrzy.js.map → chunk-c7qs1xp3.js.map} +1 -1
- package/dist/{chunk-1m3hvy3q.js → chunk-cca0grq3.js} +2 -2
- package/dist/{chunk-1m3hvy3q.js.map → chunk-cca0grq3.js.map} +1 -1
- package/dist/{chunk-g9hhdcax.js → chunk-cskqet01.js} +2 -2
- package/dist/{chunk-g9hhdcax.js.map → chunk-cskqet01.js.map} +1 -1
- package/dist/{chunk-8t6dwwz6.js → chunk-cvr5624r.js} +1 -1
- package/dist/{chunk-xzn2nmny.js → chunk-d2c3947c.js} +2 -2
- package/dist/{chunk-xzn2nmny.js.map → chunk-d2c3947c.js.map} +1 -1
- package/dist/{chunk-jg79n382.js → chunk-d5f1m3d2.js} +2 -2
- package/dist/{chunk-jg79n382.js.map → chunk-d5f1m3d2.js.map} +1 -1
- package/dist/{chunk-rpwb1t5z.js → chunk-dbx3g5ck.js} +2 -2
- package/dist/{chunk-rpwb1t5z.js.map → chunk-dbx3g5ck.js.map} +1 -1
- package/dist/chunk-dc8gyybt.js +24 -0
- package/dist/{chunk-rbm57mck.js.map → chunk-dc8gyybt.js.map} +3 -3
- package/dist/{chunk-tfdmvxza.js → chunk-dedqr5wb.js} +2 -2
- package/dist/{chunk-tfdmvxza.js.map → chunk-dedqr5wb.js.map} +1 -1
- package/dist/{chunk-aedkrck1.js → chunk-dhbgrv58.js} +1 -1
- package/dist/{chunk-nang3847.js → chunk-dwedx1jb.js} +3 -3
- package/dist/{chunk-nang3847.js.map → chunk-dwedx1jb.js.map} +1 -1
- package/dist/{chunk-m4kmetpb.js → chunk-ep0baa9g.js} +2 -2
- package/dist/{chunk-m4kmetpb.js.map → chunk-ep0baa9g.js.map} +1 -1
- package/dist/{chunk-kk77x2v4.js → chunk-er8acmch.js} +7 -7
- package/dist/{chunk-kk77x2v4.js.map → chunk-er8acmch.js.map} +3 -3
- package/dist/{chunk-thz75w6e.js → chunk-fcqx2t0p.js} +2 -2
- package/dist/{chunk-thz75w6e.js.map → chunk-fcqx2t0p.js.map} +1 -1
- package/dist/{chunk-z759yah5.js → chunk-fenc5tpv.js} +2 -2
- package/dist/{chunk-z759yah5.js.map → chunk-fenc5tpv.js.map} +1 -1
- package/dist/{chunk-hr1r3g0d.js → chunk-gc2dz11k.js} +2 -2
- package/dist/{chunk-hr1r3g0d.js.map → chunk-gc2dz11k.js.map} +1 -1
- package/dist/{chunk-pqc16rrx.js → chunk-gemzbw7f.js} +2 -2
- package/dist/{chunk-pqc16rrx.js.map → chunk-gemzbw7f.js.map} +1 -1
- package/dist/{chunk-sn04cyw0.js → chunk-gy81nd9a.js} +2 -2
- package/dist/{chunk-sn04cyw0.js.map → chunk-gy81nd9a.js.map} +1 -1
- package/dist/{chunk-gqfqnv3f.js → chunk-h43jp8ws.js} +2 -2
- package/dist/{chunk-gqfqnv3f.js.map → chunk-h43jp8ws.js.map} +1 -1
- package/dist/chunk-hhymaj0m.js +57 -0
- package/dist/{chunk-dxag6enj.js.map → chunk-hhymaj0m.js.map} +9 -7
- package/dist/chunk-htgmy3x7.js +5 -0
- package/dist/{chunk-3nf95j9e.js.map → chunk-htgmy3x7.js.map} +1 -1
- package/dist/{chunk-fsj5k511.js → chunk-jaa6xkeh.js} +2 -2
- package/dist/{chunk-fsj5k511.js.map → chunk-jaa6xkeh.js.map} +1 -1
- package/dist/{chunk-2bja99cq.js → chunk-kk18xqgc.js} +2 -2
- package/dist/{chunk-2bja99cq.js.map → chunk-kk18xqgc.js.map} +1 -1
- package/dist/{chunk-ebret82e.js → chunk-krk7mcgm.js} +3 -3
- package/dist/{chunk-ebret82e.js.map → chunk-krk7mcgm.js.map} +1 -1
- package/dist/{chunk-bz8xssrc.js → chunk-krtybgz1.js} +2 -2
- package/dist/{chunk-bz8xssrc.js.map → chunk-krtybgz1.js.map} +1 -1
- package/dist/{chunk-eke2frrm.js → chunk-m53fgf20.js} +3 -3
- package/dist/{chunk-eke2frrm.js.map → chunk-m53fgf20.js.map} +1 -1
- package/dist/{chunk-490sbcma.js → chunk-m83zm86m.js} +2 -2
- package/dist/{chunk-490sbcma.js.map → chunk-m83zm86m.js.map} +1 -1
- package/dist/{chunk-xx3zvc3g.js → chunk-meg8rtr6.js} +2 -2
- package/dist/{chunk-xx3zvc3g.js.map → chunk-meg8rtr6.js.map} +1 -1
- package/dist/{chunk-39kyz4k6.js → chunk-mr94nfp1.js} +3 -3
- package/dist/{chunk-39kyz4k6.js.map → chunk-mr94nfp1.js.map} +1 -1
- package/dist/{chunk-g5ppst76.js → chunk-nz8z8jr1.js} +3 -3
- package/dist/{chunk-g5ppst76.js.map → chunk-nz8z8jr1.js.map} +1 -1
- package/dist/{chunk-n4sdm0jn.js → chunk-pemhmjzp.js} +3 -3
- package/dist/{chunk-n4sdm0jn.js.map → chunk-pemhmjzp.js.map} +1 -1
- package/dist/{chunk-76p0rf4d.js → chunk-pn2x59ge.js} +3 -3
- package/dist/{chunk-76p0rf4d.js.map → chunk-pn2x59ge.js.map} +1 -1
- package/dist/{chunk-aqpaw4jq.js → chunk-qsz9241c.js} +2 -2
- package/dist/{chunk-aqpaw4jq.js.map → chunk-qsz9241c.js.map} +1 -1
- package/dist/{chunk-5dbpgyrx.js → chunk-qy8c0gzr.js} +2 -2
- package/dist/{chunk-5dbpgyrx.js.map → chunk-qy8c0gzr.js.map} +1 -1
- package/dist/{chunk-qkxnvpaj.js → chunk-r01aqf0q.js} +2 -2
- package/dist/{chunk-qkxnvpaj.js.map → chunk-r01aqf0q.js.map} +1 -1
- package/dist/{chunk-jf6qqzat.js → chunk-rhvc1axc.js} +2 -2
- package/dist/{chunk-jf6qqzat.js.map → chunk-rhvc1axc.js.map} +1 -1
- package/dist/{chunk-kkte8nze.js → chunk-s07v65x6.js} +3 -3
- package/dist/{chunk-kkte8nze.js.map → chunk-s07v65x6.js.map} +1 -1
- package/dist/{chunk-5cgq9c43.js → chunk-s5k3yq6t.js} +2 -2
- package/dist/{chunk-5cgq9c43.js.map → chunk-s5k3yq6t.js.map} +1 -1
- package/dist/{chunk-453rmkpm.js → chunk-sx340k85.js} +2 -2
- package/dist/{chunk-453rmkpm.js.map → chunk-sx340k85.js.map} +1 -1
- package/dist/{chunk-hm9cjxy2.js → chunk-tewhms9w.js} +2 -2
- package/dist/{chunk-pvz90a49.js.map → chunk-tewhms9w.js.map} +1 -1
- package/dist/{chunk-tzdenj0n.js → chunk-tk135gmj.js} +3 -3
- package/dist/{chunk-tzdenj0n.js.map → chunk-tk135gmj.js.map} +1 -1
- package/dist/{chunk-4c1kdd8p.js → chunk-vx7hvyvq.js} +2 -2
- package/dist/{chunk-4c1kdd8p.js.map → chunk-vx7hvyvq.js.map} +1 -1
- package/dist/{chunk-razjfecn.js → chunk-wjkh2gem.js} +1 -1
- package/dist/{chunk-vkkt7j2y.js → chunk-wnj7q0th.js} +3 -3
- package/dist/{chunk-vkkt7j2y.js.map → chunk-wnj7q0th.js.map} +1 -1
- package/dist/{chunk-p83erprx.js → chunk-wqe47c0j.js} +2 -2
- package/dist/{chunk-p83erprx.js.map → chunk-wqe47c0j.js.map} +1 -1
- package/dist/{chunk-nrezmscd.js → chunk-y6wt5b6t.js} +1 -1
- package/dist/{chunk-9pkj7sk6.js → chunk-yds7zwc3.js} +2 -2
- package/dist/{chunk-9pkj7sk6.js.map → chunk-yds7zwc3.js.map} +1 -1
- package/dist/{chunk-x6v2zex2.js → chunk-zefs2b6h.js} +2 -2
- package/dist/{chunk-x6v2zex2.js.map → chunk-zefs2b6h.js.map} +1 -1
- package/dist/{chunk-de4t48j9.js → chunk-zg6hmc48.js} +1 -1
- package/dist/{chunk-5ses4tcz.js → chunk-zrcd9hxr.js} +2 -2
- package/dist/{chunk-5ses4tcz.js.map → chunk-zrcd9hxr.js.map} +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +26 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/staticNavigation.d.ts +26 -0
- package/dist/client/staticNavigation.d.ts.map +1 -0
- package/dist/config/index.js +1 -1
- package/dist/console/run.js +2 -2
- package/dist/console/run.js.map +1 -1
- package/dist/container/index.js +2 -2
- package/dist/container/index.js.map +1 -1
- package/dist/database/index.js +2 -2
- package/dist/database/index.js.map +1 -1
- package/dist/email/index.js +2 -2
- package/dist/email/index.js.map +1 -1
- package/dist/facades/index.js +2 -2
- package/dist/facades/index.js.map +1 -1
- package/dist/foundation/index.js +2 -2
- package/dist/foundation/index.js.map +1 -1
- package/dist/http/SameSiteBounceMiddleware.d.ts +42 -0
- package/dist/http/SameSiteBounceMiddleware.d.ts.map +1 -0
- package/dist/http/ViewRouter.d.ts +36 -2
- package/dist/http/ViewRouter.d.ts.map +1 -1
- package/dist/http/index.d.ts +2 -1
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +2 -2
- package/dist/http/index.js.map +1 -1
- package/dist/i18n/dictionaryRuntime.js +2 -2
- package/dist/i18n/dictionaryRuntime.js.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/i18n/index.js.map +2 -2
- package/dist/internal/islandRuntime.d.ts +16 -0
- package/dist/internal/islandRuntime.d.ts.map +1 -1
- package/dist/internal/staticNavigationRuntime.d.ts +8 -0
- package/dist/internal/staticNavigationRuntime.d.ts.map +1 -0
- package/dist/kernel/index.js +2 -2
- package/dist/kernel/index.js.map +2 -2
- package/dist/orm/index.js +2 -2
- package/dist/orm/index.js.map +1 -1
- package/dist/server/devFetch.d.ts.map +1 -1
- package/dist/server/httpProd.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -3
- package/dist/services/index.js.map +2 -2
- package/dist/services/queue/work.js +2 -2
- package/dist/services/queue/work.js.map +1 -1
- package/dist/services/router/ViewRouteDispatcher.d.ts +5 -0
- package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
- package/dist/services/router/staticDocument.d.ts +30 -21
- package/dist/services/router/staticDocument.d.ts.map +1 -1
- package/dist/stats/bundleStats.d.ts +6 -2
- package/dist/stats/bundleStats.d.ts.map +1 -1
- package/dist/stats/route-table.js +2 -2
- package/dist/stats/route-table.js.map +3 -3
- package/dist/stats/routeTable.d.ts +5 -1
- package/dist/stats/routeTable.d.ts.map +1 -1
- package/dist/support/index.js +2 -2
- package/dist/support/index.js.map +1 -1
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +185 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/staticDocument.d.ts +80 -0
- package/dist/testing/staticDocument.d.ts.map +1 -0
- package/dist/vitest/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3nf95j9e.js +0 -5
- package/dist/chunk-dxag6enj.js +0 -57
- package/dist/chunk-rbm57mck.js +0 -24
- /package/dist/{chunk-33s2xqv1.js.map → chunk-0k02tza1.js.map} +0 -0
- /package/dist/{chunk-8t6dwwz6.js.map → chunk-cvr5624r.js.map} +0 -0
- /package/dist/{chunk-aedkrck1.js.map → chunk-dhbgrv58.js.map} +0 -0
- /package/dist/{chunk-razjfecn.js.map → chunk-wjkh2gem.js.map} +0 -0
- /package/dist/{chunk-nrezmscd.js.map → chunk-y6wt5b6t.js.map} +0 -0
- /package/dist/{chunk-de4t48j9.js.map → chunk-zg6hmc48.js.map} +0 -0
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
import{existsSync as $,readdirSync as B}from"fs";import{join as Y,relative as G}from"path";function J(K,Q=[]){let U=[],X=(H)=>{let z=G(K,H).split("\\").join("/");return Q.some((q)=>z===q||z.startsWith(`${q}/`))},V=(H)=>{for(let z of B(H,{withFileTypes:!0}).sort((q,Z)=>q.name<Z.name?-1:q.name>Z.name?1:0)){let q=Y(H,z.name);if(X(q))continue;if(z.isDirectory()){if(z.name.startsWith(".")||z.name==="node_modules")continue;if($(Y(q,"package.json")))continue;V(q);continue}if(!z.name.endsWith(".ts")&&!z.name.endsWith(".tsx"))continue;if(z.name.endsWith(".d.ts"))continue;if(/\.(test|test-d|spec|bench)\.tsx?$/.test(z.name))continue;U.push(q)}};if(!$(K))return U;return V(K),U}class A extends Error{constructor(K,Q){super(K,Q);this.name="DiscoveryError"}}async function W(K,Q,U=[],X){let V=new Set;for(let H of J(K,U)){let z;try{z=await import(H)}catch(q){throw new A(`${H} could not be imported, so the classes in it could not be discovered:
|
|
3
3
|
${q.message}
|
|
4
4
|
List the classes explicitly in the config slice for this directory to skip the walk.`,{cause:q})}for(let q of Object.values(z)){if(typeof q==="function"&&q!==Q&&Object.prototype.isPrototypeOf.call(Q,q)){V.add(q);continue}X?.(q,H)}}return[...V]}function F(){return Y(process.cwd(),process.env.GEMI_PROJECT_DIR??"")}
|
|
5
|
-
export{J as
|
|
5
|
+
export{J as cj,A as dj,W as ej,F as fj};
|
|
6
6
|
|
|
7
|
-
//# debugId=
|
|
7
|
+
//# debugId=DBFD321D5C6663C464756E2164756E21
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"import { existsSync, readdirSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\n\n/**\n * Finding the classes an application declared and never imported — the walk\n * #322 and #323 both end at.\n *\n * ### Why it has to run the files\n *\n * A job that is written and not listed does not fail; it disappears.\n * `QueueManager.run` looks a dispatched name up in the map its config built and\n * drops what is not there, so the dispatch is simply lost. A cron drifts worse:\n * nothing is waiting on a tick, so a job that never fires reports nothing to\n * anyone. What both come down to is that `app/config/queue.ts` naming every\n * `Job` subclass is the *only* thing putting those classes in the module graph —\n * the list and the directory are two spellings of one set, kept in step by hand.\n *\n * The way out of that is to read the directory, and there is no static read that\n * will do: the class does not exist until its module has run. So **every file\n * walked here is imported**, and a file that *does something* when imported does\n * it here — at boot, in production, on every start. `gemi check models` makes\n * the same trade for the same reason and pays it once per CI run; a caller of\n * this pays it once per process.\n *\n * ### What that asks of a caller\n *\n * **Point it at a directory of class declarations, not at `app/`.** The skip\n * rules on `sourceFiles` drop what certainly is not one — tests, benchmarks,\n * `.d.ts`, vendored packages — and nothing else. Widening the guesses is how a\n * discovery pass ends up quietly covering less than the directory holds, which\n * is the same silence in a new place.\n *\n * **Let a broken file stop the boot.** `discoverClasses` rethrows an import\n * failure naming the file rather than dropping it and carrying on, for the same\n * reason: four classes found out of five looks exactly like five out of five.\n *\n * **Leave a way out.** Discovery is what should happen when an app said\n * nothing. An app that lists its classes explicitly must not reach this file at\n * all — that is the escape hatch for a directory holding something this cannot\n * import, and it is the sentence an error from here should point at.\n *\n * ### One more thing worth knowing\n *\n * This imports by absolute path, while the application imports the same files\n * through the `@/app/*` alias. Bun keys its module registry by the *resolved*\n * path, so those two specifiers land on one module: a job already reached from\n * a controller is not evaluated a second time here, and the class object is the\n * same one. `gemi build` leaves that true in production — `packages: \"external\"`\n * keeps the app's own code out of `dist/server/server.mjs` and resolves it from\n * source at runtime, exactly as `gemi dev` does.\n *\n * Nothing here depends on that holding, and deliberately: `QueueManager` and the\n * `Scheduler`'s cross-reload registry are both keyed by name rather than by\n * class identity, so a build that did inline the app's modules would produce a\n * duplicate class object and still register the right job. Worth knowing before\n * writing a registry keyed the other way.\n */\n\n/**\n * The files under `dir` that could declare a class.\n *\n * Everything underneath it, because apps do group classes into folders, minus\n * what cannot be one. Each of these is going to be *imported*, so the exclusions\n * are about what is certainly not source rather than about what is probably not:\n *\n * - **Declaration files.** `.d.ts` has no runtime module behind it.\n * - **Tests, type tests and benchmarks**, by the suffix a runner already\n * recognises.\n * - **Dot-directories and `node_modules`.**\n * - **Any directory holding a `package.json`.** That is a package that happens\n * to live here — a vendored client, a generated SDK — not this app's source,\n * and importing its entry point runs somebody else's module graph. The\n * template has two under `app/models`.\n *\n * `ignore` is the escape hatch for the rest: a path prefix, relative to `dir`,\n * naming a file or a directory of adjacent code that runs something on import.\n * Nothing is ignored by default.\n *\n * The order is the same on every run over the same tree, which matters because\n * the caller is going to import in it: entries are sorted per directory before\n * recursing, and `readdirSync` order is the filesystem's rather than\n * alphabetical — a tree written `A.ts` then `B.ts` reads back `B.ts` first on\n * the machines this was tested on. Sorting per directory rather than sorting the\n * finished list is deliberate: for a tree holding both `a.ts` and `a/b.ts`, this\n * emits `a/b.ts` first, because the directory sorts before the file.\n *\n * A directory that does not exist yields an empty list rather than throwing.\n * \"The app has no jobs yet\" is an ordinary state and not this function's to\n * complain about — but it is indistinguishable from \"the app's source did not\n * ship\", so a caller that boots on the answer owes the reader a word about which\n * one it got.\n */\nexport function sourceFiles(dir: string, ignore: string[] = []): string[] {\n const out: string[] = [];\n\n const ignored = (path: string) => {\n const rel = relative(dir, path).split(\"\\\\\").join(\"/\");\n return ignore.some(\n (pattern) => rel === pattern || rel.startsWith(`${pattern}/`),\n );\n };\n\n const walk = (current: string) => {\n for (const entry of readdirSync(current, { withFileTypes: true }).sort(\n (a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0),\n )) {\n const path = join(current, entry.name);\n if (ignored(path)) continue;\n\n if (entry.isDirectory()) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\")\n continue;\n if (existsSync(join(path, \"package.json\"))) continue;\n walk(path);\n continue;\n }\n\n if (!entry.name.endsWith(\".ts\") && !entry.name.endsWith(\".tsx\")) continue;\n if (entry.name.endsWith(\".d.ts\")) continue;\n if (/\\.(test|test-d|spec|bench)\\.tsx?$/.test(entry.name)) continue;\n\n out.push(path);\n }\n };\n\n if (!existsSync(dir)) return out;\n\n walk(dir);\n return out;\n}\n\n/**\n * A class, as much of one as this file can name. `abstract` so that a base an\n * app never instantiates directly is a legal argument.\n */\ntype ClassLike = abstract new (...args: never[]) => unknown;\n\n/**\n * A file that would not import, reported with the file that would not import.\n *\n * Separate from a bare rethrow because the stack of a failed dynamic import\n * names the module that failed to *resolve*, several frames deep, and says\n * nothing about the walk that asked for it — so the reader learns that some\n * `?raw` specifier is unresolvable without learning that discovery is what\n * imported it, or that listing the classes explicitly is how they get their boot\n * back.\n */\nexport class DiscoveryError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"DiscoveryError\";\n }\n}\n\n/**\n * Every exported class under `dir` whose prototype chain reaches `base`.\n *\n * `base` is a parameter rather than an import so that this file names no\n * service and stays cheap to depend on — `bin/check-models.ts` uses the walker\n * above and is bundled into `dist/bin/gemi.js`, which is not somewhere gemi's\n * service layer should end up. It is also what lets a test hand in a base class\n * of its own instead of standing up a project that can resolve `gemi/services`.\n *\n * `base` itself is never returned. A directory whose files import their base\n * from a sibling — the shape an app reaches for when several jobs share a gate —\n * re-exports it as often as not, and a framework that scheduled the abstract\n * base along with its subclasses would be running a job nobody wrote.\n *\n * A class is returned once no matter how many exports name it. A barrel in the\n * directory re-exporting everything beside it is the ordinary case, and it makes\n * every class reachable twice.\n *\n * The order is the walk's, and within a file the module namespace's, which the\n * language sorts by name. So the answer is the same on every run — worth having\n * where the caller is a scheduler and the alternative is a boot order that\n * depends on the filesystem.\n *\n * `onSkipped` is handed every export that did *not* match, with the file it came\n * from. Discovery's characteristic failure is a thing the author wrote and this\n * walk cannot see, and by the time an export has been discarded here the\n * information about why is gone — the caller is left holding \"four classes\"\n * where the directory holds five. A caller that can recognise its own\n * near-misses, as `discoverCommands` recognises a builder chain that was never\n * finished, uses this to say so by name instead.\n *\n * @throws DiscoveryError if a walked file cannot be imported. Not a skip: a file\n * that will not load is a class the caller was going to be told about and now is\n * not, which is the failure discovery exists to remove.\n */\nexport async function discoverClasses<T extends ClassLike>(\n dir: string,\n base: T,\n ignore: string[] = [],\n onSkipped?: (value: unknown, file: string) => void,\n): Promise<T[]> {\n const found = new Set<T>();\n\n for (const path of sourceFiles(dir, ignore)) {\n let module: Record<string, unknown>;\n\n try {\n module = (await import(path)) as Record<string, unknown>;\n } catch (error) {\n throw new DiscoveryError(\n `${path} could not be imported, so the classes in it could not be ` +\n `discovered:\\n ${(error as Error).message}\\n` +\n `List the classes explicitly in the config slice for this directory ` +\n `to skip the walk.`,\n { cause: error },\n );\n }\n\n for (const value of Object.values(module)) {\n if (\n typeof value === \"function\" &&\n value !== base &&\n Object.prototype.isPrototypeOf.call(base, value)\n ) {\n found.add(value as unknown as T);\n continue;\n }\n\n onSkipped?.(value, path);\n }\n }\n\n return [...found];\n}\n\n/**\n * The directory an app's `app/` sits in, as the running process can know it.\n *\n * `ROOT_DIR` is the obvious answer and is not available: `Server.start` awaits\n * `waitForBoot()` — every provider's `register` and `boot` — and only then\n * imports the http layer that sets it. Anything resolving paths during boot is\n * earlier than the variable it would want.\n *\n * What it can use is the same rule `httpProd` computes `ROOT_DIR` with a moment\n * later, which is why that file now calls this instead of repeating it. `gemi\n * dev` and `gemi start` both spawn the server with no `cwd`, so the process\n * inherits the CLI's, and the CLI takes `process.cwd()` for the project root\n * itself — `bun/preload.ts` reads `gemi.config` from it on the same assumption.\n *\n * `httpDev` computes a bare `process.cwd()`, so it and `httpProd` already\n * disagree whenever `GEMI_PROJECT_DIR` is set. Nothing in this repo sets it and\n * `gemi start` ignores it when locating the built entry point, so the two rules\n * are the same rule for every configuration that runs today; the divergence is\n * older than this function and wants its own fix.\n */\nexport function projectRoot(): string {\n return join(process.cwd(), process.env.GEMI_PROJECT_DIR ?? \"\");\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAAA,qBAAS,iBAAY,WACrB,eAAS,cAAM,aA2FR,SAAS,CAAW,CAAC,EAAa,EAAmB,CAAC,EAAa,CACxE,IAAM,EAAgB,CAAC,EAEjB,EAAU,CAAC,IAAiB,CAChC,IAAM,EAAM,EAAS,EAAK,CAAI,EAAE,MAAM,IAAI,EAAE,KAAK,GAAG,EACpD,OAAO,EAAO,KACZ,CAAC,IAAY,IAAQ,GAAW,EAAI,WAAW,GAAG,IAAU,CAC9D,GAGI,EAAO,CAAC,IAAoB,CAChC,QAAW,KAAS,EAAY,EAAS,CAAE,cAAe,EAAK,CAAC,EAAE,KAChE,CAAC,EAAG,IAAO,EAAE,KAAO,EAAE,KAAO,GAAK,EAAE,KAAO,EAAE,KAAO,EAAI,CAC1D,EAAG,CACD,IAAM,EAAO,EAAK,EAAS,EAAM,IAAI,EACrC,GAAI,EAAQ,CAAI,EAAG,SAEnB,GAAI,EAAM,YAAY,EAAG,CACvB,GAAI,EAAM,KAAK,WAAW,GAAG,GAAK,EAAM,OAAS,eAC/C,SACF,GAAI,EAAW,EAAK,EAAM,cAAc,CAAC,EAAG,SAC5C,EAAK,CAAI,EACT,SAGF,GAAI,CAAC,EAAM,KAAK,SAAS,KAAK,GAAK,CAAC,EAAM,KAAK,SAAS,MAAM,EAAG,SACjE,GAAI,EAAM,KAAK,SAAS,OAAO,EAAG,SAClC,GAAI,oCAAoC,KAAK,EAAM,IAAI,EAAG,SAE1D,EAAI,KAAK,CAAI,IAIjB,GAAI,CAAC,EAAW,CAAG,EAAG,OAAO,EAG7B,OADA,EAAK,CAAG,EACD,EAmBF,MAAM,UAAuB,KAAM,CACxC,WAAW,CAAC,EAAiB,EAA+B,CAC1D,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,iBAEhB,CAqCA,eAAsB,CAAoC,CACxD,EACA,EACA,EAAmB,CAAC,EACpB,EACc,CACd,IAAM,EAAQ,IAAI,IAElB,QAAW,KAAQ,EAAY,EAAK,CAAM,EAAG,CAC3C,IAAI,EAEJ,GAAI,CACF,EAAU,MAAa,UACvB,MAAO,EAAO,CACd,MAAM,IAAI,EACR,GAAG;AAAA,MACoB,EAAgB;AAAA,sFAGvC,CAAE,MAAO,CAAM,CACjB,EAGF,QAAW,KAAS,OAAO,OAAO,CAAM,EAAG,CACzC,GACE,OAAO,IAAU,YACjB,IAAU,GACV,OAAO,UAAU,cAAc,KAAK,EAAM,CAAK,EAC/C,CACA,EAAM,IAAI,CAAqB,EAC/B,SAGF,IAAY,EAAO,CAAI,GAI3B,MAAO,CAAC,GAAG,CAAK,EAuBX,SAAS,CAAW,EAAW,CACpC,OAAO,EAAK,QAAQ,IAAI,EAAG,QAAQ,IAAI,kBAAoB,EAAE",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "DBFD321D5C6663C464756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Ba as y}from"./chunk-kk18xqgc.js";import{createElement as q}from"react";function z(i,n){let p=Object.keys(n).sort((s,g)=>g.length-s.length).map((s)=>s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),b=new RegExp(p.join("|"),"g");return i.replace(b,(s)=>n[s])}async function L(i,n,p=[],b){let s=[...p.map((t)=>`${i}/views/${t}.tsx`),b?`${i}/views/${b}.tsx`:`${i}/views/RootLayout.tsx`],g=new Set;for(let t of s){let u=n.moduleGraph.getModulesByFile(t);if(u)for(let x of u)g.add(x)}let e=[],l=[],r={};for(let t of g)if(t)for(let u of t.importedModules){if(u.file.includes("module.css"))r[u.file]=u.ssrTransformResult.map.sourcesContent.join("");if(u.file.includes(".css"))l.push(u.file)}for(let t of l){let u=await n.transformRequest(t+"?direct"),x=t.includes("module.css"),k="";if(x)k=z(r[t],u.default);e.push({isDev:!0,id:t,content:x?k:u.code})}return e.map((t,u)=>{return q("style",{key:u,type:"text/css","data-vite-dev-id":t.id,dangerouslySetInnerHTML:{__html:t.content}})})}async function _(i=[]){return i.map((n,p)=>{return q("style",{key:p,id:n?.id,type:"text/css",dangerouslySetInnerHTML:{__html:n.content}})})}import{existsSync as J}from"fs";import{basename as N}from"path";import{networkInterfaces as O}from"os";var v={name:"gemi",version:"0.120.0",private:!1,license:"MIT",author:"Enes Tufekci <enes@gemijs.dev>",repository:{type:"git",url:"git+https://github.com/nstfkc/gemi.git",directory:"packages/gemi"},bin:{gemi:"./dist/bin/gemi.js","gemi-orm-generator":"./dist/bin/orm-generator.js"},files:["dist/**/*","ide/typescript-plugin/package.json","skills/**/*"],module:!0,exports:{"./http":"./http/index.ts","./client":"./client/index.ts","./ai":"./ai/index.ts","./ai/client":"./ai/client/index.ts","./testing":"./testing/index.ts","./app":"./app/index.ts","./facades":"./facades/index.ts","./email":"./email/index.ts","./vite":"./dist/vite/index.mjs","./kernel":"./kernel/index.ts","./services":"./services/index.ts","./i18n":"./i18n/index.ts","./dictionary":"./i18n/dictionaryRuntime.ts","./server":"./server/index.ts","./config":"./config/index.ts","./container":"./container/index.ts","./foundation":"./foundation/index.ts","./database":"./database/index.ts","./orm":"./orm/index.ts","./support":"./support/index.ts","./console/run":"./console/run.ts","./queue/work":"./services/queue/work.ts","./stats/route-table":"./stats/route-table.ts","./ide/typescript-plugin":"./ide/typescript-plugin/index.ts","./bun/preload":"./bun/preload.ts","./bun/plugin":"./bun/plugin.ts","./vitest":"./vitest/index.ts"},scripts:{lint:"oxlint",typecheck:"tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p ide/typescript-plugin/tsconfig.json",build:"NODE_ENV=production bun run build:core && bun run build:bin && bun run build:types && bun run build:client && bun run build:plugin && bun run build:ts-plugin && bun run build:client-types && bun run build:augmentation","build:core":"bun ./scripts/build.ts","build:bin":"bun build --outdir=./dist/bin --target=bun --external=vite --external=react-dom --external=react/jsx-runtime --external=bun --external=sharp --external=@azure/storage-blob --external=typescript --sourcemap ./bin/gemi.ts ./bin/orm-generator.ts && bun ./scripts/prepare-bin.ts","build:client":"rm -rf dist/client dist/testing dist/ai/client dist/chunks && vite build -c vite.client.config.mts","build:plugin":"vite build -c vite.plugin.config.mts","build:ts-plugin":"bun ./scripts/build-ts-plugin.ts","build:types":"tsc -p tsconfig.build.json","build:client-types":"tsc -p tsconfig.browser.json",test:"bun --bun x vitest","test:types":"vitest run --typecheck.only","test:live":"bun --bun x vitest run ai/live","test:packaging":"bun --bun x vitest run --config vitest.packaging.config.ts","build:publish":"bun scripts/build-publish.ts",prepublishOnly:"echo 'Do not publish from this directory \u2014 its exports point at TS source. Run: bun run build:publish, then publish from .publish/' && exit 1","build:augmentation":"bun ./scripts/wire-augmentation.ts"},dependencies:{"@aws-sdk/client-s3":"^3.629.0","@aws-sdk/s3-request-presigner":"^3.629.0","ast-types":"^0.14.2",commander:"^12.1.0",history:"^5.3.0","jsx-email":"2.0.0-rc2.1","magic-string":"^0.30.17",open:"^10.1.0","react-error-boundary":"^6.0.0",recast:"^0.23.9",resend:"^6.12.3",satori:"^0.12.2","temporal-polyfill":"^0.2.5","twitter-api-v2":"^1.20.2","urlpattern-polyfill":"^10.0.0",uuid:"^9.0.1"},devDependencies:{"@babel/parser":"^7.25.4","@prisma/generator-helper":"^6.5.0","@repo/typescript-config":"*","@testing-library/react":"^16.3.2","@types/bun":"^1.3.14","@types/eslint":"^8.56.5","@types/node":"^20.11.24","@types/react":"^19.0.2","@types/react-dom":"^19.0.2",eslint:"^8.57.0",jsdom:"^30.0.1",oxlint:"^1.39.0",postgres:"^3.4.5",react:"19.2.3","react-dom":"19.2.3",typescript:"^5.7.3",vitest:"^4.0.0"},peerDependencies:{"@azure/storage-blob":"^12.28.0",react:">=19","react-dom":">=19",sharp:"^0.34.2",typescript:">=5",vite:"^8.0.0",postgres:"^3.4.0"},peerDependenciesMeta:{"@azure/storage-blob":{optional:!0},typescript:{optional:!0},postgres:{optional:!0}}};var Q=[" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551","\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551"," \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D"],W=Boolean(process.stdout.isTTY)&&!process.env.NO_COLOR,c=(i,n)=>W?`\x1B[${i}m${n}\x1B[0m`:n,X=(i)=>c("1",i),d=(i)=>c("2",i),j=(i)=>c("36",i),Y=(i)=>c("32",i),Z=(i)=>c("35",i);function $(){return v.version??"?"}function f(i){for(let n of Object.values(O()))for(let p of n??[])if((p.family==="IPv4"||p.family===4)&&!p.internal)return`http://${p.address}:${i}`;return null}function H(i){return y(i).filter((n)=>J(n)).map((n)=>N(n))}function T(i){let{port:n,rootDir:p}=i,b=`http://localhost:${n}`,s=f(n),g=H(p),e=(r,t)=>` ${Y("\u279C")} ${X(r.padEnd(9))}${t}`,l=["",...Q.map((r)=>Z(r)),"",` ${d("gemi")} ${j(`v${$()}`)}`,"",e("Local:",j(b)),e("Network:",s?j(s):d("unavailable")),e("Env:",g.length?g.join(", "):d("none")),""];console.log(l.join(`
|
|
3
3
|
`))}function I(i=process.env.SERVER_IDLE_TIMEOUT){if(i===void 0||i.trim()==="")return 10;let n=Number(i.trim());if(!Number.isInteger(n)||n<0||n>255)throw Error(`SERVER_IDLE_TIMEOUT must be a whole number of seconds from 0 to 255 (0 disables the timeout), got ${JSON.stringify(i)}.`);return n}
|
|
4
4
|
export{L as R,_ as S,T,I as U};
|
|
5
5
|
|
|
6
|
-
//# debugId=
|
|
6
|
+
//# debugId=ED3B875D1A3F63F764756E2164756E21
|
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
"/**\n * Bun's default, and what both servers use when `SERVER_IDLE_TIMEOUT` is unset.\n */\nexport const DEFAULT_SERVER_IDLE_TIMEOUT = 10;\n\n/**\n * The `idleTimeout` (seconds) both `gemi dev` and `gemi start` pass to\n * `Bun.serve`, from `SERVER_IDLE_TIMEOUT` (#787).\n *\n * One reader for both servers, so a long-poll that works under `gemi start`\n * also works under `gemi dev`. Before this, only `httpProd` read the variable\n * and the dev server always ran at Bun's 10 seconds.\n *\n * It is the time a connection may stay silent, a response that has not started\n * included, before Bun closes it; `0` disables it. It does not apply to an\n * upgraded websocket (the HMR relay included), which has its own\n * `websocket.idleTimeout`.\n *\n * Unset or blank means the default. Anything that is not a whole number from 0\n * to 255 (Bun's own limits) fails the boot with the variable's name, instead\n * of Bun's \"expects idleTimeout to be an integer\", which does not say where the\n * value came from.\n */\nexport function serverIdleTimeout(raw: string | undefined = process.env.SERVER_IDLE_TIMEOUT): number {\n if (raw === undefined || raw.trim() === \"\") return DEFAULT_SERVER_IDLE_TIMEOUT;\n\n const seconds = Number(raw.trim());\n if (!Number.isInteger(seconds) || seconds < 0 || seconds > 255) {\n throw new Error(\n `SERVER_IDLE_TIMEOUT must be a whole number of seconds from 0 to 255 ` +\n `(0 disables the timeout), got ${JSON.stringify(raw)}.`,\n );\n }\n return seconds;\n}\n"
|
|
8
8
|
],
|
|
9
9
|
"mappings": "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",
|
|
10
|
-
"debugId": "
|
|
10
|
+
"debugId": "ED3B875D1A3F63F764756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{S as q,T as KJ,U as OJ}from"./chunk-dbx3g5ck.js";import{oa as B,sa as L,ta as UJ}from"./chunk-a22h5cby.js";import"./chunk-kk18xqgc.js";import{De as QJ,Ee as A,Vc as a}from"./chunk-hhymaj0m.js";import"./chunk-65beps2q.js";import"./chunk-m53fgf20.js";import{Ef as o,Ff as n,If as i}from"./chunk-4acpw92g.js";import{Jg as HJ}from"./chunk-cca0grq3.js";import"./chunk-m83zm86m.js";import"./chunk-1xdrs2hx.js";import"./chunk-19dpzp4y.js";import"./chunk-yds7zwc3.js";import"./chunk-meg8rtr6.js";import"./chunk-h43jp8ws.js";import"./chunk-s07v65x6.js";import"./chunk-gc2dz11k.js";import"./chunk-cskqet01.js";import"./chunk-fenc5tpv.js";import"./chunk-nz8z8jr1.js";import"./chunk-4fx8p02c.js";import{Ui as e}from"./chunk-er8acmch.js";import"./chunk-2n3pgfnb.js";import{fj as YJ}from"./chunk-d5f1m3d2.js";import{gj as N}from"./chunk-rhvc1axc.js";import"./chunk-tewhms9w.js";import{createHash as X2}from"crypto";import{join as w,resolve as VJ,sep as zJ}from"path";import{Duplex as TJ}from"stream";import{constants as P,createBrotliCompress as RJ,createGzip as bJ}from"zlib";var kJ=["br","gzip"],SJ=1024,wJ=5,vJ=19,EJ=6;function yJ(J){if(J===void 0)return 1;if(!/^\d+(\.\d{0,3})?$/.test(J.trim()))return 1;let $=Number(J.trim());return Number.isFinite($)?Math.min($,1):1}function gJ(J){if(J===null||J===void 0)return null;let $=new Map;for(let Z of J.split(",")){let[X,...Q]=Z.split(";"),H=X.trim().toLowerCase();if(H==="")continue;let j=1;for(let Y of Q){let K=Y.indexOf("=");if(K===-1)continue;if(Y.slice(0,K).trim().toLowerCase()==="q"){j=yJ(Y.slice(K+1));break}}$.set(H,j)}return $}function b(J,$=kJ){let Z=gJ(J);if(!Z)return null;let X=Z.get("*"),Q=null,H=0;for(let j of $){let Y=Z.get(j)??X??0;if(Y>H)Q=j,H=Y}return Q}function fJ(J,$){if(!J)return!1;return J.split(",").some((Z)=>Z.trim().toLowerCase().split("=")[0].trim()===$)}function mJ(J,$){if(J==="HEAD")return!1;if($.status<200||$.status===204||$.status===206||$.status===304)return!1;if($.headers.has("Content-Range"))return!1;let Z=$.headers.get("Content-Type");if(!Z||!/^\s*text\/html\s*(;|$)/i.test(Z))return!1;if(!$.body)return!1;let X=$.headers.get("Content-Encoding");if(X&&X.trim().toLowerCase()!=="identity")return!1;if(fJ($.headers.get("Cache-Control"),"no-transform"))return!1;let Q=$.headers.get("Content-Length");if(Q!==null&&Number(Q)<SJ)return!1;return!0}function uJ(J){let $=J==="br"?RJ({params:{[P.BROTLI_PARAM_QUALITY]:wJ,[P.BROTLI_PARAM_LGWIN]:vJ},flush:P.BROTLI_OPERATION_FLUSH}):bJ({level:EJ,flush:P.Z_SYNC_FLUSH});return TJ.toWeb($)}function hJ(J){let $=J.get("Vary");if(!$){J.set("Vary","Accept-Encoding");return}let Z=$.split(",").map((X)=>X.trim().toLowerCase());if(Z.includes("*")||Z.includes("accept-encoding"))return;J.append("Vary","Accept-Encoding")}function c(J,$){if(!mJ(J.method,$))return $;let Z=new Headers($.headers);hJ(Z);let X=b(J.headers.get("Accept-Encoding"));if(!X)return new Response($.body,{status:$.status,statusText:$.statusText,headers:Z});let Q;try{Q=uJ(X)}catch{return new Response($.body,{status:$.status,statusText:$.statusText,headers:Z})}return Z.set("Content-Encoding",X),Z.delete("Content-Length"),new Response($.body.pipeThrough(Q),{status:$.status,statusText:$.statusText,headers:Z})}import{readdir as iJ,stat as t}from"fs/promises";import{join as aJ}from"path";import{mkdir as O2,readFile as cJ,stat as V2,writeFile as z2}from"fs/promises";import{dirname as L2,join as pJ}from"path";import{promisify as p}from"util";import{brotliCompress as dJ,constants as I2,gzip as lJ}from"zlib";var oJ=".vite/static-assets.json";var d={br:".br",gzip:".gz"},nJ=["br","gzip"],P2=p(dJ),_2=p(lJ);async function l(J){let $;try{$=await cJ(pJ(J,oJ),"utf8")}catch{return null}let Z;try{Z=JSON.parse($)?.files}catch{return null}if(!Z||typeof Z!=="object")return null;let X={files:{}};for(let[Q,H]of Object.entries(Z)){if(!Array.isArray(H))continue;X.files[Q]=nJ.filter((j)=>H.includes(j))}return X}function k(J){let $=J.toString(),Z=new Bun.CryptoHasher("sha1");return Z.update($),Z.digest("hex")}async function r(J){let $=new Set;async function Z(X,Q){let H;try{H=await iJ(X,{withFileTypes:!0})}catch{return}for(let j of H){if(j.name.startsWith("."))continue;if(Q&&j.name==="assets")continue;let Y=aJ(X,j.name),K=j.isDirectory(),V=j.isFile();if(j.isSymbolicLink())try{let F=await t(Y);K=F.isDirectory(),V=F.isFile()}catch{continue}if(V)$.add(Y);else if(K&&!j.isSymbolicLink())await Z(Y,!1)}}return await Z(J,!0),$}var tJ="public, max-age=31536000, must-revalidate",rJ="public, max-age=31536000, immutable";async function sJ(J,$,Z){if(Z.length===0||J.headers.has("Range"))return null;let X=b(J.headers.get("Accept-Encoding"),Z);if(!X)return null;let Q=$+d[X];try{let H=await t(Q);return H.isFile()?{encoding:X,path:Q,size:H.size}:null}catch{return null}}async function s(J,$,Z={}){let X=Bun.file($),Q=Z.encodings??[],H={"Content-Type":X.type||"application/octet-stream","Cache-Control":Z.immutable?rJ:tJ,"Accept-Ranges":"bytes"};if(Q.length>0)H.Vary="Accept-Encoding";let j=await sJ(J,$,Q);if(j){let V=Bun.file(j.path);return new Response(V.stream(),{headers:{...H,"Content-Encoding":j.encoding,"Content-Length":String(j.size),ETag:`${k(V.lastModified)}-${j.encoding}`}})}let Y=X.size;H.ETag=k(X.lastModified);let K=o(J.headers.get("Range"));if(K){let V=n(K,Y);if(!V)return a(Y);return new Response(X.slice(V.start,V.end+1).stream(),{status:206,headers:{...H,"Content-Range":i(V.start,V.end,Y),"Content-Length":String(V.length)}})}return new Response(X.stream(),{headers:{...H,"Content-Length":String(Y)}})}import{stat as Q2}from"fs/promises";var _="app/client.tsx";function JJ(J,$=B){let Z=J[_]?.file;if(!Z)return;return{module:L(Z,$),preload:M(J,_,$)}}function M(J,$,Z=B){let X=[],Q=new Set,H=(j)=>{if(Q.has(j))return;Q.add(j);let Y=J[j];if(!Y?.file)return;X.push(L(Y.file,Z));for(let K of Y.imports??[])H(K)};return H($),X}function $J(J,$){let Z=[],X=new Set,Q=new Set,H=(j)=>{if(Q.has(j))return;Q.add(j);let Y=J[j];if(!Y)return;for(let K of Y.imports??[])H(K);for(let K of Y.css??[])if(!X.has(K))X.add(K),Z.push(K)};return H($),Z}function ZJ(J,$=B){let Z=new Map;return(X)=>{if(!Z.has(X)){let Q=`${X}${e}`,H=J[Q]?.file;Z.set(X,H?{src:L(H,$),preload:M(J,Q,$)}:void 0)}return Z.get(X)}}function XJ(J,$=30000){let Z=JSON.stringify("gemi:chunk-reload"),X=JSON.stringify(`Failed to fetch dynamically imported module: ${J}`);return`var r=!1;try{var s=window.sessionStorage,m=JSON.parse(s.getItem(${Z})||"null");var d=m?Date.now()-m.at:NaN;if(navigator.onLine!==!1&&!(d>=0&&d<${$})){s.setItem(${Z},JSON.stringify({url:window.location.href,at:Date.now()}));r=!0}}catch(e){}if(r)window.location.reload();else throw new Error(${X});export {}`}var eJ=new RegExp(`^${QJ}/.+\\.m?js$`);function J2(J){return eJ.test(J)}function WJ(J){if(J2(J))return new Response(XJ(J),{headers:{"Content-Type":"application/javascript","Cache-Control":"no-store"}});if(A(J))return new Response("Not found",{status:404});return}var $2=`<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Internal Server Error</title>
|
|
8
|
+
<style>
|
|
9
|
+
body { font-family: system-ui, sans-serif; margin: 0; min-height: 100vh; display: grid; place-items: center; }
|
|
10
|
+
main { text-align: center; padding: 16px; }
|
|
11
|
+
h1 { font-size: 1.5rem; margin: 0 0 0.5rem; }
|
|
12
|
+
p { margin: 0; opacity: 0.7; }
|
|
13
|
+
</style>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<main>
|
|
17
|
+
<h1>Something went wrong</h1>
|
|
18
|
+
<p>Please try again later.</p>
|
|
19
|
+
</main>
|
|
20
|
+
</body>
|
|
21
|
+
</html>`;function S(J,$,Z){if(!Z)console.error(J);else try{Z(J instanceof Error?J:Error(String(J),{cause:J}))}catch(X){console.error(J),console.error(X)}if(N($))return new Response(JSON.stringify({error:HJ("server_error","Internal Server Error",500)}),{status:500,headers:{"Content-Type":"application/json"}});return new Response($2,{status:500,headers:{"Content-Type":"text/html; charset=utf-8"}})}var Z2={kind:"none"};function jJ(J){let $=(J??"").trim().toLowerCase();if($===""||$==="false"||$==="off"||$==="0")return Z2;if($==="true")return{kind:"all"};if(/^[1-9]\d*$/.test($))return{kind:"hops",hops:Number($)};throw Error(`GEMI_TRUST_PROXY must be "false", "true" or the number of proxies in front of the app (e.g. 1). Got ${JSON.stringify(J)}.`)}function GJ(J,$,Z){if(Z.kind==="all"){if(!J.get("x-forwarded-for")&&$)J.set("x-forwarded-for",$);return}J.delete("x-real-ip");let X=$;if(Z.kind==="hops"){let Q=(J.get("x-forwarded-for")??"").split(",").map((j)=>j.trim()).filter(Boolean),H=Q.length-Z.hops;X=H>=0?Q[H]:Q[0]??$}if(X)J.set("x-forwarded-for",X);else J.delete("x-forwarded-for")}var D=YJ(),W2=w(D,"app"),x=w(D,"dist"),C=w(x,"client");function H2(J){let $;try{$=decodeURIComponent(J)}catch{return null}let Z=VJ(C,"."+$.replace("/assets/assets","/assets"));return Z.startsWith(C+zJ)?Z:null}async function j2(J){try{return(await Q2(J)).isFile()}catch{return!1}}async function W3(J,$){let Z=await import(`${x}/client/.vite/manifest.json`),X=await import(`${x}/server/.vite/manifest.json`),Q=await UJ(`${x}/client`);process.env.ROOT_DIR=D,process.env.APP_DIR=W2,process.env.DIST_DIR=x;let H={},j={},Y={},K={},V={},F=(W,G)=>`"${W}": () => import("${G}")`,v=[];for(let W of["404",...J.getFlatComponentTree.call(J)]){let G=X[`app/views/${W}.tsx`];if(!G?.file){console.log(`Server file not found for ${W}`),console.log(G);let z=Object.keys(X),I=`app/views/${W}.tsx`;console.log(`${I} not found in server manifest`),console.log(z)}let U=await import(`${process.env.DIST_DIR}/server/${G?.file}`);H[W]=U.default,j[W]=U.OpenGraph,Y[W]=U;let O=Z[`app/views/${W}.tsx`];if(O?.css&&O?.css.length>0)K[W]=O?.css;if(O)v.push(F(W,L(O?.file,Q))),V[W]=M(Z,`app/views/${W}.tsx`,Q)}let xJ=`{${v.join(",")}}`,E=JJ(Z,Q);if(!E)console.error(`Client manifest has no "${_}" entry \u2014 dist/client is incomplete, so documents will render but never hydrate.`);let LJ=Z["app/client.tsx"]?.css??[],y=(await Promise.all(LJ.map((W)=>Bun.file(`${x}/client/${W}`).text()))).join(`
|
|
22
|
+
`),CJ=ZJ(Z,Q),FJ=X2("sha256").update(await Bun.file(`${x}/client/.vite/manifest.json`).text()).digest("base64url").slice(0,12),g=new Map,IJ=(W)=>{let G=g.get(W);if(!G)G=Bun.file(`${x}/client/${W}`).text(),g.set(W,G);return G},PJ=async(W,G)=>{let U=new Set;for(let z of G?[G,...W]:W)for(let I of $J(Z,`app/views/${z}.tsx`))U.add(I);let O=await Promise.all([...U].map(async(z)=>({id:z,content:await IJ(z)})));return q(G?O:[{content:y},...O])},_J=await r(C),f=new Map;for(let[W,G]of Object.entries((await l(C))?.files??{})){let U=VJ(C,W);if(U.startsWith(C+zJ))f.set(U,{immutable:!0,encodings:G})}async function BJ(W){let{pathname:G}=new URL(W.url);if(N(G))return await T(W,G);let U=H2(G);if(A(G)||G.startsWith("/.well-known")||U!==null&&_J.has(U)){if(!U||!await j2(U))return WJ(G)??await T(W,G);try{return await s(W,U,f.get(U))}catch(z){return J.onException?.(z),new Response("Not found",{status:404})}}return await T(W,G)}async function T(W,G){let U=J.fetch.bind(J);try{let O=await U(W);if(O instanceof Response)return O;else{let z=[];return z.push({content:y}),await O({getStyles:async(R,u)=>{if(!R)return q([]);if(u?.static)return PJ(R,u.layout);for(let NJ of R){let qJ=Z[`app/views/${NJ}.tsx`];for(let h of qJ?.css??[]){let DJ=Bun.file(`${process.env.DIST_DIR}/client/${h}`);z.push({id:h,content:await DJ.text()})}}return q(z)},clientEntry:E,modulePreloadManifest:V,loaders:xJ,viewImportMap:H,viewModules:Y,ogMap:j,cssManifest:K,assetBase:Q,resolveIsland:CJ,buildId:FJ})}}catch(O){return S(O,G,J.onException)}}let MJ=(process.env.GEMI_COMPRESSION??"auto").toLowerCase()!=="off",AJ=jJ(process.env.GEMI_TRUST_PROXY),m=Bun.serve({maxRequestBodySize:10737418240,fetch:async(W,G)=>{GJ(W.headers,G.requestIP(W)?.address??null,AJ);let U=await $(W,(O)=>J.withGlobalMiddleware(O,BJ,(z)=>S(z,new URL(O.url).pathname,J.onException)));return MJ?c(W,U):U},idleTimeout:OJ(),port:process.env.PORT||5173});return KJ({port:m.port,rootDir:D}),m}export{W3 as httpProd};
|
|
23
|
+
|
|
24
|
+
//# debugId=ADE18CB5D0F98F4264756E2164756E21
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../server/httpProd.ts", "../server/compression.ts", "../server/staticFile.ts", "../vite/precompressAssets.ts", "../server/generateEtag.ts", "../server/modulePreloads.ts", "../client/chunkLoadRecovery.ts", "../server/staticAssetMiss.ts", "../server/unhandledError.ts", "../server/forwardedFor.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { join, resolve, sep } from \"node:path\";\nimport { compressResponse } from \"./compression\";\nimport { listPublicFiles, staticFileResponse } from \"./staticFile\";\nimport { stat } from \"node:fs/promises\";\nimport { createStyles } from \"./styles\";\nimport {\n CLIENT_ENTRY_KEY,\n collectCss,\n collectModulePreloads,\n createClientEntry,\n createIslandResolver,\n} from \"./modulePreloads\";\nimport type { App } from \"../app\";\nimport { Instrumentation } from \"./types\";\nimport { printStartupBanner } from \"./banner\";\nimport { isReservedAssetPath, staticAssetMiss } from \"./staticAssetMiss\";\nimport { assetUrl, readBuiltAssetBase } from \"../config/assetBase\";\nimport { isApiPath } from \"../services/router/apiPath\";\nimport { projectRoot } from \"../support/discover\";\nimport { unhandledErrorResponse } from \"./unhandledError\";\nimport { serverIdleTimeout } from \"./idleTimeout\";\nimport { applyForwardedTrust, parseTrustProxy } from \"./forwardedFor\";\nimport { readStaticAssetsRecord } from \"../vite/precompressAssets\";\nimport type { StaticFileOptions } from \"./staticFile\";\n\n// The rule this file used to spell out itself. It moved to `projectRoot`\n// because discovery needs the same answer during `waitForBoot()`, which is\n// before `ROOT_DIR` below exists — and two spellings of \"where is the project\"\n// is how a job gets looked for in one directory and served from another.\nconst rootDir = projectRoot();\n\nconst appDir = join(rootDir, \"app\");\nconst distDir = join(rootDir, \"dist\");\n\nconst clientDir = join(distDir, \"client\");\n\n// The file in `dist/client` a static-looking pathname names, or `null` when\n// it names nothing there. The pathname is still percent-encoded, and Vite\n// writes files whose names need encoding (a public `my font.woff2`), so it is\n// decoded first. Decoding also turns `%2F` into a separator, which the URL\n// parser's own `..` normalization never saw — so the resolved path is checked\n// to still be inside `dist/client`. A malformed escape is a miss, not a 500.\nfunction clientFilePath(pathname: string): string | null {\n let decoded: string;\n try {\n decoded = decodeURIComponent(pathname);\n } catch {\n return null;\n }\n const path = resolve(clientDir, \".\" + decoded.replace(\"/assets/assets\", \"/assets\"));\n return path.startsWith(clientDir + sep) ? path : null;\n}\n\nasync function isFile(path: string) {\n try {\n return (await stat(path)).isFile();\n } catch {\n return false;\n }\n}\n\n// `app` is built by `Server.start` (from the kernel) and passed in — same as\n// `httpDev` — so prod and dev share one construction path. What differs here is\n// that views/styles are served from the built `dist/` manifests instead of\n// Vite's dev SSR graph.\nexport async function httpProd(app: App, instrumentation: Instrumentation) {\n const manifest = await import(`${distDir}/client/.vite/manifest.json`);\n const serverManifest = await import(`${distDir}/server/.vite/manifest.json`);\n // What the client build was built with, not `GEMI_ASSET_BASE` as it reads\n // now — see `readBuiltAssetBase`. Every URL below that names a chunk goes\n // through it, so the document links exactly what the bundle imports.\n const assetBase = await readBuiltAssetBase(`${distDir}/client`);\n\n process.env.ROOT_DIR = rootDir;\n process.env.APP_DIR = appDir;\n process.env.DIST_DIR = distDir;\n\n const viewImportMap = {};\n const ogMap = {};\n const viewModules = {};\n const cssManifest = {};\n // Which chunks a route's views pull in, so the shell can preload the chain\n // the client would otherwise discover one round trip at a time (#352).\n const modulePreloadManifest: Record<string, string[]> = {};\n const template = (viewName: string, path: string) => `\"${viewName}\": () => import(\"${path}\")`;\n const templates = [];\n\n for (const fileName of [\"404\", ...app.getFlatComponentTree.call(app)]) {\n const serverFile = serverManifest[`app/views/${fileName}.tsx`];\n if (!serverFile?.file) {\n console.log(`Server file not found for ${fileName}`);\n console.log(serverFile);\n const files = Object.keys(serverManifest);\n const path = `app/views/${fileName}.tsx`;\n console.log(`${path} not found in server manifest`);\n console.log(files);\n }\n const mod = await import(`${process.env.DIST_DIR}/server/${serverFile?.file}`);\n viewImportMap[fileName] = mod.default;\n ogMap[fileName] = mod.OpenGraph;\n // The whole module, so a streaming render can put the view's\n // `Loading`/`Error` exports into the shell it sends.\n viewModules[fileName] = mod;\n const clientFile = manifest[`app/views/${fileName}.tsx`];\n\n if (clientFile?.css && clientFile?.css.length > 0) {\n cssManifest[fileName] = clientFile?.css;\n }\n if (clientFile) {\n templates.push(template(fileName, assetUrl(clientFile?.file, assetBase)));\n modulePreloadManifest[fileName] = collectModulePreloads(\n manifest,\n `app/views/${fileName}.tsx`,\n assetBase,\n );\n }\n }\n\n const loaders = `{${templates.join(\",\")}}`;\n\n // Booted from the bootstrap script rather than through React's\n // `bootstrapModules`, which would preload it at `fetchPriority=\"low\"` — see\n // `clientEntry` in `ViewRouteDispatcher`.\n const clientEntry = createClientEntry(manifest, assetBase);\n if (!clientEntry) {\n // Loudly, but without dying: this is boot, and an incomplete `dist/` must\n // not cost the API routes and static assets too.\n console.error(\n `Client manifest has no \"${CLIENT_ENTRY_KEY}\" entry — dist/client is incomplete, so documents will render but never hydrate.`,\n );\n }\n\n // Vite's manifest `css` field is a `string[]` — a client entry can emit more\n // than one CSS chunk. Read and concatenate them all instead of interpolating\n // the array into a single path (which only works for a one-element array).\n const appCssFiles: string[] = manifest[\"app/client.tsx\"]?.css ?? [];\n const appCSSContent = (\n await Promise.all(appCssFiles.map((cssFile) => Bun.file(`${distDir}/client/${cssFile}`).text()))\n ).join(\"\\n\");\n\n // The island entries (`<module>?gemi-island`) a static view's document\n // loads; see `injectIslands`.\n const resolveIsland = createIslandResolver(manifest, assetBase);\n\n // A static view's CSS comes from the whole import closure of its views (and\n // its own layout's, which then replaces the app stylesheet): there is no\n // client to fetch a shared chunk's CSS later, as a hydrated page's chunk\n // loader does. Read once per file: the build does not change under a\n // running server.\n const cssFileCache = new Map<string, Promise<string>>();\n const readCss = (file: string) => {\n let text = cssFileCache.get(file);\n if (!text) {\n text = Bun.file(`${distDir}/client/${file}`).text();\n cssFileCache.set(file, text);\n }\n return text;\n };\n const staticStyles = async (views: string[], layout: string | undefined) => {\n const files = new Set<string>();\n for (const view of layout ? [layout, ...views] : views) {\n for (const file of collectCss(manifest, `app/views/${view}.tsx`)) files.add(file);\n }\n const styles = await Promise.all(\n [...files].map(async (file) => ({ id: file, content: await readCss(file) })),\n );\n return createStyles(layout ? styles : [{ content: appCSSContent }, ...styles]);\n };\n\n // Which requests are answered from `dist/client` rather than the app:\n //\n // - `/assets` and everything under it, whatever the extension. Vite writes\n // fonts, GIFs, video and `?url` JSON there too, and an allowlist of\n // extensions always trailed the build — a `.woff2` went to the router\n // and paid for an SSR attempt. The router refuses routes under `/assets`\n // at boot, so there is no app answer to lose, and `staticAssetMiss`\n // turns a miss into the reload stub or a 404.\n // - `/.well-known/*`.\n // - Any other path that names a file the build copied out of `public/`,\n // whatever its extension (#583). Any other path may be an app route, so\n // it is static only when that exact file exists — read once here, since\n // the build output does not change under a running server. A view at\n // `/manifest` keeps its data URL (`/manifest.json`) unless the app also\n // ships `public/manifest.json`, and then the file wins. View data is\n // never a file in `dist/client`, so a client-side navigation pays for no\n // filesystem lookup.\n const publicFiles = await listPublicFiles(clientDir);\n\n // The build assets `gemi build` emitted or carried over, with the\n // precompressed siblings it wrote for each (#789). Read once: the build\n // output does not change under a running server. Without the record (a\n // build made before it existed) every file is served as identity with the\n // old cache policy.\n const staticAssets = new Map<string, StaticFileOptions>();\n for (const [file, encodings] of Object.entries(\n (await readStaticAssetsRecord(clientDir))?.files ?? {},\n )) {\n const path = resolve(clientDir, file);\n if (path.startsWith(clientDir + sep)) {\n staticAssets.set(path, { immutable: true, encodings });\n }\n }\n\n async function requestHandler(req: Request) {\n const { pathname } = new URL(req.url);\n\n if (isApiPath(pathname)) {\n return await handleWithApp(req, pathname);\n }\n\n const distPath = clientFilePath(pathname);\n const isFileRequest =\n isReservedAssetPath(pathname) ||\n pathname.startsWith(\"/.well-known\") ||\n (distPath !== null && publicFiles.has(distPath));\n\n if (isFileRequest) {\n // Served from here whatever the asset base is: a CDN in front of the\n // app uses this origin as the source it fills from. A file, not merely\n // a path that exists: `/assets` itself is `dist/client/assets`, a\n // directory, and streaming one would answer 200 and then fail mid-body.\n //\n // `Bun.file(path).stream()` is lazy — a missing file only throws ENOENT\n // once the body is streamed, which is *after* this handler has returned,\n // with the response already committed as 200. So existence is checked\n // here, per request, even for a path `publicFiles` lists.\n if (!distPath || !(await isFile(distPath))) {\n return staticAssetMiss(pathname) ?? (await handleWithApp(req, pathname));\n }\n\n try {\n return await staticFileResponse(req, distPath, staticAssets.get(distPath));\n } catch (error) {\n app.onException?.(error);\n return new Response(\"Not found\", { status: 404 });\n }\n }\n\n return await handleWithApp(req, pathname);\n }\n\n async function handleWithApp(req: Request, pathname: string) {\n const handler = app.fetch.bind(app);\n\n try {\n const result = await handler(req);\n if (result instanceof Response) {\n return result;\n } else {\n const styles = [];\n\n styles.push({\n content: appCSSContent,\n });\n\n const getStyles = async (\n currentViews: string[],\n options?: { static?: boolean; layout?: string },\n ) => {\n if (!currentViews) {\n return createStyles([]);\n }\n if (options?.static) {\n return staticStyles(currentViews, options.layout);\n }\n for (const view of currentViews) {\n const clientFile = manifest[`app/views/${view}.tsx`];\n for (const cssFile of clientFile?.css ?? []) {\n const css = Bun.file(`${process.env.DIST_DIR}/client/${cssFile}`);\n styles.push({\n id: cssFile,\n content: await css.text(),\n });\n }\n }\n return createStyles(styles);\n };\n\n return await result({\n getStyles,\n clientEntry,\n modulePreloadManifest,\n loaders,\n viewImportMap,\n viewModules,\n ogMap,\n cssManifest,\n assetBase,\n resolveIsland,\n });\n }\n } catch (err) {\n return unhandledErrorResponse(err, pathname, app.onException);\n }\n }\n\n // Compression is on unless the deployment opts out — set `GEMI_COMPRESSION=off`\n // when a layer in front of the origin already compresses HTML and you would\n // rather not spend origin CPU on it.\n const compressionEnabled = (process.env.GEMI_COMPRESSION ?? \"auto\").toLowerCase() !== \"off\";\n\n // Which `X-Forwarded-For` entries to believe — see `forwardedFor.ts`. Parsed\n // before `Bun.serve` so a bad value fails the boot, not every request.\n const forwardedTrust = parseTrustProxy(process.env.GEMI_TRUST_PROXY);\n\n const server = Bun.serve({\n maxRequestBodySize: 10 * 1024 * 1024 * 1024, // 10 GB\n fetch: async (req, server) => {\n // `requestIP` is null for closed/unix sockets — guard so it never\n // throws before the request is handled.\n applyForwardedTrust(req.headers, server.requestIP(req)?.address ?? null, forwardedTrust);\n // The app's global middleware goes in front of the static handler as well\n // as the router, so it can refuse `/assets/*` too.\n const res = await instrumentation(req, (req) =>\n app.withGlobalMiddleware(req, requestHandler, (err) =>\n unhandledErrorResponse(err, new URL(req.url).pathname, app.onException),\n ),\n );\n // Applied at the very edge, after instrumentation, so every HTML response\n // goes through the same negotiation — including the ones an app's\n // instrumentation produced itself. Anything that isn't HTML comes back\n // untouched.\n return compressionEnabled ? compressResponse(req, res) : res;\n },\n idleTimeout: serverIdleTimeout(),\n port: process.env.PORT || 5173,\n });\n\n printStartupBanner({ port: server.port, rootDir });\n\n return server;\n}\n",
|
|
5
|
+
"import { createHash } from \"node:crypto\";\nimport { join, resolve, sep } from \"node:path\";\nimport { compressResponse } from \"./compression\";\nimport { listPublicFiles, staticFileResponse } from \"./staticFile\";\nimport { stat } from \"node:fs/promises\";\nimport { createStyles } from \"./styles\";\nimport {\n CLIENT_ENTRY_KEY,\n collectCss,\n collectModulePreloads,\n createClientEntry,\n createIslandResolver,\n} from \"./modulePreloads\";\nimport type { App } from \"../app\";\nimport { Instrumentation } from \"./types\";\nimport { printStartupBanner } from \"./banner\";\nimport { isReservedAssetPath, staticAssetMiss } from \"./staticAssetMiss\";\nimport { assetUrl, readBuiltAssetBase } from \"../config/assetBase\";\nimport { isApiPath } from \"../services/router/apiPath\";\nimport { projectRoot } from \"../support/discover\";\nimport { unhandledErrorResponse } from \"./unhandledError\";\nimport { serverIdleTimeout } from \"./idleTimeout\";\nimport { applyForwardedTrust, parseTrustProxy } from \"./forwardedFor\";\nimport { readStaticAssetsRecord } from \"../vite/precompressAssets\";\nimport type { StaticFileOptions } from \"./staticFile\";\n\n// The rule this file used to spell out itself. It moved to `projectRoot`\n// because discovery needs the same answer during `waitForBoot()`, which is\n// before `ROOT_DIR` below exists — and two spellings of \"where is the project\"\n// is how a job gets looked for in one directory and served from another.\nconst rootDir = projectRoot();\n\nconst appDir = join(rootDir, \"app\");\nconst distDir = join(rootDir, \"dist\");\n\nconst clientDir = join(distDir, \"client\");\n\n// The file in `dist/client` a static-looking pathname names, or `null` when\n// it names nothing there. The pathname is still percent-encoded, and Vite\n// writes files whose names need encoding (a public `my font.woff2`), so it is\n// decoded first. Decoding also turns `%2F` into a separator, which the URL\n// parser's own `..` normalization never saw — so the resolved path is checked\n// to still be inside `dist/client`. A malformed escape is a miss, not a 500.\nfunction clientFilePath(pathname: string): string | null {\n let decoded: string;\n try {\n decoded = decodeURIComponent(pathname);\n } catch {\n return null;\n }\n const path = resolve(clientDir, \".\" + decoded.replace(\"/assets/assets\", \"/assets\"));\n return path.startsWith(clientDir + sep) ? path : null;\n}\n\nasync function isFile(path: string) {\n try {\n return (await stat(path)).isFile();\n } catch {\n return false;\n }\n}\n\n// `app` is built by `Server.start` (from the kernel) and passed in — same as\n// `httpDev` — so prod and dev share one construction path. What differs here is\n// that views/styles are served from the built `dist/` manifests instead of\n// Vite's dev SSR graph.\nexport async function httpProd(app: App, instrumentation: Instrumentation) {\n const manifest = await import(`${distDir}/client/.vite/manifest.json`);\n const serverManifest = await import(`${distDir}/server/.vite/manifest.json`);\n // What the client build was built with, not `GEMI_ASSET_BASE` as it reads\n // now — see `readBuiltAssetBase`. Every URL below that names a chunk goes\n // through it, so the document links exactly what the bundle imports.\n const assetBase = await readBuiltAssetBase(`${distDir}/client`);\n\n process.env.ROOT_DIR = rootDir;\n process.env.APP_DIR = appDir;\n process.env.DIST_DIR = distDir;\n\n const viewImportMap = {};\n const ogMap = {};\n const viewModules = {};\n const cssManifest = {};\n // Which chunks a route's views pull in, so the shell can preload the chain\n // the client would otherwise discover one round trip at a time (#352).\n const modulePreloadManifest: Record<string, string[]> = {};\n const template = (viewName: string, path: string) => `\"${viewName}\": () => import(\"${path}\")`;\n const templates = [];\n\n for (const fileName of [\"404\", ...app.getFlatComponentTree.call(app)]) {\n const serverFile = serverManifest[`app/views/${fileName}.tsx`];\n if (!serverFile?.file) {\n console.log(`Server file not found for ${fileName}`);\n console.log(serverFile);\n const files = Object.keys(serverManifest);\n const path = `app/views/${fileName}.tsx`;\n console.log(`${path} not found in server manifest`);\n console.log(files);\n }\n const mod = await import(`${process.env.DIST_DIR}/server/${serverFile?.file}`);\n viewImportMap[fileName] = mod.default;\n ogMap[fileName] = mod.OpenGraph;\n // The whole module, so a streaming render can put the view's\n // `Loading`/`Error` exports into the shell it sends.\n viewModules[fileName] = mod;\n const clientFile = manifest[`app/views/${fileName}.tsx`];\n\n if (clientFile?.css && clientFile?.css.length > 0) {\n cssManifest[fileName] = clientFile?.css;\n }\n if (clientFile) {\n templates.push(template(fileName, assetUrl(clientFile?.file, assetBase)));\n modulePreloadManifest[fileName] = collectModulePreloads(\n manifest,\n `app/views/${fileName}.tsx`,\n assetBase,\n );\n }\n }\n\n const loaders = `{${templates.join(\",\")}}`;\n\n // Booted from the bootstrap script rather than through React's\n // `bootstrapModules`, which would preload it at `fetchPriority=\"low\"` — see\n // `clientEntry` in `ViewRouteDispatcher`.\n const clientEntry = createClientEntry(manifest, assetBase);\n if (!clientEntry) {\n // Loudly, but without dying: this is boot, and an incomplete `dist/` must\n // not cost the API routes and static assets too.\n console.error(\n `Client manifest has no \"${CLIENT_ENTRY_KEY}\" entry — dist/client is incomplete, so documents will render but never hydrate.`,\n );\n }\n\n // Vite's manifest `css` field is a `string[]` — a client entry can emit more\n // than one CSS chunk. Read and concatenate them all instead of interpolating\n // the array into a single path (which only works for a one-element array).\n const appCssFiles: string[] = manifest[\"app/client.tsx\"]?.css ?? [];\n const appCSSContent = (\n await Promise.all(appCssFiles.map((cssFile) => Bun.file(`${distDir}/client/${cssFile}`).text()))\n ).join(\"\\n\");\n\n // The island entries (`<module>?gemi-island`) a static view's document\n // loads; see `injectIslands`.\n const resolveIsland = createIslandResolver(manifest, assetBase);\n\n // Identifies this client build: a static page with `navigation` swaps in\n // only pages of the same build. The manifest names every content-hashed\n // file, so it changes whenever any of them does.\n const buildId = createHash(\"sha256\")\n .update(await Bun.file(`${distDir}/client/.vite/manifest.json`).text())\n .digest(\"base64url\")\n .slice(0, 12);\n\n // A static view's CSS comes from the whole import closure of its views (and\n // its own layout's, which then replaces the app stylesheet): there is no\n // client to fetch a shared chunk's CSS later, as a hydrated page's chunk\n // loader does. Read once per file: the build does not change under a\n // running server.\n const cssFileCache = new Map<string, Promise<string>>();\n const readCss = (file: string) => {\n let text = cssFileCache.get(file);\n if (!text) {\n text = Bun.file(`${distDir}/client/${file}`).text();\n cssFileCache.set(file, text);\n }\n return text;\n };\n const staticStyles = async (views: string[], layout: string | undefined) => {\n const files = new Set<string>();\n for (const view of layout ? [layout, ...views] : views) {\n for (const file of collectCss(manifest, `app/views/${view}.tsx`)) files.add(file);\n }\n const styles = await Promise.all(\n [...files].map(async (file) => ({ id: file, content: await readCss(file) })),\n );\n return createStyles(layout ? styles : [{ content: appCSSContent }, ...styles]);\n };\n\n // Which requests are answered from `dist/client` rather than the app:\n //\n // - `/assets` and everything under it, whatever the extension. Vite writes\n // fonts, GIFs, video and `?url` JSON there too, and an allowlist of\n // extensions always trailed the build — a `.woff2` went to the router\n // and paid for an SSR attempt. The router refuses routes under `/assets`\n // at boot, so there is no app answer to lose, and `staticAssetMiss`\n // turns a miss into the reload stub or a 404.\n // - `/.well-known/*`.\n // - Any other path that names a file the build copied out of `public/`,\n // whatever its extension (#583). Any other path may be an app route, so\n // it is static only when that exact file exists — read once here, since\n // the build output does not change under a running server. A view at\n // `/manifest` keeps its data URL (`/manifest.json`) unless the app also\n // ships `public/manifest.json`, and then the file wins. View data is\n // never a file in `dist/client`, so a client-side navigation pays for no\n // filesystem lookup.\n const publicFiles = await listPublicFiles(clientDir);\n\n // The build assets `gemi build` emitted or carried over, with the\n // precompressed siblings it wrote for each (#789). Read once: the build\n // output does not change under a running server. Without the record (a\n // build made before it existed) every file is served as identity with the\n // old cache policy.\n const staticAssets = new Map<string, StaticFileOptions>();\n for (const [file, encodings] of Object.entries(\n (await readStaticAssetsRecord(clientDir))?.files ?? {},\n )) {\n const path = resolve(clientDir, file);\n if (path.startsWith(clientDir + sep)) {\n staticAssets.set(path, { immutable: true, encodings });\n }\n }\n\n async function requestHandler(req: Request) {\n const { pathname } = new URL(req.url);\n\n if (isApiPath(pathname)) {\n return await handleWithApp(req, pathname);\n }\n\n const distPath = clientFilePath(pathname);\n const isFileRequest =\n isReservedAssetPath(pathname) ||\n pathname.startsWith(\"/.well-known\") ||\n (distPath !== null && publicFiles.has(distPath));\n\n if (isFileRequest) {\n // Served from here whatever the asset base is: a CDN in front of the\n // app uses this origin as the source it fills from. A file, not merely\n // a path that exists: `/assets` itself is `dist/client/assets`, a\n // directory, and streaming one would answer 200 and then fail mid-body.\n //\n // `Bun.file(path).stream()` is lazy — a missing file only throws ENOENT\n // once the body is streamed, which is *after* this handler has returned,\n // with the response already committed as 200. So existence is checked\n // here, per request, even for a path `publicFiles` lists.\n if (!distPath || !(await isFile(distPath))) {\n return staticAssetMiss(pathname) ?? (await handleWithApp(req, pathname));\n }\n\n try {\n return await staticFileResponse(req, distPath, staticAssets.get(distPath));\n } catch (error) {\n app.onException?.(error);\n return new Response(\"Not found\", { status: 404 });\n }\n }\n\n return await handleWithApp(req, pathname);\n }\n\n async function handleWithApp(req: Request, pathname: string) {\n const handler = app.fetch.bind(app);\n\n try {\n const result = await handler(req);\n if (result instanceof Response) {\n return result;\n } else {\n const styles = [];\n\n styles.push({\n content: appCSSContent,\n });\n\n const getStyles = async (\n currentViews: string[],\n options?: { static?: boolean; layout?: string },\n ) => {\n if (!currentViews) {\n return createStyles([]);\n }\n if (options?.static) {\n return staticStyles(currentViews, options.layout);\n }\n for (const view of currentViews) {\n const clientFile = manifest[`app/views/${view}.tsx`];\n for (const cssFile of clientFile?.css ?? []) {\n const css = Bun.file(`${process.env.DIST_DIR}/client/${cssFile}`);\n styles.push({\n id: cssFile,\n content: await css.text(),\n });\n }\n }\n return createStyles(styles);\n };\n\n return await result({\n getStyles,\n clientEntry,\n modulePreloadManifest,\n loaders,\n viewImportMap,\n viewModules,\n ogMap,\n cssManifest,\n assetBase,\n resolveIsland,\n buildId,\n });\n }\n } catch (err) {\n return unhandledErrorResponse(err, pathname, app.onException);\n }\n }\n\n // Compression is on unless the deployment opts out — set `GEMI_COMPRESSION=off`\n // when a layer in front of the origin already compresses HTML and you would\n // rather not spend origin CPU on it.\n const compressionEnabled = (process.env.GEMI_COMPRESSION ?? \"auto\").toLowerCase() !== \"off\";\n\n // Which `X-Forwarded-For` entries to believe — see `forwardedFor.ts`. Parsed\n // before `Bun.serve` so a bad value fails the boot, not every request.\n const forwardedTrust = parseTrustProxy(process.env.GEMI_TRUST_PROXY);\n\n const server = Bun.serve({\n maxRequestBodySize: 10 * 1024 * 1024 * 1024, // 10 GB\n fetch: async (req, server) => {\n // `requestIP` is null for closed/unix sockets — guard so it never\n // throws before the request is handled.\n applyForwardedTrust(req.headers, server.requestIP(req)?.address ?? null, forwardedTrust);\n // The app's global middleware goes in front of the static handler as well\n // as the router, so it can refuse `/assets/*` too.\n const res = await instrumentation(req, (req) =>\n app.withGlobalMiddleware(req, requestHandler, (err) =>\n unhandledErrorResponse(err, new URL(req.url).pathname, app.onException),\n ),\n );\n // Applied at the very edge, after instrumentation, so every HTML response\n // goes through the same negotiation — including the ones an app's\n // instrumentation produced itself. Anything that isn't HTML comes back\n // untouched.\n return compressionEnabled ? compressResponse(req, res) : res;\n },\n idleTimeout: serverIdleTimeout(),\n port: process.env.PORT || 5173,\n });\n\n printStartupBanner({ port: server.port, rootDir });\n\n return server;\n}\n",
|
|
6
6
|
"/**\n * Transport-level compression for SSR HTML responses.\n *\n * This lives in the runtime rather than in an app, because every gemi app\n * serves the same shape of response: a streamed `text/html` document whose\n * bulk is critical CSS, markup and the `window.__GEMI_DATA__` hydration\n * payload. Compressing it here means the win is portable across deployments —\n * it does not depend on a CDN being configured to compress on the origin's\n * behalf — and it also cuts origin→edge bandwidth, which edge compression\n * cannot.\n *\n * Compression stays strictly at the transport layer: what the client decodes\n * is byte-for-byte the HTML React rendered, so hydration is unaffected.\n *\n * Deliberately dependency-free apart from `node:zlib`/`node:stream` so it can\n * be unit tested without booting a server.\n */\n\nimport { Duplex } from \"node:stream\";\nimport { constants, createBrotliCompress, createGzip } from \"node:zlib\";\n\n/** The content codings we can produce, in the order we prefer them. */\nexport type ContentEncoding = \"br\" | \"gzip\";\n\n/**\n * Server preference, used to break q-value ties. Brotli comes first: at the\n * quality we use it is both smaller *and* no more expensive than gzip on a\n * representative SSR document (~177 kB → 28.0 kB in ~2.0 ms, versus 31.6 kB in\n * ~2.0 ms for gzip).\n */\nconst SERVER_PREFERENCE: ContentEncoding[] = [\"br\", \"gzip\"];\n\n/**\n * Below this, an encoded body plus its framing overhead is not worth the CPU.\n * Only applied when the response declares a `Content-Length` — a streamed SSR\n * response does not, and buffering one just to measure it would defeat the\n * streaming render.\n */\nconst MIN_COMPRESSIBLE_BYTES = 1024;\n\n/**\n * Brotli quality 5 (of 11). The default, 11, is meant for static assets\n * compressed once at build time — on a streamed document it costs ~175 ms,\n * two orders of magnitude more than quality 5 for ~12% more savings. Quality 5\n * is the usual choice for dynamic content.\n *\n * `LGWIN` 19 caps the window at 512 kB rather than the default 16 MB. An SSR\n * document is far smaller than that, so the ratio is unchanged, and the bound\n * matters under concurrency: the window is allocated per in-flight response.\n */\nconst BROTLI_QUALITY = 5;\nconst BROTLI_WINDOW_BITS = 19;\n\n/** zlib's default level. Level 9 costs measurably more for ~1% on HTML. */\nconst GZIP_LEVEL = 6;\n\nfunction parseQValue(raw: string | undefined): number {\n if (raw === undefined) {\n return 1;\n }\n // `q` is a fixed-point number with at most three decimals (RFC 9110 §12.4.2).\n // Anything else is malformed; treat it as an unqualified \"acceptable\" rather\n // than dropping the encoding, matching what tolerant servers do.\n if (!/^\\d+(\\.\\d{0,3})?$/.test(raw.trim())) {\n return 1;\n }\n const value = Number(raw.trim());\n return Number.isFinite(value) ? Math.min(value, 1) : 1;\n}\n\n/**\n * Parses a request `Accept-Encoding` into `coding -> qvalue`.\n *\n * Returns `null` when the header is *absent*, which is distinct from an empty\n * one. RFC 9110 §12.5.3 says an absent header means any coding is acceptable,\n * but a client that cannot decode and forgets to say so is a broken page, not\n * a slow one — so we treat \"absent\" as \"identity\" and only encode when a\n * client has explicitly opted in. An empty header (`Accept-Encoding:`) is a\n * deliberate \"identity only\" and parses to an empty map.\n */\nexport function parseAcceptEncoding(header: string | null | undefined): Map<string, number> | null {\n if (header === null || header === undefined) {\n return null;\n }\n\n const accepted = new Map<string, number>();\n for (const part of header.split(\",\")) {\n const [rawCoding, ...params] = part.split(\";\");\n const coding = rawCoding.trim().toLowerCase();\n if (coding === \"\") {\n continue;\n }\n\n let q = 1;\n for (const param of params) {\n const separator = param.indexOf(\"=\");\n if (separator === -1) {\n continue;\n }\n if (param.slice(0, separator).trim().toLowerCase() === \"q\") {\n q = parseQValue(param.slice(separator + 1));\n break;\n }\n }\n\n accepted.set(coding, q);\n }\n\n return accepted;\n}\n\n/**\n * Picks the coding to use, or `null` for identity.\n *\n * A `q=0` is a refusal, `*` covers codings the client did not name, and ties\n * fall back to `available`'s order — so a plain `Accept-Encoding: gzip, br`\n * (equal q of 1) resolves to our preference rather than the client's.\n */\nexport function negotiateEncoding(\n header: string | null | undefined,\n available: ContentEncoding[] = SERVER_PREFERENCE,\n): ContentEncoding | null {\n const accepted = parseAcceptEncoding(header);\n if (!accepted) {\n return null;\n }\n\n const wildcard = accepted.get(\"*\");\n let best: ContentEncoding | null = null;\n let bestQ = 0;\n\n for (const coding of available) {\n const q = accepted.get(coding) ?? wildcard ?? 0;\n if (q > bestQ) {\n best = coding;\n bestQ = q;\n }\n }\n\n return best;\n}\n\nfunction hasDirective(headerValue: string | null, directive: string): boolean {\n if (!headerValue) {\n return false;\n }\n // Token match, not substring: `no-transform` must not be found inside\n // something like `x-no-transform`.\n return headerValue\n .split(\",\")\n .some((token) => token.trim().toLowerCase().split(\"=\")[0].trim() === directive);\n}\n\n/**\n * Whether this response's representation is one we may encode — and therefore\n * one that varies by `Accept-Encoding`, even on the requests where we end up\n * sending identity.\n *\n * HTML only, on purpose. JSON view-data and API responses are left alone so\n * that this change cannot alter how they are produced, framed or cached;\n * widening the set is a separate decision.\n */\nexport function isCompressible(method: string, res: Response): boolean {\n // A HEAD response carries no body to encode, and emitting `Content-Encoding`\n // without one would describe a body the client never receives.\n if (method === \"HEAD\") {\n return false;\n }\n\n // 204/304 are bodyless; 206 is a byte range of an already-committed\n // representation and re-encoding it would invalidate its `Content-Range`.\n if (res.status < 200 || res.status === 204 || res.status === 206 || res.status === 304) {\n return false;\n }\n\n if (res.headers.has(\"Content-Range\")) {\n return false;\n }\n\n const contentType = res.headers.get(\"Content-Type\");\n if (!contentType || !/^\\s*text\\/html\\s*(;|$)/i.test(contentType)) {\n return false;\n }\n\n // Only once the status and headers have ruled a range out: on Bun 1.3.14 on\n // Linux, reading `.body` of a Response built on a sliced Blob makes it send\n // past the slice's end (#725), so `.body` is never touched on a non-HTML\n // response this function hands back untouched.\n if (!res.body) {\n return false;\n }\n\n // Already encoded upstream — `identity` is the one value that means \"not\n // encoded\" and is safe to replace.\n const contentEncoding = res.headers.get(\"Content-Encoding\");\n if (contentEncoding && contentEncoding.trim().toLowerCase() !== \"identity\") {\n return false;\n }\n\n // RFC 9110 §5.2.2.6: `no-transform` forbids intermediaries *and* us from\n // changing the representation's encoding.\n if (hasDirective(res.headers.get(\"Cache-Control\"), \"no-transform\")) {\n return false;\n }\n\n const contentLength = res.headers.get(\"Content-Length\");\n if (contentLength !== null && Number(contentLength) < MIN_COMPRESSIBLE_BYTES) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Builds the encoder as a web `TransformStream`-shaped pair.\n *\n * Both codings are driven through `node:zlib` with an explicit per-write flush.\n * Without it the compressor holds output until its internal buffer fills,\n * which would sit on React's shell flush and turn a streamed render into a\n * buffered one — the compression win would be paid for in time to first byte.\n */\nexport function createEncoderStream(encoding: ContentEncoding) {\n const compressor =\n encoding === \"br\"\n ? createBrotliCompress({\n params: {\n [constants.BROTLI_PARAM_QUALITY]: BROTLI_QUALITY,\n [constants.BROTLI_PARAM_LGWIN]: BROTLI_WINDOW_BITS,\n },\n flush: constants.BROTLI_OPERATION_FLUSH,\n })\n : createGzip({ level: GZIP_LEVEL, flush: constants.Z_SYNC_FLUSH });\n\n return Duplex.toWeb(compressor) as unknown as ReadableWritablePair<Uint8Array, Uint8Array>;\n}\n\nfunction withVaryAcceptEncoding(headers: Headers) {\n const vary = headers.get(\"Vary\");\n if (!vary) {\n headers.set(\"Vary\", \"Accept-Encoding\");\n return;\n }\n const tokens = vary.split(\",\").map((token) => token.trim().toLowerCase());\n // `Vary: *` already means \"never reuse for another request\"; narrowing it\n // would be a downgrade.\n if (tokens.includes(\"*\") || tokens.includes(\"accept-encoding\")) {\n return;\n }\n headers.append(\"Vary\", \"Accept-Encoding\");\n}\n\n/**\n * Compresses an SSR HTML response when the client asked for it.\n *\n * Non-HTML responses are returned untouched — same object, same body, so this\n * is safe to apply at the edge of the server for every request.\n *\n * HTML responses always gain `Vary: Accept-Encoding`, whether or not this\n * particular request got an encoded body: without it a shared cache could\n * serve a stored encoded variant to a client that cannot decode it.\n */\nexport function compressResponse(req: Request, res: Response): Response {\n if (!isCompressible(req.method, res)) {\n return res;\n }\n\n const headers = new Headers(res.headers);\n withVaryAcceptEncoding(headers);\n\n const encoding = negotiateEncoding(req.headers.get(\"Accept-Encoding\"));\n if (!encoding) {\n return new Response(res.body, {\n status: res.status,\n statusText: res.statusText,\n headers,\n });\n }\n\n let encoder: ReadableWritablePair<Uint8Array, Uint8Array>;\n try {\n encoder = createEncoderStream(encoding);\n } catch {\n // A compressor we cannot construct is not worth failing a page render\n // over. Serve identity — with the `Vary` we already added.\n return new Response(res.body, {\n status: res.status,\n statusText: res.statusText,\n headers,\n });\n }\n\n headers.set(\"Content-Encoding\", encoding);\n // The length of the identity representation says nothing about the encoded\n // body, and a stale one would truncate the response.\n headers.delete(\"Content-Length\");\n\n return new Response(res.body!.pipeThrough(encoder), {\n status: res.status,\n statusText: res.statusText,\n headers,\n });\n}\n",
|
|
7
7
|
"import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { createUnsatisfiableResponse } from \"../http/createStreamResponse\";\nimport { formatContentRange, parseRangeHeader, resolveRange } from \"../http/range\";\nimport { SIBLING_EXTENSION } from \"../vite/precompressAssets\";\nimport { type ContentEncoding, negotiateEncoding } from \"./compression\";\nimport { generateETag } from \"./generateEtag\";\n\n/**\n * Every file in `dist/client` outside `/assets`, as absolute paths — what\n * Vite copied out of `public/` (#583).\n *\n * A root-level path may be an app route, so the static handler may only take\n * one that names a file the app really ships. This used to be guessed from the\n * extension, and every extension the list missed (`.mp4` on 0.58, `.wasm`,\n * `.csv` …) was answered by the router with a rendered 404 page. The build\n * output is fixed for the life of the process, so the exact set is read once\n * at boot instead.\n *\n * `assets/` is left out because the static handler takes everything under it\n * anyway. A name starting with a dot is left out at any depth: `.vite/` is\n * build metadata (both manifests and the asset base record), and a stray\n * `.DS_Store` or `.env` copied in from `public/` is nothing a request should\n * reach. `/.well-known` is served by its own rule.\n */\nexport async function listPublicFiles(clientDir: string): Promise<Set<string>> {\n const files = new Set<string>();\n\n async function walk(dir: string, topLevel: boolean) {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\")) continue;\n if (topLevel && entry.name === \"assets\") continue;\n const path = join(dir, entry.name);\n let isDir = entry.isDirectory();\n let isFile = entry.isFile();\n if (entry.isSymbolicLink()) {\n try {\n const target = await stat(path);\n isDir = target.isDirectory();\n isFile = target.isFile();\n } catch {\n continue;\n }\n }\n if (isFile) files.add(path);\n // A symlinked directory is not followed: a link back up the tree would\n // never end, and `clientFilePath` only names paths inside `dist/client`.\n else if (isDir && !entry.isSymbolicLink()) await walk(path, false);\n }\n }\n\n await walk(clientDir, true);\n return files;\n}\n\nconst LONG_LIVED = \"public, max-age=31536000, must-revalidate\";\n\n/**\n * A content-hashed build asset never changes under its name: a new build\n * writes a new name. So a browser or edge may keep it a year without asking\n * again (#789).\n */\nconst IMMUTABLE = \"public, max-age=31536000, immutable\";\n\nexport interface StaticFileOptions {\n /**\n * The file is a content-hashed build asset (it is in the build's\n * `static-assets.json`), so it is sent as `immutable`.\n */\n immutable?: boolean;\n /**\n * The precompressed siblings the build wrote for it (`file.br`,\n * `file.gz`), in preference order. Offering any makes the response vary by\n * `Accept-Encoding`, so it says so even when it sends identity.\n */\n encodings?: ContentEncoding[];\n}\n\nasync function encodedSibling(\n req: Request,\n path: string,\n encodings: ContentEncoding[],\n): Promise<{ encoding: ContentEncoding; path: string; size: number } | null> {\n // A range is a byte range of the identity representation: an encoded\n // variant has no stable offsets to slice, so a range request gets identity.\n if (encodings.length === 0 || req.headers.has(\"Range\")) {\n return null;\n }\n const encoding = negotiateEncoding(req.headers.get(\"Accept-Encoding\"), encodings);\n if (!encoding) {\n return null;\n }\n const siblingPath = path + SIBLING_EXTENSION[encoding];\n try {\n // Checked per request, like the file itself: a sibling deleted under a\n // running server would otherwise fail mid-body after a committed 200.\n const info = await stat(siblingPath);\n return info.isFile() ? { encoding, path: siblingPath, size: info.size } : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The response for a file in `dist/client` that is known to exist.\n *\n * Honours a single byte `Range`, so a `<video>` pointed at a public `.mp4`\n * can seek — Safari will not play one at all from a server that answers its\n * `bytes=0-1` probe with the whole file. Recent Bun releases slice a\n * file-backed 200 themselves; doing it here keeps that from depending on the\n * Bun version a deployment runs, and answers an unsatisfiable range with the\n * same 416 the `stream()` responses use.\n *\n * A build asset with precompressed siblings is sent as the one\n * `Accept-Encoding` prefers (brotli, then gzip, then identity), with the\n * original's `Content-Type`. Nothing is compressed here: a file without a\n * sibling is sent as is.\n *\n * `Bun.file().type` is the mime lookup, and is `application/octet-stream` for\n * an extension it does not know.\n */\nexport async function staticFileResponse(\n req: Request,\n path: string,\n options: StaticFileOptions = {},\n): Promise<Response> {\n const file = Bun.file(path);\n const encodings = options.encodings ?? [];\n\n const headers: Record<string, string> = {\n \"Content-Type\": file.type || \"application/octet-stream\",\n \"Cache-Control\": options.immutable ? IMMUTABLE : LONG_LIVED,\n \"Accept-Ranges\": \"bytes\",\n };\n if (encodings.length > 0) {\n headers.Vary = \"Accept-Encoding\";\n }\n\n const sibling = await encodedSibling(req, path, encodings);\n if (sibling) {\n const encoded = Bun.file(sibling.path);\n return new Response(encoded.stream(), {\n headers: {\n ...headers,\n \"Content-Encoding\": sibling.encoding,\n \"Content-Length\": String(sibling.size),\n // A different representation, so a different validator.\n ETag: `${generateETag(encoded.lastModified)}-${sibling.encoding}`,\n },\n });\n }\n\n const total = file.size;\n headers.ETag = generateETag(file.lastModified);\n\n const range = parseRangeHeader(req.headers.get(\"Range\"));\n\n if (range) {\n const resolved = resolveRange(range, total);\n if (!resolved) {\n return createUnsatisfiableResponse(total);\n }\n return new Response(file.slice(resolved.start, resolved.end + 1).stream(), {\n status: 206,\n headers: {\n ...headers,\n \"Content-Range\": formatContentRange(resolved.start, resolved.end, total),\n \"Content-Length\": String(resolved.length),\n },\n });\n }\n\n return new Response(file.stream(), {\n headers: { ...headers, \"Content-Length\": String(total) },\n });\n}\n",
|
|
8
8
|
"import { mkdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { availableParallelism } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { brotliCompress, constants, gzip } from \"node:zlib\";\n\nimport type { ContentEncoding } from \"../server/compression\";\n\n/**\n * Build-time compression of the client bundle (#789).\n *\n * `gemi start` compresses SSR HTML per request, but a hashed chunk is the same\n * bytes for the life of a release, so compressing it per request would spend\n * origin CPU on every visitor for a result that never changes. `gemi build`\n * writes `file.br` (brotli quality 11) and `file.gz` (gzip level 9) next to\n * every compressible build asset instead, once, and the server picks one by\n * `Accept-Encoding`.\n *\n * What the build emitted (and what it carried over from earlier releases, see\n * `previousAssets.ts`) is recorded in `dist/client/.vite/static-assets.json`,\n * with the encodings each file has. The server reads it at boot: a file in the\n * record is a content-hashed build asset, so it is sent as `immutable`, and\n * only the encodings listed for it are offered. A file not in the record (one\n * copied from `public/assets/`, or anything in a build made before this\n * existed) is served as before.\n */\n\n/** Relative to `dist/client`; beside Vite's own manifest, so never served. */\nexport const STATIC_ASSETS_RECORD = \".vite/static-assets.json\";\n\n/**\n * Below this, the encoded body plus its header is not worth a second request\n * representation: a 600-byte chunk saves a few hundred bytes at most, and\n * every file with siblings adds a `stat` per request.\n */\nexport const PRECOMPRESS_MIN_BYTES = 1024;\n\n/**\n * Text-like formats that compress well. Already-compressed formats (images,\n * `woff`/`woff2`, video) are left out: brotli shaves a percent or two off\n * them at best. Source maps are left out because a page never loads one, and\n * only devtools would gain from the extra build time.\n */\nconst COMPRESSIBLE = /\\.(?:m?js|cjs|css|svg|json|webmanifest|wasm|txt|xml|ttf|otf|eot)$/i;\n\nconst TEXT = /\\.(?:m?js|cjs|css|svg|json|webmanifest|txt|xml)$/i;\nconst FONT = /\\.(?:ttf|otf|eot)$/i;\n\nexport const SIBLING_EXTENSION: Record<ContentEncoding, string> = {\n br: \".br\",\n gzip: \".gz\",\n};\n\n/** Server preference: brotli is ~15% smaller than gzip -9 on a JS chunk. */\nconst ENCODINGS: ContentEncoding[] = [\"br\", \"gzip\"];\n\nexport interface StaticAssetsRecord {\n /**\n * Path relative to `dist/client` (`assets/client-DJhrQPW5.js`) → the\n * precompressed siblings it has, in preference order. An empty list is a\n * build asset that is served as identity only (an image, a small file).\n */\n files: Record<string, ContentEncoding[]>;\n}\n\nexport interface PrecompressStats {\n files: number;\n identityBytes: number;\n brBytes: number;\n gzipBytes: number;\n}\n\nconst brotli = promisify(brotliCompress);\nconst gzipAsync = promisify(gzip);\n\nexport function isPrecompressible(file: string): boolean {\n return COMPRESSIBLE.test(file);\n}\n\n/** `true` for `x.js.br` / `x.js.gz`: a sibling, not an asset of its own. */\nexport function isEncodedSibling(file: string): boolean {\n return file.endsWith(\".br\") || file.endsWith(\".gz\");\n}\n\nasync function encode(encoding: ContentEncoding, file: string, input: Buffer): Promise<Buffer> {\n if (encoding === \"gzip\") {\n return gzipAsync(input, { level: 9 });\n }\n return brotli(input, {\n params: {\n [constants.BROTLI_PARAM_QUALITY]: constants.BROTLI_MAX_QUALITY,\n [constants.BROTLI_PARAM_MODE]: TEXT.test(file)\n ? constants.BROTLI_MODE_TEXT\n : FONT.test(file)\n ? constants.BROTLI_MODE_FONT\n : constants.BROTLI_MODE_GENERIC,\n [constants.BROTLI_PARAM_SIZE_HINT]: input.length,\n },\n });\n}\n\nasync function fileSize(path: string): Promise<number | null> {\n try {\n const info = await stat(path);\n return info.isFile() ? info.size : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes the `.br`/`.gz` siblings of `files` (paths relative to `clientDir`)\n * and returns the encodings each one ended up with.\n *\n * A sibling is only kept when it is smaller than the file itself; one that is\n * not would cost bytes on the wire, so the file is served as identity for\n * that encoding. With `reuseExisting`, a sibling already on disk is trusted\n * rather than rebuilt — for files carried from an earlier release, whose\n * siblings were copied with them and match by content hash.\n */\nexport async function precompressAssets(\n clientDir: string,\n files: Iterable<string>,\n options: {\n reuseExisting?: boolean;\n minBytes?: number;\n concurrency?: number;\n } = {},\n): Promise<{ record: StaticAssetsRecord; stats: PrecompressStats }> {\n const minBytes = options.minBytes ?? PRECOMPRESS_MIN_BYTES;\n const record: StaticAssetsRecord = { files: {} };\n const stats: PrecompressStats = {\n files: 0,\n identityBytes: 0,\n brBytes: 0,\n gzipBytes: 0,\n };\n\n const queue = [...new Set(files)];\n for (const file of queue) {\n record.files[file] = [];\n }\n\n async function work(file: string) {\n if (!isPrecompressible(file)) {\n return;\n }\n const path = join(clientDir, file);\n const size = await fileSize(path);\n if (size === null || size < minBytes) {\n return;\n }\n\n let input: Buffer | null = null;\n const available: ContentEncoding[] = [];\n const sizes: Partial<Record<ContentEncoding, number>> = {};\n for (const encoding of ENCODINGS) {\n const siblingPath = path + SIBLING_EXTENSION[encoding];\n const existing = options.reuseExisting ? await fileSize(siblingPath) : null;\n if (existing !== null) {\n if (existing < size) {\n available.push(encoding);\n sizes[encoding] = existing;\n }\n continue;\n }\n input ??= await readFile(path);\n const output = await encode(encoding, file, input);\n if (output.length < size) {\n await writeFile(siblingPath, output);\n available.push(encoding);\n sizes[encoding] = output.length;\n }\n }\n\n record.files[file] = available;\n if (available.length > 0) {\n stats.files += 1;\n stats.identityBytes += size;\n stats.brBytes += sizes.br ?? size;\n stats.gzipBytes += sizes.gzip ?? size;\n }\n }\n\n // zlib's async calls run on the libuv thread pool; a few files in flight\n // keep it busy without reading the whole bundle into memory at once.\n const concurrency = Math.max(1, options.concurrency ?? Math.min(8, availableParallelism()));\n let next = 0;\n await Promise.all(\n Array.from({ length: Math.min(concurrency, queue.length) }, async () => {\n while (next < queue.length) {\n await work(queue[next++]);\n }\n }),\n );\n\n return { record, stats };\n}\n\nexport async function writeStaticAssetsRecord(clientDir: string, record: StaticAssetsRecord) {\n const path = join(clientDir, STATIC_ASSETS_RECORD);\n await mkdir(dirname(path), { recursive: true });\n // Sorted, so two builds of the same tree write the same file.\n const files = Object.fromEntries(\n Object.entries(record.files).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n );\n await writeFile(path, `${JSON.stringify({ files }, null, 2)}\\n`);\n}\n\n/**\n * The record a build wrote, or `null` when there is none (a build made before\n * precompression, or an incomplete `dist/`): the server then serves every file\n * as before. A malformed entry is dropped rather than trusted.\n */\nexport async function readStaticAssetsRecord(\n clientDir: string,\n): Promise<StaticAssetsRecord | null> {\n let raw: string;\n try {\n raw = await readFile(join(clientDir, STATIC_ASSETS_RECORD), \"utf8\");\n } catch {\n return null;\n }\n let files: unknown;\n try {\n files = JSON.parse(raw)?.files;\n } catch {\n return null;\n }\n if (!files || typeof files !== \"object\") {\n return null;\n }\n const record: StaticAssetsRecord = { files: {} };\n for (const [file, encodings] of Object.entries(files)) {\n if (!Array.isArray(encodings)) continue;\n record.files[file] = ENCODINGS.filter((encoding) => encodings.includes(encoding));\n }\n return record;\n}\n",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"import { stringEraRefusal } from \"../http/Error\";\nimport { isApiPath } from \"../services/router/apiPath\";\n\n// The production server's last resort: an error nothing on the way here turned\n// into a response. Request breakers (auth, 404s, 416s) are answered by the\n// dispatchers before this, so what arrives is a genuine failure — and its\n// message and stack are for the developer, not for whoever triggered it. They\n// can carry absolute paths, dependency versions, SQL fragments and column\n// names. The dev server renders them on purpose (`httpDev.ts`); this does not.\n\nconst GENERIC_500_HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Internal Server Error</title>\n <style>\n body { font-family: system-ui, sans-serif; margin: 0; min-height: 100vh; display: grid; place-items: center; }\n main { text-align: center; padding: 16px; }\n h1 { font-size: 1.5rem; margin: 0 0 0.5rem; }\n p { margin: 0; opacity: 0.7; }\n </style>\n </head>\n <body>\n <main>\n <h1>Something went wrong</h1>\n <p>Please try again later.</p>\n </main>\n </body>\n</html>`;\n\nexport function unhandledErrorResponse(\n err: unknown,\n pathname: string,\n onException?: (error: Error) => void,\n): Response {\n // `onException` is the report, and the default one `App` installs is a\n // `console.error`, so logging here as well printed every failure twice\n // (three times for `/api`, whose dispatcher logs before rethrowing). Only\n // without a reporter does this log itself.\n //\n // Reported for `/api` too: an app's error tracking should see an API failure\n // that got this far, not only a page one. `onRequestFail` is a different\n // hook (route config, called by the dispatchers), so this is not a second\n // report through the same channel.\n if (!onException) {\n console.error(err);\n } else {\n try {\n // The hook is typed to receive an `Error`; a thrown string or object is\n // wrapped so a reporter reading `.stack` or `.name` gets one.\n onException(err instanceof Error ? err : new Error(String(err), { cause: err }));\n } catch (reportError) {\n // A broken reporter must not turn a 500 into a leaked stack either.\n console.error(err);\n console.error(reportError);\n }\n }\n\n if (isApiPath(pathname)) {\n return new Response(\n JSON.stringify({ error: stringEraRefusal(\"server_error\", \"Internal Server Error\", 500) }),\n {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n\n return new Response(GENERIC_500_HTML, {\n status: 500,\n headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n });\n}\n",
|
|
14
14
|
"/**\n * Which `X-Forwarded-For` entries the production server believes (#8).\n *\n * `X-Forwarded-For` is written by whoever sends the request. A client talking\n * to the app directly — or through a proxy that appends to the header rather\n * than replacing it — picks any address it likes, and `clientIp` (the rate\n * limiter's default key) used to read the left-most entry, which is exactly\n * the one the client wrote. So the server decides here, once, at the edge,\n * and hands the app a single address it can rely on:\n *\n * - `none` (the default): no proxy is trusted. The header is replaced with the\n * socket's peer address, and `X-Real-IP` is dropped.\n * - `hops` (`GEMI_TRUST_PROXY=<n>`): the `n` proxies nearest the app are\n * trusted. Each appends the address it was reached from, so the client is\n * the `n`-th entry from the right of `X-Forwarded-For`. Anything\n * further left was written by someone the app does not trust and is dropped.\n * - `all` (`GEMI_TRUST_PROXY=true`): the inbound header is passed through\n * unchanged, as before 0.88. Only sound behind a proxy that overwrites\n * `X-Forwarded-For` (and `X-Real-IP`) rather than appending to it.\n */\nexport type ForwardedTrust =\n | { kind: \"none\" }\n | { kind: \"all\" }\n | { kind: \"hops\"; hops: number };\n\nconst NONE: ForwardedTrust = { kind: \"none\" };\n\n/**\n * `GEMI_TRUST_PROXY` as a policy. Unset, empty, `false`, `off` and `0` trust\n * nothing; `true` trusts everything; a positive integer is a hop count.\n * Anything else throws, so a typo fails the boot instead of silently trusting\n * nothing (every client sharing the proxy's address) or everything.\n */\nexport function parseTrustProxy(value: string | undefined): ForwardedTrust {\n const raw = (value ?? \"\").trim().toLowerCase();\n if (raw === \"\" || raw === \"false\" || raw === \"off\" || raw === \"0\") {\n return NONE;\n }\n if (raw === \"true\") {\n return { kind: \"all\" };\n }\n if (/^[1-9]\\d*$/.test(raw)) {\n return { kind: \"hops\", hops: Number(raw) };\n }\n throw new Error(\n `GEMI_TRUST_PROXY must be \"false\", \"true\" or the number of proxies in front of the app (e.g. 1). Got ${JSON.stringify(value)}.`,\n );\n}\n\n/**\n * Rewrites `headers` so `X-Forwarded-For` holds what `trust` says the client\n * address is. `peer` is the socket's remote address — `null` for a unix\n * socket, where the immediate hop is still counted as one proxy.\n */\nexport function applyForwardedTrust(\n headers: Headers,\n peer: string | null,\n trust: ForwardedTrust,\n): void {\n if (trust.kind === \"all\") {\n if (!headers.get(\"x-forwarded-for\") && peer) {\n headers.set(\"x-forwarded-for\", peer);\n }\n return;\n }\n\n // Under any other policy `X-Real-IP` is as client-written as the rest; the\n // address the app should use is the one left in `X-Forwarded-For`.\n headers.delete(\"x-real-ip\");\n\n let client: string | null = peer;\n if (trust.kind === \"hops\") {\n const entries = (headers.get(\"x-forwarded-for\") ?? \"\")\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean);\n // The chain is `entries` + `peer`; the client sits `hops` places left of\n // its end, i.e. `entries[entries.length - hops]`. A shorter chain than\n // expected means the request skipped a proxy, so its left-most hop is the\n // furthest thing seen — never anything further left than that.\n const index = entries.length - trust.hops;\n client = index >= 0 ? entries[index]! : (entries[0] ?? peer);\n }\n\n if (client) {\n headers.set(\"x-forwarded-for\", client);\n } else {\n headers.delete(\"x-forwarded-for\");\n }\n}\n"
|
|
15
15
|
],
|
|
16
|
-
"mappings": "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",
|
|
17
|
-
"debugId": "
|
|
16
|
+
"mappings": "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",
|
|
17
|
+
"debugId": "ADE18CB5D0F98F4264756E2164756E21",
|
|
18
18
|
"names": []
|
|
19
19
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{G as B,I as p,O as _}from"./chunk-
|
|
2
|
+
import{G as B,I as p,O as _}from"./chunk-5tdxbwzg.js";import{P as v}from"./chunk-7g649j8h.js";import{Q as D}from"./chunk-0ejjgzwc.js";import"./chunk-3wnghdsx.js";import"./chunk-gy81nd9a.js";import"./chunk-s5k3yq6t.js";import{aa as d}from"./chunk-32n8t8x6.js";import"./chunk-ep0baa9g.js";import{ij as n}from"./chunk-tewhms9w.js";var x=n(D(),1),E=n(B(),1),i=n(d(),1);import M from"fs/promises";var C=n(d(),1);var A="169.254.170.2",O="169.254.170.23",b="[fd00:ec2::23]",S=(e,a)=>{if(e.protocol==="https:")return;if(e.hostname===A||e.hostname===O||e.hostname===b)return;if(e.hostname.includes("[")){if(e.hostname==="[::1]"||e.hostname==="[0000:0000:0000:0000:0000:0000:0000:0001]")return}else{if(e.hostname==="localhost")return;let c=e.hostname.split("."),r=(t)=>{let s=parseInt(t,10);return 0<=s&&s<=255};if(c[0]==="127"&&r(c[1])&&r(c[2])&&r(c[3])&&c.length===4)return}throw new C.CredentialsProviderError(`URL not accepted. It must either be HTTPS or match one of the following:
|
|
3
3
|
- loopback CIDR 127.0.0.0/8 or [::1/128]
|
|
4
4
|
- ECS container host 169.254.170.2
|
|
5
5
|
- EKS container host 169.254.170.23 or [fd00:ec2::23]`,{logger:a})};var o=n(d(),1),g=n(v(),1),w=n(_(),1),I=n(p(),1);function P(e){return new g.HttpRequest({protocol:e.protocol,hostname:e.hostname,port:Number(e.port),path:e.pathname,query:Array.from(e.searchParams.entries()).reduce((a,[c,r])=>{return a[c]=r,a},{}),fragment:e.hash})}async function K(e,a){let r=await I.sdkStreamMixin(e.body).transformToString();if(e.statusCode===200){let t=JSON.parse(r);if(typeof t.AccessKeyId!=="string"||typeof t.SecretAccessKey!=="string"||typeof t.Token!=="string"||typeof t.Expiration!=="string")throw new o.CredentialsProviderError("HTTP credential provider response not of the required format, an object matching: { AccessKeyId: string, SecretAccessKey: string, Token: string, Expiration: string(rfc3339) }",{logger:a});return{accessKeyId:t.AccessKeyId,secretAccessKey:t.SecretAccessKey,sessionToken:t.Token,expiration:w.parseRfc3339DateTime(t.Expiration)}}if(e.statusCode>=400&&e.statusCode<500){let t={};try{t=JSON.parse(r)}catch(s){}throw Object.assign(new o.CredentialsProviderError(`Server responded with status: ${e.statusCode}`,{logger:a}),{Code:t.Code,Message:t.Message})}throw new o.CredentialsProviderError(`Server responded with status: ${e.statusCode}`,{logger:a})}var T=(e,a,c)=>{return async()=>{for(let r=0;r<a;++r)try{return await e()}catch(t){await new Promise((s)=>setTimeout(s,c))}return await e()}};var N="AWS_CONTAINER_CREDENTIALS_RELATIVE_URI",j="http://169.254.170.2",H="AWS_CONTAINER_CREDENTIALS_FULL_URI",J="AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE",$="AWS_CONTAINER_AUTHORIZATION_TOKEN",G=(e={})=>{e.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");let a,c=e.awsContainerCredentialsRelativeUri??process.env[N],r=e.awsContainerCredentialsFullUri??process.env[H],t=e.awsContainerAuthorizationToken??process.env[$],s=e.awsContainerAuthorizationTokenFile??process.env[J],m=e.logger?.constructor?.name==="NoOpLogger"||!e.logger?.warn?console.warn:e.logger.warn.bind(e.logger);if(c&&r)m("@aws-sdk/credential-provider-http: you have set both awsContainerCredentialsRelativeUri and awsContainerCredentialsFullUri."),m("awsContainerCredentialsFullUri will take precedence.");if(t&&s)m("@aws-sdk/credential-provider-http: you have set both awsContainerAuthorizationToken and awsContainerAuthorizationTokenFile."),m("awsContainerAuthorizationToken will take precedence.");if(r)a=r;else if(c)a=`${j}${c}`;else throw new i.CredentialsProviderError(`No HTTP credential provider host provided.
|
|
6
6
|
Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI.`,{logger:e.logger});let y=new URL(a);S(y,e.logger);let R=E.NodeHttpHandler.create({requestTimeout:e.timeout??1000,connectionTimeout:e.timeout??1000});return T(async()=>{let f=P(y);if(t)f.headers.Authorization=t;else if(s)f.headers.Authorization=(await M.readFile(s)).toString();try{let h=await R.handle(f);return K(h.response).then((u)=>x.setCredentialFeature(u,"CREDENTIALS_HTTP","z"))}catch(h){throw new i.CredentialsProviderError(String(h),{logger:e.logger})}},e.maxRetries??3,e.timeout??1000)};export{G as fromHttp};
|
|
7
7
|
|
|
8
|
-
//# debugId=
|
|
8
|
+
//# debugId=6E8E8907ACC67E0564756E2164756E21
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
"export const retryWrapper = (toRetry, maxRetries, delayMs) => {\n return async () => {\n for (let i = 0; i < maxRetries; ++i) {\n try {\n return await toRetry();\n }\n catch (e) {\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n return await toRetry();\n };\n};\n"
|
|
9
9
|
],
|
|
10
10
|
"mappings": "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",
|
|
11
|
-
"debugId": "
|
|
11
|
+
"debugId": "6E8E8907ACC67E0564756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{fa as k,ga as p}from"./chunk-
|
|
2
|
+
import{fa as k,ga as p}from"./chunk-pemhmjzp.js";function D(){return{name:"gemi-custom-request",setup(x){x.onLoad({filter:k},async(j)=>{let y=await Bun.file(j.path).text();return{contents:await p(y),loader:j.path.endsWith(".tsx")?"tsx":"ts"}})}}}
|
|
3
3
|
export{D as ea};
|
|
4
4
|
|
|
5
5
|
//# debugId=92CE5F11E40AB21B64756E2164756E21
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Ih as k,Kh as T0}from"./chunk-meg8rtr6.js";import{Lh as S0}from"./chunk-h43jp8ws.js";import{Nh as N0,Oh as R0,Ph as Q0,Rh as C,Th as q,ai as B0}from"./chunk-s07v65x6.js";import{pi as H0}from"./chunk-gc2dz11k.js";import{Mi as W0,Pi as b}from"./chunk-nz8z8jr1.js";import{Yi as M0}from"./chunk-2n3pgfnb.js";class p{entries=new Map;counters=new Map;async acquire(z,V,Y){let Z=Date.now(),$=this.entries.get(z);if($&&($.expiresAt>Z||$.fences>0))return null;let X=($?.token??0)+1;return this.entries.set(z,{owner:V,token:X,expiresAt:Z+Math.max(0,Y),fences:0}),X}async extend(z,V,Y,Z){let $=this.current(z,V,Y);if(!$)return!1;return $.expiresAt=Date.now()+Math.max(0,Z),!0}async release(z,V,Y){let Z=this.current(z,V,Y);if(!Z)return!1;return Z.owner="",Z.expiresAt=0,!0}async holder(z){let V=this.entries.get(z);if(!V||V.expiresAt<=Date.now())return null;return{owner:V.owner,token:V.token}}async held(z,V,Y){return this.current(z,V,Y)!==void 0}async advance(z,V){if((this.counters.get(z)??-1/0)>=V)return!1;return this.counters.set(z,V),!0}async fence(z,V,Y,Z){let $=this.current(z,V,Y);if(!$)throw new k(z,Y);$.fences++;try{return await Z()}finally{$.fences--}}windows=new Map;async hit(z,V,Y){let Z=Date.now(),$=this.windows.get(z);if(!$||$.endsAt<=Z)$={count:0,endsAt:Z+Math.max(1,Y)},this.windows.set(z,$);if($.count>=V)return{allowed:!1,resetInMs:$.endsAt-Z};return $.count++,{allowed:!0,resetInMs:$.endsAt-Z}}async refund(z){let V=this.windows.get(z);if(V&&V.endsAt>Date.now()&&V.count>0)V.count--}current(z,V,Y){let Z=this.entries.get(z);if(!Z||Z.owner!==V||Z.expiresAt<=Date.now())return;if(Y!==void 0&&Z.token!==Y)return;return Z}}class y{table;sql;dialect;connection;busyTimeout;configured;constructor(z,V={}){let Y=V.table??"gemi_locks";if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(Y))throw Error(`The lock table name "${Y}" is not a plain identifier. Use letters, digits and underscores.`);this.table=Y,this.sql=z.sql,this.dialect=z.dialect,this.connection=z.name,this.busyTimeout=V.busyTimeout??1000}async createTable(){await this.configure();for(let z of v0(this.dialect,this.table))await this.sql.unsafe(z)}async acquire(z,V,Y){await this.configure();let Z=this.sql,$=this.now(Z);if(await this.seed(Z,z),this.mysql){let H=await Z`
|
|
3
3
|
UPDATE ${this.name(Z)}
|
|
4
4
|
SET owner = ${V}, token = token + 1, expires_at = ${$} + ${this.ms(Z,Y)},
|
|
5
5
|
updated_at = ${$}
|
|
@@ -411,6 +411,6 @@ ADD COLUMN IF NOT EXISTS "progress" ${Y}`,`CREATE INDEX IF NOT EXISTS "${V}_batc
|
|
|
411
411
|
}
|
|
412
412
|
};
|
|
413
413
|
`],"worker.ts"),$=URL.createObjectURL(Z);return new Worker($)}async function s0(z,V){let Y=i0();return Y.postMessage({jobName:z,args:V}),await new Promise((Z,$)=>{Y.onmessage=(X)=>{let H=X.data;if("error"in H)$(H.error);else Z(H.result)}})}var n0=new c0("gemi.queue"),a0=60000;class h{static token="queue";jobs={};config;driver;application;inFlight=new Map;state="idle";looping=!1;claiming;woken=!1;claimFailures=0;resume;unsubscribe;heartbeatTimer;releasedNames=new Set;lockManager;workflowRuntime;constructor(z={},V={}){if(this.config=S0(C0(),z),this.application=V.application,this.driver=zz(this.config.driver,this.application),this.useJobs(this.config.jobs),this.config.workflows.length>0)this.useWorkflows(this.config.workflows)}useJobs(z){this.config.jobs=z,this.jobs={};for(let V of z)this.claim(V);this.registerTickJob()}useWorkflows(z){this.config.workflows=z,this.workflows.use(z),this.registerTickJob()}get registeredWorkflows(){return[...this.config.workflows]}get workflows(){return this.workflowRuntime??=new $0(this),this.workflowRuntime}registerTickJob(){if(!this.workflowRuntime||Object.keys(this.workflowRuntime.workflows).length===0)return;let z=this.workflowRuntime.tickJob;if(this.jobs[z.name]&&this.jobs[z.name]!==z){console.error(`A queued job is named "${z.name}", which the workflow runtime uses. Workflows will not run until it is renamed.`);return}this.jobs[z.name]=z}registerJob(z){this.config.jobs=[...this.config.jobs,z],this.claim(z)}claim(z){if(this.jobs[z.name]){console.error(`Two queued jobs are named "${z.name}" \u2014 the first is registered `+"and this one is not, so dispatching either would have run one of them. A class name is the queue's key, so only one job can hold it. Rename one.");return}this.jobs[z.name]=z}get registeredJobs(){return[...this.config.jobs]}dispatchJob(z,V){if(this.jobs[z])return new this.jobs[z]().run(JSON.parse(V))}push(z,V,Y={}){let Z=this.uniqueKey(z,V);if(Z)return this.pushUnique(z,V,Z,Y);let $=this.driver.joinsTransaction?.()===!0;if(!$){let X=Bun.randomUUIDv7();if(C(()=>this.record(z,V,{id:X,reportFailure:!0,committed:!0}).then(()=>{},()=>{})))return Promise.resolve(X)}return this.record(z,V,{reportFailure:Y.reportFailure,joins:$})}pushBatch(z,V,Y={}){let Z=this.buildBatch(z,V,Y),$={id:Z.id,total:V.length},X=this.driver.joinsTransaction?.()===!0;if(!X){if(C(()=>this.recordBatch(Z,{committed:!0}).then(()=>{},()=>{})))return Promise.resolve($)}return this.recordBatch(Z,{joins:X}).then(()=>$)}buildBatch(z,V,Y={}){if(!this.driver.enqueueBatch)throw Error("This queue's driver does not support batches. The memory and database drivers do.");if(new z().worker)throw Error(`${z.name} is a worker job, and a worker job cannot be dispatched in a batch: its thread has no way to report progress or reach the batch.`);if(z.prototype.uniqueId!==S.prototype.uniqueId)throw Error(`${z.name} is unique (it defines uniqueId), and a unique job cannot be dispatched in a batch: a duplicate would resolve to a job outside the batch, and the batch would wait for it forever.`);let $={};for(let X of["then","catch","finally"]){let H=Y[X];if(H===void 0)continue;if(typeof H?.name!=="string"||!Array.isArray(H.args))throw Error(`The batch's ${X} callback is not a job call. Build it with SomeJob.with(...args).`);$[X]={name:H.name,args:H.args}}return{id:Bun.randomUUIDv7(),name:Y.name??null,job:z.name,args:V,allowFailures:Y.allowFailures===!0,callbacks:$}}recordBatch(z,V){let Y=this.driver.enqueueBatch(z);this.startIfIdle();let Z=()=>!this.driver.subscribe&&this.state==="running"&&this.wake(),$=V.joins===!0&&C(Z);return Y.then(()=>$||Z(),(X)=>{if(!V.committed)return;console.error(`[gemi] The queue driver could not record a batch of ${z.job}, which was held until its transaction committed. The transaction stays committed; the batch's jobs did not run and will not be retried.`,X)}),Y}async findBatch(z){if(!this.driver.findBatch)throw Error("This queue's driver does not support batches.");return this.driver.findBatch(z)}async cancelBatch(z){if(!this.driver.cancelBatch)throw Error("This queue's driver does not support batches.");let V=await this.driver.cancelBatch(z);if(V)this.claimSoon();return V}get locks(){return this.lockManager??=new T0(this.resolveLockStore()),this.lockManager}resolveLockStore(){let z=this.config.locks;if(z==="auto"){let V=this.driver.lockStore?.();if(V)return V;if(this.durable)console.warn('[gemi] The queue driver keeps no locks, so unique jobs, withoutOverlapping and onOneServer only hold within this process. Set the queue slice\'s `locks` to "database" or a LockStore.');return new p}if(z==="memory")return new p;if(z==="database"||typeof z==="function"){if(!this.application&&(z==="database"||z.length>0))throw Error("The queue's locks need the application they belong to, and this QueueManager was built without one. Pass { application }.");if(z==="database")return new y(this.application.make(H0));return z(this.application)}if(typeof z==="string")throw Error(`Unknown queue locks "${z}". The queue slice's locks is "auto", "memory", "database", a LockStore, or a function returning one.`);return z}uniqueKey(z,V){if(z.prototype.uniqueId===S.prototype.uniqueId)return;let Y=new z,Z=Y.uniqueId(...JSON.parse(V));if(Z===void 0||Z===null||Z==="")return;return{key:L0(z.name,Z),ttl:Math.max(1,Y.uniqueFor)}}pushUnique(z,V,Y,Z){let $=Bun.randomUUIDv7();if(C(()=>this.recordUnique(z,V,Y,$,{report:!0,committed:!0}).then(()=>{},()=>{})))return Promise.resolve($);return this.recordUnique(z,V,Y,$,{report:Z.reportFailure!==!1,committed:!1})}recordUnique(z,V,Y,Z,$){let X=this.locks.store,H=(async()=>{for(let G=0;G<5;G++){if(await X.acquire(Y.key,Z,Y.ttl)!==null)try{return await this.record(z,V,{id:Z,reportFailure:!1})}catch(B){throw await X.release(Y.key,Z).catch(()=>{}),B}let Q=await X.holder(Y.key);if(Q)return Q.owner}throw Error(`The unique key "${Y.key}" kept changing hands, so ${z.name} was not queued.`)})();return H.catch((G)=>{if(!$.report)return;console.error(`[gemi] The queue could not record the unique job ${z.name}`+($.committed?", which was held until its transaction committed. The transaction stays committed; the job did not run and will not be retried.":", so it did not run and will not be retried."),G)}),H}async releaseUnique(z,V,Y){if(z.uniqueId===S.prototype.uniqueId)return;try{let Z=z.uniqueId(...V);if(Z===void 0||Z===null||Z==="")return;await this.locks.store.release(L0(Y.name,Z),Y.id)}catch(Z){console.error(`[gemi] Could not free the unique key of ${Y.name} (${Y.id}); it frees itself after uniqueFor.`,Z)}}record(z,V,Y){let Z=this.driver.enqueue({name:z.name,args:V,...Y.id===void 0?{}:{id:Y.id}});this.startIfIdle();let $=()=>!this.driver.subscribe&&this.state==="running"&&this.wake(),X=Y.joins===!0&&C($);return Z.then(()=>X||$(),(H)=>{if(Y.reportFailure===!1)return;console.error(`[gemi] The queue driver could not record ${z.name}`+(Y.committed?", which was held until its transaction committed. The transaction stays committed; the job did not run and will not be retried.":", so it did not run and will not be retried."),H)}),Z}async retryDead(z){if(!this.driver.retryDead)throw Error("This queue's driver keeps nothing of a dead-lettered job, so there is nothing to retry. The database driver keeps them.");let V=await this.driver.retryDead(z);if(V)this.claimSoon();return V}startIfIdle(){if(this.state==="idle"&&(!this.durable||this.mayClaimHere()))this.start()}claimSoon(){if(this.startIfIdle(),!this.driver.subscribe&&this.state==="running")this.wake()}start(){if(this.state==="running")return;if(this.state="running",this.durable&&this.application&&this.mayClaimHere()&&!r0())globalThis.__gemiDevQueue=this;if(this.unsubscribe=this.driver.subscribe?.(()=>this.wake()),this.looping)return this.wake();n0.runInAsyncScope(()=>void this.loop())}async drain(z=1/0){if(this.state="stopped",globalThis.__gemiDevQueue===this)globalThis.__gemiDevQueue=void 0;this.unsubscribe?.(),this.unsubscribe=void 0,this.wake();let V,Y=new Promise(($)=>{if(z!==1/0)V=setTimeout($,z)}),Z=(async()=>{await this.claiming?.catch(()=>{}),await Promise.allSettled([...this.inFlight.values()].map(($)=>$.done))})();return await Promise.race([Z,Y]),clearTimeout(V),{unfinished:[...this.inFlight.values()].map(($)=>({...$.job}))}}stop(){return this.drain(0)}get running(){return this.inFlight.size}async loop(){this.looping=!0;try{await this.claimWhileRunning()}finally{this.looping=!1}}async claimWhileRunning(){while(this.state==="running"){let z=this.durable&&M0()?0:this.config.concurrency-this.inFlight.size;if(z>0){this.woken=!1;let V=this.driver.claim(z,{...this.lease(),registered:{names:Object.keys(this.jobs),graceMs:this.config.unknownJobGrace}});this.claiming=V;let Y=[];try{Y=await V,this.claimFailures=0}catch(Z){this.claimFailures++,console.error(`The queue could not claim jobs from its driver; it will try again in ${this.retryDelay()}ms.`,Z)}finally{this.claiming=void 0}for(let Z of Y)this.execute(Z);if(Y.length===z)continue;if(this.woken&&this.inFlight.size<this.config.concurrency)continue}await this.sleep()}}sleep(){return new Promise((z)=>{let V,Y=this.claimFailures>0?this.retryDelay():this.driver.subscribe?void 0:this.config.pollInterval;if(Y!==void 0)V=setTimeout(()=>this.wake(),Y),V.unref?.();this.resume=()=>{clearTimeout(V),z()}})}retryDelay(){let z=Math.min(Math.max(0,this.claimFailures-1),30);return Math.min(this.config.pollInterval*2**z,a0)}wake(){this.woken=!0;let z=this.resume;this.resume=void 0,z?.()}get durable(){return!(this.driver instanceof i)}mayClaimHere(){return!this.application||t0()}lease(){return{visibilityTimeoutMs:this.config.visibilityTimeout}}execute(z){let V=`${z.id}:${z.attempt}`,Y=()=>this.run(z),Z=(this.application?W0.run(this.application,Y):Y()).catch(($)=>{console.error(`The queue could not record the outcome of ${z.name}.`,$)}).finally(()=>{this.inFlight.delete(V),this.wake()});this.inFlight.set(V,{job:z,done:Z}),this.heartbeat()}heartbeat(){let z=this.driver;if(!z.heartbeat||this.heartbeatTimer)return;this.heartbeatTimer=setInterval(()=>{if(this.inFlight.size===0){clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0;return}let V=[...this.inFlight.values()].map((Y)=>Y.job);z.heartbeat(V,this.lease()).catch((Y)=>{console.error("The queue could not extend its job leases.",Y)})},Math.max(1,Math.floor(this.config.visibilityTimeout/3))),this.heartbeatTimer.unref?.()}async run(z){let V=this.jobs[z.name];if(!V){let B=Date.now()-z.createdAt;if(this.durable&&B<this.config.unknownJobGrace){if(!this.releasedNames.has(z.name))this.releasedNames.add(z.name),console.error(`Left a queued "${z.name}" for another replica: nothing is registered here under that name. It is dead-lettered if no replica has run it within unknownJobGrace (${this.config.unknownJobGrace}ms) of its dispatch.`);await this.driver.release(z,{retryInMs:Math.round(this.config.pollInterval*(1+Math.random()))});return}console.error(`Dropped a queued job: nothing is registered under the name "${z.name}". If the class exists, it was not `+"discovered \u2014 check that it is under the queue slice's jobsDir "+"(app/jobs by default), or list it in app/config/queue.ts."),await this.driver.fail(z,{error:`No job is registered under the name "${z.name}".`,retryInMs:null});return}let Y;try{Y=new V}catch(B){console.error(`Dropped a queued ${z.name}: it could not be constructed.`,B),await this.driver.fail(z,{error:`The job could not be constructed: ${String(B)}`,retryInMs:null});return}let Z;try{Z=JSON.parse(z.args)}catch(B){console.error(`Dropped a queued ${z.name}: its arguments are not JSON.`,B),await this.driver.fail(z,{error:`The arguments are not JSON: ${String(B)}`,retryInMs:null});return}if(z.attempt>Math.max(1,Y.maxAttempts)){let B=Error(`${z.name} was claimed for attempt ${z.attempt} of ${Y.maxAttempts}: an earlier attempt never finished, most likely because the process running it exited. Dead-lettered without running it again.`);X0(`${z.name}.onDeadletter`,()=>Y.onDeadletter(B,...Z)),await this.driver.fail(z,{error:B.message,retryInMs:null}),await this.releaseUnique(Y,Z,z);return}if(Y.$claimed={...z},z.batchId!==void 0){if((await this.driver.findBatch?.(z.batchId,{progress:!1}))?.cancelledAt!=null){await this.driver.fail(z,{error:"Its batch was cancelled before it ran.",retryInMs:null,cancelled:!0});return}let K=this.batchHandle(z);Y.batch=K.batch,Y.$progress=K.progress}let $=await this.admit(Y,Z,z);if(!$)return;let X,H;try{H=await(Y.worker?s0(z.name,z.args):Y.run(...Z))}catch(B){X=B}finally{await $.done()}let G=Y.$outcome;if(X===void 0&&G?.kind==="release"){await this.driver.release(z,{retryInMs:Math.max(0,G.delayMs)});return}if(X===void 0&&G?.kind==="fail")X=G.error;let Q=G?.kind==="fail"?G.retry:!0;if(X===void 0)try{Y.onSuccess(H,...Z)}catch(B){X=B}if(X!==void 0){let B=String(X?.stack??X);if(X0(`${z.name}.onFail`,()=>Y.onFail(X,...Z)),!Q||z.attempt>=Y.maxAttempts)X0(`${z.name}.onDeadletter`,()=>Y.onDeadletter(X,...Z)),await this.driver.fail(z,{error:B,retryInMs:null}),await this.releaseUnique(Y,Z,z);else await this.driver.fail(z,{error:B,retryInMs:s(Y.backoff,z.attempt)});return}await this.driver.complete(z),await this.releaseUnique(Y,Z,z)}batchHandle(z){let V=z.batchId,Y=this.driver;return{batch:{id:V,cancelled:async()=>(await Y.findBatch?.(V,{progress:!1}))?.cancelledAt!=null},progress:(Z)=>Y.reportProgress?.(z,Z)??Promise.resolve()}}async admit(z,V,Y){let Z=z.concurrency(...V),$=[z.throttle(...V)??[]].flat();if(!Z&&$.length===0)return{done:async()=>{}};let X=this.locks,H;if(Z&&Z.limit>0){let Q=this.config.visibilityTimeout;for(let B=0;B<Z.limit&&!H;B++)H=await X.acquire(`gemi:concurrency:${Z.key}:${B}`,{ttl:Q,renew:!0})??void 0;if(!H){await this.driver.release(Y,{retryInMs:Math.round(this.config.pollInterval*(1+Math.random()))});return}}let G=[];for(let Q of $){let B=`gemi:throttle:${Q.key}`,K=await X.store.hit(B,Q.limit,Q.window);if(!K.allowed){await Promise.all(G.map((A)=>X.store.refund(A))),await H?.release(),await this.driver.release(Y,{retryInMs:Math.max(1,K.resetInMs)});return}G.push(B)}return{done:async()=>{await H?.release().catch((Q)=>{console.error(`[gemi] Could not free a concurrency slot of ${Y.name}.`,Q)})}}}}function L0(z,V){return`gemi:job:${z}:${String(V)}`}function X0(z,V){try{V()}catch(Y){console.error(`${z} threw; the job's claim was ended anyway.`,Y)}}function r0(){return Bun.env.NODE_ENV==="production"}function t0(){if(!l0)return!1;if(e0())return!0;return process.env.ROOT_DIR!==void 0&&!o0()}function o0(z=process.env){return(z.GEMI_QUEUE_CLAIM??"").trim().toLowerCase()==="off"}var x0=Symbol.for("gemi.queue.worker");function tz(z=!0){globalThis[x0]=z}function e0(){return globalThis[x0]===!0}function zz(z,V){if(z==="memory")return new i;if(z==="database"||typeof z==="function"){if(!V&&(z==="database"||z.length>0))throw Error("The queue driver needs the application it belongs to, and this QueueManager was built without one. Pass { application }.");if(z==="database")return new z0(V.make(H0));return z(V)}if(typeof z==="string")throw Error(`Unknown queue driver "${z}". The queue slice's driver is "memory", "database", a QueueDriver, or a function returning one.`);return z}class S{static name="unset";worker=!1;maxAttempts=3;backoff=0;uniqueId(...z){return}uniqueFor=3600000;throttle(...z){return}concurrency(...z){return}release(z=0){this.$outcome={kind:"release",delayMs:z}}fail(z,V={}){this.$outcome={kind:"fail",error:z instanceof Error?z:Error(String(z)),retry:V.retry??!0}}batch=void 0;async progress(z){let V=E(z);await this.$progress?.(V)}$progress;$claimed;$outcome;run(...z){}onFail(z,...V){}onSuccess(z,...V){}onDeadletter(z,...V){}static dispatch(...z){if(this.name==="unset")throw Error("Cannot dispatch a job with no name");return b(h).push(this,JSON.stringify(z))}static dispatchBatch(z,V={}){if(this.name==="unset")throw Error("Cannot dispatch a job with no name");return b(h).pushBatch(this,z.map((Y)=>JSON.stringify(Y)),V)}static with(...z){if(this.name==="unset")throw Error("Cannot use a job with no name as a callback");return JSON.stringify(z),{name:this.name,args:z}}static findBatch(z){return b(h).findBatch(z)}static cancelBatch(z){return b(h).cancelBatch(z)}}
|
|
414
|
-
export{p as
|
|
414
|
+
export{p as wc,y as xc,o as yc,F0 as zc,z0 as Ac,S as Bc,Nz as Cc,C0 as Dc,V0 as Ec,i as Fc,I0 as Gc,Y0 as Hc,E0 as Ic,O0 as Jc,Z0 as Kc,$0 as Lc,h as Mc,t0 as Nc,o0 as Oc,tz as Pc,e0 as Qc};
|
|
415
415
|
|
|
416
|
-
//# debugId=
|
|
416
|
+
//# debugId=118381F984FA970564756E2164756E21
|