gemi 0.56.0 → 0.58.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/app/index.js +1 -1
- package/dist/broadcasting/index.js +1 -1
- package/dist/bun/plugin.js +1 -1
- package/dist/bun/preload.js +1 -1
- package/dist/{chunk-jdj7k3r9.js → chunk-0a2xgcj3.js} +2 -2
- package/dist/{chunk-jdj7k3r9.js.map → chunk-0a2xgcj3.js.map} +1 -1
- package/dist/{chunk-3e88tyee.js → chunk-3337e5g0.js} +2 -2
- package/dist/{chunk-3e88tyee.js.map → chunk-3337e5g0.js.map} +1 -1
- package/dist/chunk-3aa287k7.js +6 -0
- package/dist/{chunk-cv9w5cmb.js.map → chunk-3aa287k7.js.map} +2 -2
- package/dist/{chunk-01am9k5v.js → chunk-3g5bjvdf.js} +2 -2
- package/dist/{chunk-01am9k5v.js.map → chunk-3g5bjvdf.js.map} +1 -1
- package/dist/{chunk-w9k9s4wh.js → chunk-3xadx444.js} +2 -2
- package/dist/{chunk-w9k9s4wh.js.map → chunk-3xadx444.js.map} +1 -1
- package/dist/{chunk-npg72mez.js → chunk-3zxwscmf.js} +2 -2
- package/dist/{chunk-kgmr9qxx.js.map → chunk-3zxwscmf.js.map} +1 -1
- package/dist/{chunk-64s1pzz1.js → chunk-437085pe.js} +2 -2
- package/dist/{chunk-64s1pzz1.js.map → chunk-437085pe.js.map} +1 -1
- package/dist/{chunk-eqrd31ye.js → chunk-4yt5x8s2.js} +2 -2
- package/dist/{chunk-eqrd31ye.js.map → chunk-4yt5x8s2.js.map} +1 -1
- package/dist/{chunk-9r0sb4zn.js → chunk-5athahgr.js} +2 -2
- package/dist/{chunk-9r0sb4zn.js.map → chunk-5athahgr.js.map} +1 -1
- package/dist/{chunk-g30q4n5y.js → chunk-5n2rvfh3.js} +2 -2
- package/dist/{chunk-g30q4n5y.js.map → chunk-5n2rvfh3.js.map} +1 -1
- package/dist/{chunk-1zfsgffv.js → chunk-6235kb30.js} +3 -3
- package/dist/{chunk-1zfsgffv.js.map → chunk-6235kb30.js.map} +1 -1
- package/dist/{chunk-javjeayw.js → chunk-7b0x860b.js} +2 -2
- package/dist/{chunk-javjeayw.js.map → chunk-7b0x860b.js.map} +1 -1
- package/dist/{chunk-4qwwy968.js → chunk-7ef5n8k2.js} +2 -2
- package/dist/{chunk-4qwwy968.js.map → chunk-7ef5n8k2.js.map} +1 -1
- package/dist/{chunk-q0waxxz5.js → chunk-7j6wbv12.js} +2 -2
- package/dist/{chunk-q0waxxz5.js.map → chunk-7j6wbv12.js.map} +1 -1
- package/dist/chunk-86jebsm4.js +9 -0
- package/dist/{chunk-kry5vwam.js.map → chunk-86jebsm4.js.map} +3 -3
- package/dist/chunk-87qab82w.js +5 -0
- package/dist/chunk-87qab82w.js.map +37 -0
- package/dist/{chunk-36pg61vt.js → chunk-8gew8b9a.js} +2 -2
- package/dist/{chunk-36pg61vt.js.map → chunk-8gew8b9a.js.map} +1 -1
- package/dist/{chunk-v6v6sem5.js → chunk-9m2tbf3n.js} +2 -2
- package/dist/{chunk-v6v6sem5.js.map → chunk-9m2tbf3n.js.map} +1 -1
- package/dist/{chunk-gzdf2025.js → chunk-a2sgjpvq.js} +2 -2
- package/dist/{chunk-gzdf2025.js.map → chunk-a2sgjpvq.js.map} +1 -1
- package/dist/chunk-b35e128b.js +5 -0
- package/dist/{chunk-b50zmz3t.js.map → chunk-b35e128b.js.map} +1 -1
- package/dist/{chunk-ct274qts.js → chunk-cyaz97p5.js} +2 -2
- package/dist/{chunk-ct274qts.js.map → chunk-cyaz97p5.js.map} +1 -1
- package/dist/{chunk-v06qcyj5.js → chunk-d125j8t0.js} +3 -3
- package/dist/{chunk-v06qcyj5.js.map → chunk-d125j8t0.js.map} +1 -1
- package/dist/{chunk-hs5v3eqj.js → chunk-dgsgjg53.js} +2 -2
- package/dist/{chunk-hs5v3eqj.js.map → chunk-dgsgjg53.js.map} +1 -1
- package/dist/{chunk-xjy5apyr.js → chunk-eejmhtnc.js} +2 -2
- package/dist/{chunk-xjy5apyr.js.map → chunk-eejmhtnc.js.map} +1 -1
- package/dist/{chunk-3y75q5a2.js → chunk-fjm4y8bn.js} +2 -2
- package/dist/{chunk-3y75q5a2.js.map → chunk-fjm4y8bn.js.map} +1 -1
- package/dist/{chunk-9c89q2mz.js → chunk-grdahng8.js} +2 -2
- package/dist/{chunk-9c89q2mz.js.map → chunk-grdahng8.js.map} +1 -1
- package/dist/{chunk-699z6d8y.js → chunk-gw6agevz.js} +3 -3
- package/dist/{chunk-699z6d8y.js.map → chunk-gw6agevz.js.map} +1 -1
- package/dist/{chunk-62ke19q4.js → chunk-hppagzz4.js} +4 -4
- package/dist/{chunk-62ke19q4.js.map → chunk-hppagzz4.js.map} +1 -1
- package/dist/chunk-hwa5sqw5.js +19 -0
- package/dist/{chunk-tmnhkphv.js.map → chunk-hwa5sqw5.js.map} +12 -6
- package/dist/chunk-hxf1re93.js +4 -0
- package/dist/{chunk-vkngcrzq.js.map → chunk-hxf1re93.js.map} +6 -5
- package/dist/{chunk-d36dfqxw.js → chunk-j0c6ytkj.js} +3 -3
- package/dist/{chunk-d36dfqxw.js.map → chunk-j0c6ytkj.js.map} +1 -1
- package/dist/{chunk-kgmr9qxx.js → chunk-jhkjz9jr.js} +2 -2
- package/dist/{chunk-npg72mez.js.map → chunk-jhkjz9jr.js.map} +1 -1
- package/dist/{chunk-62723jyy.js → chunk-k0fvsyeh.js} +1 -1
- package/dist/{chunk-31kcf7dq.js → chunk-keehyx51.js} +2 -2
- package/dist/{chunk-31kcf7dq.js.map → chunk-keehyx51.js.map} +1 -1
- package/dist/{chunk-enhkf60v.js → chunk-m3xy5xyf.js} +2 -2
- package/dist/{chunk-enhkf60v.js.map → chunk-m3xy5xyf.js.map} +1 -1
- package/dist/{chunk-c75mymmq.js → chunk-mkfpnymy.js} +1 -1
- package/dist/{chunk-rgb69nh1.js → chunk-mwpdp09e.js} +2 -2
- package/dist/{chunk-rgb69nh1.js.map → chunk-mwpdp09e.js.map} +1 -1
- package/dist/chunk-pmhd6zfc.js +37 -0
- package/dist/chunk-pmhd6zfc.js.map +20 -0
- package/dist/chunk-qb5mv6pj.js +5 -0
- package/dist/chunk-qb5mv6pj.js.map +12 -0
- package/dist/{chunk-1pwwrpa3.js → chunk-qgxr0g36.js} +2 -2
- package/dist/{chunk-1pwwrpa3.js.map → chunk-qgxr0g36.js.map} +1 -1
- package/dist/{chunk-4yafsffx.js → chunk-sy7jbdeb.js} +2 -2
- package/dist/{chunk-4yafsffx.js.map → chunk-sy7jbdeb.js.map} +1 -1
- package/dist/{chunk-gasdfwva.js → chunk-szss069z.js} +2 -2
- package/dist/{chunk-gasdfwva.js.map → chunk-szss069z.js.map} +1 -1
- package/dist/{chunk-m0ggfy1m.js → chunk-tss5svjr.js} +2 -2
- package/dist/{chunk-m0ggfy1m.js.map → chunk-tss5svjr.js.map} +1 -1
- package/dist/{chunk-dzzmqv0j.js → chunk-vr90r27j.js} +2 -2
- package/dist/{chunk-dzzmqv0j.js.map → chunk-vr90r27j.js.map} +1 -1
- package/dist/{chunk-pvdbrt4z.js → chunk-w62m5f0n.js} +3 -3
- package/dist/{chunk-pvdbrt4z.js.map → chunk-w62m5f0n.js.map} +1 -1
- package/dist/{chunk-cn2r5jfj.js → chunk-w7rf99w6.js} +2 -2
- package/dist/{chunk-cn2r5jfj.js.map → chunk-w7rf99w6.js.map} +1 -1
- package/dist/{chunk-tja0c815.js → chunk-wbrj0gya.js} +2 -2
- package/dist/{chunk-tja0c815.js.map → chunk-wbrj0gya.js.map} +1 -1
- package/dist/{chunk-rsdg619q.js → chunk-xdv1b8mr.js} +2 -2
- package/dist/{chunk-rsdg619q.js.map → chunk-xdv1b8mr.js.map} +1 -1
- package/dist/{chunk-h3mwgbg7.js → chunk-xey9cbap.js} +2 -2
- package/dist/{chunk-h3mwgbg7.js.map → chunk-xey9cbap.js.map} +1 -1
- package/dist/{chunk-wgpa04jb.js → chunk-xzk827r3.js} +2 -2
- package/dist/{chunk-wgpa04jb.js.map → chunk-xzk827r3.js.map} +1 -1
- package/dist/{chunk-x14sk95v.js → chunk-y6a8r2bn.js} +3 -3
- package/dist/{chunk-x14sk95v.js.map → chunk-y6a8r2bn.js.map} +1 -1
- package/dist/{chunk-33wjsw4r.js → chunk-yed5whgs.js} +3 -3
- package/dist/{chunk-33wjsw4r.js.map → chunk-yed5whgs.js.map} +1 -1
- package/dist/{chunk-02gdzs5t.js → chunk-yf7vz71n.js} +1 -1
- package/dist/{chunk-y9fp58bg.js → chunk-yjzs247s.js} +2 -2
- package/dist/{chunk-y9fp58bg.js.map → chunk-yjzs247s.js.map} +1 -1
- package/dist/{chunk-kgg1eqne.js → chunk-yy0eb9wn.js} +2 -2
- package/dist/{chunk-kgg1eqne.js.map → chunk-yy0eb9wn.js.map} +1 -1
- package/dist/{chunk-4xx78ba9.js → chunk-zbxgbr12.js} +2 -2
- package/dist/{chunk-4xx78ba9.js.map → chunk-zbxgbr12.js.map} +1 -1
- package/dist/{chunk-8k1zqrvh.js → chunk-zh2egcyb.js} +2 -2
- package/dist/{chunk-8k1zqrvh.js.map → chunk-zh2egcyb.js.map} +1 -1
- package/dist/chunks/ThemeProvider-li1J_igh.js.map +1 -1
- package/dist/client/ClientRouter.d.ts.map +1 -1
- package/dist/client/ProgressManager.d.ts +1 -1
- package/dist/client/RouteStateContext.d.ts +9 -0
- package/dist/client/RouteStateContext.d.ts.map +1 -1
- package/dist/client/ServerDataProvider.d.ts +7 -0
- package/dist/client/ServerDataProvider.d.ts.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +68 -10
- package/dist/client/index.js.map +1 -1
- package/dist/client/rpc.d.ts +42 -0
- package/dist/client/rpc.d.ts.map +1 -1
- package/dist/client/useFeature.d.ts +40 -0
- package/dist/client/useFeature.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/Features.d.ts +57 -0
- package/dist/facades/Features.d.ts.map +1 -0
- package/dist/facades/index.d.ts +1 -0
- package/dist/facades/index.d.ts.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/gemi.d.ts +13 -5
- package/dist/http/ApiRouter.d.ts +3 -2
- package/dist/http/ApiRouter.d.ts.map +1 -1
- package/dist/http/HttpRequest.d.ts +4 -0
- package/dist/http/HttpRequest.d.ts.map +1 -1
- package/dist/http/ViewRouter.d.ts +127 -4
- package/dist/http/ViewRouter.d.ts.map +1 -1
- package/dist/http/index.d.ts +1 -0
- 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/http/middlewareList.d.ts +25 -0
- package/dist/http/middlewareList.d.ts.map +1 -0
- package/dist/http/requestContext.d.ts +57 -0
- package/dist/http/requestContext.d.ts.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 +1 -1
- package/dist/ide/typescript-plugin/index.js +1206 -0
- package/dist/ide/typescript-plugin/index.js.map +17 -0
- package/dist/kernel/index.js +3 -3
- package/dist/kernel/index.js.map +3 -3
- package/dist/kernel/providers.d.ts +16 -4
- package/dist/kernel/providers.d.ts.map +1 -1
- package/dist/orm/context.d.ts +65 -0
- package/dist/orm/context.d.ts.map +1 -1
- package/dist/orm/index.js +2 -2
- package/dist/orm/index.js.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/services/discovery.d.ts +27 -0
- package/dist/services/discovery.d.ts.map +1 -1
- package/dist/services/events/Event.d.ts +208 -0
- package/dist/services/events/Event.d.ts.map +1 -0
- package/dist/services/events/EventManager.d.ts +285 -0
- package/dist/services/events/EventManager.d.ts.map +1 -0
- package/dist/services/events/EventServiceProvider.d.ts +46 -0
- package/dist/services/events/EventServiceProvider.d.ts.map +1 -0
- package/dist/services/events/FakeEventManager.d.ts +155 -0
- package/dist/services/events/FakeEventManager.d.ts.map +1 -0
- package/dist/services/events/FakeEventManager.test-d.d.ts +2 -0
- package/dist/services/events/FakeEventManager.test-d.d.ts.map +1 -0
- package/dist/services/events/Listener.d.ts +189 -0
- package/dist/services/events/Listener.d.ts.map +1 -0
- package/dist/services/events/Listener.test-d.d.ts +2 -0
- package/dist/services/events/Listener.test-d.d.ts.map +1 -0
- package/dist/services/events/config.d.ts +55 -0
- package/dist/services/events/config.d.ts.map +1 -0
- package/dist/services/events/listenerJob.d.ts +43 -0
- package/dist/services/events/listenerJob.d.ts.map +1 -0
- package/dist/services/features/FeatureFlagStore.d.ts +60 -0
- package/dist/services/features/FeatureFlagStore.d.ts.map +1 -0
- package/dist/services/features/FeatureManager.d.ts +82 -0
- package/dist/services/features/FeatureManager.d.ts.map +1 -0
- package/dist/services/features/FeaturesServiceProvider.d.ts +6 -0
- package/dist/services/features/FeaturesServiceProvider.d.ts.map +1 -0
- package/dist/services/features/bucket.d.ts +57 -0
- package/dist/services/features/bucket.d.ts.map +1 -0
- package/dist/services/features/config.d.ts +57 -0
- package/dist/services/features/config.d.ts.map +1 -0
- package/dist/services/features/context.d.ts +31 -0
- package/dist/services/features/context.d.ts.map +1 -0
- package/dist/services/features/defineFeature.d.ts +145 -0
- package/dist/services/features/defineFeature.d.ts.map +1 -0
- package/dist/services/features/evaluate.d.ts +74 -0
- package/dist/services/features/evaluate.d.ts.map +1 -0
- package/dist/services/features/sources/DatabaseFeatureFlagSource.d.ts +19 -0
- package/dist/services/features/sources/DatabaseFeatureFlagSource.d.ts.map +1 -0
- package/dist/services/features/sources/FeatureFlagSource.d.ts +30 -0
- package/dist/services/features/sources/FeatureFlagSource.d.ts.map +1 -0
- package/dist/services/features/sources/StaticFeatureFlagSource.d.ts +24 -0
- package/dist/services/features/sources/StaticFeatureFlagSource.d.ts.map +1 -0
- package/dist/services/features/types.d.ts +63 -0
- package/dist/services/features/types.d.ts.map +1 -0
- package/dist/services/index.d.ts +18 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +8 -8
- package/dist/services/index.js.map +8 -4
- package/dist/services/queue/QueueManager.d.ts +31 -0
- package/dist/services/queue/QueueManager.d.ts.map +1 -1
- package/dist/services/router/ViewRouteDispatcher.d.ts +8 -0
- package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
- package/dist/services/router/createFlatViewRoutes.d.ts +14 -0
- package/dist/services/router/createFlatViewRoutes.d.ts.map +1 -1
- package/dist/services/router/streamQueryInjection.d.ts.map +1 -1
- package/dist/support/index.js +2 -2
- package/dist/support/index.js.map +1 -1
- package/dist/testing/Page.d.ts +12 -0
- package/dist/testing/Page.d.ts.map +1 -1
- package/dist/testing/index.d.ts +24 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +7 -3
- package/dist/testing/index.js.map +1 -1
- package/ide/typescript-plugin/package.json +5 -0
- package/package.json +4 -2
- package/dist/chunk-4t80js0n.js +0 -33
- package/dist/chunk-4t80js0n.js.map +0 -18
- package/dist/chunk-98a576s9.js +0 -5
- package/dist/chunk-98a576s9.js.map +0 -30
- package/dist/chunk-b50zmz3t.js +0 -5
- package/dist/chunk-cv9w5cmb.js +0 -6
- package/dist/chunk-f9mfw82d.js +0 -5
- package/dist/chunk-f9mfw82d.js.map +0 -12
- package/dist/chunk-kry5vwam.js +0 -9
- package/dist/chunk-tmnhkphv.js +0 -19
- package/dist/chunk-vkngcrzq.js +0 -4
- /package/dist/{chunk-62723jyy.js.map → chunk-k0fvsyeh.js.map} +0 -0
- /package/dist/{chunk-c75mymmq.js.map → chunk-mkfpnymy.js.map} +0 -0
- /package/dist/{chunk-02gdzs5t.js.map → chunk-yf7vz71n.js.map} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../services/cron/Scheduler.ts", "../auth/AuthServiceProvider.ts", "../services/cron/ScheduleServiceProvider.ts", "../services/features/sources/FeatureFlagSource.ts", "../services/features/sources/DatabaseFeatureFlagSource.ts", "../services/features/config.ts", "../services/features/FeaturesServiceProvider.ts", "../services/email/MailServiceProvider.ts", "../services/events/listenerJob.ts", "../services/events/EventManager.ts", "../services/events/EventServiceProvider.ts", "../services/file-storage/FilesystemServiceProvider.ts", "../services/image-optimization/ImageServiceProvider.ts", "../services/kernel-id/KernelIdServiceProvider.ts", "../services/logging/config.ts", "../services/logging/LogServiceProvider.ts", "../services/middleware/MiddlewareServiceProvider.ts", "../services/pubsub/config.ts", "../services/pubsub/BroadcastServiceProvider.ts", "../services/queue/QueueServiceProvider.ts", "../services/rate-limiter/drivers/RateLimiterDriver.ts", "../services/rate-limiter/slidingWindow.ts", "../services/rate-limiter/drivers/InMemoryRateLimiterDriver.ts", "../services/rate-limiter/config.ts", "../services/rate-limiter/RateLimiterServiceProvider.ts", "../services/redis/config.ts", "../services/redis/RedisServiceProvider.ts", "../services/router/RouteServiceProvider.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { CronJob } from \"./CronJob\";\nimport type { ScheduleConfig } from \"./config\";\n\n// The handle the in-process `Bun.cron(schedule, callback)` overload returns\n// (has `.stop()`). `ReturnType<typeof Bun.cron>` can't be used — it resolves to\n// the module-path overload's `Promise<void>` instead.\ntype BunCronHandle = Bun.CronJob;\n\n// Runs a tick inside whatever async context the framework needs, so a job body\n// can resolve services exactly like a request handler can.\nexport type ScheduleRunner = <T>(cb: () => T | Promise<T>) => Promise<T> | T;\n\ndeclare global {\n // Registered cron jobs keyed by name, kept on `globalThis` so it survives\n // `bun --hot` reloads. Re-registering a name stops the previous schedule\n // first, so a reload *updates* the job in place instead of stacking a\n // duplicate. (Bun also stops all in-process cron jobs before re-evaluating on\n // hot reload; this makes the intent explicit and covers any re-construction.)\n var __gemiCronJobs: Map<string, BunCronHandle> | undefined;\n}\n\n/**\n * One tick of one job: the gate, then the three hooks in order.\n *\n * Named and exported rather than left inline in `start()` because otherwise the\n * only way to reach it is to wait — the tightest schedule `Bun.cron` accepts is\n * once a minute, which is not a thing a test can honestly sit through. What a\n * caller gives up by calling this directly is Bun's clock; what it keeps is\n * everything the scheduler puts between the clock and the job, which is the\n * part that has behaviour.\n *\n * The three hooks each catch and log, so one throwing does not stop the next —\n * `onComplete` in particular runs whether `callback` returned or threw, closer\n * to a `finally` than to a success handler.\n */\nexport async function runTick(job: CronJob): Promise<void> {\n try {\n // Plain truthiness, not `!== false`. The sloppy gate an app writes is\n // `if (!isProduction) return false;`, which returns `undefined` on the path\n // that was meant to run — and between the two readings of that, the one\n // that skips a recurring tick is recoverable and the one that mails a\n // customer from a developer's laptop is not. The declared return type makes\n // that method a compile error anyway, so the type system catches it while\n // it is still being written and the runtime stays on the safe side.\n if (!(await job.shouldRun.call(job))) {\n return;\n }\n } catch (error) {\n // Fail closed, for the same reason. A gate that throws has told us nothing\n // about whether the job may run, and the framework already refuses to\n // schedule a job whose name or expression it cannot read rather than run\n // something half-declared. The throw is logged, so this is loud; the missed\n // tick comes back on the next one.\n console.error(\n `Error evaluating shouldRun for cron job ${job.name}:`,\n error,\n );\n return;\n }\n\n try {\n await job.onTick.call(job);\n } catch (error) {\n console.error(`Error executing cron job ${job.name}:`, error);\n }\n try {\n await job.callback.call(job);\n } catch (error) {\n console.error(`Error in cron job ${job.name}:`, error);\n }\n try {\n await job.onComplete.call(job);\n } catch (error) {\n console.error(`Error completing cron job ${job.name}:`, error);\n }\n}\n\nexport class Scheduler {\n static token = \"scheduler\";\n\n private handles: BunCronHandle[] = [];\n private resolved: Array<new () => CronJob>;\n\n constructor(config: Required<ScheduleConfig>) {\n this.resolved = config.jobs;\n }\n\n /**\n * The jobs this scheduler will run, or ran — declared in the config slice or\n * discovered under `app/cron`, whichever the slice asked for.\n *\n * #323 turned an application's schedule from an array it could import into a\n * directory it cannot, and an app that had a test walking that array —\n * asserting every report has an owner, that no two share an expression — was\n * about to lose it. This is where that test goes instead, and it is the\n * better question anyway: the config slice says what was asked for, this says\n * what the scheduler took.\n *\n * It lists what `start()` iterates, not what `Bun.cron` accepted. A job with\n * no name, no expression, or a name another job already claimed is logged and\n * skipped, and still appears here — a test walking this should see the\n * problem rather than have it tidied away.\n *\n * A copy, so that walk cannot edit the set the scheduler is running from.\n */\n get jobs(): ReadonlyArray<new () => CronJob> {\n return [...this.resolved];\n }\n\n /**\n * Replaces the job set, for the provider to hand over what it found under\n * `app/cron` before it calls `start()`.\n *\n * The scheduler is constructed in `register()`, where reading a directory and\n * importing what is in it is not allowed to happen — that phase is\n * synchronous and resolves nothing. So it is built from whatever the slice\n * declared and corrected in `boot()`, one line before it starts. Calling this\n * after `start()` changes what `jobs` reports and nothing else; the schedules\n * are already registered.\n */\n useJobs(jobs: Array<new () => CronJob>) {\n this.resolved = jobs;\n }\n\n /**\n * Schedules every configured job. Called from `ScheduleServiceProvider.boot()`\n * — never from the constructor — so a job body may resolve any service the\n * container holds by the time it first ticks. That ordering is what replaced\n * the old `kernel.waitForBoot()` handshake.\n */\n start(run: ScheduleRunner = (cb) => cb()) {\n if (this.resolved.length === 0) {\n return;\n }\n\n const registry = (globalThis.__gemiCronJobs ??= new Map());\n\n // Names claimed during *this* pass, which is a different question from what\n // `registry` holds. `registry` spans hot reloads and is supposed to already\n // contain the previous reload's handle under the same name; this starts\n // empty every time and is how a name claimed twice in one schedule is told\n // apart from the same job coming back after an edit.\n const claimed = new Map<string, string>();\n\n for (const Job of this.resolved) {\n const job = new Job();\n if (!job.name) {\n // Named by its class, because under discovery nobody wrote this job\n // down anywhere and `JSON.stringify(job)` on a nameless one prints\n // `{}`. The overwhelmingly common cause is the second sentence: a\n // shared base class sitting in the walked directory. `abstract` is\n // erased before this code runs, so there is nothing here that could\n // tell a base class from a job — only the message can.\n console.error(\n `Cron job must have a name — ${Job.name || \"an anonymous class\"} ` +\n `has none, so it is not scheduled. If this is a base class that ` +\n `other jobs extend, move it out of the discovered directory: ` +\n `\\`abstract\\` does not survive to runtime, so a class under ` +\n `app/cron is indistinguishable from a job.`,\n );\n continue;\n }\n if (!job.cron) {\n console.error(`Cron job must have an expression. Job: ${job.name}`);\n continue;\n }\n const taken = claimed.get(job.name);\n if (taken !== undefined) {\n // Refusing the second one, rather than letting it through to the\n // `registry.get(...).stop()` below — which is what used to happen, and\n // it stopped the *first* job's schedule while leaving both classes in\n // `jobs`. That is the failure #323 exists to remove wearing a disguise:\n // a report that silently stops arriving, and a test walking `jobs` that\n // sees two healthy entries and passes.\n console.error(\n `Two cron jobs claim the name \"${job.name}\" — ${taken} is ` +\n `scheduled and ${Job.name || \"an anonymous class\"} is not. A name ` +\n `is the scheduler's key, so only one job can hold it. Rename one.`,\n );\n continue;\n }\n claimed.set(job.name, Job.name || \"an anonymous class\");\n\n // Update in place: stop any schedule previously registered under this name\n // before re-registering, so a hot reload replaces rather than duplicates.\n registry.get(job.name)?.stop();\n\n // Inside `run`, gate included: a `shouldRun` that resolves a service to\n // decide is the ordinary case, and evaluating it out here would leave it\n // without the application context every other line of the tick has.\n const handle = Bun.cron(job.cron, () => run(() => runTick(job)));\n\n registry.set(job.name, handle);\n this.handles.push(handle);\n }\n }\n\n stop() {\n for (const handle of this.handles) {\n handle.stop();\n }\n this.handles = [];\n }\n}\n",
|
|
6
|
+
"import { ServiceProvider } from \"../support/ServiceProvider\";\nimport type { AuthConfig } from \"./config\";\nimport { AuthManager } from \"./AuthManager\";\n\nexport class AuthServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n AuthManager,\n () => new AuthManager(this.app.config.get<AuthConfig>(\"auth\", {})),\n );\n }\n}\n",
|
|
7
|
+
"import { kernelContext } from \"../../kernel/context\";\nimport { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { discoverCronJobs } from \"../discovery\";\nimport { scheduleConfigDefaults, type ScheduleConfig } from \"./config\";\nimport { Scheduler } from \"./Scheduler\";\n\nexport class ScheduleServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n Scheduler,\n () =>\n new Scheduler(\n withDefaults(\n scheduleConfigDefaults(),\n this.app.config.get<ScheduleConfig>(\"schedule\", {}),\n ),\n ),\n );\n }\n\n /**\n * Resolves the schedule, then starts it.\n *\n * Cron jobs are scheduled in phase two, not in `register()`: a job body is\n * free to resolve any service, and by the time `boot()` runs every provider\n * has registered. Each tick re-enters the application context so the job sees\n * the same container a request handler would.\n *\n * ### Why the raw slice and not the scheduler's config\n *\n * The decision here is whether the app said anything, and by the time the\n * scheduler holds a config it can no longer tell: `withDefaults` treats an\n * absent key and an `undefined` one alike and substitutes the default `[]`,\n * which is the same value an app writes when it means \"nothing scheduled, and\n * I mean it\". Reading the slice before defaults are applied is the only place\n * that difference still exists.\n *\n * So: `jobs` present, including `jobs: []`, is used verbatim and no directory\n * is read. Absent or `undefined` — which includes an app with no `schedule`\n * slice at all — the classes under `jobsDir` are, which is the case #323 is\n * about: a cron job that is written and never listed fires never, and nothing\n * downstream is waiting to notice.\n */\n async boot() {\n const scheduler = this.app.make(Scheduler);\n const slice = this.app.config.get<ScheduleConfig>(\"schedule\", {});\n\n if (slice.jobs === undefined) {\n const { jobsDir } = withDefaults(scheduleConfigDefaults(), slice);\n scheduler.useJobs(await discoverCronJobs(jobsDir));\n }\n\n // Resolved, listed, and not started.\n //\n // `gemi run` sets this on the process it spawns. Booting the application is\n // how a console command reaches the container, and starting the schedule is\n // a side effect of that which nobody asked for: a `gemi run backfill` that\n // takes four minutes would otherwise fire the application's whole cron\n // schedule in a process no operator is watching, and `Bun.cron` handles hold\n // the loop open besides.\n //\n // Deliberately above `start` and below `useJobs`, so `app(Scheduler).jobs`\n // still answers honestly — a command that wants to fire a tick by hand can,\n // and a test asking what this application schedules gets the same answer\n // either way.\n //\n // An environment variable rather than a config field, because this is a\n // property of *this process* and not of the application: the same variable\n // is how a deploy runs one cron dyno beside several web ones, and a config\n // slice would have to know which command started it.\n if (process.env.GEMI_NO_SCHEDULE === \"1\") return;\n\n const app = this.app;\n scheduler.start((cb) => kernelContext.run(app, cb));\n }\n}\n",
|
|
8
|
+
"/**\n * Where the on/off switches come from.\n *\n * A seam rather than a hardcoded query for two reasons that already exist: the\n * database source cannot run in a unit test without a schema and a connection,\n * and an application that outgrows a table — a control plane, a config service —\n * should not have to fork the evaluator to move.\n *\n * `load()` returns **raw rows**, not booleans. A source fetches; the store\n * interprets, because the store is the half that knows which keys are declared.\n */\nexport abstract class FeatureFlagSource {\n /**\n * Every row.\n *\n * Returning `[]` means \"nothing is switched on\", which is a normal state — it\n * is what a fresh database looks like, and every feature is correctly off.\n * **Throwing** means \"I could not tell you\", which is different: the store\n * keeps serving whatever it last had rather than treating an outage as a mass\n * switch-off.\n */\n abstract load(): Promise<Record<string, unknown>[]>;\n}\n\n/** Raised when the application never added the model this source reads. */\nexport class FeatureModelMissingError extends Error {\n readonly kind = \"FeatureModelMissing\";\n\n constructor(readonly modelName: string) {\n super(\n `No \"${modelName}\" model is registered, so every feature stays off. Add the model to prisma/schema.prisma and export it from app/models — see docs/feature-flags.md.`,\n );\n }\n}\n",
|
|
9
|
+
"import * as registry from \"../../../orm/registry\";\nimport { FeatureFlagSource, FeatureModelMissingError } from \"./FeatureFlagSource\";\n\n/**\n * Reads the application's `FeatureFlag` table — one row per feature, carrying\n * one meaningful column.\n *\n * The model is resolved from the ORM registry **by name, at call time**, the way\n * `auth/UserProvider` resolves `User`. The framework cannot import a class the\n * application generates, and resolving lazily also means constructing this\n * source does not require the app's models to have been imported yet — only\n * loading does.\n */\nexport class DatabaseFeatureFlagSource extends FeatureFlagSource {\n constructor(readonly modelName: string = \"FeatureFlag\") {\n super();\n }\n\n /** Whether the application has registered the model at all. */\n get available(): boolean {\n return registry.has(this.modelName);\n }\n\n async load(): Promise<Record<string, unknown>[]> {\n if (!this.available) {\n throw new FeatureModelMissingError(this.modelName);\n }\n\n const model = registry.get<any>(this.modelName);\n\n // `asSystem` for the same reason auth uses it: features are read before\n // there is a user — on an anonymous page load, in a cron tick — and a policy\n // that denies by default would turn \"nobody is signed in\" into \"no rows\",\n // which silently switches every feature off for logged-out traffic.\n return await model.asSystem(() => model.findMany());\n }\n}\n",
|
|
10
|
+
"import type { HttpRequest } from \"../../http/HttpRequest\";\nimport type { FeatureRegistry } from \"./defineFeature\";\nimport { DatabaseFeatureFlagSource } from \"./sources/DatabaseFeatureFlagSource\";\nimport type { FeatureFlagSource } from \"./sources/FeatureFlagSource\";\nimport type { FeatureContext, FeatureEvaluation } from \"./types\";\n\n// Config key: `features`. Derived from `FeaturesServiceProvider`.\nexport interface FeaturesConfig {\n /**\n * The application's declarations — the default export of\n * `app/features/index.ts`.\n *\n * Named here as well as in the framework's `gemi.d.ts` because the two layers\n * cannot share one reference: the type augmentation resolves `@/app/features`\n * through the app's tsconfig paths, which exists only at compile time. This is\n * the runtime half. They should point at the same object.\n */\n features?: FeatureRegistry;\n\n /**\n * Master switch. `false` skips loading and evaluation entirely: every feature\n * reads off and the SSR payload carries `{}`.\n */\n enabled?: boolean;\n\n /** Where the on/off switches come from. The database by default. */\n source?: FeatureFlagSource;\n\n /** ORM registry name of the model, when using the database source. */\n model?: string;\n\n /**\n * Snapshot lifetime in **seconds**.\n *\n * This is the propagation delay: switching a feature on or off is live on\n * every instance within this window. Lower it if that matters more than the\n * query volume — there is no cross-instance invalidation.\n */\n ttl?: number;\n\n /**\n * Extra attributes for every evaluation — country, cohort, build, plan.\n * Reachable in a `when` as `ctx.attributes`.\n *\n * Runs on every request inside the render path, so keep it cheap and free of\n * I/O. If it throws, evaluation degrades to no attributes rather than failing\n * the page.\n */\n context?: (req: HttpRequest | null) => Record<string, unknown> | Promise<Record<string, unknown>>;\n\n /**\n * Called once per key per request after evaluation — the hook an analytics or\n * experiment pipeline reads exposures from. Errors are caught and logged.\n */\n onEvaluate?: (key: string, evaluation: FeatureEvaluation, ctx: FeatureContext) => void;\n\n /** Warn once per boot above this many client-visible features. */\n maxClientFlags?: number;\n}\n\nexport function defineFeaturesConfig(config: FeaturesConfig): FeaturesConfig {\n return config;\n}\n\nexport function featuresConfigDefaults(): Required<\n Omit<FeaturesConfig, \"features\" | \"context\" | \"onEvaluate\">\n> & {\n features: FeaturesConfig[\"features\"];\n context: FeaturesConfig[\"context\"];\n onEvaluate: FeaturesConfig[\"onEvaluate\"];\n} {\n return {\n features: undefined,\n enabled: true,\n source: new DatabaseFeatureFlagSource(),\n model: \"FeatureFlag\",\n ttl: 30,\n context: undefined,\n onEvaluate: undefined,\n maxClientFlags: 200,\n };\n}\n\nexport type ResolvedFeaturesConfig = ReturnType<typeof featuresConfigDefaults>;\n",
|
|
11
|
+
"import { Log } from \"../../facades/Log\";\nimport { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { featuresConfigDefaults, type FeaturesConfig } from \"./config\";\nimport { FeatureManager } from \"./FeatureManager\";\nimport { DatabaseFeatureFlagSource } from \"./sources/DatabaseFeatureFlagSource\";\n\nexport class FeaturesServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(FeatureManager, () => {\n const declared = this.app.config.get<FeaturesConfig>(\"features\", {});\n const config = withDefaults(featuresConfigDefaults(), declared);\n\n // The default source is constructed by `featuresConfigDefaults()` with the\n // default model name, so a `model` override would otherwise be ignored\n // unless the app also replaced the source. Rebuild it here instead of\n // making every app that renames the table also know about the source.\n //\n // Keyed on what the *application* wrote, not on the merged values. The\n // merged `model` is always set — it defaults to `\"FeatureFlag\"` — so\n // comparing it against the source's name would fire for an app that\n // configured only `source: new DatabaseFeatureFlagSource(\"Flags\")`,\n // throwing that source away and pointing the replacement at a table the\n // app never mentioned. Every feature would then read off with nothing to\n // explain why.\n //\n // An explicit `source` always wins: it is the more specific statement, and\n // it is the only one of the two that can name something other than the\n // local table.\n if (declared?.model !== undefined && declared?.source === undefined) {\n config.source = new DatabaseFeatureFlagSource(declared.model);\n } else if (\n declared?.model !== undefined &&\n declared.source instanceof DatabaseFeatureFlagSource &&\n declared.source.modelName !== declared.model\n ) {\n Log.warning(\n `app/config/features.ts sets \\`model: \"${declared.model}\"\\` and a source reading \"${declared.source.modelName}\". The source wins; drop \\`model\\` to silence this.`,\n );\n }\n\n return new FeatureManager(config, (message) => Log.warning(message));\n });\n }\n\n async boot() {\n const features = this.app.make(FeatureManager);\n if (!features.config.enabled) return;\n\n // Warmed at boot so the first request is served from memory rather than\n // paying for the cold load. Wrapped because a database that is not up yet\n // must not fail the boot — the store fails closed, every feature reads off,\n // and it recovers on its own once the next TTL elapses.\n try {\n await features.refresh();\n } catch (error) {\n Log.error(\n `Could not warm the feature flag cache at boot. ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n}\n",
|
|
12
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport type { MailConfig } from \"./config\";\nimport { MailManager } from \"./MailManager\";\n\nexport class MailServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n MailManager,\n () => new MailManager(this.app.config.get<MailConfig>(\"mail\", {})),\n );\n }\n}\n",
|
|
13
|
+
"import { app } from \"../../foundation/app\";\nimport { Job } from \"../queue/Job\";\nimport { EventManager } from \"./EventManager\";\nimport type { Listener, ListenerClass } from \"./Listener\";\n\n/**\n * The adapter that lets `queued = true` be one line: a `Job` subclass, built at\n * registration, that runs exactly one listener.\n *\n * Retries, `maxAttempts`, dead-lettering, `concurrency` and worker-thread\n * execution are four features the queue already has, already documents for\n * applications, and is already tested on. A second queue for listeners would be\n * four features that are almost the same as those, differing in ways nobody\n * decided. So a queued listener is not queued by anything written here — it is\n * a job, and everything after `push` is the queue's.\n */\n\n/**\n * The name a listener's synthetic job is registered under.\n *\n * Prefixed, and visibly so. The synthetic jobs land in\n * `QueueManager.registeredJobs` alongside the app's own, because that getter is\n * documented as reporting what the manager was handed and a queued listener\n * genuinely is something the queue will run — hiding them would make a queue\n * introspection tool lie about what is about to execute. The prefix is what\n * keeps an author from reading `SendWelcomeEmail` there and looking for a job\n * file they never wrote.\n */\nexport function listenerJobName(listenerName: string): string {\n return `listener:${listenerName}`;\n}\n\n/**\n * Builds the `Job` subclass that runs one queued listener.\n *\n * `instance` is the listener the caller already constructed to read `queued`\n * off; the three fields that decide where the work runs are read from that one\n * instance rather than from a fresh one per attempt, so a listener's\n * constructor runs once at boot instead of once per retry.\n *\n * What crosses the queue is `[eventName, constructorArguments]` as JSON — a\n * name and the arguments, never the event instance and never the classes. That\n * is invariant 1 at its second boundary: the class objects on the pushing side\n * and the running side can come from two different module graphs (a minified\n * bundle and a source-side discovery walk), so a name declared as a string\n * literal is the only thing both ends agree on. `EventManager.rehydrate` turns\n * it back into an event.\n */\nexport function jobForListener(\n listener: ListenerClass,\n instance: Listener,\n): new () => Job {\n refuseImplicitName(listener);\n\n const attempts = instance.maxAttempts;\n const inWorker = instance.worker;\n const boundTo = listener.event.name;\n\n const job = class extends Job {\n maxAttempts = attempts;\n worker = inWorker;\n\n async run(...payload: unknown[]) {\n const [eventName, args] = readPayload(payload);\n const event = app(EventManager).rehydrate(eventName, args);\n await new listener().handle(event);\n }\n\n // The queue's failure path is silent unless a job writes to it: `onFail`\n // and `onDeadletter` on `Job` are empty bodies, and `QueueManager.run`\n // routes every rejection into exactly those two. Without these overrides a\n // queued listener that throws produces no output anywhere — `dispatch`\n // returned long ago, the sync path's \"the listener X threw while handling\n // Y\" line is on a branch this listener never takes, and the last thing that\n // happens is the entry leaving the queue. A welcome email that stopped\n // being sent in production would look exactly like one that was never\n // dispatched.\n //\n // That is also what makes `rehydrate`'s throw the informative failure it is\n // documented as: a payload naming an event this process does not know is\n // the shape a `worker = true` listener hits when its thread booted a\n // different build of the application, and it is unreachable from the\n // dispatcher's stack.\n //\n // Both hooks, not one. `onFail` carries the error and fires per attempt, so\n // a listener failing differently on each is visible; `onDeadletter` fires\n // once and reports the fact no attempt is left, which is a different thing\n // to know and the only line that means the work is gone. The final attempt\n // logs both, deliberately.\n //\n // The event is named from `static event` rather than from the payload:\n // reading the payload here means parsing it, and a throw out of either hook\n // would escape through `QueueManager.run`'s `catch` into a `run()` nobody\n // awaits.\n onFail(error: Error) {\n console.error(\n `The listener ${listener.name} threw while handling ${boundTo} off ` +\n `the queue. The queue will retry it up to ${attempts} times in ` +\n `total; nothing the dispatcher did is waiting on it.`,\n error,\n );\n }\n\n onDeadletter(error: Error) {\n console.error(\n `The listener ${listener.name} failed every one of its ${attempts} ` +\n `attempts at ${boundTo} and has been dead-lettered, so this side ` +\n `effect did not happen and will not be retried.`,\n error,\n );\n }\n };\n\n // The `value` is load-bearing: the queue keys its registry off `job.name`,\n // so without it the entry would be named after whatever binding this class\n // expression picked up. `writable: true` is the other half, and nothing\n // reads it today — it is here so the descriptor matches the one a declared\n // `static name = \"...\"` field produces. Every \"was this name declared?\"\n // check in the framework is a descriptor read rather than a value read\n // (`discovery.ts`, and `refuseImplicitName` below), because in development\n // the declared and the implicit spelling read the same string; and\n // redefining `name` without the flag leaves the class's own non-writable\n // descriptor in place. So a check later pointed at a *registered* job rather\n // than a discovered one — the queue's registry is the obvious place to move\n // one — would report every synthetic entry as a job the author never wrote,\n // under a fix they cannot apply. Cheap to keep, wrong to drop.\n Object.defineProperty(job, \"name\", {\n value: listenerJobName(listener.name),\n writable: true,\n });\n\n return job;\n}\n\n/**\n * Refuses to queue a listener whose name is the implicit class binding.\n *\n * A sync listener's name is only ever read inside one module graph, so\n * discovery warns about this and moves on. A queued one puts the name on the\n * wire: the push side looks the job up by `listener:<name>` in its registry and\n * the running side looks it up in *its* registry, and those two can be\n * different builds of the same application — the main process discovering\n * `app/listeners` from source while a `worker = true` listener runs in a thread\n * that imported `dist/server/bootstrap.mjs`, where minification renamed the\n * class. The names then disagree, `dispatchJob` resolves nothing, the worker\n * reports success, and the side effect silently stops happening in production.\n *\n * A throw rather than a warning because the failure is invisible from every\n * side once it happens, and because the fix is one line the author can read in\n * the message.\n */\nfunction refuseImplicitName(listener: ListenerClass): void {\n if (Object.getOwnPropertyDescriptor(listener, \"name\")?.writable) return;\n\n throw new Error(\n `The listener ${listener.name} sets \\`queued = true\\` but does not ` +\n `declare \\`static name\\`, so it would be registered with the queue ` +\n `under its class name — which a production build renames while the ` +\n `payload that names it does not. Add: static name = \"${listener.name}\";`,\n );\n}\n\n/**\n * The payload, whichever of the two shapes the queue handed it over in.\n *\n * The queue calls `run` two different ways and this is the only place that has\n * to know. In-process, `QueueManager.run` spreads the parsed arguments:\n * `run(\"UserRegistered\", [7, \"ada@example.com\"])`. Through a worker thread the\n * far side is `QueueManager.dispatchJob`, which passes the parsed array whole:\n * `run([\"UserRegistered\", [7, \"ada@example.com\"]])`. Reading only the first\n * shape would make `worker = true` a listener that receives an event named\n * `undefined` — a throw out of `rehydrate`, in a worker thread, retried to\n * dead-letter.\n *\n * The two are told apart by what is in the first slot rather than by counting\n * arguments, because the payload's own first element is always the event name\n * and a name is always a string.\n */\nfunction readPayload(payload: unknown[]): [string, unknown[]] {\n return (typeof payload[0] === \"string\" ? payload : payload[0]) as [\n string,\n unknown[],\n ];\n}\n",
|
|
14
|
+
"import { app } from \"../../foundation/app\";\nimport { deferUntilCommit } from \"../../orm/context\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport type { Job } from \"../queue/Job\";\nimport { QueueManager } from \"../queue/QueueManager\";\nimport { eventConfigDefaults, type EventConfig } from \"./config\";\nimport type { Event, EventClass } from \"./Event\";\nimport { jobForListener } from \"./listenerJob\";\nimport type { ListenerClass } from \"./Listener\";\n\n/**\n * One listener, and where it runs.\n *\n * `queued` is an instance field, so answering \"does this one go on the queue?\"\n * means constructing the listener — done once here, at registration, rather\n * than once per dispatch. The synthetic job is built at the same moment for the\n * same reason: `EventServiceProvider.boot()` has to hand it to the queue before\n * the first dispatch, and a job built per dispatch would be a different class\n * object each time under the same registry key.\n */\ntype Registration = {\n listener: ListenerClass;\n /** The job a queued listener is pushed as, or `null` when it runs inline. */\n job: (new () => Job) | null;\n};\n\n/**\n * The registry a dispatch fans out through: event name -> the listeners bound\n * to it.\n *\n * Shaped after `QueueManager` deliberately — constructed in `register()` from\n * whatever the config slice declared, handed the discovered set in `boot()`,\n * and reporting through a `registered*` getter what it was *given* rather than\n * what it accepted, so a test can see a collision instead of having it tidied\n * away.\n *\n * Three things are not `QueueManager`'s, and each is a decision rather than a\n * detail:\n *\n * **Many listeners per key.** Two listeners for one event is the normal case\n * here, where two jobs for one name is the pathological one. So the map holds\n * arrays and `useListeners` appends. The collision it does refuse is two\n * *listener classes* claiming one `static name`.\n *\n * **Registration order is the walk's order, and means nothing.** It is stable —\n * `discoverClasses` sorts per directory and the module namespace sorts by name\n * — so it is reproducible, but no listener may depend on running before\n * another, because nothing about a filesystem layout was chosen to express\n * that. What makes it safe to say is the rule below: nothing a listener does\n * can stop the next one.\n *\n * **A dispatch nobody handles warns.** That is the entire early-warning system\n * for the subsystem, and it is why it is not optional; see `dispatchAndWait`.\n *\n * A `queued` listener is not run here at all. It is registered with the\n * `QueueManager` as a synthetic job and pushed to it on dispatch, so retries,\n * `maxAttempts`, dead-lettering and worker threads are the queue's rather than\n * a second implementation of the queue's — and nothing the request had (the\n * current actor, the ambient transaction) is still promised by the time it\n * runs. See `Listener.queued`.\n *\n * **A dispatch does not always fan out at the dispatch.** An event declaring\n * `static afterCommit` has the whole of it — queued listeners included — held\n * on the ORM's transaction scope and drained when that transaction commits, or\n * dropped when it rolls back. That is the only thing in this file that reads\n * ambient state, and `deferToCommit` is where it happens.\n */\nexport class EventManager {\n static token = \"events\";\n\n /** Event name -> every listener bound to it, in registration order. */\n private listeners: Record<string, Registration[]> = {};\n\n /**\n * Event name -> the class to rebuild it from, for a listener coming back off\n * the queue.\n *\n * Read from each listener's `static event` at registration, which is the one\n * place in the subsystem an event class is dereferenced. An event nobody\n * listens for is never in here, and that is exactly right: nothing can have\n * been queued for it.\n */\n private events: Record<string, EventClass> = {};\n\n /**\n * Event names already warned about. Per-manager, and the manager is per\n * application, so a test that builds a fresh kernel gets a fresh set.\n */\n private warnedFor = new Set<string>();\n\n /**\n * Event names already warned about for the `dispatchAndWait` + `afterCommit`\n * pairing. A second set rather than a second entry in the one above: the two\n * warnings are about different mistakes, and sharing the set would mean a\n * dispatch that legitimately has no listeners silences the one that says a\n * caller is awaiting nothing.\n */\n private warnedAboutWaiting = new Set<string>();\n\n readonly config: Required<EventConfig>;\n\n constructor(config: EventConfig = {}) {\n this.config = withDefaults(eventConfigDefaults(), config);\n this.useListeners(this.config.listeners);\n }\n\n /**\n * Replaces the registered set, for the provider to hand over what it found\n * under `app/listeners`.\n *\n * Two phases, for the reason `QueueManager.useJobs` documents: the manager is\n * constructed in `register()`, which is synchronous and must resolve nothing,\n * while reading a directory and importing what is in it is neither. So the\n * manager is built from whatever the config slice declared — nothing, when\n * the app left `listeners` out — and the discovered set arrives in `boot()`.\n *\n * The consequence worth knowing: anything that constructs an application and\n * skips phase two dispatches into an empty registry, and an empty registry is\n * a legal steady state rather than an error. The development-only warning\n * below is the only thing that says so.\n *\n * Every listener is **constructed once here**, to read the fields that decide\n * where it runs — `queued`, and through it `maxAttempts` and `worker`. A\n * listener's constructor therefore runs at boot as well as on every dispatch,\n * so it wants to assign fields and nothing else. A queued one also has its\n * synthetic job built here; `EventServiceProvider` hands those to the queue\n * once boot reaches it, so calling this again *after* boot would leave the\n * queue holding jobs for listeners this registry no longer has.\n */\n useListeners(listeners: ListenerClass[]) {\n this.config.listeners = listeners;\n\n this.listeners = {};\n this.events = {};\n const claimed = new Set<string>();\n\n for (const listener of listeners) {\n // Declared as required on the base class and still checked here: every\n // subclass inherits the declaration whether or not it assigns to it, so\n // `typeof SomeListener` satisfies `ListenerClass` either way and the\n // compiler cannot see the omission. Refused rather than registered under\n // some fallback, because there is no fallback — a listener with no event\n // is a file the author wrote that nothing will ever call.\n if (!listener.event) {\n console.error(\n `Listener ${listener.name} does not declare \\`static event\\`, so ` +\n `there is no event name to register it under and its handle will ` +\n `never run. Add: static event = SomeEvent;`,\n );\n continue;\n }\n\n // Two classes with one name, refused here and nowhere else — which is\n // what keeps the queue from being handed two jobs called\n // `listener:NotifyAdmins` and having to decide between them one layer\n // down, where the loser is a side effect that reports success. A\n // directory walk is what makes the clash ordinary, since nothing forces\n // the import alias a hand-written list would have demanded.\n if (claimed.has(listener.name)) {\n console.error(\n `Two event listeners are named \"${listener.name}\" — the first is ` +\n `registered and this one is not. A listener's name identifies it ` +\n `across the framework, so only one class can hold it. Rename one.`,\n );\n continue;\n }\n claimed.add(listener.name);\n\n // The one place the event class is dereferenced, and deliberately the\n // only one: this runs in the module graph that declared the class, so the\n // name it yields is the source-side one that discovery and a minified\n // dispatcher both agree on. Nothing downstream keeps the class object —\n // except `this.events`, which keeps it under that same string so a\n // listener coming back off the queue has something to rebuild from. First\n // claim wins there too: a name is what identifies an event to everything\n // downstream, so two classes declaring one are one event already.\n const name = listener.event.name;\n const instance = new listener();\n\n this.events[name] ??= listener.event;\n (this.listeners[name] ??= []).push({\n listener,\n job: instance.queued ? jobForListener(listener, instance) : null,\n });\n }\n }\n\n /**\n * The synthetic jobs the queue has to be told about — one per queued\n * listener, named `listener:<name>`.\n *\n * `EventServiceProvider.boot()` is the only caller. It reads this rather than\n * having the manager reach for the `QueueManager` itself, because\n * registration happens in `register()`, where resolving another service is\n * exactly what a provider must not do. A copy, so the caller cannot edit what\n * a dispatch pushes.\n */\n get queuedListenerJobs(): ReadonlyArray<new () => Job> {\n return Object.values(this.listeners)\n .flat()\n .flatMap(({ job }) => (job ? [job] : []));\n }\n\n /**\n * What the manager was handed, discovered or declared.\n *\n * \"Is this listener registered?\" is a question with a silent wrong answer —\n * an unregistered listener is a side effect that does not happen, and nothing\n * is waiting on it to notice. This is where a test asks it out loud.\n *\n * It reports what came in, not what the registry accepted, so a name claimed\n * twice appears twice here — deliberately, the same way `QueueManager` and\n * `Scheduler` do. A copy, so a walk over it cannot edit what dispatch reads.\n */\n get registeredListeners(): ReadonlyArray<ListenerClass> {\n return [...this.config.listeners];\n }\n\n /**\n * Fires the event and returns. The sync listeners run to completion after the\n * caller has moved on.\n *\n * Nothing is awaited and nothing can reject: `runListeners` catches every\n * listener's failure itself, so the floating promise here has no rejection to\n * float.\n *\n * `args` is the event's constructor arguments; see `dispatchAndWait`.\n *\n * On an `afterCommit` event inside a transaction, \"after the caller has moved\n * on\" becomes \"after that transaction commits\" — see `deferToCommit`.\n */\n dispatch(event: Event, args?: readonly unknown[]): void {\n if (this.deferToCommit(event, args, false)) return;\n void this.runListeners(event, args);\n }\n\n /**\n * Fires the event and resolves once every **sync** listener has settled.\n *\n * On an `afterCommit` event inside an open transaction it resolves\n * **immediately, having run nothing** — there is no listener to wait for yet,\n * and the transaction it would be waiting on is the caller's own. That is the\n * sharp edge `Event.afterCommit` documents and the reason the flag ships\n * opt-in; it warns once per event name in development, because nothing else\n * about the call site can show it.\n */\n async dispatchAndWait(\n event: Event,\n args?: readonly unknown[],\n ): Promise<void> {\n if (this.deferToCommit(event, args, true)) return;\n return this.runListeners(event, args);\n }\n\n /**\n * Queues the fan-out on the open transaction when the event asked for that,\n * and reports whether it did — `false` means the caller runs it now.\n *\n * Three cases, and only the third defers: an event without\n * `static afterCommit` behaves exactly as it did before this existed; one\n * with it, dispatched outside a transaction, has nothing to wait for; one\n * with it, inside a transaction, runs when that transaction commits and not\n * at all if it rolls back.\n *\n * `currentTransaction()` is not consulted directly, and the difference\n * matters: `deferUntilCommit` also answers `false` for a scope carrying a\n * handle that `withTransaction` did not open, which has no commit hook and\n * therefore no list that will ever be drained. Reading the handle alone would\n * queue the dispatch onto nothing and lose it silently.\n *\n * The whole fan-out is deferred, sync listeners and queued ones alike. A\n * queued listener is *pushed* at commit rather than at dispatch, which is the\n * only correct reading of `afterCommit`: the queue drains in-process and\n * often synchronously from `push`, so pushing early is running early.\n */\n private deferToCommit(\n event: Event,\n args: readonly unknown[] | undefined,\n awaited: boolean,\n ): boolean {\n // Read off the constructor, the same way the registry key is, and typed\n // structurally for the same reason: `Event` arrives here as a type-only\n // import, and the class object an application dispatches may have come from\n // a different module graph than the one this file was compiled against.\n const { name, afterCommit } = event.constructor as {\n name: string;\n afterCommit?: boolean;\n };\n if (!afterCommit) return false;\n\n const deferred = deferUntilCommit(() => this.runListeners(event, args));\n if (deferred && awaited) this.warnNothingIsWaitedFor(name);\n return deferred;\n }\n\n /**\n * Runs every **sync** listener bound to this event, in registration order,\n * and resolves when the last of them has settled. Every queued one is handed\n * to the `QueueManager` on the way past and is not waited for.\n *\n * The dispatch itself is `dispatch` and `dispatchAndWait` above; this is what\n * they run, and what an `afterCommit` event's transaction runs later. Split\n * out so that \"when does the fan-out happen\" is decided in exactly one place\n * rather than in each entry point.\n *\n * ### Sync and queued in one pass\n *\n * A queued listener is pushed at the point in the order it occupies, so its\n * *dispatch* is ordered with the rest and its *execution* is not: the queue\n * decides when. What that costs is worth knowing — `dispatchAndWait`\n * resolving says every sync listener has finished and says nothing at all\n * about a queued one, which may not have started or may already have failed\n * twice. Whether a listener is queued is therefore a decision about what the\n * caller can rely on having happened, not only about latency.\n *\n * @param args the arguments the event's constructor was called with, which\n * `Event.dispatch` forwards. Only a queued listener needs them: the event\n * instance itself never crosses the queue, and what is rebuilt on the other\n * side is `new EventClass(...args)`. Dispatching a hand-built instance\n * straight at the manager therefore cannot queue, and says so on stderr\n * rather than pushing a payload that would rehydrate into an event with\n * `undefined` fields.\n *\n * ### One at a time, deliberately\n *\n * Each listener is awaited before the next one starts, rather than started\n * together under a `Promise.allSettled`. Concurrency would make \"registration\n * order\" a claim about start order only, and the order it is a claim about is\n * the one `registeredListeners` reports and the discovery tests assert on.\n *\n * What it costs is worth knowing, because it is the one way listener\n * independence is not total: a listener that *hangs* — an un-timed-out\n * `fetch` to a host that never answers — delays every listener after it for\n * as long as it hangs, and under `dispatch` the caller has already moved on,\n * so an audit row a later listener writes simply is not there yet. A throw is\n * not this: that is caught below and the next listener runs immediately. A\n * listener that can block indefinitely is a listener that wants its own\n * timeout, or a `Job`.\n *\n * ### Errors\n *\n * Each listener runs inside its own `try`. A throw is logged with the event\n * name, the listener name, and the error, and the loop continues — listeners\n * are independent side effects, and letting listener 2 cancel 3 through 5\n * would make a filesystem walk's order load-bearing. Neither this nor\n * `dispatch` ever rejects, for the same reason from the caller's side: a\n * rejection would make listener 1's failure the dispatcher's problem while\n * listener 5's silently is not.\n *\n * ### Why zero listeners is worth a line on stderr\n *\n * A registry keyed by the wrong string, a `static name` that does not survive\n * a production build, a typo, and a listener directory that was never walked\n * all produce the same single symptom: nobody handled it. Zero listeners is\n * also a perfectly legal steady state, so the warning is development-only and\n * fires once per event name — a dispatch in a loop would otherwise bury the\n * terminal.\n */\n protected async runListeners(\n event: Event,\n args?: readonly unknown[],\n ): Promise<void> {\n const name = (event.constructor as { name: string }).name;\n const handlers = this.listeners[name];\n\n if (!handlers?.length) {\n this.warnNothingIsListening(name);\n return;\n }\n\n for (const { listener: Listener, job } of handlers) {\n if (job) {\n this.enqueue(job, Listener, name, args);\n continue;\n }\n\n try {\n await new Listener().handle(event);\n } catch (error) {\n console.error(\n `The listener ${Listener.name} threw while handling ${name}. The ` +\n `listeners after it still ran — a listener's failure is its own.`,\n error,\n );\n }\n }\n }\n\n /**\n * Rebuilds an event from what crossed the queue.\n *\n * The queue carries a name and an argument array, because that is all JSON\n * can carry: **the constructor arguments are what is serialized, not the\n * instance** — the same bargain `Job.dispatch` makes. So an event whose\n * constructor does work beyond assigning fields does that work a second time\n * here, in the worker, with none of the dispatching request around it.\n *\n * A name that resolves to nothing throws, and is the one place in this file\n * that does. The payload is already off the queue by the time this runs and\n * the listener is one line away from being handed `undefined`, so the\n * alternative is a `handle` reading `event.email` off nothing, several frames\n * further on, with the name that would have explained it no longer in scope.\n * A throw here is caught by `QueueManager.run` and takes the queue's ordinary\n * retry-then-dead-letter path.\n */\n rehydrate(eventName: string, args: readonly unknown[] = []): Event {\n const EventClass = this.events[eventName];\n\n if (!EventClass) {\n throw new Error(\n `Cannot rebuild the event \"${eventName}\" that came off the queue: no ` +\n `registered listener binds to an event of that name, so there is no ` +\n `class to construct. A queued listener runs in an application that ` +\n `discovered its own listeners — check that this process sees the ` +\n `same app/listeners as the one that dispatched, and that the event ` +\n `declares \\`static name = \"${eventName}\"\\`.`,\n );\n }\n\n return new EventClass(...args);\n }\n\n /**\n * Hands one queued listener to the queue, as `[eventName, args]`.\n *\n * Nothing is awaited: `push` returns as soon as the entry is on the queue,\n * which is the whole of what `queued = true` buys. The event instance the\n * sync listeners share does not go with it — only the name and the arguments\n * do, so nothing that was resolved from the request's context can be smuggled\n * across into an application that does not have it.\n *\n * Failing to queue is caught for the same reason a listener's throw is: it is\n * one listener's problem, and the listeners after it in the walk did not do\n * anything to deserve it. Two things reach that catch — an argument JSON\n * cannot serialise, and an application with no queue bound — and both would\n * otherwise reject `dispatchAndWait`, which is documented never to.\n */\n private enqueue(\n job: new () => Job,\n listener: ListenerClass,\n eventName: string,\n args?: readonly unknown[],\n ) {\n if (args === undefined) {\n console.error(\n `The listener ${listener.name} is queued, but ${eventName} reached ` +\n `the dispatcher without its constructor arguments, so there is ` +\n `nothing for the queue to rebuild it from and the listener was ` +\n `skipped. Dispatch through ${eventName}.dispatch(...) or ` +\n `${eventName}.dispatchAndWait(...), which carry them.`,\n );\n return;\n }\n\n try {\n app(QueueManager).push(job, JSON.stringify([eventName, args]));\n } catch (error) {\n console.error(\n `The listener ${listener.name} could not be queued for ${eventName}, ` +\n `so it did not run and will not be retried. The listeners after it ` +\n `still ran.`,\n error,\n );\n }\n }\n\n /**\n * The one warning for the pairing that reads as doing something and does not.\n *\n * `await UserRegistered.dispatchAndWait(...)` inside a transaction, on an\n * event that defers to commit, resolves with nothing having run — the\n * listeners are queued on a transaction the caller has not finished. There is\n * no other symptom: the promise resolves, the listeners do run later, and the\n * only thing that is wrong is that the caller's `await` bought it nothing.\n * Code that reads what a listener wrote on the next line finds it missing,\n * and nothing connects the two.\n *\n * Development only and once per event name, on the same terms as the\n * zero-listener warning: both are legal steady states that are usually a\n * mistake, and a dispatch in a loop must not bury the terminal.\n */\n private warnNothingIsWaitedFor(name: string) {\n if (process.env.NODE_ENV === \"production\") return;\n if (this.warnedAboutWaiting.has(name)) return;\n this.warnedAboutWaiting.add(name);\n\n console.warn(\n `[gemi] ${name}.dispatchAndWait() was called inside a transaction and ` +\n `${name} declares \\`static afterCommit = true\\`, so it resolved ` +\n `immediately with no listener having run — they run when the ` +\n `transaction commits. Await the transaction instead, or drop ` +\n `afterCommit if the caller needs the side effects first. Development ` +\n `only.`,\n );\n }\n\n private warnNothingIsListening(name: string) {\n if (process.env.NODE_ENV === \"production\") return;\n if (this.warnedFor.has(name)) return;\n this.warnedFor.add(name);\n\n console.warn(\n `[gemi] ${name} was dispatched and nothing is listening for it. A ` +\n `listener registers under the name its event declares, so check that ` +\n `app/listeners holds a Listener with \\`static event = ${name}\\` and ` +\n `that ${name} declares \\`static name = \"${name}\"\\`. Development only.`,\n );\n }\n}\n",
|
|
15
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { discoverListeners } from \"../discovery\";\nimport { QueueManager } from \"../queue/QueueManager\";\nimport { eventConfigDefaults, type EventConfig } from \"./config\";\nimport { EventManager } from \"./EventManager\";\n\nexport class EventServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n EventManager,\n () => new EventManager(this.app.config.get<EventConfig>(\"events\", {})),\n );\n }\n\n /**\n * Fills in the listener registry when the app did not declare one.\n *\n * ### Why the raw slice and not the manager's config\n *\n * The decision here is whether the app said anything, and by the time the\n * manager holds a config it can no longer tell: `withDefaults` treats an\n * absent key and an `undefined` one alike and substitutes the default `[]`,\n * which is the same value an app writes when it means \"no listeners, and I\n * mean it\". Reading the slice before defaults are applied is the only place\n * the difference still exists.\n *\n * So: `listeners` present, including `listeners: []`, is used verbatim and no\n * directory is read. Absent or `undefined`, the classes under `listenersDir`\n * are.\n *\n * ### Why phase two\n *\n * Discovery imports every file it walks, which is asynchronous, and\n * `register()` is not. It also has to finish before the first dispatch rather\n * than before the first request — a dispatch against an empty registry is not\n * an error, it is a side effect that quietly does not happen — so the\n * registry has to be complete by the end of boot.\n *\n * ### Why the queue is handed the listener jobs from here\n *\n * A queued listener is registered with the `QueueManager` as a synthetic job,\n * and that registration cannot happen in `register()`: resolving another\n * service is the one thing a `register()` must not do, and the jobs are not\n * known until discovery has run anyway. It also cannot happen before\n * `QueueServiceProvider.boot()` fills the queue's registry, which is why this\n * provider sits after it in `frameworkProviders` — `useJobs` replaces that\n * registry wholesale, so the queue has to be finished with it before\n * `registerJob` starts adding to it.\n *\n * The declared-listeners path falls through to it rather than returning\n * early: an app that lists its listeners in `app/config/events.ts` still has\n * queued ones, and skipping the queue for them would make `queued = true` a\n * field that silently does nothing depending on how the app registers.\n */\n async boot() {\n const manager = this.app.make(EventManager);\n const slice = this.app.config.get<EventConfig>(\"events\", {});\n\n if (slice.listeners === undefined) {\n const { listenersDir } = withDefaults(eventConfigDefaults(), slice);\n manager.useListeners(await discoverListeners(listenersDir));\n }\n\n // Nothing queued, nothing to resolve. An application assembled out of this\n // provider alone — a test, a script — has no `QueueManager` bound, and\n // asking for one it has no use for would turn that into a boot failure.\n const jobs = manager.queuedListenerJobs;\n if (jobs.length === 0) return;\n\n const queue = this.app.make(QueueManager);\n for (const job of jobs) {\n queue.registerJob(job);\n }\n }\n}\n",
|
|
16
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport type { FilesystemConfig } from \"./config\";\nimport { FilesystemManager } from \"./FilesystemManager\";\n\nexport class FilesystemServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n FilesystemManager,\n () =>\n new FilesystemManager(\n this.app.config.get<FilesystemConfig>(\"filesystem\", {}),\n ),\n );\n }\n}\n",
|
|
17
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport type { ImageConfig } from \"./config\";\nimport { ImageManager } from \"./ImageManager\";\n\nexport class ImageServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n ImageManager,\n () => new ImageManager(this.app.config.get<ImageConfig>(\"image\", {})),\n );\n }\n}\n",
|
|
18
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { KernelId } from \"./KernelId\";\n\n// Config-less by nature: the id is generated per process, never declared.\nexport class KernelIdServiceProvider extends ServiceProvider {\n register() {\n this.app.instance(KernelId, new KernelId());\n }\n}\n",
|
|
19
|
+
"import type { LogEntry } from \"./types\";\n\n// Config key: `log`. Derived from `LoggingServiceProvider`.\nexport interface LogConfig {\n maxFileSize?: number;\n\n onLogFileClosed?: (file: File) => void | Promise<void>;\n onLogCreated?: (logEntry: LogEntry) => void | Promise<void>;\n}\n\nexport function defineLogConfig(config: LogConfig): LogConfig {\n return config;\n}\n\nexport function logConfigDefaults(): Required<LogConfig> {\n return {\n maxFileSize: 1024 * 1024 * 10, // 10MB\n onLogFileClosed: () => {},\n onLogCreated: () => {},\n };\n}\n",
|
|
20
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { LogManager } from \"./LogManager\";\nimport { logConfigDefaults, type LogConfig } from \"./config\";\n\nexport class LogServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n LogManager,\n () =>\n new LogManager(\n withDefaults(\n logConfigDefaults(),\n this.app.config.get<LogConfig>(\"log\", {}),\n ),\n ),\n );\n }\n\n /**\n * The log directory is created once at kernel boot rather than on the first\n * `Log.info()`, which is what the old eagerly-constructed container did.\n * Resolving here is deliberate: it is the one service whose readiness is a\n * boot-time side effect, and paying for it lazily mid-request would add file\n * IO to whichever handler happened to log first.\n */\n async boot() {\n await this.app.make(LogManager).boot();\n }\n}\n",
|
|
21
|
+
"import {\n middlewareConfigDefaults,\n type MiddlewareConfig,\n} from \"../../http/middleware-config\";\nimport { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { MiddlewareRegistry } from \"./MiddlewareRegistry\";\n\nexport class MiddlewareServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n MiddlewareRegistry,\n () =>\n new MiddlewareRegistry(\n withDefaults(\n middlewareConfigDefaults(),\n this.app.config.get<MiddlewareConfig>(\"middleware\", {}),\n ),\n ),\n );\n }\n}\n",
|
|
22
|
+
"import type { BroadcastingChannel } from \"../../broadcasting/BroadcastingChannel\";\n\n// Config key: `broadcast`. Derived from `BroadcastingServiceProvider`.\nexport interface BroadcastConfig {\n channels?: Record<string, new () => BroadcastingChannel>;\n}\n\nexport function defineBroadcastConfig(\n config: BroadcastConfig,\n): BroadcastConfig {\n return config;\n}\n\nexport function broadcastConfigDefaults(): Required<BroadcastConfig> {\n return {\n channels: {},\n };\n}\n",
|
|
23
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { BroadcastManager } from \"./BroadcastManager\";\nimport { broadcastConfigDefaults, type BroadcastConfig } from \"./config\";\n\nexport class BroadcastServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n BroadcastManager,\n () =>\n new BroadcastManager(\n withDefaults(\n broadcastConfigDefaults(),\n this.app.config.get<BroadcastConfig>(\"broadcast\", {}),\n ),\n ),\n );\n }\n}\n",
|
|
24
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { discoverJobs } from \"../discovery\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { queueConfigDefaults, type QueueConfig } from \"./config\";\nimport { QueueManager } from \"./QueueManager\";\n\nexport class QueueServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n QueueManager,\n () => new QueueManager(this.app.config.get<QueueConfig>(\"queue\", {})),\n );\n }\n\n /**\n * Fills in the job registry when the app did not declare one.\n *\n * ### Why the raw slice and not the manager's config\n *\n * The decision here is whether the app said anything, and by the time the\n * manager holds a config it can no longer tell: `withDefaults` treats an\n * absent key and an `undefined` one alike and substitutes the default `[]`,\n * which is the same value an app writes when it means \"no jobs, and I mean\n * it\". Reading the slice before defaults are applied is the only place the\n * difference still exists.\n *\n * So: `jobs` present, including `jobs: []`, is used verbatim and no directory\n * is read. Absent or `undefined`, the classes under `jobsDir` are.\n *\n * ### Why phase two\n *\n * Discovery imports every file it walks, which is asynchronous, and\n * `register()` is not. It also has to happen before the first dispatch rather\n * than before the first tick — there is no equivalent of the scheduler's\n * `start()` to hang it off, so the registry has to be complete by the end of\n * boot.\n */\n async boot() {\n const slice = this.app.config.get<QueueConfig>(\"queue\", {});\n if (slice.jobs !== undefined) return;\n\n const { jobsDir } = withDefaults(queueConfigDefaults(), slice);\n this.app.make(QueueManager).useJobs(await discoverJobs(jobsDir));\n }\n}\n",
|
|
25
|
+
"import type { ConsumeParams, RateLimitResult } from \"../types\";\n\nexport abstract class RateLimiterDriver {\n /**\n * Records one request against `params.key` and reports whether it fits.\n *\n * Implementations must decide *and* record atomically — two concurrent calls\n * for the same key may never both be told they were the last one that fit.\n *\n * May be sync or async: the in-memory driver answers immediately, a network\n * backed driver returns a promise. Callers always `await` the result.\n */\n abstract consume(\n params: ConsumeParams,\n ): Promise<RateLimitResult> | RateLimitResult;\n}\n",
|
|
26
|
+
"import type { RateLimitResult } from \"./types\";\n\n/**\n * The sliding-window-counter algorithm, shared by every driver.\n *\n * A fixed window is cheap but lets a client spend its whole budget at the end\n * of one window and again at the start of the next — twice the limit across a\n * window's worth of time. A true sliding log fixes that but has to keep a\n * timestamp per request.\n *\n * The counter variant keeps two integers per key (this window and the one\n * before it) and estimates usage by weighting the previous window by how much\n * of it still overlaps the trailing window:\n *\n * usage = previous * (window - elapsed) / window + current\n *\n * That is a ~0.003% error on real traffic and costs two integers per key, so\n * it is what the in-memory and Redis drivers both implement.\n */\n\n/** Epoch ms of the start of the window `now` falls into. */\nexport function windowStartFor(now: number, window: number) {\n return Math.floor(now / window) * window;\n}\n\n/** Weight of the previous window's count, from `1` down to `0`. */\nexport function previousWeight(elapsed: number, window: number) {\n if (window <= 0) return 0;\n return Math.min(1, Math.max(0, (window - elapsed) / window));\n}\n\n/** Estimated usage of the trailing `window` ending at `now`. */\nexport function estimateUsage(\n current: number,\n previous: number,\n elapsed: number,\n window: number,\n) {\n return previous * previousWeight(elapsed, window) + current;\n}\n\n/**\n * How long until a request costing `cost` would be admitted, in milliseconds.\n *\n * Solves the usage equation for `elapsed` instead of guessing: the caller gets\n * a `Retry-After` that lands the moment capacity actually frees up rather than\n * at the end of the window, which for a sliding window is usually far too late.\n */\nexport function timeUntilAllowed(params: {\n current: number;\n previous: number;\n elapsed: number;\n window: number;\n limit: number;\n cost: number;\n}) {\n const { current, previous, elapsed, window, limit, cost } = params;\n // Usage the bucket may sit at for this request to still fit.\n const budget = limit - cost;\n\n // The request can never fit, no matter how long the caller waits. Report a\n // full window rather than `Infinity` so a `Retry-After` header stays usable.\n if (budget < 0) return window;\n\n const remainingWindow = Math.max(0, window - elapsed);\n\n // Phase 1 — capacity frees up inside the current window as `previous` decays.\n if (previous > 0) {\n // previous * (window - e) / window + current = budget => solve for e\n const target = window * (1 - (budget - current) / previous);\n if (target <= window) {\n return Math.max(0, Math.ceil(target - elapsed));\n }\n }\n\n // Phase 2 — `current` alone is already over budget, so nothing frees up until\n // the window rolls and `current` becomes the decaying `previous`.\n if (current <= budget) return remainingWindow;\n if (current <= 0) return remainingWindow;\n\n const target = window * (1 - budget / current);\n return remainingWindow + Math.max(0, Math.ceil(target));\n}\n\n/**\n * Turns a driver's post-operation counters into the result the caller sees.\n * `current` and `previous` are the counts *after* an allowed request has been\n * recorded, so every driver reports the same numbers for the same state.\n */\nexport function buildResult(params: {\n allowed: boolean;\n current: number;\n previous: number;\n now: number;\n elapsed: number;\n window: number;\n limit: number;\n cost: number;\n}): RateLimitResult {\n const { allowed, current, previous, now, elapsed, window, limit, cost } =\n params;\n\n if (allowed) {\n const usage = estimateUsage(current, previous, elapsed, window);\n return {\n allowed: true,\n limit,\n remaining: Math.max(0, Math.floor(limit - usage)),\n resetAt: now - elapsed + window,\n retryAfter: 0,\n };\n }\n\n const retryAfter = timeUntilAllowed({\n current,\n previous,\n elapsed,\n window,\n limit,\n cost,\n });\n\n return {\n allowed: false,\n limit,\n remaining: 0,\n resetAt: now + retryAfter,\n retryAfter,\n };\n}\n",
|
|
27
|
+
"import { buildResult, estimateUsage, windowStartFor } from \"../slidingWindow\";\nimport type { ConsumeParams, RateLimitResult } from \"../types\";\nimport { RateLimiterDriver } from \"./RateLimiterDriver\";\n\ninterface Bucket {\n /** Window length this bucket was counted with, so config changes reset it. */\n window: number;\n windowStart: number;\n current: number;\n previous: number;\n}\n\nexport interface InMemoryRateLimiterOptions {\n /**\n * Hard cap on tracked keys. Reached only by traffic that never repeats a key\n * (spoofed `x-forwarded-for`, for instance); the map is swept of dead buckets\n * first and only then evicts live ones, oldest touched first.\n *\n * Defaults to 100k keys — a few MB, and far more than a single instance\n * legitimately sees inside one window.\n */\n maxKeys?: number;\n}\n\n/**\n * Per-process rate limiter. The default driver, and the right one for a single\n * instance or for development.\n *\n * State lives in this process only: with N instances behind a load balancer the\n * effective limit is N × the configured limit, and it resets on deploy. Point\n * the service provider at `RedisRateLimiter` once you run more than one.\n */\nexport class InMemoryRateLimiter extends RateLimiterDriver {\n private buckets = new Map<string, Bucket>();\n private maxKeys: number;\n\n constructor(options: InMemoryRateLimiterOptions = {}) {\n super();\n this.maxKeys = Math.max(1, options.maxKeys ?? 100_000);\n }\n\n consume(params: ConsumeParams): RateLimitResult {\n const { key, limit, window } = params;\n const cost = params.cost ?? 1;\n const now = Date.now();\n const windowStart = windowStartFor(now, window);\n const elapsed = now - windowStart;\n\n const bucket = this.roll(key, window, windowStart);\n const usage = estimateUsage(\n bucket.current,\n bucket.previous,\n elapsed,\n window,\n );\n const allowed = usage + cost <= limit;\n\n if (allowed) {\n bucket.current += cost;\n }\n\n // Re-inserting moves the key to the end of the iteration order, which is\n // what makes eviction least-recently-used rather than arbitrary.\n this.buckets.delete(key);\n this.buckets.set(key, bucket);\n if (this.buckets.size > this.maxKeys) {\n this.evict(now);\n }\n\n return buildResult({\n allowed,\n current: bucket.current,\n previous: bucket.previous,\n now,\n elapsed,\n window,\n limit,\n cost,\n });\n }\n\n /** Drops all counters. Mainly useful in tests. */\n clear() {\n this.buckets.clear();\n }\n\n /** Number of tracked keys. Exposed for tests and diagnostics. */\n get size() {\n return this.buckets.size;\n }\n\n /** Advances a bucket to `windowStart`, creating it when absent or stale. */\n private roll(key: string, window: number, windowStart: number): Bucket {\n const bucket = this.buckets.get(key);\n\n if (!bucket || bucket.window !== window) {\n return { window, windowStart, current: 0, previous: 0 };\n }\n\n if (bucket.windowStart === windowStart) {\n return bucket;\n }\n\n if (bucket.windowStart + window === windowStart) {\n bucket.previous = bucket.current;\n bucket.current = 0;\n bucket.windowStart = windowStart;\n return bucket;\n }\n\n // Idle for more than a full window: everything it held has decayed away.\n bucket.previous = 0;\n bucket.current = 0;\n bucket.windowStart = windowStart;\n return bucket;\n }\n\n private evict(now: number) {\n for (const [key, bucket] of this.buckets) {\n // Fully decayed — it would be reset on the next read anyway.\n if (now - bucket.windowStart >= bucket.window * 2) {\n this.buckets.delete(key);\n }\n }\n\n // Still over the cap, so the traffic is live rather than stale. Drop the\n // least recently touched keys; the worst case is that a client whose bucket\n // was dropped gets a fresh budget, which beats growing without bound.\n for (const key of this.buckets.keys()) {\n if (this.buckets.size <= this.maxKeys) break;\n this.buckets.delete(key);\n }\n }\n}\n",
|
|
28
|
+
"import { InMemoryRateLimiter } from \"./drivers/InMemoryRateLimiterDriver\";\nimport type { RateLimiterDriver } from \"./drivers/RateLimiterDriver\";\n\n// Config key: `ratelimiter`. Derived from `RateLimiterServiceProvider`.\nexport interface RateLimiterConfig {\n /**\n * Where counters live. In-process by default; swap in `RedisRateLimiter` once\n * the app runs on more than one instance.\n */\n driver?: RateLimiterDriver;\n\n /** Requests allowed per window when the `rate-limit` DSL omits a limit. */\n limit?: number;\n\n /** Window length in **seconds** when the `rate-limit` DSL omits one. */\n window?: number;\n}\n\nexport function defineRateLimiterConfig(\n config: RateLimiterConfig,\n): RateLimiterConfig {\n return config;\n}\n\nexport function rateLimiterConfigDefaults(): Required<RateLimiterConfig> {\n return {\n driver: new InMemoryRateLimiter(),\n limit: 1000,\n window: 60,\n };\n}\n",
|
|
29
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { RateLimiter } from \"./RateLimiter\";\nimport { rateLimiterConfigDefaults, type RateLimiterConfig } from \"./config\";\n\nexport class RateLimiterServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n RateLimiter,\n () =>\n new RateLimiter(\n withDefaults(\n rateLimiterConfigDefaults(),\n this.app.config.get<RateLimiterConfig>(\"ratelimiter\", {}),\n ),\n ),\n );\n }\n}\n",
|
|
30
|
+
"import type { RedisOptions } from \"bun\";\n\n// Config key: `redis`. Derived from `RedisServiceProvider`.\nexport interface RedisConfig {\n // Connection URL for Bun's Redis client. Defaults to the `REDIS_URL`\n // environment variable (Bun itself falls back to `redis://localhost:6379`\n // when unset).\n url?: string;\n\n // Optional Bun Redis client options (TLS, timeouts, auto-reconnect, ...).\n options?: RedisOptions;\n}\n\nexport function defineRedisConfig(config: RedisConfig): RedisConfig {\n return config;\n}\n\nexport function redisConfigDefaults(): RedisConfig {\n return {\n url: process.env.REDIS_URL,\n options: undefined,\n };\n}\n",
|
|
31
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { withDefaults } from \"../../support/withDefaults\";\nimport { redisConfigDefaults, type RedisConfig } from \"./config\";\nimport { RedisManager } from \"./RedisManager\";\n\nexport class RedisServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n RedisManager,\n () =>\n new RedisManager(\n withDefaults(\n redisConfigDefaults(),\n this.app.config.get<RedisConfig>(\"redis\", {}),\n ),\n ),\n );\n }\n}\n",
|
|
32
|
+
"import { ServiceProvider } from \"../../support/ServiceProvider\";\nimport { ApiRouteDispatcher } from \"./ApiRouteDispatcher\";\nimport { ViewRouteDispatcher } from \"./ViewRouteDispatcher\";\nimport type { ApiRouteConfig, ViewRouteConfig } from \"./config\";\nimport type { Repository } from \"../../support/Repository\";\n\nfunction readConfig<T>(config: Repository, key: string): T {\n const slice = config.get<T>(key);\n if (!slice) {\n throw new Error(\n `Missing \"${key}\" configuration. Route dispatching needs a root router — declare it in \"app/config/route.ts\".`,\n );\n }\n return slice;\n}\n\n/**\n * Owns both route dispatchers. Laravel ships a single RouteServiceProvider for\n * every route file it loads; the api/view split is a config slice, not a\n * separate provider.\n */\nexport class RouteServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n ApiRouteDispatcher,\n () =>\n new ApiRouteDispatcher(\n readConfig<ApiRouteConfig>(this.app.config, \"route.api\"),\n ),\n );\n\n this.app.singleton(\n ViewRouteDispatcher,\n () =>\n new ViewRouteDispatcher(\n readConfig<ViewRouteConfig>(this.app.config, \"route.view\"),\n ),\n );\n }\n\n /**\n * The two dispatchers are the one pair of services that must not be built\n * lazily: constructing them flattens the route tables and runs\n * `assertNoReservedRoutePaths`, so a missing `route` config or a route under\n * a reserved prefix has to fail the boot rather than the first request that\n * happens to hit it.\n */\n boot() {\n this.app.make(ApiRouteDispatcher);\n this.app.make(ViewRouteDispatcher);\n }\n}\n"
|
|
33
|
+
],
|
|
34
|
+
"mappings": "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",
|
|
35
|
+
"debugId": "5D03A6748D65150C64756E2164756E21",
|
|
36
|
+
"names": []
|
|
37
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{$ as v,_ as D}from"./chunk-
|
|
2
|
+
import{$ as v,_ as D}from"./chunk-3aa287k7.js";import"./chunk-tkdxv6cq.js";import{Vb as q}from"./chunk-fjm4y8bn.js";import{Dc as V,sc as P}from"./chunk-hwa5sqw5.js";import"./chunk-86jebsm4.js";import"./chunk-y6a8r2bn.js";import"./chunk-7j6wbv12.js";import"./chunk-hxf1re93.js";import"./chunk-qb5mv6pj.js";import"./chunk-3g5bjvdf.js";import"./chunk-sy7jbdeb.js";import"./chunk-cyaz97p5.js";import"./chunk-d125j8t0.js";import"./chunk-dgsgjg53.js";import"./chunk-jhkjz9jr.js";import{join as E}from"path";import{Duplex as o}from"stream";import{constants as T,createBrotliCompress as l,createGzip as n}from"zlib";var i=["br","gzip"],t=1024,a=5,s=19,r=6;function e($){if($===void 0)return 1;if(!/^\d+(\.\d{0,3})?$/.test($.trim()))return 1;let J=Number($.trim());return Number.isFinite(J)?Math.min(J,1):1}function JJ($){if($===null||$===void 0)return null;let J=new Map;for(let H of $.split(",")){let[Z,...X]=H.split(";"),j=Z.trim().toLowerCase();if(j==="")continue;let x=1;for(let K of X){let O=K.indexOf("=");if(O===-1)continue;if(K.slice(0,O).trim().toLowerCase()==="q"){x=e(K.slice(O+1));break}}J.set(j,x)}return J}function $J($,J=i){let H=JJ($);if(!H)return null;let Z=H.get("*"),X=null,j=0;for(let x of J){let K=H.get(x)??Z??0;if(K>j)X=x,j=K}return X}function HJ($,J){if(!$)return!1;return $.split(",").some((H)=>H.trim().toLowerCase().split("=")[0].trim()===J)}function UJ($,J){if($==="HEAD")return!1;if(!J.body)return!1;if(J.status<200||J.status===204||J.status===206||J.status===304)return!1;if(J.headers.has("Content-Range"))return!1;let H=J.headers.get("Content-Type");if(!H||!/^\s*text\/html\s*(;|$)/i.test(H))return!1;let Z=J.headers.get("Content-Encoding");if(Z&&Z.trim().toLowerCase()!=="identity")return!1;if(HJ(J.headers.get("Cache-Control"),"no-transform"))return!1;let X=J.headers.get("Content-Length");if(X!==null&&Number(X)<t)return!1;return!0}function ZJ($){let J=$==="br"?l({params:{[T.BROTLI_PARAM_QUALITY]:a,[T.BROTLI_PARAM_LGWIN]:s},flush:T.BROTLI_OPERATION_FLUSH}):n({level:r,flush:T.Z_SYNC_FLUSH});return o.toWeb(J)}function zJ($){let J=$.get("Vary");if(!J){$.set("Vary","Accept-Encoding");return}let H=J.split(",").map((Z)=>Z.trim().toLowerCase());if(H.includes("*")||H.includes("accept-encoding"))return;$.append("Vary","Accept-Encoding")}function F($,J){if(!UJ($.method,J))return J;let H=new Headers(J.headers);zJ(H);let Z=$J($.headers.get("Accept-Encoding"));if(!Z)return new Response(J.body,{status:J.status,statusText:J.statusText,headers:H});let X;try{X=ZJ(Z)}catch{return new Response(J.body,{status:J.status,statusText:J.statusText,headers:H})}return H.set("Content-Encoding",Z),H.delete("Content-Length"),new Response(J.body.pipeThrough(X),{status:J.status,statusText:J.statusText,headers:H})}function y($){let J=$.toString(),H=new Bun.CryptoHasher("sha1");return H.update(J),H.digest("hex")}if(!globalThis.URLPattern)globalThis.URLPattern=P;import{exists as GJ}from"fs/promises";var g="app/client.tsx";function w($){let J=$["app/client.tsx"]?.file;if(!J)return;return{module:`/${J}`,preload:S($,"app/client.tsx")}}function S($,J){let H=[],Z=new Set,X=(j)=>{if(Z.has(j))return;Z.add(j);let x=$[j];if(!x?.file)return;H.push(`/${x.file}`);for(let K of x.imports??[])X(K)};return X(J),H}var I=q(),XJ=E(I,"app"),L=E(I,"dist");async function VJ($,J){let H=await import(`${L}/client/.vite/manifest.json`),Z=await import(`${L}/server/.vite/manifest.json`);process.env.ROOT_DIR=I,process.env.APP_DIR=XJ,process.env.DIST_DIR=L;let X={},j={},x={},K={},O={},f=(U,G)=>`"${U}": () => import("${G}")`,k=[];for(let U of["404",...$.getFlatComponentTree.call($)]){let G=Z[`app/views/${U}.tsx`];if(!G?.file){console.log(`Server file not found for ${U}`),console.log(G);let W=Object.keys(Z),A=`app/views/${U}.tsx`;console.log(`${A} not found in server manifest`),console.log(W)}let Q=await import(`${process.env.DIST_DIR}/server/${G?.file}`);X[U]=Q.default,j[U]=Q.OpenGraph,x[U]=Q;let z=H[`app/views/${U}.tsx`];if(z?.css&&z?.css.length>0)K[U]=z?.css;if(z)k.push(f(U,`/${z?.file}`)),O[U]=S(H,`app/views/${U}.tsx`)}let u=`{${k.join(",")}}`,N=w(H);if(!N)console.error(`Client manifest has no "${g}" entry \u2014 dist/client is incomplete, so documents will render but never hydrate.`);let m=H["app/client.tsx"]?.css??[],h=(await Promise.all(m.map((U)=>Bun.file(`${L}/client/${U}`).text()))).join(`
|
|
3
3
|
`),c=new P({pathname:"/*.:filetype(png|txt|js|css|jpg|svg|jpeg|avif|webp|ico|ttf|map)"});async function p(U){let{pathname:G}=new URL(U.url),Q=G.startsWith("/.well-known"),z=c.test({pathname:G})||Q,W=G.startsWith("/api");if(z&&!W){let A=new URL(U.url),b=U.url.replace(A.origin,"").split("?")[0],B=`${L}/client${b.replace("/assets/assets","/assets")}`,C=await GJ(B);if(!C&&A.pathname.includes(".js"))return new Response(`if(caches){caches?.delete("${B}")}window.location.reload();export {}`,{headers:{"Content-Type":"application/javascript"}});if(!C){if(G===V||G.startsWith(`${V}/`))return new Response("Not found",{status:404});return await R(U,G)}try{let Y=Bun.file(B),_=y(Y.lastModified);return new Response(Y.stream(),{headers:{"Content-Type":Y.type,"Cache-Control":"public, max-age=31536000, must-revalidate","Content-Length":String(Y.size),ETag:_}})}catch(Y){return $.onException?.(Y),new Response("Not found",{status:404})}}return await R(U,G)}async function R(U,G){let Q=$.fetch.bind($);try{let z=await Q(U);if(z instanceof Response)return z;else{let W=[];return W.push({content:h}),await z({getStyles:async(b)=>{if(!b)return D([]);for(let B of b){let C=H[`app/views/${B}.tsx`];for(let Y of C?.css??[]){let _=Bun.file(`${process.env.DIST_DIR}/client/${Y}`);W.push({id:Y,content:await _.text()})}}return D(W)},clientEntry:N,modulePreloadManifest:O,loaders:u,viewImportMap:X,viewModules:x,ogMap:j,cssManifest:K})}}catch(z){if(console.error(z),G.startsWith("/api"))return new Response(JSON.stringify({error:z.message}),{status:500,headers:{"Content-Type":"application/json"}});return $.onException?.(z),new Response(z.stack,{status:500})}}let d=(process.env.GEMI_COMPRESSION??"auto").toLowerCase()!=="off",M=Bun.serve({maxRequestBodySize:10737418240,fetch:async(U,G)=>{if(!U.headers.get("x-forwarded-for")){let z=G.requestIP(U);if(z)U.headers.set("x-forwarded-for",z.address)}let Q=await J(U,p);return d?F(U,Q):Q},idleTimeout:Number(process.env.SERVER_IDLE_TIMEOUT??10),port:process.env.PORT||5173});return v({port:M.port,rootDir:I}),M}export{VJ as httpProd};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=5BD3C85C09F63E1D64756E2164756E21
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
"/** The subset of a Vite manifest entry this module reads. */\nexport interface ViteManifestChunk {\n file: string;\n imports?: string[];\n dynamicImports?: string[];\n}\n\nexport type ViteManifest = Record<string, ViteManifestChunk>;\n\n/** Vite's manifest key for the module that boots hydration. */\nexport const CLIENT_ENTRY_KEY = \"app/client.tsx\";\n\n/**\n * How the shell boots hydration in production: `module` is imported from the\n * bootstrap script, `preload` is every chunk that import pulls in — see\n * `clientEntry` in `ViewRouteDispatcher` for why the entry does not go through\n * React's `bootstrapModules`.\n *\n * `undefined` when the manifest has no client entry, which means a `dist/`\n * interrupted between the server and client build passes. Degrading beats\n * throwing here: this runs at boot, so a deref would take down API routes,\n * static assets and health checks over what is only a document concern, and\n * the dispatcher already renders a shell that simply does not hydrate.\n */\nexport function createClientEntry(\n manifest: ViteManifest,\n): { module: string; preload: string[] } | undefined {\n const file = manifest[CLIENT_ENTRY_KEY]?.file;\n if (!file) {\n return undefined;\n }\n return {\n module: `/${file}`,\n preload: collectModulePreloads(manifest, CLIENT_ENTRY_KEY),\n };\n}\n\n/**\n * Every chunk URL that importing `entryKey` pulls in, itself first.\n *\n * The browser can only discover these one parse at a time — it learns about a\n * chunk's static imports after the chunk has arrived and been parsed — so a\n * `layout -> view -> child component` graph costs one round trip per level.\n * Handing the whole list to the shell as `modulepreload` hints turns that\n * chain into one parallel fetch (#352).\n *\n * `dynamicImports` are deliberately left out: those are the pieces the app\n * asked to load lazily, and preloading them would download code the current\n * route may never render.\n */\nexport function collectModulePreloads(manifest: ViteManifest, entryKey: string): string[] {\n const urls: string[] = [];\n // Chunk graphs are cyclic often enough (two chunks importing each other\n // through a shared module) that walking them without a visited set hangs.\n const visited = new Set<string>();\n\n const walk = (key: string) => {\n if (visited.has(key)) return;\n visited.add(key);\n const chunk = manifest[key];\n if (!chunk?.file) return;\n urls.push(`/${chunk.file}`);\n for (const imported of chunk.imports ?? []) {\n walk(imported);\n }\n };\n\n walk(entryKey);\n\n return urls;\n}\n"
|
|
10
10
|
],
|
|
11
11
|
"mappings": "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",
|
|
12
|
-
"debugId": "
|
|
12
|
+
"debugId": "5BD3C85C09F63E1D64756E2164756E21",
|
|
13
13
|
"names": []
|
|
14
14
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
2
|
+
import{Ef as t,Hf as A}from"./chunk-jhkjz9jr.js";var o=t((b)=>{var i=(r)=>typeof ArrayBuffer==="function"&&r instanceof ArrayBuffer||Object.prototype.toString.call(r)==="[object ArrayBuffer]";b.isArrayBuffer=i});var y=t((g)=>{var m=o(),f=A("buffer"),B=(r,e=0,u=r.byteLength-e)=>{if(!m.isArrayBuffer(r))throw TypeError(`The "input" argument must be ArrayBuffer. Received type ${typeof r} (${r})`);return f.Buffer.from(r,e,u)},a=(r,e)=>{if(typeof r!=="string")throw TypeError(`The "input" argument must be of type string. Received type ${typeof r} (${r})`);return e?f.Buffer.from(r,e):f.Buffer.from(r)};g.fromArrayBuffer=B;g.fromString=a});var x=t((w)=>{var n=y(),s=(r)=>{let e=n.fromString(r,"utf8");return new Uint8Array(e.buffer,e.byteOffset,e.byteLength/Uint8Array.BYTES_PER_ELEMENT)},h=(r)=>{if(typeof r==="string")return s(r);if(ArrayBuffer.isView(r))return new Uint8Array(r.buffer,r.byteOffset,r.byteLength/Uint8Array.BYTES_PER_ELEMENT);return new Uint8Array(r)},p=(r)=>{if(typeof r==="string")return r;if(typeof r!=="object"||typeof r.byteOffset!=="number"||typeof r.byteLength!=="number")throw Error("@smithy/util-utf8: toUtf8 encoder function only accepts string | Uint8Array.");return n.fromArrayBuffer(r.buffer,r.byteOffset,r.byteLength).toString("utf8")};w.fromUtf8=s;w.toUint8Array=h;w.toUtf8=p});
|
|
3
3
|
export{o as K,y as L,x as M};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=3E0CF9F34F383BC564756E2164756E21
|
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
"'use strict';\n\nvar utilBufferFrom = require('@smithy/util-buffer-from');\n\nconst fromUtf8 = (input) => {\n const buf = utilBufferFrom.fromString(input, \"utf8\");\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength / Uint8Array.BYTES_PER_ELEMENT);\n};\n\nconst toUint8Array = (data) => {\n if (typeof data === \"string\") {\n return fromUtf8(data);\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength / Uint8Array.BYTES_PER_ELEMENT);\n }\n return new Uint8Array(data);\n};\n\nconst toUtf8 = (input) => {\n if (typeof input === \"string\") {\n return input;\n }\n if (typeof input !== \"object\" || typeof input.byteOffset !== \"number\" || typeof input.byteLength !== \"number\") {\n throw new Error(\"@smithy/util-utf8: toUtf8 encoder function only accepts string | Uint8Array.\");\n }\n return utilBufferFrom.fromArrayBuffer(input.buffer, input.byteOffset, input.byteLength).toString(\"utf8\");\n};\n\nexports.fromUtf8 = fromUtf8;\nexports.toUint8Array = toUint8Array;\nexports.toUtf8 = toUtf8;\n"
|
|
8
8
|
],
|
|
9
9
|
"mappings": ";+DAEA,IAAM,EAAgB,CAAC,IAAS,OAAO,cAAgB,YAAc,aAAe,aAChF,OAAO,UAAU,SAAS,KAAK,CAAG,IAAM,uBAEpC,gBAAgB,kBCHxB,IAAI,MACA,cAEE,EAAkB,CAAC,EAAO,EAAS,EAAG,EAAS,EAAM,WAAa,IAAW,CAC/E,GAAI,CAAC,EAAc,cAAc,CAAK,EAClC,MAAU,UAAU,2DAA2D,OAAO,MAAU,IAAQ,EAE5G,OAAO,EAAO,OAAO,KAAK,EAAO,EAAQ,CAAM,GAE7C,EAAa,CAAC,EAAO,IAAa,CACpC,GAAI,OAAO,IAAU,SACjB,MAAU,UAAU,8DAA8D,OAAO,MAAU,IAAQ,EAE/G,OAAO,EAAW,EAAO,OAAO,KAAK,EAAO,CAAQ,EAAI,EAAO,OAAO,KAAK,CAAK,GAG5E,kBAAkB,EAClB,aAAa,kBCjBrB,IAAI,MAEE,EAAW,CAAC,IAAU,CACxB,IAAM,EAAM,EAAe,WAAW,EAAO,MAAM,EACnD,OAAO,IAAI,WAAW,EAAI,OAAQ,EAAI,WAAY,EAAI,WAAa,WAAW,iBAAiB,GAG7F,EAAe,CAAC,IAAS,CAC3B,GAAI,OAAO,IAAS,SAChB,OAAO,EAAS,CAAI,EAExB,GAAI,YAAY,OAAO,CAAI,EACvB,OAAO,IAAI,WAAW,EAAK,OAAQ,EAAK,WAAY,EAAK,WAAa,WAAW,iBAAiB,EAEtG,OAAO,IAAI,WAAW,CAAI,GAGxB,EAAS,CAAC,IAAU,CACtB,GAAI,OAAO,IAAU,SACjB,OAAO,EAEX,GAAI,OAAO,IAAU,UAAY,OAAO,EAAM,aAAe,UAAY,OAAO,EAAM,aAAe,SACjG,MAAU,MAAM,8EAA8E,EAElG,OAAO,EAAe,gBAAgB,EAAM,OAAQ,EAAM,WAAY,EAAM,UAAU,EAAE,SAAS,MAAM,GAGnG,WAAW,EACX,eAAe,EACf,SAAS",
|
|
10
|
-
"debugId": "
|
|
10
|
+
"debugId": "3E0CF9F34F383BC564756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{A as B,C as p,I as _}from"./chunk-
|
|
2
|
+
import{A as B,C as p,I as _}from"./chunk-j0c6ytkj.js";import{J as v}from"./chunk-5athahgr.js";import"./chunk-9m2tbf3n.js";import"./chunk-grdahng8.js";import"./chunk-tss5svjr.js";import{X as D}from"./chunk-3337e5g0.js";import{Y as d}from"./chunk-xey9cbap.js";import"./chunk-zh2egcyb.js";import{Df as n}from"./chunk-jhkjz9jr.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=76573FB17661998564756E2164756E21
|
|
@@ -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": "76573FB17661998564756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Xb as o}from"./chunk-437085pe.js";import{Yb as i}from"./chunk-4yt5x8s2.js";import{qf as t}from"./chunk-sy7jbdeb.js";import{wf as r}from"./chunk-cyaz97p5.js";class n extends i{register(){this.app.singleton(r,()=>new r(t(o(),this.app.config.get("translation",{}))))}}
|
|
3
|
+
export{n as Qa};
|
|
4
|
+
|
|
5
|
+
//# debugId=367CF69A359EB0A064756E2164756E21
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"import { ServiceProvider } from \"../support/ServiceProvider\";\nimport { withDefaults } from \"../support/withDefaults\";\nimport { Translator } from \"./Translator\";\nimport { translationConfigDefaults, type TranslationConfig } from \"./config\";\n\nexport class TranslationServiceProvider extends ServiceProvider {\n register() {\n this.app.singleton(\n Translator,\n () =>\n new Translator(\n withDefaults(\n translationConfigDefaults(),\n this.app.config.get<TranslationConfig>(\"translation\", {}),\n ),\n ),\n );\n }\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";sLAKO,AAAM,IAAmC,LAAgB,CAC9D,QAAQ,EAAG,CACT,KAAK,IAAI,UACP,EACA,IACE,IAAI,EACF,EACE,EAA0B,EAC1B,KAAK,IAAI,OAAO,IAAuB,cAAe,CAAC,CAAC,CAC1D,CACF,CACJ,EAEJ",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "367CF69A359EB0A064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
class K{config;static token="translator";translations={};isEnabled=!1;constructor(z){this.config=z;let j={};for(let[G,I]of Object.entries(this.config.prefetch))for(let C of this.config.supportedLocales){if(!j[C])j[C]={};j[C][G]={};for(let F of I){j[C][G][F.name]={};for(let[H,J]of Object.entries(F.dictionary))this.isEnabled=!0,j[C][G][F.name][H]=J[C]}}this.translations=j}get isLocaleAware(){return this.isEnabled||this.config.supportedLocales.length>0}get supportedLocales(){return this.config.supportedLocales}get defaultLocale(){return this.config.defaultLocale}get components(){return this.config.components}onLocaleChange(z){return this.config.onLocaleChange(z)}detectLocale(z){let j=this.config.defaultLocale??this.config.supportedLocales[0]??"en-US",G=this.config.detectLocale(z);if(this.config.supportedLocales.includes(G))return G;let C=z.cookies.get("i18n-locale")??(z.headers.get("accept-language")||j),[F]=C.split(",");if(this.config.supportedLocales.includes(F))return F;if(F.length===2){for(let H of this.config.supportedLocales)if(H.startsWith(F))return H}return j}getPageTranslations(z,j){if(this.translations[z][j])return this.translations[z][j];return{}}}
|
|
3
|
-
export{K as
|
|
3
|
+
export{K as wf};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=6BDD7227EB332BDD64756E2164756E21
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"import type { HttpRequest } from \"../http/HttpRequest\";\nimport type { Dictionary } from \"./Dictionary\";\nimport type { TranslationConfig } from \"./config\";\n\nexport class Translator {\n static token = \"translator\";\n\n translations = {};\n isEnabled = false;\n\n constructor(public config: Required<TranslationConfig>) {\n const translations = {};\n\n for (const [route, dicArray] of Object.entries(this.config.prefetch)) {\n for (const locale of this.config.supportedLocales) {\n if (!translations[locale]) {\n translations[locale] = {};\n }\n translations[locale][route] = {};\n for (const dic of dicArray) {\n translations[locale][route][dic.name] = {};\n for (const [key, value] of Object.entries(dic.dictionary)) {\n this.isEnabled = true;\n translations[locale][route][dic.name][key] = value[locale];\n }\n }\n }\n }\n this.translations = translations;\n }\n\n /**\n * Whether the app does locale-aware routing and rendering at all.\n *\n * `isEnabled` only means the legacy `prefetch` config has dictionaries to\n * serve. An app on `defineDictionary` has an empty `prefetch` and declares\n * its locales through `supportedLocales` alone, so gating on `isEnabled`\n * leaves it without locale detection or a locale URL prefix. Both the render\n * path and the redirect read this, because when they disagreed a migrated app\n * rendered a non-default locale at `/` with no redirect and no `Vary` — one\n * cache fill away from serving that document to everyone.\n */\n get isLocaleAware(): boolean {\n return this.isEnabled || this.config.supportedLocales.length > 0;\n }\n\n get supportedLocales(): string[] {\n return this.config.supportedLocales;\n }\n\n get defaultLocale(): string {\n return this.config.defaultLocale;\n }\n\n get components(): Record<string, Dictionary<any>> {\n return this.config.components;\n }\n\n onLocaleChange(locale: string): Promise<void> | void {\n return this.config.onLocaleChange(locale);\n }\n\n detectLocale(req: HttpRequest<any, any>) {\n const fallbackLocale =\n this.config.defaultLocale ?? this.config.supportedLocales[0] ?? \"en-US\";\n const detectedLocale = this.config.detectLocale(req);\n if (this.config.supportedLocales.includes(detectedLocale)) {\n return detectedLocale;\n }\n\n const previousLocale = req.cookies.get(\"i18n-locale\");\n const locale =\n previousLocale ?? (req.headers.get(\"accept-language\") || fallbackLocale);\n\n const [_locale] = locale.split(\",\");\n\n if (this.config.supportedLocales.includes(_locale)) {\n return _locale;\n }\n\n if (_locale.length === 2) {\n for (const supportedLocale of this.config.supportedLocales) {\n if (supportedLocale.startsWith(_locale)) {\n return supportedLocale;\n }\n }\n }\n\n return fallbackLocale;\n }\n\n getPageTranslations(locale: string, scope: string) {\n if (this.translations[locale][scope]) {\n return this.translations[locale][scope];\n }\n return {};\n }\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAIO,MAAM,CAAW,CAMH,aALZ,OAAQ,aAEf,aAAe,CAAC,EAChB,UAAY,GAEZ,WAAW,CAAQ,EAAqC,CAArC,cACjB,IAAM,EAAe,CAAC,EAEtB,QAAY,EAAO,KAAa,OAAO,QAAQ,KAAK,OAAO,QAAQ,EACjE,QAAW,KAAU,KAAK,OAAO,iBAAkB,CACjD,GAAI,CAAC,EAAa,GAChB,EAAa,GAAU,CAAC,EAE1B,EAAa,GAAQ,GAAS,CAAC,EAC/B,QAAW,KAAO,EAAU,CAC1B,EAAa,GAAQ,GAAO,EAAI,MAAQ,CAAC,EACzC,QAAY,EAAK,KAAU,OAAO,QAAQ,EAAI,UAAU,EACtD,KAAK,UAAY,GACjB,EAAa,GAAQ,GAAO,EAAI,MAAM,GAAO,EAAM,IAK3D,KAAK,aAAe,KAclB,cAAa,EAAY,CAC3B,OAAO,KAAK,WAAa,KAAK,OAAO,iBAAiB,OAAS,KAG7D,iBAAgB,EAAa,CAC/B,OAAO,KAAK,OAAO,oBAGjB,cAAa,EAAW,CAC1B,OAAO,KAAK,OAAO,iBAGjB,WAAU,EAAoC,CAChD,OAAO,KAAK,OAAO,WAGrB,cAAc,CAAC,EAAsC,CACnD,OAAO,KAAK,OAAO,eAAe,CAAM,EAG1C,YAAY,CAAC,EAA4B,CACvC,IAAM,EACJ,KAAK,OAAO,eAAiB,KAAK,OAAO,iBAAiB,IAAM,QAC5D,EAAiB,KAAK,OAAO,aAAa,CAAG,EACnD,GAAI,KAAK,OAAO,iBAAiB,SAAS,CAAc,EACtD,OAAO,EAIT,IAAM,EADiB,EAAI,QAAQ,IAAI,aAAa,IAE/B,EAAI,QAAQ,IAAI,iBAAiB,GAAK,IAEpD,GAAW,EAAO,MAAM,GAAG,EAElC,GAAI,KAAK,OAAO,iBAAiB,SAAS,CAAO,EAC/C,OAAO,EAGT,GAAI,EAAQ,SAAW,GACrB,QAAW,KAAmB,KAAK,OAAO,iBACxC,GAAI,EAAgB,WAAW,CAAO,EACpC,OAAO,EAKb,OAAO,EAGT,mBAAmB,CAAC,EAAgB,EAAe,CACjD,GAAI,KAAK,aAAa,GAAQ,GAC5B,OAAO,KAAK,aAAa,GAAQ,GAEnC,MAAO,CAAC,EAEZ",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "6BDD7227EB332BDD64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
3
|
-
export{D as
|
|
2
|
+
import{Cf as j}from"./chunk-dgsgjg53.js";function $(z){return z.split(".")}class X{static token="config";items;constructor(z={}){this.items=z}has(z){let H=this.items;for(let G of $(z)){if(H===null||typeof H!=="object"||!(G in H))return!1;H=H[G]}return!0}get(z,H){let G=this.items;for(let J of $(z)){if(G===null||typeof G!=="object"||!(J in G))return H;G=G[J]}return G===void 0?H:G}getMany(z){let H=Array.isArray(z)?z.map((J)=>[J,void 0]):Object.entries(z),G={};for(let[J,Y]of H)G[J]=this.get(J,Y);return G}set(z,H){let G=typeof z==="string"?[[z,H]]:Object.entries(z);for(let[J,Y]of G){let E=$(J),K=E.pop(),U=this.items;for(let Z of E){let F=U[Z];if(F===null||typeof F!=="object")U[Z]={};U=U[Z]}U[K]=Y}}prepend(z,H){let G=this.get(z,[]);G.unshift(H),this.set(z,G)}push(z,H){let G=this.get(z,[]);G.push(H),this.set(z,G)}merge(z){for(let[H,G]of Object.entries(z)){let J=this.items[H];if(J!==null&&typeof J==="object"&&!Array.isArray(J)&&G!==null&&typeof G==="object"&&!Array.isArray(G))this.items[H]={...J,...G};else this.items[H]=G}}all(){return this.items}}var W=Symbol.for("gemi.foundation.Application");class Q extends j{[W]=!0;static isApplication(z){return typeof z==="object"&&z!==null&&W in z}config;providers=[];booted=!1;constructor(z=new X){super();this.config=z,this.instance(X,z)}static currentInstance;static getInstance(){return Q.currentInstance}static setInstance(z){return Q.currentInstance=z,z}register(z){let H=this.providers.find((J)=>J instanceof z);if(H)return H;let G=new z(this);return G.register(),this.providers.push(G),G}registerMany(z){for(let H of z)this.register(H)}getProviders(){return[...this.providers]}isBooted(){return this.booted}async boot(){if(this.booted)return;for(let z of this.providers)await z.boot();this.booted=!0}flush(){super.flush(),this.instance(X,this.config),this.providers=[],this.booted=!1}}import{AsyncLocalStorage as _}from"async_hooks";var D=new _;function I(z){let H=D.getStore(),G=Q.isApplication(H)?H:Q.getInstance();if(!G)throw Error("No Application instance is available. Boot a Kernel before resolving services.");return z?G.make(z):G}
|
|
3
|
+
export{D as xf,X as yf,Q as zf,I as Af};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=06BDE3AC754080D964756E2164756E21
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
"import type { ServiceToken } from \"../container/Container\";\nimport { kernelContext } from \"../kernel/context\";\nimport { Application } from \"./Application\";\n\n/**\n * Resolves the Application for the current async context. Reads the kernel\n * AsyncLocalStorage — there is exactly one ALS in the framework, and\n * `Kernel.run()` stores the Application in it, so this is the primary path for\n * anything running inside a request, a websocket message or a cron tick.\n *\n * The static instance (Laravel's `Container::setInstance`, set by\n * `Kernel.boot()`) is the fallback for code that runs outside any `run()`\n * scope — build-time tooling, module top level, a stray `setTimeout`.\n */\nexport function app(): Application;\nexport function app<T>(token: ServiceToken<T>): T;\nexport function app<T>(token?: ServiceToken<T>): Application | T {\n const store = kernelContext.getStore();\n const instance = Application.isApplication(store)\n ? store\n : Application.getInstance();\n\n if (!instance) {\n throw new Error(\n \"No Application instance is available. Boot a Kernel before resolving services.\",\n );\n }\n\n return token ? instance.make(token) : instance;\n}\n"
|
|
9
9
|
],
|
|
10
10
|
"mappings": "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",
|
|
11
|
-
"debugId": "
|
|
11
|
+
"debugId": "06BDE3AC754080D964756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
class A extends Error{constructor(p,q){super(`Target [${p}] is not bound in the container.`+(q.length>0?` Bound tokens: ${q.join(", ")}.`:" No tokens are bound \u2014 was the application booted?"));this.name="BindingResolutionError"}}class C{bindings=new Map;instances=new Map;bind(p,q){this.bindings.set(p.token,{factory:q,shared:!1}),this.instances.delete(p.token)}singleton(p,q){this.bindings.set(p.token,{factory:q,shared:!0}),this.instances.delete(p.token)}instance(p,q){return this.instances.set(p.token,q),q}bound(p){return this.bindings.has(p.token)||this.instances.has(p.token)}resolved(p){return this.instances.has(p.token)}make(p){let q=p.token;if(this.instances.has(q))return this.instances.get(q);let v=this.bindings.get(q);if(!v)throw new A(q,this.keys());let x=v.factory(this);if(v.shared)this.instances.set(q,x);return x}forget(p){this.instances.delete(p.token)}keys(){return[...new Set([...this.bindings.keys(),...this.instances.keys()])]}flush(){this.bindings.clear(),this.instances.clear()}}
|
|
3
|
-
export{A as
|
|
3
|
+
export{A as Bf,C as Cf};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=0B7A8BC6BE86AE6364756E2164756E21
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
"/**\n * Tokens are the service classes themselves, so `make(MailManager)` is typed\n * `MailManager` without a cast. The container keys its bindings off the class's\n * `static token` string rather than the constructor object: the built binary\n * (`dist/bin/gemi.js`) bundles its own copy of gemi while the app resolves\n * `gemi/*` to source, so the same service is two distinct class objects across\n * that boundary. A string survives it. Laravel binds both `'mail'` and\n * `MailManager::class` for the same reason.\n */\nexport type ServiceToken<T> = (abstract new (...args: any[]) => T) & {\n token: string;\n};\n\nexport type Factory<T> = (app: Container) => T;\n\ninterface Binding {\n factory: Factory<any>;\n shared: boolean;\n}\n\nexport class BindingResolutionError extends Error {\n constructor(token: string, known: string[]) {\n super(\n `Target [${token}] is not bound in the container.` +\n (known.length > 0\n ? ` Bound tokens: ${known.join(\", \")}.`\n : \" No tokens are bound — was the application booted?\"),\n );\n this.name = \"BindingResolutionError\";\n }\n}\n\nexport class Container {\n private bindings = new Map<string, Binding>();\n private instances = new Map<string, any>();\n\n bind<T>(token: ServiceToken<T>, factory: Factory<T>) {\n this.bindings.set(token.token, { factory, shared: false });\n this.instances.delete(token.token);\n }\n\n /**\n * Lazy by design — `factory` is not called until the first `make()`.\n */\n singleton<T>(token: ServiceToken<T>, factory: Factory<T>) {\n this.bindings.set(token.token, { factory, shared: true });\n this.instances.delete(token.token);\n }\n\n instance<T>(token: ServiceToken<T>, object: T): T {\n this.instances.set(token.token, object);\n return object;\n }\n\n bound<T>(token: ServiceToken<T>): boolean {\n return (\n this.bindings.has(token.token) || this.instances.has(token.token)\n );\n }\n\n resolved<T>(token: ServiceToken<T>): boolean {\n return this.instances.has(token.token);\n }\n\n make<T>(token: ServiceToken<T>): T {\n const key = token.token;\n\n if (this.instances.has(key)) {\n return this.instances.get(key) as T;\n }\n\n const binding = this.bindings.get(key);\n if (!binding) {\n throw new BindingResolutionError(key, this.keys());\n }\n\n const object = binding.factory(this) as T;\n if (binding.shared) {\n this.instances.set(key, object);\n }\n return object;\n }\n\n forget<T>(token: ServiceToken<T>) {\n this.instances.delete(token.token);\n }\n\n keys(): string[] {\n return [\n ...new Set([...this.bindings.keys(), ...this.instances.keys()]),\n ];\n }\n\n flush() {\n this.bindings.clear();\n this.instances.clear();\n }\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAoBO,MAAM,UAA+B,KAAM,CAChD,WAAW,CAAC,EAAe,EAAiB,CAC1C,MACE,WAAW,qCACR,EAAM,OAAS,EACZ,kBAAkB,EAAM,KAAK,IAAI,KACjC,0DACR,EACA,KAAK,KAAO,yBAEhB,CAEO,MAAM,CAAU,CACb,SAAW,IAAI,IACf,UAAY,IAAI,IAExB,IAAO,CAAC,EAAwB,EAAqB,CACnD,KAAK,SAAS,IAAI,EAAM,MAAO,CAAE,UAAS,OAAQ,EAAM,CAAC,EACzD,KAAK,UAAU,OAAO,EAAM,KAAK,EAMnC,SAAY,CAAC,EAAwB,EAAqB,CACxD,KAAK,SAAS,IAAI,EAAM,MAAO,CAAE,UAAS,OAAQ,EAAK,CAAC,EACxD,KAAK,UAAU,OAAO,EAAM,KAAK,EAGnC,QAAW,CAAC,EAAwB,EAAc,CAEhD,OADA,KAAK,UAAU,IAAI,EAAM,MAAO,CAAM,EAC/B,EAGT,KAAQ,CAAC,EAAiC,CACxC,OACE,KAAK,SAAS,IAAI,EAAM,KAAK,GAAK,KAAK,UAAU,IAAI,EAAM,KAAK,EAIpE,QAAW,CAAC,EAAiC,CAC3C,OAAO,KAAK,UAAU,IAAI,EAAM,KAAK,EAGvC,IAAO,CAAC,EAA2B,CACjC,IAAM,EAAM,EAAM,MAElB,GAAI,KAAK,UAAU,IAAI,CAAG,EACxB,OAAO,KAAK,UAAU,IAAI,CAAG,EAG/B,IAAM,EAAU,KAAK,SAAS,IAAI,CAAG,EACrC,GAAI,CAAC,EACH,MAAM,IAAI,EAAuB,EAAK,KAAK,KAAK,CAAC,EAGnD,IAAM,EAAS,EAAQ,QAAQ,IAAI,EACnC,GAAI,EAAQ,OACV,KAAK,UAAU,IAAI,EAAK,CAAM,EAEhC,OAAO,EAGT,MAAS,CAAC,EAAwB,CAChC,KAAK,UAAU,OAAO,EAAM,KAAK,EAGnC,IAAI,EAAa,CACf,MAAO,CACL,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,KAAK,EAAG,GAAG,KAAK,UAAU,KAAK,CAAC,CAAC,CAChE,EAGF,KAAK,EAAG,CACN,KAAK,SAAS,MAAM,EACpB,KAAK,UAAU,MAAM,EAEzB",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "0B7A8BC6BE86AE6364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|