@lunora/runtime 1.0.0-alpha.87 → 1.0.0-alpha.89

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.
Files changed (25) hide show
  1. package/README.md +14 -10
  2. package/dist/index.d.mts +76 -12
  3. package/dist/index.d.ts +76 -12
  4. package/dist/index.mjs +1 -1
  5. package/dist/packem_shared/analyticsEngineSink-DOreZlpn.mjs +1 -0
  6. package/dist/packem_shared/composeWorker-CF00w7XW.mjs +6 -0
  7. package/dist/packem_shared/{createCrossShardRelationCapabilities-BYNkv1Ys.mjs → createCrossShardRelationCapabilities-DzObCaSU.mjs} +1 -1
  8. package/dist/packem_shared/{createKvCursorStore-dBxlYrXY.mjs → createKvCursorStore-ChbbIB16.mjs} +1 -1
  9. package/dist/packem_shared/createQueryCoordinator-DlWITOu1.mjs +1 -0
  10. package/dist/packem_shared/{createShardClient-DoKTlCKb.mjs → createShardClient-DwR7Y6U6.mjs} +1 -1
  11. package/dist/packem_shared/decorateResponse-CCRm2CFM.mjs +1 -0
  12. package/dist/packem_shared/emitLogEvent-CiOzTq1X.mjs +1 -0
  13. package/dist/packem_shared/{export-tap-CGR3Xd9F.mjs → export-tap-BLr9Lp0x.mjs} +1 -1
  14. package/dist/packem_shared/observability-B1hLjwgx.mjs +1 -0
  15. package/dist/packem_shared/{portable-json-DpqTEd22.mjs → portable-json-fgh98-LE.mjs} +1 -1
  16. package/dist/packem_shared/{toAirbyteMessages-DvYrhqLf.mjs → toAirbyteMessages-CQQ9KTJV.mjs} +1 -1
  17. package/dist/packem_shared/wire-codec-Du-i3W6b.mjs +1 -0
  18. package/package.json +5 -4
  19. package/dist/packem_shared/analyticsEngineSink-B3sQ6FPW.mjs +0 -1
  20. package/dist/packem_shared/composeWorker-DnsDkxiF.mjs +0 -6
  21. package/dist/packem_shared/createQueryCoordinator-Ctr3eqmp.mjs +0 -1
  22. package/dist/packem_shared/decorateResponse-BuqVnrmc.mjs +0 -1
  23. package/dist/packem_shared/emitLogEvent-qlixolZi.mjs +0 -1
  24. package/dist/packem_shared/observability-vDK-rMbs.mjs +0 -1
  25. package/dist/packem_shared/wire-codec-CMVqBlcF.mjs +0 -1
package/README.md CHANGED
@@ -88,20 +88,24 @@ export { ShardDO };
88
88
 
89
89
  ### Workers Cache
90
90
 
91
- When `cache: { enabled: true }` is present in `wrangler.jsonc` and `compatibility_date >= "2026-05-01"`, the runtime forwards the Worker's `ExecutionContext.cache` into action handlers as `ctx.cache`. This lets you purge cache by tag from HTTP action handlers:
91
+ When `cache: { enabled: true }` is present in `wrangler.jsonc` and `compatibility_date >= "2026-05-01"`, the runtime forwards the Worker's `ExecutionContext.cache` into the **HTTP action** context as `ctx.cache`. This lets you purge cache by tag from an `httpRouter()` handler:
92
92
 
93
93
  ```ts
94
- export const refreshProducts = action.action(async ({ ctx }) => {
95
- if (!ctx.cache) {
96
- throw new Error("Workers Cache is not enabled in wrangler.jsonc");
97
- }
98
-
99
- await ctx.cache.purge({ tags: ["products"] });
100
- return { ok: true };
101
- });
94
+ app.post(
95
+ "/admin/refresh-products",
96
+ httpAction(async (ctx) => {
97
+ if (!ctx.cache) {
98
+ return new Response("Workers Cache is not enabled in wrangler.jsonc", { status: 501 });
99
+ }
100
+
101
+ await ctx.cache.purge({ tags: ["products"] });
102
+
103
+ return Response.json({ ok: true });
104
+ }),
105
+ );
102
106
  ```
103
107
 
104
- The `ctx.cache` binding is only available in **action** handlers (not query/mutation), because actions run in the Worker while queries/mutations run inside the Durable Object. Cache header declarations on `httpRoute` (`.cacheControl()`, `.cacheTag()`, `.vary()`) are attached by `@lunora/server` before the response leaves the handler.
108
+ The `ctx.cache` binding reaches **HTTP action handlers only**. Queries, mutations, and RPC actions all run inside the Durable Object, which has no cache binding, so `ctx.cache` is `undefined` for every one of them — always branch on it. Cache header declarations on `httpRoute` (`.cacheControl()`, `.cacheTag()`, `.vary()`) are attached by `@lunora/server` before the response leaves the handler.
105
109
 
106
110
  ### Scheduled backups
107
111
 
package/dist/index.d.mts CHANGED
@@ -885,7 +885,21 @@ interface FanOutSpec {
885
885
  * UI.
886
886
  */
887
887
  interface ShardError {
888
- /** Human-readable; tests assert on `.includes("timeout")` and similar. */
888
+ /**
889
+ * Machine-readable failure code, from the same `toErrorBody` shaping every
890
+ * other error leaving this runtime goes through: a shard's own
891
+ * `LunoraError` code when it had one, `SHARD_TIMEOUT` / `SHARD_HTTP_ERROR`
892
+ * for the transport failures this coordinator detects itself, and `INTERNAL`
893
+ * for anything else. Callers branch on this rather than on `message`.
894
+ */
895
+ code: string;
896
+ /**
897
+ * Human-readable; tests assert on `.includes("timeout")` and similar. Shaped
898
+ * by `toErrorBody`, so an internal-coded or non-`LunoraError` throw is
899
+ * redacted here exactly as it would be on the single-shard path — the
900
+ * fan-out envelope is `Response.json`-ed straight to the caller, and a raw
901
+ * `error.message` from a shard is platform detail that must not ride out.
902
+ */
889
903
  message: string;
890
904
  shardKey: string;
891
905
  /** Set when the per-shard timeout fired. */
@@ -2677,8 +2691,16 @@ interface ResolvedSecurity {
2677
2691
  * and `LUNORA_ALLOWED_ORIGINS` / `LUNORA_CORS_ALLOW_CREDENTIALS` configure CORS
2678
2692
  * when it isn't set in code. **Code config wins** — an explicit `security.*` in
2679
2693
  * {@link SecurityOptions} overrides the matching env knob — so the env var only
2680
- * relaxes or fills the secure default, and the DO security audit (which reads the
2681
- * same vars) and the running worker stay in agreement.
2694
+ * relaxes or fills the secure default.
2695
+ *
2696
+ * That precedence is exactly why the two can disagree, so pick one place per
2697
+ * layer. The Durable Object's security audit (`buildSecurityAudit`) sees only
2698
+ * `env` — the DO has no view of what was passed to `createWorker` — so
2699
+ * `security: { headers: true }` in code plus an `off` value for
2700
+ * `LUNORA_SECURITY_HEADERS` in env leaves the worker applying the headers while the audit reports
2701
+ * `security-headers-disabled`, and the same holds for `csrf`. The audit is
2702
+ * reporting the deployment var honestly; it is not a claim about the resolved
2703
+ * worker. Setting a layer in code means leaving its env var unset.
2682
2704
  */
2683
2705
  declare const resolveSecurity: (security: SecurityOptions | undefined, env?: Record<string, unknown>) => ResolvedSecurity;
2684
2706
  /**
@@ -2717,10 +2739,12 @@ declare const decorateResponse: (response: Response, request: Request, resolved:
2717
2739
  * Continuing an inbound W3C `traceparent` is what makes a distributed waterfall
2718
2740
  * stitch end to end, but the header is caller-supplied: on a public worker,
2719
2741
  * trusting it lets anyone choose which trace their spans and `ctx.log` lines land
2720
- * in, and because `shared/sampling` derives the head verdict from the trace id
2721
- * choose their own sampling outcome. Whether that matters is a *deployment*
2722
- * question ("can an untrusted client reach this worker directly?"), which no
2723
- * amount of request inspection can answer on its own.
2742
+ * in and, since a trusted upstream is also what makes the head verdict key on
2743
+ * that caller-supplied TRACE id, choose their own sampling outcome. (Untrusted,
2744
+ * the verdict keys on the server-minted span id instead, which is precisely the
2745
+ * hole this option closes.) Whether that matters is a *deployment* question
2746
+ * ("can an untrusted client reach this worker directly?"), which no amount of
2747
+ * request inspection can answer on its own.
2724
2748
  *
2725
2749
  * So rather than ask users to hand-roll a security predicate, this module ships
2726
2750
  * the answers that are actually sound, named:
@@ -2878,6 +2902,16 @@ interface HttpActionContext {
2878
2902
  * dependency; the server side narrows it to the real `Storage`.
2879
2903
  */
2880
2904
  storage?: unknown;
2905
+ /**
2906
+ * The request's `ExecutionContext.waitUntil`, forwarded so a handler can
2907
+ * keep work alive past the returned `Response` — the shape an HTTP action
2908
+ * exists for ("ack the webhook now, finish the work after"). Optional
2909
+ * because {@link ExecutionContextLike.waitUntil} is: a framework mount seam
2910
+ * or a unit test may hand over a partial context, and this is absent rather
2911
+ * than a throwing stub so a caller can tell "no deferral available here"
2912
+ * from "deferred". Mirrors `HttpActionCtx.waitUntil` on the server side.
2913
+ */
2914
+ waitUntil?: (promise: Promise<unknown>) => void;
2881
2915
  }
2882
2916
  /**
2883
2917
  * The scheduler surface on an HTTP action context. Mirrors `@lunora/server`'s
@@ -4736,10 +4770,21 @@ declare const pipelineLogSink: (options: PipelineLogSinkOptions) => Observabilit
4736
4770
  * Everything the exporter buffered for one flush window, grouped so a
4737
4771
  * {@link TailSampler} can judge a trace as a whole.
4738
4772
  *
4739
- * This is what makes it *tail* sampling rather than another head decision: by
4740
- * flush time the trace's spans have all settled, so "keep it if anything in it
4741
- * was slow or failed" is answerable — which it is not at the moment the first
4742
- * span starts.
4773
+ * This is what makes it *tail* sampling rather than another head decision: the
4774
+ * signals in the window have settled by the time it is judged, so "keep it if
4775
+ * anything here was slow or failed" is answerable — which it is not at the
4776
+ * moment the first span starts.
4777
+ *
4778
+ * **It is one sink instance's window, not the whole trace.** A batcher lives in
4779
+ * the isolate that created it, so in production a request's signals are split
4780
+ * across at least two of them: the worker's sink holds the SERVER `rpc` event,
4781
+ * and the shard's sink holds that dispatch's `ctx.trace` spans, `ctx.log` lines
4782
+ * and metrics. The sampler therefore runs once per isolate over its own half,
4783
+ * and the halves can disagree — the worker keeping the SERVER span while the
4784
+ * Durable Object drops its children, or the reverse — leaving a partial trace at
4785
+ * the collector. Write a predicate that reaches the same verdict from either
4786
+ * half (judge on `traceId`, on any `ok: false`, on a duration threshold), and
4787
+ * treat it as a cost control rather than a guarantee that a trace arrives whole.
4743
4788
  */
4744
4789
  interface TailSamplerInput {
4745
4790
  /** Log records emitted under this trace. */
@@ -4787,7 +4832,7 @@ interface OtlpBatchOptions {
4787
4832
  * with no invocation boundary. Default 200ms.
4788
4833
  */
4789
4834
  maxDelayMs?: number;
4790
- /** Flush as soon as this many events are buffered. Default 512. */
4835
+ /** Flush as soon as this many events are buffered. Default 512. Must be a positive integer — `otlpSink` throws `ENV_INVALID` otherwise. */
4791
4836
  maxItems?: number;
4792
4837
  }
4793
4838
  /** Options for {@link otlpSink}. */
@@ -4844,6 +4889,25 @@ interface OtlpSinkOptions extends OnlyErrorsOption {
4844
4889
  * see {@link postProcess}.
4845
4890
  */
4846
4891
  postProcessor?: OtlpPostProcessor;
4892
+ /**
4893
+ * Default-redact `ctx.log` records (the structured `fields` bag and the
4894
+ * rendered `message`) before they are exported. Default `true`.
4895
+ *
4896
+ * On because the alternative is the sinks disagreeing about one event: the
4897
+ * console/Logpush line already redacts `fields`, and the span pipeline
4898
+ * already redacts error messages, precisely because a developer can attach
4899
+ * anything to a fields bag — `ctx.log.info("charged", { email, cardLast4 })`.
4900
+ * A collector is the sink with third-party fan-out, so it is the last place
4901
+ * that should see more than the others.
4902
+ *
4903
+ * Set `false` ONLY when the collector is as trusted as the worker itself and
4904
+ * you need verbatim values (a self-hosted collector behind your own
4905
+ * network). The masking is `@visulima/redact`'s standard rules — key-name
4906
+ * matches on the bag plus PII patterns in text — so it is a net, not a
4907
+ * general secret scrubber; see `redactArgs` in `@lunora/observability`.
4908
+ * `postProcessor.log` still runs either way, and runs after this.
4909
+ */
4910
+ redactLogs?: boolean;
4847
4911
  /**
4848
4912
  * Additional resource attributes to attach to every exported signal. These
4849
4913
  * ride alongside the built-in `service.name` and any convenience fields
package/dist/index.d.ts CHANGED
@@ -885,7 +885,21 @@ interface FanOutSpec {
885
885
  * UI.
886
886
  */
887
887
  interface ShardError {
888
- /** Human-readable; tests assert on `.includes("timeout")` and similar. */
888
+ /**
889
+ * Machine-readable failure code, from the same `toErrorBody` shaping every
890
+ * other error leaving this runtime goes through: a shard's own
891
+ * `LunoraError` code when it had one, `SHARD_TIMEOUT` / `SHARD_HTTP_ERROR`
892
+ * for the transport failures this coordinator detects itself, and `INTERNAL`
893
+ * for anything else. Callers branch on this rather than on `message`.
894
+ */
895
+ code: string;
896
+ /**
897
+ * Human-readable; tests assert on `.includes("timeout")` and similar. Shaped
898
+ * by `toErrorBody`, so an internal-coded or non-`LunoraError` throw is
899
+ * redacted here exactly as it would be on the single-shard path — the
900
+ * fan-out envelope is `Response.json`-ed straight to the caller, and a raw
901
+ * `error.message` from a shard is platform detail that must not ride out.
902
+ */
889
903
  message: string;
890
904
  shardKey: string;
891
905
  /** Set when the per-shard timeout fired. */
@@ -2677,8 +2691,16 @@ interface ResolvedSecurity {
2677
2691
  * and `LUNORA_ALLOWED_ORIGINS` / `LUNORA_CORS_ALLOW_CREDENTIALS` configure CORS
2678
2692
  * when it isn't set in code. **Code config wins** — an explicit `security.*` in
2679
2693
  * {@link SecurityOptions} overrides the matching env knob — so the env var only
2680
- * relaxes or fills the secure default, and the DO security audit (which reads the
2681
- * same vars) and the running worker stay in agreement.
2694
+ * relaxes or fills the secure default.
2695
+ *
2696
+ * That precedence is exactly why the two can disagree, so pick one place per
2697
+ * layer. The Durable Object's security audit (`buildSecurityAudit`) sees only
2698
+ * `env` — the DO has no view of what was passed to `createWorker` — so
2699
+ * `security: { headers: true }` in code plus an `off` value for
2700
+ * `LUNORA_SECURITY_HEADERS` in env leaves the worker applying the headers while the audit reports
2701
+ * `security-headers-disabled`, and the same holds for `csrf`. The audit is
2702
+ * reporting the deployment var honestly; it is not a claim about the resolved
2703
+ * worker. Setting a layer in code means leaving its env var unset.
2682
2704
  */
2683
2705
  declare const resolveSecurity: (security: SecurityOptions | undefined, env?: Record<string, unknown>) => ResolvedSecurity;
2684
2706
  /**
@@ -2717,10 +2739,12 @@ declare const decorateResponse: (response: Response, request: Request, resolved:
2717
2739
  * Continuing an inbound W3C `traceparent` is what makes a distributed waterfall
2718
2740
  * stitch end to end, but the header is caller-supplied: on a public worker,
2719
2741
  * trusting it lets anyone choose which trace their spans and `ctx.log` lines land
2720
- * in, and because `shared/sampling` derives the head verdict from the trace id
2721
- * choose their own sampling outcome. Whether that matters is a *deployment*
2722
- * question ("can an untrusted client reach this worker directly?"), which no
2723
- * amount of request inspection can answer on its own.
2742
+ * in and, since a trusted upstream is also what makes the head verdict key on
2743
+ * that caller-supplied TRACE id, choose their own sampling outcome. (Untrusted,
2744
+ * the verdict keys on the server-minted span id instead, which is precisely the
2745
+ * hole this option closes.) Whether that matters is a *deployment* question
2746
+ * ("can an untrusted client reach this worker directly?"), which no amount of
2747
+ * request inspection can answer on its own.
2724
2748
  *
2725
2749
  * So rather than ask users to hand-roll a security predicate, this module ships
2726
2750
  * the answers that are actually sound, named:
@@ -2878,6 +2902,16 @@ interface HttpActionContext {
2878
2902
  * dependency; the server side narrows it to the real `Storage`.
2879
2903
  */
2880
2904
  storage?: unknown;
2905
+ /**
2906
+ * The request's `ExecutionContext.waitUntil`, forwarded so a handler can
2907
+ * keep work alive past the returned `Response` — the shape an HTTP action
2908
+ * exists for ("ack the webhook now, finish the work after"). Optional
2909
+ * because {@link ExecutionContextLike.waitUntil} is: a framework mount seam
2910
+ * or a unit test may hand over a partial context, and this is absent rather
2911
+ * than a throwing stub so a caller can tell "no deferral available here"
2912
+ * from "deferred". Mirrors `HttpActionCtx.waitUntil` on the server side.
2913
+ */
2914
+ waitUntil?: (promise: Promise<unknown>) => void;
2881
2915
  }
2882
2916
  /**
2883
2917
  * The scheduler surface on an HTTP action context. Mirrors `@lunora/server`'s
@@ -4736,10 +4770,21 @@ declare const pipelineLogSink: (options: PipelineLogSinkOptions) => Observabilit
4736
4770
  * Everything the exporter buffered for one flush window, grouped so a
4737
4771
  * {@link TailSampler} can judge a trace as a whole.
4738
4772
  *
4739
- * This is what makes it *tail* sampling rather than another head decision: by
4740
- * flush time the trace's spans have all settled, so "keep it if anything in it
4741
- * was slow or failed" is answerable — which it is not at the moment the first
4742
- * span starts.
4773
+ * This is what makes it *tail* sampling rather than another head decision: the
4774
+ * signals in the window have settled by the time it is judged, so "keep it if
4775
+ * anything here was slow or failed" is answerable — which it is not at the
4776
+ * moment the first span starts.
4777
+ *
4778
+ * **It is one sink instance's window, not the whole trace.** A batcher lives in
4779
+ * the isolate that created it, so in production a request's signals are split
4780
+ * across at least two of them: the worker's sink holds the SERVER `rpc` event,
4781
+ * and the shard's sink holds that dispatch's `ctx.trace` spans, `ctx.log` lines
4782
+ * and metrics. The sampler therefore runs once per isolate over its own half,
4783
+ * and the halves can disagree — the worker keeping the SERVER span while the
4784
+ * Durable Object drops its children, or the reverse — leaving a partial trace at
4785
+ * the collector. Write a predicate that reaches the same verdict from either
4786
+ * half (judge on `traceId`, on any `ok: false`, on a duration threshold), and
4787
+ * treat it as a cost control rather than a guarantee that a trace arrives whole.
4743
4788
  */
4744
4789
  interface TailSamplerInput {
4745
4790
  /** Log records emitted under this trace. */
@@ -4787,7 +4832,7 @@ interface OtlpBatchOptions {
4787
4832
  * with no invocation boundary. Default 200ms.
4788
4833
  */
4789
4834
  maxDelayMs?: number;
4790
- /** Flush as soon as this many events are buffered. Default 512. */
4835
+ /** Flush as soon as this many events are buffered. Default 512. Must be a positive integer — `otlpSink` throws `ENV_INVALID` otherwise. */
4791
4836
  maxItems?: number;
4792
4837
  }
4793
4838
  /** Options for {@link otlpSink}. */
@@ -4844,6 +4889,25 @@ interface OtlpSinkOptions extends OnlyErrorsOption {
4844
4889
  * see {@link postProcess}.
4845
4890
  */
4846
4891
  postProcessor?: OtlpPostProcessor;
4892
+ /**
4893
+ * Default-redact `ctx.log` records (the structured `fields` bag and the
4894
+ * rendered `message`) before they are exported. Default `true`.
4895
+ *
4896
+ * On because the alternative is the sinks disagreeing about one event: the
4897
+ * console/Logpush line already redacts `fields`, and the span pipeline
4898
+ * already redacts error messages, precisely because a developer can attach
4899
+ * anything to a fields bag — `ctx.log.info("charged", { email, cardLast4 })`.
4900
+ * A collector is the sink with third-party fan-out, so it is the last place
4901
+ * that should see more than the others.
4902
+ *
4903
+ * Set `false` ONLY when the collector is as trusted as the worker itself and
4904
+ * you need verbatim values (a self-hosted collector behind your own
4905
+ * network). The masking is `@visulima/redact`'s standard rules — key-name
4906
+ * matches on the bag plus PII patterns in text — so it is a net, not a
4907
+ * general secret scrubber; see `redactArgs` in `@lunora/observability`.
4908
+ * `postProcessor.log` still runs either way, and runs after this.
4909
+ */
4910
+ redactLogs?: boolean;
4847
4911
  /**
4848
4912
  * Additional resource attributes to attach to every exported signal. These
4849
4913
  * ride alongside the built-in `service.name` and any convenience fields
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{BACKUP_KEY_PREFIX as t,backupManifestKey as a,backupObjectKey as s,backupObjectKeyOfManifest as i,isBackupManifestEntry as n,isBackupManifestKey as p,normalizeBackupPrefix as c}from"./packem_shared/BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toAirbyteMessages as f,toFivetranResponse as E}from"./packem_shared/toAirbyteMessages-DvYrhqLf.mjs";import{composeWorker as x,createLunoraHandler as S,createWorker as l,defineRpcEnvelope as u,resolveLunoraOptions as _,withFrameworkWorker as d}from"./packem_shared/composeWorker-DnsDkxiF.mjs";import{createCrossShardRelationCapabilities as y}from"./packem_shared/createCrossShardRelationCapabilities-BYNkv1Ys.mjs";import{DEFAULT_REGISTRY_CACHE_TTL_MS as O,SHARD_REGISTRY_DO_NAME as b,createDynamicShardRegistry as A}from"./packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-D5O7elXI.mjs";import{LunoraError as T,toErrorResponse as h}from"./packem_shared/LunoraError-DksAgIpa.mjs";import{c as P,a as g,d as v,r as I,b as D,s as M,w as F}from"./packem_shared/export-tap-CGR3Xd9F.mjs";import{HEALTH_PATH as G,HEALTH_READY_PATH as K,buildHealthRoutes as U,d1Probe as B,durableObjectProbe as Y,presenceProbe as w}from"./packem_shared/HEALTH_PATH-jZsuCmSs.mjs";import{LOG_ARCHIVE_PATH as X,resolveLogArchiveFromEnv as j}from"./packem_shared/LOG_ARCHIVE_PATH-Hmjpz_Ko.mjs";import{memoizeIdentity as W,memoizeIdentityPerRequest as q}from"./packem_shared/memoizeIdentity-DnOj3QRi.mjs";import{e as J,a as Z}from"./packem_shared/observability-vDK-rMbs.mjs";import{analyticsEngineSink as ee,combineSinks as re,consoleSink as oe,otlpSink as te,pipelineLogSink as ae,sentrySink as se,webhookSink as ie}from"./packem_shared/analyticsEngineSink-B3sQ6FPW.mjs";import{D as pe,c as ce}from"./packem_shared/pipeline-log-reader-C-nuWG_e.mjs";import{createQueryCoordinator as fe,createStaticShardRegistry as Ee}from"./packem_shared/createQueryCoordinator-Ctr3eqmp.mjs";import{applyJurisdiction as xe,resolveShard as Se}from"./packem_shared/applyJurisdiction-C0ddU7Tg.mjs";import{a as ue,r as _e,b as de}from"./packem_shared/rest-cache-CPSyD1RD.mjs";import{a as ye,b as Ce,c as Oe,r as be}from"./packem_shared/rest-routes-ZZES0ngM.mjs";import{decorateResponse as Le,enforceOrigin as Te,handleCorsPreflight as he,resolveSecurity as He}from"./packem_shared/decorateResponse-BuqVnrmc.mjs";import{createShardClient as ge}from"./packem_shared/createShardClient-DoKTlCKb.mjs";import{STORAGE_UPLOAD_MAX_BODY_BYTES as Ie}from"./packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{LOG_ARCHIVE_NOT_CONFIGURED as Me}from"./packem_shared/LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{NOOP_EXECUTION_CONTEXT as Ne}from"./packem_shared/NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{composeIdentityResolvers as Ke,routeIdentityResolvers as Ue}from"./packem_shared/composeIdentityResolvers-BHZ4jH8o.mjs";const e="0.0.0";export{t as BACKUP_KEY_PREFIX,pe as DEFAULT_LOG_COLUMNS,O as DEFAULT_REGISTRY_CACHE_TTL_MS,G as HEALTH_PATH,K as HEALTH_READY_PATH,Me as LOG_ARCHIVE_NOT_CONFIGURED,X as LOG_ARCHIVE_PATH,T as LunoraError,Ne as NOOP_EXECUTION_CONTEXT,b as SHARD_REGISTRY_DO_NAME,Ie as STORAGE_UPLOAD_MAX_BODY_BYTES,e as VERSION,ee as analyticsEngineSink,xe as applyJurisdiction,ue as applyRestCache,ye as argsFromQuery,a as backupManifestKey,s as backupObjectKey,i as backupObjectKeyOfManifest,U as buildHealthRoutes,Ce as buildRestRoutes,re as combineSinks,Ke as composeIdentityResolvers,x as composeWorker,oe as consoleSink,y as createCrossShardRelationCapabilities,A as createDynamicShardRegistry,P as createKvCursorStore,S as createLunoraHandler,g as createMemoryCursorStore,ce as createPipelineLogReader,fe as createQueryCoordinator,Oe as createRestRateLimit,ge as createShardClient,Ee as createStaticShardRegistry,l as createWorker,B as d1Probe,Le as decorateResponse,v as defineExportSink,u as defineRpcEnvelope,Y as durableObjectProbe,J as emitLogEvent,Z as emitRpcEvent,Te as enforceOrigin,he as handleCorsPreflight,n as isBackupManifestEntry,p as isBackupManifestKey,W as memoizeIdentity,q as memoizeIdentityPerRequest,c as normalizeBackupPrefix,te as otlpSink,ae as pipelineLogSink,w as presenceProbe,I as r2Sink,_e as requestCarriesCredentials,j as resolveLogArchiveFromEnv,_ as resolveLunoraOptions,He as resolveSecurity,Se as resolveShard,de as restCacheHeaders,be as restSurfaceFromRegistry,Ue as routeIdentityResolvers,D as runExportTap,M as sanitizeChange,se as sentrySink,f as toAirbyteMessages,h as toErrorResponse,E as toFivetranResponse,F as webhookExportSink,ie as webhookSink,d as withFrameworkWorker};
1
+ import{BACKUP_KEY_PREFIX as t,backupManifestKey as a,backupObjectKey as s,backupObjectKeyOfManifest as i,isBackupManifestEntry as n,isBackupManifestKey as p,normalizeBackupPrefix as c}from"./packem_shared/BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toAirbyteMessages as f,toFivetranResponse as E}from"./packem_shared/toAirbyteMessages-CQQ9KTJV.mjs";import{composeWorker as x,createLunoraHandler as S,createWorker as l,defineRpcEnvelope as u,resolveLunoraOptions as _,withFrameworkWorker as d}from"./packem_shared/composeWorker-CF00w7XW.mjs";import{createCrossShardRelationCapabilities as y}from"./packem_shared/createCrossShardRelationCapabilities-DzObCaSU.mjs";import{DEFAULT_REGISTRY_CACHE_TTL_MS as O,SHARD_REGISTRY_DO_NAME as b,createDynamicShardRegistry as A}from"./packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-D5O7elXI.mjs";import{LunoraError as T,toErrorResponse as h}from"./packem_shared/LunoraError-DksAgIpa.mjs";import{c as P,a as g,d as v,r as I,b as D,s as M,w as F}from"./packem_shared/export-tap-BLr9Lp0x.mjs";import{HEALTH_PATH as G,HEALTH_READY_PATH as K,buildHealthRoutes as U,d1Probe as B,durableObjectProbe as Y,presenceProbe as w}from"./packem_shared/HEALTH_PATH-jZsuCmSs.mjs";import{LOG_ARCHIVE_PATH as X,resolveLogArchiveFromEnv as j}from"./packem_shared/LOG_ARCHIVE_PATH-Hmjpz_Ko.mjs";import{memoizeIdentity as W,memoizeIdentityPerRequest as q}from"./packem_shared/memoizeIdentity-DnOj3QRi.mjs";import{e as J,a as Z}from"./packem_shared/observability-B1hLjwgx.mjs";import{analyticsEngineSink as ee,combineSinks as re,consoleSink as oe,otlpSink as te,pipelineLogSink as ae,sentrySink as se,webhookSink as ie}from"./packem_shared/analyticsEngineSink-DOreZlpn.mjs";import{D as pe,c as ce}from"./packem_shared/pipeline-log-reader-C-nuWG_e.mjs";import{createQueryCoordinator as fe,createStaticShardRegistry as Ee}from"./packem_shared/createQueryCoordinator-DlWITOu1.mjs";import{applyJurisdiction as xe,resolveShard as Se}from"./packem_shared/applyJurisdiction-C0ddU7Tg.mjs";import{a as ue,r as _e,b as de}from"./packem_shared/rest-cache-CPSyD1RD.mjs";import{a as ye,b as Ce,c as Oe,r as be}from"./packem_shared/rest-routes-ZZES0ngM.mjs";import{decorateResponse as Le,enforceOrigin as Te,handleCorsPreflight as he,resolveSecurity as He}from"./packem_shared/decorateResponse-CCRm2CFM.mjs";import{createShardClient as ge}from"./packem_shared/createShardClient-DwR7Y6U6.mjs";import{STORAGE_UPLOAD_MAX_BODY_BYTES as Ie}from"./packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{LOG_ARCHIVE_NOT_CONFIGURED as Me}from"./packem_shared/LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{NOOP_EXECUTION_CONTEXT as Ne}from"./packem_shared/NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{composeIdentityResolvers as Ke,routeIdentityResolvers as Ue}from"./packem_shared/composeIdentityResolvers-BHZ4jH8o.mjs";const e="0.0.0";export{t as BACKUP_KEY_PREFIX,pe as DEFAULT_LOG_COLUMNS,O as DEFAULT_REGISTRY_CACHE_TTL_MS,G as HEALTH_PATH,K as HEALTH_READY_PATH,Me as LOG_ARCHIVE_NOT_CONFIGURED,X as LOG_ARCHIVE_PATH,T as LunoraError,Ne as NOOP_EXECUTION_CONTEXT,b as SHARD_REGISTRY_DO_NAME,Ie as STORAGE_UPLOAD_MAX_BODY_BYTES,e as VERSION,ee as analyticsEngineSink,xe as applyJurisdiction,ue as applyRestCache,ye as argsFromQuery,a as backupManifestKey,s as backupObjectKey,i as backupObjectKeyOfManifest,U as buildHealthRoutes,Ce as buildRestRoutes,re as combineSinks,Ke as composeIdentityResolvers,x as composeWorker,oe as consoleSink,y as createCrossShardRelationCapabilities,A as createDynamicShardRegistry,P as createKvCursorStore,S as createLunoraHandler,g as createMemoryCursorStore,ce as createPipelineLogReader,fe as createQueryCoordinator,Oe as createRestRateLimit,ge as createShardClient,Ee as createStaticShardRegistry,l as createWorker,B as d1Probe,Le as decorateResponse,v as defineExportSink,u as defineRpcEnvelope,Y as durableObjectProbe,J as emitLogEvent,Z as emitRpcEvent,Te as enforceOrigin,he as handleCorsPreflight,n as isBackupManifestEntry,p as isBackupManifestKey,W as memoizeIdentity,q as memoizeIdentityPerRequest,c as normalizeBackupPrefix,te as otlpSink,ae as pipelineLogSink,w as presenceProbe,I as r2Sink,_e as requestCarriesCredentials,j as resolveLogArchiveFromEnv,_ as resolveLunoraOptions,He as resolveSecurity,Se as resolveShard,de as restCacheHeaders,be as restSurfaceFromRegistry,Ue as routeIdentityResolvers,D as runExportTap,M as sanitizeChange,se as sentrySink,f as toAirbyteMessages,h as toErrorResponse,E as toFivetranResponse,F as webhookExportSink,ie as webhookSink,d as withFrameworkWorker};
@@ -0,0 +1 @@
1
+ import{LunoraError as Z}from"@lunora/errors";import{redactArgs as j}from"@lunora/observability";import{e as l,L as y,o as $,c as S,O as V,f as Q,g as v,h as z,w as rr,i as tr,j as or,m as er}from"./otlp-resource-DeXhb949.mjs";const sr=r=>{if(typeof r=="string")return r;try{return JSON.stringify(r)??String(r)}catch{return String(r)}},W=r=>typeof r=="boolean"||typeof r=="number"||typeof r=="string"?r:sr(r),nr=512,ir=200,ar=r=>{const e=r.maxItems??nr,o=r.maxDelayMs??ir;let t=[],s,c,n;const a=()=>{s!==void 0&&(clearTimeout(s),s=void 0)},h=async()=>{a();const p=t;t=[];const d=n;c=void 0,n=void 0;try{p.length>0&&await r.export(p)}catch{}finally{d?.()}},m=p=>{c===void 0&&(c=new Promise(d=>{n=d}),s=setTimeout(()=>{h()},o)),p?.(c)};return{add:(p,d)=>{for(t.push(p);t.length>e;)t.shift();m(d),t.length>=e&&h()},flush:async p=>{if(t.length===0){a();return}const d=h();return p?.(d),d},get size(){return t.length}}},cr=/["\\\u0000-\u001F\uD800-\uDFFF]/,B=r=>cr.test(r)?JSON.stringify(r):`"${r}"`,A=r=>{if(r===void 0)return"null";if(typeof r=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof r=="number"){if(Number.isNaN(r))return"nan";if(r===1/0)return"inf";if(r===-1/0)return"-inf";if(Object.is(r,-0))return"-0"}if(typeof r=="string")return B(r);if(r===null||typeof r!="object")return JSON.stringify(r);if(Array.isArray(r)){let n="[";for(let a=0;a<r.length;a++)a>0&&(n+=","),n+=A(r[a]);return n+"]"}const e=Object.getPrototypeOf(r);if(e!==null&&e!==Object.prototype){const n=r.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${n} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const o=r,t=Object.keys(o).sort();let s="{",c=!0;for(const n of t){const a=o[n];a!==void 0&&(c?c=!1:s+=",",s+=B(n),s+=":",s+=A(a))}return s+"}"},dr=(r,e)=>{const o=[l(y.functionPath,r.functionPath),l(y.ok,r.ok)];r.method!==void 0&&o.push(l("http.request.method",r.method)),r.path!==void 0&&o.push(l("url.path",r.path)),o.push(l("http.route",r.functionPath)),r.scheme!==void 0&&o.push(l("url.scheme",r.scheme)),r.host!==void 0&&o.push(l("server.address",r.host)),r.port!==void 0&&o.push(l("server.port",r.port)),r.userAgent!==void 0&&o.push(l("user_agent.original",r.userAgent)),r.shardKey!==void 0&&o.push(l(y.shardKey,r.shardKey)),o.push(l("http.response.status_code",r.error?.status??200)),r.error&&o.push(l(y.errorType,r.error.code),l("lunora.error_status",r.error.status)),r.fanOut&&o.push(l("lunora.fanout.table",r.fanOut.table),l("lunora.fanout.shards",r.fanOut.shards),l("lunora.fanout.failed",r.fanOut.failed));const t={attributes:o,endTimeUnixNano:S(e),kind:V.server,name:r.functionPath,...r.parentSpanId===void 0?{}:{parentSpanId:r.parentSpanId},spanId:r.spanId??$(8),startTimeUnixNano:S(e-r.durationMs),status:r.ok?{code:1}:{code:2,message:r.error?.message??""},traceId:r.traceId??$(16)};return r.traceFlags!==void 0&&(t.flags=r.traceFlags),r.error&&(t.events=[{attributes:[l("exception.type",r.error.code),l("exception.message",r.error.message)],name:"exception",timeUnixNano:S(e)}]),t},M=(r,e)=>{const o=new Map([[y.functionPath,l(y.functionPath,r.functionPath)]]);r.shardKey!==void 0&&o.set(y.shardKey,l(y.shardKey,r.shardKey)),r.userId!==void 0&&o.set(y.userId,l(y.userId,r.userId)),r.errorType!==void 0&&o.set(y.errorType,l(y.errorType,r.errorType));for(const[t,s]of Object.entries(e??{}))o.set(t,l(t,W(s)));return[...o.values()]},ur=r=>{const e={attributes:M({errorType:r.error?.type,functionPath:r.functionPath,shardKey:r.shardKey,userId:r.userId},r.attributes),endTimeUnixNano:S(r.startTs+r.durationMs),kind:V[r.kind??"internal"],name:r.name,parentSpanId:r.parentSpanId,spanId:r.spanId,startTimeUnixNano:S(r.startTs),status:r.ok?{code:1}:{code:2,message:r.error?.message??""},traceId:r.traceId},o=t=>v(Object.fromEntries(Object.entries(t??{}).map(([s,c])=>[s,W(c)])));return r.events!==void 0&&r.events.length>0&&(e.events=r.events.map(t=>({attributes:o(t.attributes),name:t.name,timeUnixNano:S(t.ts)}))),r.links!==void 0&&r.links.length>0&&(e.links=r.links.map(t=>({attributes:o(t.attributes),spanId:t.spanId,traceId:t.traceId}))),e},lr=r=>{const e=S(r.ts),o=M({functionPath:r.functionPath,shardKey:r.shardKey},r.attributes),t={asDouble:r.value,attributes:o,timeUnixNano:e};return r.kind==="gauge"?{gauge:{dataPoints:[t]},name:r.name}:r.kind==="histogram"?{histogram:{aggregationTemporality:1,dataPoints:[{attributes:o,bucketCounts:["1"],count:"1",explicitBounds:[],max:r.value,min:r.value,sum:r.value,timeUnixNano:e}]},name:r.name}:{name:r.name,sum:{aggregationTemporality:1,dataPoints:[t],isMonotonic:!0}}},pr=r=>{const e={attributes:M({functionPath:r.functionPath,shardKey:r.shardKey,userId:r.userId},r.fields),body:{stringValue:r.message},severityNumber:Q[r.level],severityText:r.level.toUpperCase(),timeUnixNano:S(r.ts)};return r.traceId!==void 0&&(e.traceId=r.traceId),r.spanId!==void 0&&(e.spanId=r.spanId),r.eventName!==void 0&&(e.eventName=r.eventName,e.attributes.push(l("event.name",r.eventName))),e},fr=1024,J=5;let R=0;const mr=(r,e)=>{if(R>=J)return;R+=1;let o;try{o=new URL(r).host}catch{o="<unparseable endpoint>"}const t=R===J?" Further OTLP rejections are silenced until the isolate restarts.":"";console.error(`[lunora:otlp] collector ${o} rejected the export with HTTP ${String(e)}; the batch is DROPPED (there is no retry).${t}`)},hr=async r=>{const e=new Blob([r]).stream().pipeThrough(new CompressionStream("gzip"));return new Response(e).arrayBuffer()},X=async(r,e,o,t)=>{try{const s=JSON.stringify(e),{byteLength:c}=new TextEncoder().encode(s),n=(c<fr?fetch(r,{body:s,headers:o,method:"POST"}):hr(s).then(a=>fetch(r,{body:a,headers:{...o,"content-encoding":"gzip"},method:"POST"}))).then(a=>{a.ok||mr(r,a.status)},()=>{});t?.(n),await n}catch{}},yr=(r,e,o,t)=>{X(r,e,o,t?.waitUntil).catch(()=>{})},O=(r,e)=>e===!0&&r.ok,gr=r=>r.kind==="metric"?void 0:r.event.traceId,br=r=>{const e=Map.groupBy(r,t=>gr(t)),o=e.get(void 0)??[];return e.delete(void 0),{byTrace:e,untraced:o}},C=5,kr=(r,e,o)=>{if(e===void 0)return r;const{byTrace:t,untraced:s}=br(r),c=[...s];let n=0,a;for(const[h,m]of t){let p;try{p=e({logs:m.filter(d=>d.kind==="log").map(d=>d.event),rpc:m.filter(d=>d.kind==="rpc").map(d=>d.event),spans:m.filter(d=>d.kind==="span").map(d=>d.event),traceId:h})}catch(d){n+=1,n===1&&(a=d),p=!0}p&&c.push(...m)}return n>0&&o(a,n),c},P=(r,e)=>{if(e===void 0)return r;try{return e(r)??void 0}catch{return}},Sr=r=>({...r,...r.fields===void 0?{}:{fields:j(r.fields)},message:j(r.message)}),H=(r,e,o)=>{if(r.kind==="rpc"){const s=P(r.event,e?.rpc);return s===void 0?void 0:{bucket:"spans",encoded:dr(s,r.endMs)}}if(r.kind==="span"){const s=P(r.event,e?.span);return s===void 0?void 0:{bucket:"spans",encoded:ur(s)}}if(r.kind==="log"){const s=P(o?Sr(r.event):r.event,e?.log);return s===void 0?void 0:{bucket:"logs",encoded:pr(s)}}const t=P(r.event,e?.metric);return t===void 0?void 0:{bucket:"metrics",encoded:lr(t)}},Ir=["fuseCloudflareTraces","instrumentDatabase","metricHistory","traceFetch"],Or=(r={})=>{const{onlyErrors:e}=r;return{onLog:o=>{o.level==="error"||o.level==="fatal"?console.error("[lunora:log]",o.functionPath,o.message):console.log("[lunora:log]",o.functionPath,o.message)},onMetric:o=>{console.log("[lunora:metric]",`${o.name}=${String(o.value)}`,o.kind,o.functionPath)},onRpc:o=>{O(o,e)||(o.ok?console.log("[lunora:rpc]",o):console.error("[lunora:rpc]",o))},onSpan:o=>{const t=o.ok?"ok":`error ${o.error?.type??""}`.trim();console.log("[lunora:span]",o.name,`${String(o.durationMs)}ms`,t,o.functionPath)}}},Nr=r=>{const{headers:e,onlyErrors:o,transform:t,transformLog:s,url:c}=r,n=z({"content-type":"application/json"},e),a=(h,m)=>{try{const p=fetch(c,{body:JSON.stringify(h),headers:n,method:"POST"}).catch(()=>{});m?.waitUntil&&m.waitUntil(p)}catch{}};return{onLog:(h,m)=>{const p=P(h,s);p!==void 0&&a(p,m)},onRpc:(h,m)=>{if(O(h,o))return;const p=P(h,t);p!==void 0&&a(p,m)}}},Er=r=>{const{capture:e,captureLog:o}=r;if(typeof e!="function")throw new TypeError("sentrySink requires a `capture` callback — wire your own Sentry client, e.g. `sentrySink({ capture: (event) => Sentry.captureMessage(event.name) })`. There is no `dsn` option; the runtime bundles no Sentry client.");const t=r.onlyErrors??!0;return{onLog:o?s=>{try{o(s)}catch{}}:void 0,onRpc:s=>{if(!O(s,t))try{e(s)}catch{}}}},Lr=r=>{const{dataset:e,onlyErrors:o}=r;return{onRpc:t=>{if(!O(t,o))try{e.writeDataPoint({blobs:[t.functionPath,t.ok?"ok":"error",t.shardKey??"",t.error?.code??"",t.fanOut?.table??""],doubles:[t.durationMs,t.ok?0:1,t.fanOut?.shards??0,t.fanOut?.failed??0],indexes:[t.functionPath]})}catch{}}}},Rr=r=>{const{pipeline:e,serializeFields:o}=r;return{onLog:(t,s)=>{try{const c={functionPath:t.functionPath,level:t.level,message:t.message,ts:t.ts};t.fields&&(c.fields=o===!0?JSON.stringify(t.fields):t.fields);for(const a of["shardKey","userId","traceId","spanId"])t[a]!==void 0&&(c[a]=t[a]);const n=e.send([c]).catch(()=>{});s?.waitUntil&&s.waitUntil(n)}catch{}}}},Ar=r=>{const{batch:e,deploymentEnvironment:o,detectResources:t,endpoint:s,headers:c,onlyErrors:n,postProcessor:a,resourceAttributes:h,serviceNamespace:m,serviceVersion:p,tailSampler:d,token:q}=r,x=r.serviceName??"lunora",U=r.redactLogs??!0;if(e!==!1&&e?.maxItems!==void 0&&(!Number.isInteger(e.maxItems)||e.maxItems<1))throw new Z("ENV_INVALID",`otlpSink: \`batch.maxItems\` must be a positive integer, received ${String(e.maxItems)}.`);const _={...p===void 0?{}:{"service.version":p},...m===void 0?{}:{"service.namespace":m},...o===void 0?{}:{"deployment.environment":o},...h},D=new WeakMap,k=u=>{if(t!==!0||u?.resourceAttributes===void 0)return _;const i=D.get(u);if(i!==void 0)return i;const f=er(u.resourceAttributes(),_);return D.set(u,f),f};let I=s;for(;I.endsWith("/");)I=I.slice(0,-1);const F={logs:{url:`${I}/v1/logs`,wrap:or},metrics:{url:`${I}/v1/metrics`,wrap:tr},spans:{url:`${I}/v1/traces`,wrap:rr}},K=z({"content-type":"application/json"},c,q);let L=0;const G=(u,i)=>{if(L>=C)return;L+=1;const f=L===C?" Further tailSampler failures from this sink are silenced until the isolate restarts.":"";console.error(`[lunora:otlp] tailSampler threw for ${String(i)} trace(s) in this flush window; keeping them (fail-open), so the sampling policy did NOT apply.${f}`,u)},Y=async u=>{const i=kr(u,d,G),f=new Map;for(const g of i){const b=H(g,a,U);if(b===void 0)continue;const E=A(g.resource);let T=f.get(E);T===void 0&&(T={logs:[],metrics:[],resource:g.resource,spans:[]},f.set(E,T)),T[b.bucket].push(b.encoded)}const w=[];for(const[,g]of f)for(const b of["spans","logs","metrics"])if(g[b].length>0){const{url:E,wrap:T}=F[b];w.push(X(E,T(g[b],"@lunora/runtime",x,g.resource),K))}await Promise.all(w)};if(e===!1){const u=(i,f)=>{const w=H(i,a,U);if(w!==void 0){const{url:g,wrap:b}=F[w.bucket];yr(g,b(w.encoded,"@lunora/runtime",x,i.resource),K,f)}};return{onLog:(i,f)=>{u({event:i,kind:"log",resource:k(f)},f)},onMetric:(i,f)=>{u({event:i,kind:"metric",resource:k(f)},f)},onRpc:(i,f)=>{O(i,n)||u({endMs:Date.now(),event:i,kind:"rpc",resource:k(f)},f)},onSpan:(i,f)=>{u({event:i,kind:"span",resource:k(f)},f)}}}const N=ar({export:Y,...e?.maxDelayMs===void 0?{}:{maxDelayMs:e.maxDelayMs},...e?.maxItems===void 0?{}:{maxItems:e.maxItems}});return{flush:u=>{N.flush(u?.waitUntil).catch(()=>{})},onLog:(u,i)=>{N.add({event:u,kind:"log",resource:k(i)},i?.waitUntil)},onMetric:(u,i)=>{N.add({event:u,kind:"metric",resource:k(i)},i?.waitUntil)},onRpc:(u,i)=>{O(u,n)||N.add({endMs:Date.now(),event:u,kind:"rpc",resource:k(i)},i?.waitUntil)},onSpan:(u,i)=>{N.add({event:u,kind:"span",resource:k(i)},i?.waitUntil)}}},Mr=(...r)=>{const e=(t,s)=>{for(const c of r){const n=c[t];if(n)try{n.apply(c,s)}catch{}}},o={};for(const t of r)for(const s of Ir)o[s]===void 0&&t[s]!==void 0&&(o[s]=t[s]);return{...o,flush:t=>{e("flush",[t])},onLog:(t,s)=>{e("onLog",[t,s])},onMetric:(t,s)=>{e("onMetric",[t,s])},onRpc:(t,s)=>{e("onRpc",[t,s])},onSpan:(t,s)=>{e("onSpan",[t,s])}}};export{Lr as analyticsEngineSink,Mr as combineSinks,Or as consoleSink,Ar as otlpSink,Rr as pipelineLogSink,Er as sentrySink,Nr as webhookSink};
@@ -0,0 +1,6 @@
1
+ import{isLunoraError as Dn,toErrorBody as Un}from"@lunora/errors";import{e as Ut}from"./evict-oldest-BNXsKx4s.mjs";import{NOOP_EXECUTION_CONTEXT as Cn}from"./NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{t as Bn,f as xn}from"./base64-Bl1_r2k1.mjs";import{e as Hn,a as Ln}from"./identity-header-C4Z5pldl.mjs";import{o as Oe,b as jn,p as Mn,m as Kn,d as $n,a as Fn,r as Gn}from"./otlp-resource-DeXhb949.mjs";import{e as ze,d as Qn}from"./wire-codec-Du-i3W6b.mjs";import{d as Z,e as be,M as Ct,b as zn,f as Wn,g as Bt,h as xt}from"./rest-routes-ZZES0ngM.mjs";import{LunoraError as d,toErrorResponse as at}from"./LunoraError-DksAgIpa.mjs";import{a as K,m as me}from"./method-guard-BG_vJNTl.mjs";import{normalizeBackupPrefix as Ve,BACKUP_KEY_PREFIX as Je,isBackupManifestKey as Vn,backupObjectKeyOfManifest as Ht,backupObjectKey as Jn,backupManifestKey as qn}from"./BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toHex as Yn,buildStorageAdminRoutes as Xn,STORAGE_UPLOAD_MAX_BODY_BYTES as Zn,STORAGE_PATH as er}from"./STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{b as tr,e as nr,f as st,g as rr,h as or}from"./export-tap-BLr9Lp0x.mjs";import{buildHealthRoutes as ar,durableObjectProbe as sr,d1Probe as ir,presenceProbe as xe}from"./HEALTH_PATH-jZsuCmSs.mjs";import{wrapResolverWithContract as cr}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{composeIdentityResolvers as Is,routeIdentityResolvers as Ps}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{buildLogArchiveAdminRoutes as dr}from"./LOG_ARCHIVE_PATH-Hmjpz_Ko.mjs";import{r as ur,f as it,a as ie}from"./observability-B1hLjwgx.mjs";import{resolveShard as we,applyJurisdiction as ct}from"./applyJurisdiction-C0ddU7Tg.mjs";import{resolveSecurity as dt,handleCorsPreflight as lr,enforceOrigin as hr,decorateResponse as He,enforceWebSocketOrigin as ut}from"./decorateResponse-CCRm2CFM.mjs";const fr=e=>{const t=e??{};if(typeof t.bucket=="function")return t;const n=t.bucketName,a={...t,bucketName:typeof n=="string"&&n!==""?n:"default"};return a.bucket=()=>a,a},Lt="__lunoraBranch",pr=e=>typeof e=="object"&&e!==null&&Object.hasOwn(e,Lt),mr=`may not contain the reserved workflow branch-marker key ("${Lt}")`,wr=async e=>{const t=[];let n;for(;;){const r=await e(n);if(t.push(...Array.isArray(r.records)?r.records:[]),r.truncated!==!0||typeof r.cursor!="string"||r.cursor.length===0)return t;if(r.cursor===n)throw new Error("collectPages: the list did not advance its cursor — refusing to page forever");n=r.cursor}},qe=(e,t)=>{const n=Math.max(e.length,t.length);let r=e.length^t.length;for(let a=0;a<n;a+=1){const i=a<e.length?e.charCodeAt(a):0,u=a<t.length?t.charCodeAt(a):0;r|=i^u}return r===0},gr=(e,t,n,r)=>{const a=e.get(t);if(a!==void 0)return a;Ut(e,r);const i=n().catch(u=>{throw e.get(t)===i&&e.delete(t),u});return e.set(t,i),i},Ye=new TextEncoder,yr=Array.from({length:32},(e,t)=>t);new RegExp(`[${yr.map(e=>String.fromCodePoint(e)).join("")}]`,"u");const br=64,_r=new Map,jt=async e=>gr(_r,e,async()=>crypto.subtle.importKey("raw",Ye.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),br),Mt=async(e,t)=>{const n=await jt(e),r=await crypto.subtle.sign("HMAC",n,Ye.encode(t));return Bn(new Uint8Array(r))},Rr=async(e,t,n)=>{const r=await jt(e);return crypto.subtle.verify("HMAC",r,n,Ye.encode(t))},Er=["wnam","enam","sam","weur","eeur","apac","apac-ne","apac-se","oc","afr","me"];new Set(Er);const Sr=new Set(["AE","BH","IL","IQ","IR","JO","KW","LB","OM","PS","QA","SA","SY","TR","YE"]),Ar=-100,Tr=15,Or=e=>{const t=Number(e.longitude??Number.NaN);switch(e.continent){case"AF":return"afr";case"AS":return e.country!==void 0&&Sr.has(e.country)?"me":"apac";case"EU":return Number.isFinite(t)&&t>Tr?"eeur":"weur";case"NA":return Number.isFinite(t)&&t<Ar?"wnam":"enam";case"OC":return"oc";case"SA":return"sam";default:return}},lt=e=>{const t=e.cf;return t===void 0?void 0:Or(t)},Kt="::relay::",vr=(e,t)=>`${e}${Kt}${String(t)}`,$t="::replica::",kr=(e,t)=>`${e}${$t}${t}`,Ir=e=>{if(e==null||!/^\d+$/.test(e))return;const t=Number.parseInt(e,10);return Number.isSafeInteger(t)&&t>0?t:void 0},Pr=new Set(["1","enabled","on","true","yes"]),Nr=new Set(["0","disabled","false","no","off"]),Dr=(e,t)=>{const n=(e??"").trim().toLowerCase();return Pr.has(n)?!0:Nr.has(n)?!1:t},Ft="v1",Ur=6e4,Cr=async(e,t={})=>{const n=(t.now??Date.now())+(t.ttlMs??Ur),r=`${Ft}.${String(n)}`,a=await Mt(e,r);return{expiresAtMs:n,token:`${r}.${a}`}},Br=async(e,t,n=Date.now())=>{if(e.length===0||t.length===0)return!1;const r=t.split(".");if(r.length!==3)return!1;const[a,i,u]=r;if(a!==Ft||u.length===0)return!1;const h=Number(i);if(!Number.isFinite(h)||h<=n)return!1;let f;try{f=xn(u)}catch{return!1}return Rr(e,`${a}.${i}`,f)},P="/_lunora/admin/auth",xr={INVITER_REQUIRED:400,ORG_SLUG_INVALID:400,ORG_SLUG_TAKEN:409,PASSWORD_TOO_LONG:400,PASSWORD_TOO_SHORT:400,USER_ALREADY_EXISTS:409,USER_NOT_FOUND:404},D=(e,t)=>{const n=e[t];if(typeof n!="string"||n==="")throw new d(`\`${t}\` is required`,{code:"BAD_REQUEST",status:400});return n},he=(e,t)=>{const n=e(t);if(n===void 0)throw new d(`\`${t}\` query parameter is required`,{code:"BAD_REQUEST",status:400});return n},Gt=e=>{if(typeof e=="string"||Array.isArray(e)&&e.every(t=>typeof t=="string"))return e},re=(e,t)=>typeof e[t]=="string"?e[t]:void 0,Le=(e,t)=>{const n=e[t];return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:void 0},ht=e=>{const t=Gt(e.role);if(t===void 0||typeof t=="string"&&t.trim()==="")throw new d("`role` is required",{code:"BAD_REQUEST",status:400});return t},ft=e=>{const t=e.permission;if(typeof t!="object"||t===null||Array.isArray(t))throw new d("`permission` object is required",{code:"BAD_REQUEST",status:400});const n={};for(const[r,a]of Object.entries(t))Array.isArray(a)&&a.every(i=>typeof i=="string")&&(n[r]=a);return n},Hr={[`${P}/capabilities`]:{build:()=>({}),http:"GET",method:"capabilities"},[`${P}/users`]:{build:({paging:e,query:t})=>{const n=t("sortDirection");return{...e,filterField:t("filterField"),filterValue:t("filterValue"),search:t("search"),searchField:t("searchField"),sortBy:t("sortBy"),sortDirection:n==="asc"||n==="desc"?n:void 0}},http:"GET",method:"listUsers"},[`${P}/sessions`]:{build:({paging:e,query:t})=>({...e,userId:t("userId")}),http:"GET",method:"listSessions"},[`${P}/accounts`]:{build:({query:e})=>({userId:he(e,"userId")}),http:"GET",method:"listAccounts"},[`${P}/passkeys`]:{build:({query:e})=>({userId:he(e,"userId")}),http:"GET",method:"listPasskeys"},[`${P}/organizations`]:{build:({paging:e})=>({...e}),http:"GET",method:"listOrganizations"},[`${P}/organizations/members`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listMembers"},[`${P}/organizations/invitations`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listInvitations"},[`${P}/config`]:{build:()=>({}),http:"GET",method:"config"},[`${P}/organizations/teams`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listTeams"},[`${P}/organizations/teams/members`]:{build:({paging:e,query:t})=>({...e,teamId:he(t,"teamId")}),http:"GET",method:"listTeamMembers"},[`${P}/organizations/roles`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listOrgRoles"},[`${P}/users/create`]:{build:({body:e})=>({data:Le(e,"data"),email:D(e,"email"),name:D(e,"name"),password:re(e,"password"),role:Gt(e.role)}),http:"POST",method:"createUser"},[`${P}/users/update`]:{build:({body:e})=>{const{data:t}=e;if(typeof t!="object"||t===null||Array.isArray(t))throw new d("`data` object is required",{code:"BAD_REQUEST",status:400});return{data:t,userId:D(e,"userId")}},http:"POST",method:"updateUser"},[`${P}/users/role`]:{build:({body:e})=>({role:ht(e),userId:D(e,"userId")}),http:"POST",method:"setRole"},[`${P}/users/ban`]:{build:({body:e})=>({expiresInSeconds:typeof e.expiresInSeconds=="number"?e.expiresInSeconds:void 0,reason:re(e,"reason"),userId:D(e,"userId")}),http:"POST",method:"banUser"},[`${P}/users/unban`]:{build:({body:e})=>({userId:D(e,"userId")}),http:"POST",method:"unbanUser"},[`${P}/users/password`]:{build:({body:e})=>({newPassword:D(e,"newPassword"),userId:D(e,"userId")}),http:"POST",method:"setUserPassword",returns:"void"},[`${P}/users/remove`]:{build:({body:e})=>({userId:D(e,"userId")}),http:"POST",method:"removeUser",returns:"void"},[`${P}/users/impersonate`]:{build:({body:e})=>({userId:D(e,"userId")}),http:"POST",method:"impersonateUser"},[`${P}/sessions/revoke`]:{build:({body:e})=>({sessionId:D(e,"sessionId")}),http:"POST",method:"revokeUserSession",returns:"void"},[`${P}/sessions/revoke-all`]:{build:({body:e})=>({userId:D(e,"userId")}),http:"POST",method:"revokeUserSessions",returns:"void"},[`${P}/accounts/unlink`]:{build:({body:e})=>({accountId:D(e,"accountId"),userId:D(e,"userId")}),http:"POST",method:"unlinkAccount",returns:"void"},[`${P}/two-factor/disable`]:{build:({body:e})=>({userId:D(e,"userId")}),http:"POST",method:"disableTwoFactor",returns:"void"},[`${P}/passkeys/delete`]:{build:({body:e})=>({passkeyId:D(e,"passkeyId")}),http:"POST",method:"deletePasskey",returns:"void"},[`${P}/organizations/members/remove`]:{build:({body:e})=>({memberId:D(e,"memberId")}),http:"POST",method:"removeMember",returns:"void"},[`${P}/organizations/invitations/cancel`]:{build:({body:e})=>({invitationId:D(e,"invitationId")}),http:"POST",method:"cancelInvitation",returns:"void"},[`${P}/organizations/create`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:Le(e,"metadata"),name:D(e,"name"),ownerId:re(e,"ownerId"),slug:re(e,"slug")}),http:"POST",method:"createOrganization"},[`${P}/organizations/update`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:Le(e,"metadata"),name:re(e,"name"),organizationId:D(e,"organizationId"),slug:re(e,"slug")}),http:"POST",method:"updateOrganization"},[`${P}/organizations/remove`]:{build:({body:e})=>({organizationId:D(e,"organizationId")}),http:"POST",method:"deleteOrganization",returns:"void"},[`${P}/organizations/members/add`]:{build:({body:e})=>({organizationId:D(e,"organizationId"),role:re(e,"role"),userId:D(e,"userId")}),http:"POST",method:"addMember"},[`${P}/organizations/members/invite`]:{build:({body:e})=>({email:D(e,"email"),inviterId:re(e,"inviterId"),organizationId:D(e,"organizationId"),role:re(e,"role")}),http:"POST",method:"inviteMember"},[`${P}/organizations/members/role`]:{build:({body:e})=>({memberId:D(e,"memberId"),role:ht(e)}),http:"POST",method:"updateMemberRole"},[`${P}/organizations/teams/create`]:{build:({body:e})=>({name:D(e,"name"),organizationId:D(e,"organizationId")}),http:"POST",method:"createTeam"},[`${P}/organizations/teams/update`]:{build:({body:e})=>({name:D(e,"name"),teamId:D(e,"teamId")}),http:"POST",method:"updateTeam"},[`${P}/organizations/teams/remove`]:{build:({body:e})=>({teamId:D(e,"teamId")}),http:"POST",method:"removeTeam",returns:"void"},[`${P}/organizations/teams/members/add`]:{build:({body:e})=>({teamId:D(e,"teamId"),userId:D(e,"userId")}),http:"POST",method:"addTeamMember"},[`${P}/organizations/teams/members/remove`]:{build:({body:e})=>({teamMemberId:D(e,"teamMemberId")}),http:"POST",method:"removeTeamMember",returns:"void"},[`${P}/organizations/roles/create`]:{build:({body:e})=>({organizationId:D(e,"organizationId"),permission:ft(e),role:D(e,"role")}),http:"POST",method:"createOrgRole"},[`${P}/organizations/roles/update`]:{build:({body:e})=>({permission:ft(e),roleId:D(e,"roleId")}),http:"POST",method:"updateOrgRole"},[`${P}/organizations/roles/remove`]:{build:({body:e})=>({roleId:D(e,"roleId")}),http:"POST",method:"deleteOrgRole",returns:"void"}},Lr=e=>{const t=async a=>{try{return await a()}catch(i){if(i instanceof d)throw i;const u=i,h=typeof u.code=="string"?u.code:"AUTH_ADMIN_ERROR";throw console.error("[lunora] auth admin operation failed:",i),new d("auth admin operation failed",{code:h,status:xr[h]??500})}},n=async(a,i)=>{if(e.assertAdmin(a),a.method!==i.http)throw new d(`Auth admin endpoint requires ${i.http}`,{code:"METHOD_NOT_ALLOWED",status:405});const u=e.getAuthAdmin();if(u===void 0)throw new d("auth endpoints require an `authAdmin` on the worker",{code:"AUTH_NOT_CONFIGURED",status:400});const h=u[i.method];if(h===void 0)throw new d(`auth admin does not support \`${i.method}\``,{code:"AUTH_OP_NOT_SUPPORTED",status:400});const f=new URL(a.url),m={body:i.http==="POST"?await e.readJsonBody(a):{},paging:e.parsePaging(a),query:T=>e.queryParameter(f,T)},S=i.build(m),A=await t(()=>h(S));return Response.json(i.returns==="void"?{ok:!0}:A,{headers:{"cache-control":"no-store","content-type":"application/json"},status:200})},r={};for(const[a,i]of Object.entries(Hr))r[a]=u=>n(u,i);return r},jr="__lunora_admin__:getAuthAuditLog",pt=e=>typeof e=="string"&&e!==""?e:void 0,mt=e=>typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0,Mr=e=>async(n,r)=>{e.assertAdmin(n);const a=e.getReader();if(a===void 0)throw new d("the auth/security audit endpoint requires an `authAuditReader` on the worker",{code:"AUTH_AUDIT_NOT_CONFIGURED",status:400});const i=pt(r.actorId),u=pt(r.event),h=mt(r.sinceSeq),f=mt(r.limit),m={...i===void 0?{}:{actorId:i},...u===void 0?{}:{event:u},...h===void 0?{}:{sinceSeq:h},...f===void 0?{}:{limit:f}};let S;try{S=await a.read(m)}catch(T){throw T instanceof d?T:(console.error("[lunora] auth audit read failed:",T),new d("auth audit read failed",{code:"AUTH_AUDIT_READ_FAILED",status:500}))}const A={entries:S};return Response.json({result:ze(A)},{headers:{"content-type":"application/json"},status:200})},Kr=(e,t)=>{const n=[],r=[];if(t&&t.length>0)for(const a of t)e.resolveTableSharding?.(a)?.mode.kind==="global"?r.push(a):n.push(a);return{globalTables:r,shardLocalTables:n}},$r=async(e,t,n,r,a,i,u)=>{if(n!==void 0&&r.length===0)return;const h=await e.orchestrateExport(i,{args:{tables:r},defaultShardKey:u,headers:t,tables:r});for(const f of h.shards)if(!f.error)for(const m of f.rows??[])a(m)},Qt=async(e,t,n,r,a,i)=>{const u=r??e.listSchemaTables?.();r===void 0&&e.listSchemaTables===void 0&&console.warn("[lunora] export: no table list available (`listSchemaTables` is unset and no `tables` were named), so only the default shard is reachable. A `.shardBy()` deployment's other shards will be missing from this export. Name the tables explicitly, or regenerate the worker so codegen supplies the list.");const{globalTables:h,shardLocalTables:f}=Kr(e,u);await $r(t,n,u,f,a,i,e.defaultShardKey??"__root__");const m=e.exportGlobals;if((r===void 0||h.length>0)&&m)for await(const A of m({tables:h}))a(A)},Fr=new TextEncoder,Gr=1e3,zt=10,Qr=200,wt=8,Wt="lunoraBackupCron",gt=24*1048576,yt=e=>{const t=e.slice(0,zt).map(r=>Ht(r)),n=e.length-t.length;return`${t.join(", ")}${n>0?` (+${String(n)} more)`:""}`},zr=(e,t)=>{const n=new Uint8Array(new ArrayBuffer(t));let r=0;for(const a of e)n.set(a,r),r+=a.byteLength;return n},Xe=async(e,t,n,r)=>{if(n===void 0||!Number.isInteger(n)||n<=0)return{eligible:0,stale:[]};const a=[];let i;for(let u=0;u<Gr;u+=1){const h=await e.list({cursor:i,include:["customMetadata"],prefix:t});for(const f of h.objects)Vn(f.key)&&f.customMetadata?.[Wt]===r&&a.push(f.key);if(!h.truncated||h.cursor===void 0)break;i=h.cursor}return{eligible:a.length,stale:a.toSorted((u,h)=>h.localeCompare(u)).slice(n)}},Wr=async(e,t,n,r,a)=>{const{stale:i}=await Xe(e,t,n,r),u=new Set(a),h=i.filter(g=>u.has(g)),f=h.slice(0,Qr),m=i.length-f.length,S=a.length-h.length;if(f.length===0)return{deleted:[],failed:[],ignored:S,remaining:m};const A=[],T=[];for(let g=0;g<f.length;g+=wt){const y=await Promise.allSettled(f.slice(g,g+wt).map(async _=>(await e.delete(Ht(_)),await e.delete(_),_)));for(const[_,p]of y.entries())p.status==="fulfilled"?A.push(p.value):T.push(f[g+_])}return A.length>0&&console.info(`[lunora] backup prune kept the newest ${String(n)} and deleted ${String(A.length)}: ${yt(A)}`),T.length>0&&console.warn(`[lunora] backup prune failed to remove ${String(T.length)}: ${yt(T)}`),{deleted:A,failed:T,ignored:S,remaining:m}},Vr=async e=>{const t=e.backupStore;if(!t)throw new d("backup retention preview requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const n=Ve(e.backupPrefix??Je),r=e.backupCron,{eligible:a,stale:i}=r===void 0?{eligible:0,stale:[]}:await Xe(t,n,e.backupRetain,r);return{cron:r,eligible:a,keep:e.backupRetain??0,prefix:n,wouldDelete:i}},Jr=async(e,t,n,r)=>{const a=e.backupStore,i=e.queryCoordinator;if(!a)throw new d("scheduled backup requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!i)throw new d("scheduled backup requires a `queryCoordinator` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!n||n.length===0)throw new d("scheduled backup requires an `adminToken` (or `env.LUNORA_ADMIN_TOKEN`) to authenticate the per-shard export gate",{code:"BACKUP_NOT_CONFIGURED",status:500});const u={authorization:`Bearer ${n}`,"content-type":"application/json"},h=e.backupTables;let f=0,m=0,S=[];await Qt(e,i,u,h,N=>{const j=Fr.encode(`${JSON.stringify(N)}
2
+ `);if(f+=1,m+=j.byteLength,m>gt)throw new d(`scheduled backup reached ${String(m)} bytes of NDJSON, past the ${String(gt)}-byte limit for a snapshot assembled inside a Worker — nothing was written. Narrow it with \`backupTables\`, or take this snapshot off-platform with \`lunora backup create --bucket\`.`,{code:"BACKUP_TOO_LARGE",status:507});S.push(j)},t);const T=Ve(e.backupPrefix??Je),g=new Date(r.scheduledTime).toISOString(),y=Jn(T,g),_=zr(S,m);S=[];const p=Yn(await crypto.subtle.digest("SHA-256",_));await a.put(y,_,{httpMetadata:{contentType:"application/x-ndjson"},sha256:p});const O={bytes:m,createdAt:g,cron:r.cron,file:y,id:g,rows:f,scheduledTime:r.scheduledTime,sha256:p,...h?{tables:h.join(",")}:{}};await a.put(qn(y),`${JSON.stringify(O,void 0,2)}
3
+ `,{customMetadata:{[Wt]:r.cron},httpMetadata:{contentType:"application/json"}});try{const{stale:N}=await Xe(a,T,e.backupRetain,r.cron);if(N.length>0){const j=N.slice(0,zt),k=N.length-j.length;console.info(`[lunora] backup retention: ${String(N.length)} snapshot(s) past the newest ${String(e.backupRetain)} — run \`lunora backup prune\` to remove them: ${j.join(", ")}${k>0?` (+${String(k)} more)`:""}`)}}catch(N){console.warn(`[lunora] backup ${y} was written, but the retention report failed:`,N)}},qr=async(e,t)=>{const n=e.backupStore;if(!n)throw new d("backup prune requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const r=e.backupCron,a=e.backupRetain;if(r===void 0||a===void 0||!Number.isInteger(a)||a<=0)throw new d("backup prune needs a retention window: set `backupRetain` (and `backupCron`, which decides whose snapshots retention owns) on the worker. Without one there is nothing past the window to remove.",{code:"BACKUP_RETENTION_NOT_CONFIGURED",status:400});return Wr(n,Ve(e.backupPrefix??Je),a,r,t)},Yr="/_lunora/admin/backup/retention",Xr="/_lunora/admin/backup/prune",Zr=e=>{const{options:t,readJsonBody:n,requireAdminOption:r}=e,a=(h,f)=>{r(h,t.backupStore,{code:"BACKUP_NOT_CONFIGURED",message:`backup ${f} requires a \`backupStore\` on the worker`})},i=async h=>(K(h,"GET","Backup-retention"),a(h,"retention preview"),Response.json(await Vr(t),{headers:{"cache-control":"no-store"}})),u=async h=>{K(h,"POST","Backup-prune"),a(h,"prune");const{confirm:f}=await n(h);if(!Array.isArray(f)||f.some(m=>typeof m!="string"))throw new d("backup prune requires a `confirm` array of the sidecar keys to remove — read them from `GET /_lunora/admin/backup/retention` and pass back the ones you mean to delete",{code:"BAD_REQUEST",status:400});return Response.json(await qr(t,f),{headers:{"cache-control":"no-store"}})};return{[Xr]:u,[Yr]:i}},bt=500,eo=(e,t,n)=>{if(typeof e!="object"||e===null||Array.isArray(e))throw new d("each batch call must be an object",{code:"BAD_REQUEST",status:400});const r=e;if(typeof r.functionPath!="string")throw new d("each batch call needs a string `functionPath`",{code:"BAD_REQUEST",status:400});if(r.functionPath.startsWith("__lunora_relation__:")||r.functionPath.startsWith("__lunora_admin__"))throw new d("reserved function path cannot be batched",{code:"FORBIDDEN",status:403});if(r.args!==void 0&&(typeof r.args!="object"||r.args===null||Array.isArray(r.args)))throw new d("each batch call `args` must be an object",{code:"BAD_REQUEST",status:400});return{entry:{args:r.args===void 0?{}:r.args,clientId:typeof r.clientId=="string"?r.clientId:void 0,clientSeq:typeof r.clientSeq=="number"?r.clientSeq:void 0,functionPath:r.functionPath,id:typeof r.id=="number"?r.id:t,mutationId:typeof r.mutationId=="string"?r.mutationId:void 0},shardKey:typeof r.shardKey=="string"?r.shardKey:n}},to=(e,t)=>{if(e.length>bt)throw new d(`RPC batch exceeds the ${String(bt)}-call limit`,{code:"BAD_REQUEST",status:400});const n=new Map;for(const[r,a]of e.entries()){const{entry:i,shardKey:u}=eo(a,r,t),h=n.get(u)??[];h.push(i),n.set(u,h)}return n},no="/_lunora/admin/export",ro="/_lunora/admin/import",oo="/_lunora/admin/sync",ao="/_lunora/admin/connector/sync",so="/_lunora/admin/apply",io="/_lunora/admin/export-tap/run",co=new TextEncoder,uo=async e=>{const n=await be(e,"Export")??{};if(n.tables===void 0)return{tables:void 0};if(!Array.isArray(n.tables))throw new d("Export `tables` must be a string array",{code:"BAD_REQUEST",status:400});const r=[];for(const a of n.tables){if(typeof a!="string"||a.length===0)throw new d("Export `tables` entries must be non-empty strings",{code:"BAD_REQUEST",status:400});r.push(a)}return{tables:r}},je=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):void 0,lo=e=>{const{applyGlobals:t,defaultShardKey:n,exportCursorStore:r,exportSinks:a,knownTables:i,queryCoordinator:u,assertAdmin:h,requireAdminOption:f,resolveForwardContext:m,shardDO:S,streamExportRows:A,streamingImport:T,syncGlobals:g}=e,y=async(k,F)=>{const H=me(k,["POST"]);if(H)return H;const Y=f(k,u,{code:"BAD_REQUEST",message:"Export endpoint requires a `queryCoordinator` on the worker"}),C=await uo(k),{headers:G}=await m(k,F),Q=new ReadableStream({async pull(J){const M=$=>{J.enqueue(co.encode(`${JSON.stringify($)}
4
+ `))};try{await A(Y,G,C.tables,M),J.close()}catch($){J.error($)}}});return new Response(Q,{headers:{"content-type":"application/x-ndjson"},status:200})},_=async(k,F)=>{const H=me(k,["POST"]);if(H)return H;const Y=f(k,u,{code:"BAD_REQUEST",message:"Sync endpoint requires a `queryCoordinator` on the worker"}),C=await Z(k),G=typeof C.cursors=="object"&&C.cursors!==null?C.cursors:{},Q=typeof C.limit=="number"?C.limit:void 0,J=typeof C.globalCursor=="number"?C.globalCursor:0,M=je(C.tables),{headers:$}=await m(k,F),oe=M??i(),z=await Y.orchestrateCdcSync(S,{cursors:G,defaultShardKey:n,headers:$,limit:Q,tables:oe}),de=g?await g({limit:Q,sinceSeq:J}):void 0;return Response.json({global:de,shards:z.shards},{status:200})},p=async(k,F)=>{const H=me(k,["POST"]);if(H)return H;const Y=f(k,u,{code:"BAD_REQUEST",message:"Connector sync endpoint requires a `queryCoordinator` on the worker"}),C=await Z(k),G=nr(C.cursor),Q=typeof C.limit=="number"&&C.limit>0?C.limit:void 0,J=je(C.tables),{headers:M}=await m(k,F),$=J??i(),oe=await Y.orchestrateCdcSync(S,{cursors:G.s,defaultShardKey:n,headers:M,limit:Q,tables:$}),z=[],de={...G.s};let ue=!1;for(const ae of oe.shards)ue=st(z,ae.changes??[],or(Q))||ue,de[ae.shardKey]=ae.cursor;let _e=G.g;if(g){const ae=await g({limit:Q,sinceSeq:G.g});ue=st(z,ae.changes,Q)||ue,_e=ae.cursor}const ve=rr({g:_e,s:de,v:1}),ke={changes:z,hasMore:ue,nextCursor:ve};return Response.json(ke,{status:200})},O=async(k,F)=>{const H=me(k,["POST"]);if(H)return H;const Y=f(k,u,{code:"BAD_REQUEST",message:"Apply endpoint requires a `queryCoordinator` on the worker"}),C=await Z(k),Q=(Array.isArray(C.batches)?C.batches:[]).map(z=>z).filter(z=>z!==null&&typeof z=="object"&&typeof z.shardKey=="string"&&Array.isArray(z.changes)),J=Array.isArray(C.globalChanges)?C.globalChanges:[],{headers:M}=await m(k,F),$=await Y.orchestrateApplyCdc(S,{batches:Q,headers:M}),oe=J.length>0&&t?await t({changes:J}):0;return Response.json({applied:$.applied+oe,failed:$.failed,ok:$.ok},{status:200})},N=async(k,F)=>{const H=me(k,["POST"]);if(H)return H;h(k);const{headers:Y}=await m(k,F),C=await T(k,Y);return Response.json(C,{headers:{"content-type":"application/json"},status:C.failed.length>0?207:200})},j=async(k,F)=>{const H=me(k,["POST"]);if(H)return H;const Y=f(k,u,{code:"BAD_REQUEST",message:"Export-tap endpoint requires a `queryCoordinator` on the worker"});if(a===void 0||Object.keys(a).length===0||r===void 0)throw new d("Export-tap endpoint requires `exportSinks` + `exportCursorStore` on the worker",{code:"EXPORT_TAP_NOT_CONFIGURED",status:400});const C=await Z(k),G=typeof C.sink=="string"?C.sink:void 0,Q=typeof C.limit=="number"&&C.limit>0?C.limit:void 0,J=je(C.tables);if(G===void 0)throw new d("Export-tap `sink` must name a configured sink",{code:"BAD_REQUEST",status:400});const M=a[G];if(M===void 0)throw new d(`Export-tap sink "${G}" is not configured`,{code:"NOT_FOUND",status:404});const{headers:$}=await m(k,F),oe=J??i(),z=await tr({coordinator:Y,cursorStore:r,defaultShardKey:n,headers:$,limit:Q,shardDO:S,sink:M,tables:oe});return Response.json(z,{headers:{"content-type":"application/json"},status:200})};return{[so]:O,[ao]:p,[no]:y,[io]:j,[ro]:N,[oo]:_}},ho=(e,t)=>{let n;try{n=JSON.parse(e)}catch{return{error:{code:"BAD_ROW",line:t,message:"line is not valid JSON",table:""},ok:!1}}if(!n||typeof n!="object"||Array.isArray(n))return{error:{code:"BAD_ROW",line:t,message:"row must be a JSON object",table:""},ok:!1};const r=n;return typeof r.table!="string"||r.table.length===0?{error:{code:"BAD_ROW",line:t,message:"row is missing `table`",table:""},ok:!1}:!r.doc||typeof r.doc!="object"||Array.isArray(r.doc)?{error:{code:"BAD_ROW",line:t,message:"row is missing or malformed `doc`",table:r.table},ok:!1}:{doc:r.doc,ok:!0,table:r.table}},fo=(e,t,n,r,a)=>{if(n?.mode.kind==="shardBy"&&typeof n.mode.field=="string"){const i=e[n.mode.field];return i==null?{error:{code:"BAD_ROW",line:a,message:`row missing shard field "${n.mode.field}" for table "${t}"`,table:t},ok:!1}:{ok:!0,shardKey:typeof i=="string"?i:JSON.stringify(i)}}return{ok:!0,shardKey:r}},po=async(e,t,n)=>{if(!e.body)throw new d("Import endpoint requires a request body",{code:"BAD_REQUEST",status:400});const r=[],a=[],i=new Map;let u=0,h=0;const f=e.body.getReader(),m=new TextDecoder;let S="",A=0;const T=g=>{h+=1;const y=g.trim();if(y.length===0)return;u+=1;const _=ho(y,h);if(!_.ok){r.push(_.error);return}const{doc:p,table:O}=_,N=t.resolveTableSharding?.(O);if(N?.mode.kind==="global"){a.push({doc:p,line:h,table:O});return}const j=fo(p,O,N,n,h);if(!j.ok){r.push(j.error);return}const k=i.get(j.shardKey);k?k.rows.push({doc:p,table:O}):i.set(j.shardKey,{rows:[{doc:p,table:O}],shardKey:j.shardKey,startLine:h})};for(;;){const{done:g,value:y}=await f.read();if(g)break;if(y&&(A+=y.byteLength,A>Ct))throw await f.cancel().catch(()=>{}),new d("Body too large",{code:"PAYLOAD_TOO_LARGE",status:413});S+=m.decode(y,{stream:!0});let _=S.indexOf(`
5
+ `);for(;_!==-1;){const p=S.slice(0,_);S=S.slice(_+1),T(p),_=S.indexOf(`
6
+ `)}}return S.length>0&&T(S),{errors:r,globalRows:a,perShard:i,received:u}},mo=e=>e.flatMap(t=>t.error?[{message:t.error.message,shardKey:t.shardKey,timedOut:t.error.timedOut}]:[]),_t=(e,t)=>{for(const[n,r]of Object.entries(t.inserted))e.inserted[n]=(e.inserted[n]??0)+r;for(const n of t.errors)e.errors.push({...n});e.conflicts+=t.conflicts},wo=async(e,t,n,r)=>{const a=t.defaultShardKey??"__root__",{errors:i,globalRows:u,perShard:h,received:f}=await po(e,t,a),m={conflicts:0,errors:i,failed:[],inserted:{}},S=[];if(t.resolveTableSharding===void 0&&h.size>0&&S.push("no `resolveTableSharding` is configured, so every row was routed to the default shard and no row could be recognised as `.global()` — correct for a single-shard app, silent misplacement for a sharded one"),h.size>0){const A=t.queryCoordinator;if(!A)throw new d("Import endpoint requires a `queryCoordinator` on the worker",{code:"BAD_REQUEST",status:400});const T=await A.orchestrateImport(r,{batches:[...h.values()],headers:n});_t(m,T),m.failed.push(...mo(T.shards))}if(u.length>0)if(t.importGlobals){const A=u[0]?.line??1,T=await t.importGlobals({rows:u,startLine:A});_t(m,T)}else for(const A of u)m.errors.push({code:"GLOBAL_NOT_CONFIGURED",line:A.line,message:`row targets global table "${A.table}" but no \`importGlobals\` is configured`,table:A.table});return{conflicts:m.conflicts,errors:m.errors,failed:m.failed,inserted:m.inserted,received:f,...S.length>0?{warnings:S}:{}}},Me=e=>typeof e=="object"&&e!==null?e:{},Ke=e=>typeof e.kind=="string"?e.kind:"unknown",go=(e,t)=>{let n=Me(t),r=!1;Ke(n)==="optional"&&(r=!0,n=Me(n._meta?.inner));const a=Ke(n),i=n._meta??{},u={kind:a,name:e,optional:r};if(a==="id"&&typeof i.tableName=="string"&&(u.table=i.tableName),a==="array"){const h=Ke(Me(i.inner));h!=="unknown"&&(u.element=h)}return u},yo=e=>typeof e!="object"||e===null?[]:Object.entries(e).map(([t,n])=>go(t,n)).toSorted((t,n)=>t.name.localeCompare(n.name)),bo="/_lunora/admin/functions",_o="/_lunora/admin/cron-jobs",Ro="/_lunora/admin/openapi",Eo="/_lunora/admin/openrpc",So="/_lunora/admin/global/tables",Ao="/_lunora/admin/global/table",To="/_lunora/admin/global/facet",Rt=e=>{if(e===void 0||e==="")return;let t;try{t=Qn(JSON.parse(e))}catch{return}if(!Array.isArray(t))return;const n=t.flatMap(r=>{if(typeof r!="object"||r===null||typeof r.column!="string")return[];const{column:a,value:i}=r;return[{column:a,value:i}]});return n.length===0?void 0:n},Oo=Object.freeze({info:{description:'No OpenAPI spec is configured on this worker. Run `lunora codegen`, then wire the generated module to `createWorker`: `import { openApiSpec } from "./lunora/_generated/openapi"`.',title:"Lunora API",version:"0.0.0"},openapi:"3.1.0",paths:{}}),vo=Object.freeze({info:{description:'No OpenRPC spec is configured on this worker. Run `lunora codegen --api-spec openrpc` (or `both`), then wire the generated module to `createWorker`: `import { openRpcSpec } from "./lunora/_generated/openrpc"`.',title:"Lunora RPC",version:"0.0.0"},methods:[],openrpc:"1.3.2"}),ko=e=>{const{assertAdmin:t,options:n,parsePaging:r,queryParameter:a,requireAdminOption:i}=e,u=g=>{K(g,"GET","Functions");const y=i(g,n.functions,{code:"FUNCTIONS_NOT_CONFIGURED",message:"functions endpoint requires a `functions` registry on the worker"}),_=Object.entries(y).flatMap(([p,O])=>O.visibility==="internal"||O.kind==="stream"?[]:[{args:yo(O.args),kind:O.kind,path:p}]).toSorted((p,O)=>p.path.localeCompare(O.path));return Response.json({functions:_},{headers:{"content-type":"application/json"},status:200})},h=g=>{K(g,"GET","Cron-jobs");const y=i(g,n.cronJobs,{code:"CRON_JOBS_NOT_CONFIGURED",message:"cron-jobs endpoint requires a `cronJobs` map on the worker"}),_=Object.entries(y).flatMap(([p,O])=>O.map(N=>({args:N.args,cron:p,functionPath:N.functionPath,name:N.name,shardKey:N.shardKey,workflow:N.workflow}))).toSorted((p,O)=>p.name.localeCompare(O.name));return Response.json({jobs:_},{headers:{"content-type":"application/json"},status:200})},f=g=>(K(g,"GET","OpenAPI"),t(g),Response.json(n.openApiSpec??Oo,{headers:{"content-type":"application/json"},status:200})),m=g=>(K(g,"GET","OpenRPC"),t(g),Response.json(n.openRpcSpec??vo,{headers:{"content-type":"application/json"},status:200})),S=async g=>{K(g,"GET","Global-tables");const y=i(g,n.globalIntrospector,{code:"GLOBALS_NOT_CONFIGURED",message:"global endpoints require a `globalIntrospector` on the worker"});return Response.json(await y.listTables(),{headers:{"content-type":"application/json"},status:200})},A=async g=>{K(g,"GET","Global-table");const y=i(g,n.globalIntrospector,{code:"GLOBALS_NOT_CONFIGURED",message:"global endpoints require a `globalIntrospector` on the worker"}),_=new URL(g.url),p=a(_,"table");if(p===void 0)throw new d("Global-table endpoint requires a `table` query param",{code:"BAD_REQUEST",status:400});const O=await y.readTablePage({...r(g),filters:Rt(a(_,"filters")),table:p});return Response.json(O,{headers:{"content-type":"application/json"},status:200})},T=async g=>{K(g,"GET","Global-facet");const y=i(g,n.globalIntrospector,{code:"GLOBALS_NOT_CONFIGURED",message:"global endpoints require a `globalIntrospector` on the worker"}),_=new URL(g.url),p=a(_,"table"),O=a(_,"column");if(p===void 0||O===void 0)throw new d("Global-facet endpoint requires `table` and `column` query params",{code:"BAD_REQUEST",status:400});const N=a(_,"limit"),j=N===void 0?void 0:Number(N),k=await y.facetColumn({column:O,filters:Rt(a(_,"filters")),limit:j!==void 0&&Number.isFinite(j)?j:void 0,table:p});return Response.json(k,{headers:{"content-type":"application/json"},status:200})};return{[_o]:h,[bo]:u,[To]:T,[Ao]:A,[So]:S,[Ro]:f,[Eo]:m}},Io="/_lunora/admin/kv/namespaces",Po="/_lunora/admin/kv/keys",Vt="/_lunora/admin/kv/value",Jt=32*1048576,Et=60,No=e=>{const{readJsonBody:t,requireAdminOption:n}=e,r=y=>n(y,e.kvIntrospector,{code:"KV_NOT_CONFIGURED",message:"KV endpoints require a `kvIntrospector` on the worker"}),a=y=>Response.json(y,{headers:{"content-type":"application/json"},status:200}),i=(y,_)=>{const p=new URL(y.url),O=p.searchParams.get("namespace")??"",N=p.searchParams.get("key")??"";if(O==="")throw new d(`KV-value ${_} request requires a \`namespace\` query parameter`,{code:"BAD_REQUEST",status:400});if(N==="")throw new d(`KV-value ${_} request requires a \`key\` query parameter`,{code:"BAD_REQUEST",status:400});return{key:N,namespace:O}},u=async(y,_)=>{if(!(await y.listNamespaces()).some(O=>O.binding===_))throw new d(`Unknown KV namespace binding \`${_}\``,{code:"NOT_FOUND",status:404})},h=async y=>(K(y,"GET","KV-namespaces"),a({namespaces:await r(y).listNamespaces()})),f=async y=>{K(y,"GET","KV-keys");const _=r(y),p=new URL(y.url),O=p.searchParams.get("namespace")??"";if(O==="")throw new d("KV-keys request requires a `namespace` query parameter",{code:"BAD_REQUEST",status:400});const N=p.searchParams.get("prefix")??void 0,j=p.searchParams.get("cursor")??void 0,k=p.searchParams.get("limit"),F=k===null?void 0:Number.parseInt(k,10);if(F!==void 0&&(!Number.isInteger(F)||F<1))throw new d("KV-keys `limit` must be a positive integer",{code:"BAD_REQUEST",status:400});const H=F===void 0?void 0:Math.min(F,1e3);return await u(_,O),a(await _.listKeys({cursor:j,limit:H,namespace:O,prefix:N}))},T={DELETE:async y=>{const _=r(y),p=i(y,"DELETE");return await u(_,p.namespace),await _.deleteKey(p),a({deleted:!0})},GET:async y=>{const _=r(y),p=i(y,"GET");return await u(_,p.namespace),a(await _.getValue(p))},PUT:async y=>{const _=r(y),p=await t(y,Jt);if(typeof p.namespace!="string"||p.namespace==="")throw new d("KV-value PUT request requires a `namespace` string",{code:"BAD_REQUEST",status:400});if(typeof p.key!="string"||p.key==="")throw new d("KV-value PUT request requires a `key` string",{code:"BAD_REQUEST",status:400});if(typeof p.value!="string")throw new d("KV-value PUT request requires a `value` string",{code:"BAD_REQUEST",status:400});if(p.expirationTtl!==void 0&&(typeof p.expirationTtl!="number"||!Number.isInteger(p.expirationTtl)||p.expirationTtl<Et))throw new d("KV-value PUT `expirationTtl` must be an integer ≥ 60",{code:"BAD_REQUEST",status:400});const O=Math.floor(Date.now()/1e3)+Et;if(p.expiration!==void 0&&(typeof p.expiration!="number"||!Number.isInteger(p.expiration)||p.expiration<O))throw new d("KV-value PUT `expiration` must be a Unix-seconds timestamp at least 60 seconds in the future",{code:"BAD_REQUEST",status:400});return await u(_,p.namespace),await _.putValue({expiration:p.expiration,expirationTtl:p.expirationTtl,key:p.key,metadata:p.metadata,namespace:p.namespace,value:p.value}),a({ok:!0})}},g=y=>{const _=T[y.method];if(!_)throw new d("KV-value endpoint requires GET, PUT, or DELETE",{code:"METHOD_NOT_ALLOWED",status:405});return _(y)};return{[Io]:h,[Po]:f,[Vt]:g}},Do="/_lunora/migrate",Uo="/_lunora/admin/pitr",Co="/_lunora/admin/rank",Bo="/_lunora/admin/rankpage",xo="/_lunora/admin/shard-traffic",Ho=new Set(["__lunora_admin__:migrationStatus","__lunora_admin__:runMigration"]),Lo=new Set(["__lunora_admin__:getPitrBookmark","__lunora_admin__:pitrRestore"]),jo=async e=>{const n=await be(e,"Migration")??{};if(typeof n.table!="string"||n.table.length===0)throw new d("Migration request is missing `table`",{code:"BAD_REQUEST",status:400});if(typeof n.functionPath!="string"||!Ho.has(n.functionPath))throw new d("Migration request `functionPath` must be a migration admin op",{code:"BAD_REQUEST",status:400});return{args:n.args??{},functionPath:n.functionPath,table:n.table}},Mo=async e=>{const n=await be(e,"Rank")??{};if(typeof n.table!="string"||n.table.length===0)throw new d("Rank request is missing `table`",{code:"BAD_REQUEST",status:400});if(typeof n.index!="string"||n.index.length===0)throw new d("Rank request is missing `index`",{code:"BAD_REQUEST",status:400});if(typeof n.partitionKey!="string")throw new d("Rank request `partitionKey` must be a string",{code:"BAD_REQUEST",status:400});if(typeof n.rowId!="string"||n.rowId.length===0)throw new d("Rank request is missing `rowId`",{code:"BAD_REQUEST",status:400});if(!Array.isArray(n.sortValues))throw new d("Rank request `sortValues` must be an array",{code:"BAD_REQUEST",status:400});return{index:n.index,partitionKey:n.partitionKey,rowId:n.rowId,sortValues:n.sortValues,table:n.table}},Ko=e=>{if(e!==void 0){if(!Array.isArray(e)||e.some(t=>t!=="asc"&&t!=="desc"))throw new d('Rank page request `directions` must be an array of "asc"|"desc"',{code:"BAD_REQUEST",status:400});return e}},$o=e=>{if(typeof e.table!="string"||e.table.length===0)throw new d("Rank page request is missing `table`",{code:"BAD_REQUEST",status:400});if(typeof e.index!="string"||e.index.length===0)throw new d("Rank page request is missing `index`",{code:"BAD_REQUEST",status:400});if(e.partitionKey!==void 0&&typeof e.partitionKey!="string")throw new d("Rank page request `partitionKey` must be a string",{code:"BAD_REQUEST",status:400});if(e.take!==void 0&&(typeof e.take!="number"||!Number.isFinite(e.take)))throw new d("Rank page request `take` must be a number",{code:"BAD_REQUEST",status:400});if(e.cursor!==void 0&&e.cursor!==null&&typeof e.cursor!="string")throw new d("Rank page request `cursor` must be a string or null",{code:"BAD_REQUEST",status:400})},Fo=async e=>{const n=await be(e,"Rank page")??{};$o(n);const r=Ko(n.directions);return{cursor:typeof n.cursor=="string"?n.cursor:null,directions:r,index:n.index,partitionKey:typeof n.partitionKey=="string"?n.partitionKey:void 0,table:n.table,take:typeof n.take=="number"?n.take:void 0}},Go=async e=>{const n=await be(e,"Shard-traffic")??{};if(typeof n.table!="string"||n.table.length===0)throw new d("Shard-traffic request is missing `table`",{code:"BAD_REQUEST",status:400});return{table:n.table}},Qo=async e=>{const n=await Z(e);if(typeof n.functionPath!="string"||!Lo.has(n.functionPath))throw new d("PITR request `functionPath` must be a PITR admin op",{code:"BAD_REQUEST",status:400});if(n.shardKey!==void 0&&typeof n.shardKey!="string")throw new d("PITR `shardKey` must be a string",{code:"BAD_REQUEST",status:400});return{args:n.args??{},functionPath:n.functionPath,shardKey:n.shardKey}},zo=e=>{const{defaultShard:t,forwardToShard:n,isAdmin:r,queryCoordinator:a,resolveForwardContext:i,shardDO:u}=e,h=(g,y)=>{if(g.method!=="POST")throw new d(`${y} endpoint requires POST`,{code:"METHOD_NOT_ALLOWED",status:405});if(!r(g))throw new d("Admin auth required",{code:"FORBIDDEN",status:403});if(!a)throw new d(`${y} endpoint requires a \`queryCoordinator\` on the worker`,{code:"BAD_REQUEST",status:400});return a},f=async(g,y)=>{const _=h(g,"Migration"),p=await jo(g),{headers:O}=await i(g,y),N=await _.orchestrateMigration(u,{args:p.args,defaultShardKey:t,functionPath:p.functionPath,headers:O,table:p.table});return Response.json(N,{headers:{"content-type":"application/json"},status:200})},m=async(g,y)=>{const _=h(g,"Rank"),p=await Mo(g),{headers:O}=await i(g,y),N=await _.orchestrateRank(u,{headers:O,index:p.index,partitionKey:p.partitionKey,rowId:p.rowId,sortValues:p.sortValues,table:p.table});return Response.json(N,{headers:{"content-type":"application/json"},status:200})},S=async(g,y)=>{const _=h(g,"Rank page"),p=await Fo(g),{headers:O}=await i(g,y),N=await _.orchestrateRankPage(u,{...p,headers:O});return Response.json(N,{headers:{"content-type":"application/json"},status:200})},A=async(g,y)=>{const _=h(g,"Shard-traffic"),p=await Go(g),{headers:O}=await i(g,y),N=await _.orchestrateShardTraffic(u,{headers:O,table:p.table});return Response.json(N,{headers:{"content-type":"application/json"},status:200})},T=async(g,y)=>{if(K(g,"POST","PITR"),!r(g))throw new d("admin PITR endpoint requires a valid admin bearer",{code:"ADMIN_FORBIDDEN",status:403});const _=await Qo(g),{headers:p}=await i(g,y),O=new Request("https://shard.internal/rpc",{body:JSON.stringify({args:_.args,functionPath:_.functionPath}),headers:p,method:"POST"});return n(u,_.shardKey??t,O)};return{[Do]:f,[Uo]:T,[Co]:m,[Bo]:S,[xo]:A}},Wo=1,Vo=0,Jo=32,qo=512,Yo=/^[a-z][\d_a-z*/-]{0,255}(?:@[a-z][\d_a-z*/-]{0,13})?=[\u0020-\u002B\u002D-\u003C\u003E-\u007E]{1,256}$/,Xo=e=>{if(e==null)return;const t=e.trim();if(t.length===0||t.length>qo)return;const n=t.split(",");if(!(n.length>Jo)){for(const r of n)if(!Yo.test(r.trim()))return;return t}},Zo=e=>{const t=Mn(e.headers.get("traceparent"));if(t===void 0)return;const n=Xo(e.headers.get("tracestate"));return{parentSpanId:t.parentSpanId,sampled:t.sampled,traceId:t.traceId,...n===void 0?{}:{traceState:n}}},ea=(e,t={})=>{const n=Zo(e),r=t.trustInbound===!0?n:void 0,a=Oe(8),i=r?.traceId??Oe(16),u=ur(t.sampling,r===void 0?a:i),h=u.isTraced&&(r===void 0||r.sampled);return{decision:u,ignoredUpstream:n!==void 0&&r===void 0,trace:{sampled:h,spanId:a,traceFlags:h?Wo:Vo,traceId:i,...r?.parentSpanId===void 0?{}:{parentSpanId:r.parentSpanId},...r?.traceState===void 0?{}:{traceState:r.traceState}}}},ta=(e,t)=>{t.traceparent=jn(e.traceId,e.spanId,e.sampled),e.traceState!==void 0&&(t.tracestate=e.traceState)},na=(e,t)=>{let n;return()=>{if(n===void 0){const r=Gn(e),a=t===void 0?void 0:t.cf;n=Kn(Fn(r),$n(r,a))}return n}},ra="/_lunora/admin/scheduled",oa="/_lunora/admin/scheduled/status",aa="/_lunora/admin/scheduled/ws",sa="/_lunora/admin/scheduled/cancel",ia="/_lunora/admin/scheduled/dead",ca="/_lunora/admin/scheduled/dead/retry",da="/_lunora/admin/scheduled/dead/cancel",ua="/_lunora/admin/scheduled/pool/release",la=e=>{const{checkWsAdmin:t,requireSchedulerNamespace:n,resolveSchedulerStub:r,schedulerInstanceName:a}=e,i=(m,S)=>A=>{if(A.method!=="GET")throw new d(`${S} endpoint requires GET`,{code:"METHOD_NOT_ALLOWED",status:405});const T=new URL(A.url).searchParams.get("cursor"),g=T===null||T===""?"":`?cursor=${encodeURIComponent(T)}`;return r(A).fetch(new Request(`https://scheduler.internal${m}${g}`,{method:"GET"}))},u=(m,S,A=S)=>async T=>{if(T.method!=="POST")throw new d(`${A} requires POST`,{code:"METHOD_NOT_ALLOWED",status:405});const g=r(T),y=await T.json().catch(()=>{});if(typeof y?.id!="string"||y.id==="")throw new d(`${S} requires a string \`id\``,{code:"BAD_REQUEST",status:400});return g.fetch(new Request(`https://scheduler.internal${m}`,{body:JSON.stringify({id:y.id}),headers:{"content-type":"application/json"},method:"POST"}))},h=async m=>{if(m.method!=="POST")throw new d("Scheduled pool-release endpoint requires POST",{code:"METHOD_NOT_ALLOWED",status:405});const S=r(m),A=await m.json().catch(()=>{});if(typeof A?.pool!="string"||A.pool==="")throw new d("Scheduled pool-release requires a string `pool`",{code:"BAD_REQUEST",status:400});const T=typeof A.id=="string"&&A.id!==""?A.id:void 0;return S.fetch(new Request("https://scheduler.internal/complete",{body:JSON.stringify(T===void 0?{pool:A.pool}:{id:T,pool:A.pool}),headers:{"content-type":"application/json"},method:"POST"}))},f=async m=>{if(m.headers.get("Upgrade")!=="websocket")throw new d("WebSocket upgrade header missing",{code:"BAD_REQUEST",status:426});if(!await t(m))throw new d("admin authorization required",{code:"ADMIN_FORBIDDEN",status:403});const S=n();return we(S,a).fetch(new Request("https://scheduler.internal/ws",{headers:{Upgrade:"websocket"}}))};return{[sa]:u("/cancel","Scheduled-cancel","Scheduled-cancel endpoint"),[da]:u("/dead/cancel","Scheduled dead-letter action"),[ia]:i("/dead","Scheduled dead-letter"),[ca]:u("/dead/retry","Scheduled dead-letter action"),[ra]:i("/list","Scheduled-list"),[ua]:h,[oa]:i("/status","Scheduler-status"),[aa]:f}},ha=(e,...t)=>{let n=e.cf;for(const r of t){if(typeof n!="object"||n===null)return;n=n[r]}return typeof n=="string"?n:void 0},St={mtls:e=>ha(e,"tlsClientAuth","certVerified")==="SUCCESS"},fa=e=>e===void 0||e===!1?()=>!1:e===!0?()=>!0:typeof e=="function"?e:(Object.hasOwn(St,e)?St[e]:void 0)??(()=>!1),pa=e=>{if(e!==void 0)return()=>{};let t=!1;return()=>{t||(t=!0,console.warn('[lunora] Ignored an inbound `traceparent`, so this request starts a new trace instead of joining the caller\'s. That is the safe default: the header is caller-supplied, and trusting it lets any client choose which trace its spans and logs join. If this worker sits behind a gateway, service mesh, or Cloudflare Access that sets `traceparent` itself, set `trustInboundTraceContext: true` on createWorker() (or `"mtls"` to trust only edge-verified client certificates). Set it to `false` to keep this behaviour and silence this message.'))}},ma="/_lunora/admin/vector/indexes",wa="/_lunora/admin/vector/query",ga=e=>{const{readJsonBody:t,requireAdminOption:n}=e,r=async i=>{K(i,"GET","Vector-indexes");const u=n(i,e.vectorIntrospector,{code:"VECTORS_NOT_CONFIGURED",message:"vector endpoints require a `vectorIntrospector` on the worker"});return Response.json({indexes:await u.listIndexes()},{headers:{"content-type":"application/json"},status:200})},a=async i=>{K(i,"POST","Vector-query");const u=n(i,e.vectorIntrospector,{code:"VECTORS_NOT_CONFIGURED",message:"vector endpoints require a `vectorIntrospector` on the worker"});if(u.queryIndex===void 0)throw new d("vector index querying is not enabled on this worker",{code:"VECTOR_QUERY_UNSUPPORTED",status:400});const f=await t(i);if(typeof f.name!="string"||f.name==="")throw new d("Vector-query request requires a `name` string",{code:"BAD_REQUEST",status:400});if(typeof f.text!="string"||f.text==="")throw new d("Vector-query request requires a `text` string",{code:"BAD_REQUEST",status:400});if(f.topK!==void 0&&(typeof f.topK!="number"||!Number.isInteger(f.topK)||f.topK<1))throw new d("Vector-query `topK` must be a positive integer",{code:"BAD_REQUEST",status:400});const m=await u.queryIndex({name:f.name,text:f.text,topK:f.topK});return Response.json(m,{headers:{"content-type":"application/json"},status:200})};return{[ma]:r,[wa]:a}},ya="/_lunora/admin/workflows/instances",ba="/_lunora/admin/workflows/instance",_a="/_lunora/admin/workflows/status",Ra={complete:!0,errored:!0,paused:!0,queued:!0,running:!0,terminated:!0,unknown:!0,waiting:!0,waitingForPause:!0},Ea=e=>e!==null&&Object.hasOwn(Ra,e)?e:void 0,At=(e,t)=>{const n=e.searchParams.get(t);if(n===null)return;const r=Number(n);return Number.isInteger(r)&&r>0?r:void 0},$e=(e,t)=>{const n=e.searchParams.get(t);if(n===null||n==="")throw new d(`Workflows admin endpoint requires a \`${t}\` query parameter`,{code:"BAD_REQUEST",status:400});return n},Tt=()=>{throw new d("Workflow inspection is unconfigured. Set CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN in your .dev.vars to enable it.",{code:"WORKFLOWS_NOT_CONFIGURED",status:501})},Sa=e=>{const{assertAdmin:t,resolveWorkflowsClient:n}=e,r=async(u,h,f)=>{K(u,"GET","Workflows instances"),t(u);const m=n(h);if(!m)return Response.json({configured:!1,instances:[],page:1,perPage:0,totalCount:0});const S=$e(f,"name"),A=Ea(f.searchParams.get("status"));return Response.json(await m.listInstances({page:At(f,"page"),perPage:At(f,"perPage"),status:A,workflowName:S}))},a=async(u,h,f)=>{K(u,"GET","Workflows instance"),t(u);const m=n(h);return m?Response.json(await m.getInstance({instanceId:$e(f,"id"),workflowName:$e(f,"name")})):Tt()},i=async(u,h)=>{K(u,"POST","Workflows status"),t(u);const f=n(h);if(!f)return Tt();const m=await u.json().catch(()=>{});if(typeof m?.name!="string"||m.name===""||typeof m.id!="string"||m.id==="")throw new d("Workflows status action requires string `name` and `id`",{code:"BAD_REQUEST",status:400});const{action:S}=m;if(S!=="pause"&&S!=="resume"&&S!=="terminate")throw new d("Workflows status action must be one of: pause, resume, terminate",{code:"BAD_REQUEST",status:400});return Response.json(await f.setInstanceStatus({action:S,instanceId:m.id,workflowName:m.name}))};return{[ba]:a,[ya]:r,[_a]:i}},Aa={[Vt]:Jt,[er]:Zn},Ot="/_lunora/rpc",Ta="/_lunora/rpc-batch",Oa="/_lunora/ws",Ee=(e,t,n)=>({resourceAttributes:na(e,t),...n===void 0?{}:{waitUntil:n}}),Fe=e=>e?.waitUntil?{waitUntil:t=>e.waitUntil?.(t)}:{},vt=e=>({spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId,...e.parentSpanId===void 0?{}:{parentSpanId:e.parentSpanId}}),Ge=e=>{const{method:t}=e,n=e.headers.get("user-agent")??void 0;let r;try{r=new URL(e.url)}catch{return{method:t,userAgent:n}}const a=r.port===""?void 0:Number(r.port);return{host:r.hostname,method:t,path:r.pathname,port:Number.isNaN(a)?void 0:a,scheme:r.protocol.replace(":",""),userAgent:n}},kt="/_lunora/voice/",va="/_lunora/scheduler/dispatch",ka="/_lunora/admin/cron-jobs/run",Ia="/_lunora/admin/ws-token",Pa="/_lunora/admin/",Na="/_lunora/migrate",Da="/_lunora/status",Ua=e=>e.startsWith(Pa)||e===Na,Se=async e=>await e===!0,Ca=e=>{const t=e.headers.get("x-lunora-userid"),n=e.headers.get("x-lunora-identity");if(!(t===null&&n===null))return{...n===null?{}:{identity:n},...t===null?{}:{userId:t}}},Ba="/api/auth",xa="__lunora_admin__:recordAuthEvent",Ha="__lunora_admin__:listPushSubscriptions",La=["/sign-in","/sign-up","/callback"],ja=(e,t)=>{const n=t.endsWith("/")?t.slice(0,-1):t;if(!e.startsWith(`${n}/`))return!1;const r=e.slice(n.length);return La.some(a=>r===a||r.startsWith(`${a}/`))},Ae=(e,t,n,r)=>{const a=Dn(n),i=a?n.code:"INTERNAL_SERVER_ERROR",u=a?n.status:500,h=n instanceof Error?n.message:String(n);return{durationMs:t,error:{code:i,message:h,status:u},functionPath:e,ok:!1,...r.fanOut?{fanOut:{failed:0,shards:0,table:r.fanOut.table}}:{},...r.shardKey?{shardKey:r.shardKey}:{}}},Ma=e=>{const{exp:t,expiresAtMs:n}=e;if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof t=="number"&&Number.isFinite(t))return t*1e3},It=e=>e.waitUntil?{waitUntil:t=>{e.waitUntil?.(t)}}:void 0,Ka=e=>{const t=e?.queue;return typeof t=="string"&&t.length>0?t:"unknown"},We=new WeakMap,ce=async(e,t,n,r=We.get(e))=>{const a={"content-type":"application/json"},i=e.headers.get("authorization"),u=e.headers.get("cookie"),h=e.headers.get("x-d1-bookmark"),f=e.headers.get("x-lunora-mutation-id"),m=e.headers.get("x-lunora-client-id"),S=e.headers.get("x-lunora-client-seq");i&&(a.authorization=i),u&&(a.cookie=u),h&&(a["x-d1-bookmark"]=h),f&&(a["x-lunora-mutation-id"]=f),m&&(a["x-lunora-client-id"]=m),S&&(a["x-lunora-client-seq"]=S);const A=e.headers.get("cf-connecting-ip");if(A&&(a["x-lunora-client-ip"]=A),!n)return{claims:null,headers:a,identity:null,userId:null};const T=await n(e,t,r);if(!T||typeof T.userId!="string"||T.userId.length===0)return{claims:null,headers:a,identity:null,userId:null};a["x-lunora-userid"]=Hn(T.userId);const g=Ma(T);g!==void 0&&(a["x-lunora-identity-exp"]=String(g));const{userId:y,..._}=T,p=Object.keys(_).length>0?_:null;return p&&(a["x-lunora-identity"]=Ln(p)),{claims:p,headers:a,identity:T,userId:y}},$a=new Set(["concat","first","groupBy","max","min","rank","sum","topK"]),Fa=e=>{if(e===void 0)return;if(!e||typeof e!="object")throw new d("RPC `fanOut` must be an object",{code:"BAD_REQUEST",status:400});const t=e;if(typeof t.table!="string"||t.table.length===0)throw new d("RPC `fanOut.table` must be a non-empty string",{code:"BAD_REQUEST",status:400});if(!t.merge||typeof t.merge!="object")throw new d("RPC `fanOut.merge` must be an object",{code:"BAD_REQUEST",status:400});const n=t.merge;if(typeof n.kind!="string"||!$a.has(n.kind))throw new d("RPC `fanOut.merge.kind` is not a recognized merge strategy",{code:"BAD_REQUEST",status:400});if(n.kind==="topK"){if(typeof n.k!="number"||!Number.isInteger(n.k)||n.k<0)throw new d("RPC `fanOut.merge.k` must be a non-negative integer",{code:"BAD_REQUEST",status:400});if(typeof n.by!="string"||n.by.length===0)throw new d("RPC `fanOut.merge.by` must be a non-empty string",{code:"BAD_REQUEST",status:400})}return t},Ga=(e,t)=>{e?.LUNORA_DEBUG_RPC&&console.warn(`[lunora:rpc] ${t.fanOut?"fan-out":`shard=${t.shardKey??"(root)"}`} ${t.functionPath}`)},Qe=(e,t)=>{const n=t.functions?.[e.functionPath]?.x402;if(n){if(e.fanOut)throw new d("a paid (`.x402`) function cannot be fanned out",{code:"BAD_REQUEST",status:400});if(!t.x402Charge)throw new d(`function "${e.functionPath}" is marked paid (.x402) but no x402Charge gate is configured on the worker`,{code:"MISCONFIGURED",status:500});return n}},Qa=async e=>{const t=await xt(e);let n;try{n=JSON.parse(t)}catch{throw new d("RPC body must be valid JSON",{code:"BAD_REQUEST",status:400})}if(!n||typeof n!="object"||typeof n.functionPath!="string")throw new d("RPC envelope is missing `functionPath`",{code:"BAD_REQUEST",status:400});const r=n;if(r.args!==void 0&&Bt(r.args,"RPC"),r.shardKey!==void 0&&typeof r.shardKey!="string")throw new d("RPC `shardKey` must be a string",{code:"BAD_REQUEST",status:400});const a=n,i=Fa(a.fanOut),u=a.args??{};if(i&&a.functionPath.startsWith("__lunora_relation__:")){const h=u.table;if(typeof h=="string"&&h!==i.table)throw new d("RPC `args.table` must match the authorized `fanOut.table` for a relation fan-out",{code:"BAD_REQUEST",status:400});u.table=i.table}return{args:u,fanOut:i,functionPath:a.functionPath,shardKey:a.shardKey}},Te=new Map,za=5e3,Wa=4096,Va=async(e,t)=>{const n=Date.now(),r=Te.get(t);if(r!==void 0&&r.expiresMs>n)return r.relayCount;r!==void 0&&Te.delete(t);let a=0;try{const i=await we(e,t).fetch(new Request("https://shard.internal/_lunora/route"));if(i.ok){const h=(await i.json()).relayCount;typeof h=="number"&&h>0&&(a=Math.floor(h))}}catch{a=0}return Ut(Te,Wa),Te.set(t,{expiresMs:n+za,relayCount:a}),a},Pt=(e,t)=>{if(!(e===null||typeof e!="object"))return Object.entries(e).find(([,n])=>n===t)?.[0]},ye=(e,t,n)=>new Request("https://shard.internal/rpc",{body:JSON.stringify({args:t,functionPath:e}),headers:n,method:"POST"}),Ja=["x-lunora-userid","x-lunora-identity","x-lunora-identity-exp"],qa=(e,t)=>{for(const n of Ja){e.delete(n);const r=t[n];r!==void 0&&e.set(n,r)}},Nt=(e,t)=>{const n=new Headers(e.headers),r=[...n.keys()];for(const a of r)a.startsWith("x-lunora-")&&n.delete(a);return qa(n,t),n},Ya=async(e,t,n)=>e.length===0||n.length===0?!1:qe(await Mt(e,t),n),Dt=(e,t)=>{if(!t||t.length===0)return!1;const n=e.headers.get("authorization");if(!n)return!1;const[r,...a]=n.split(" ");return r?.toLowerCase()!=="bearer"?!1:qe(t,a.join(" ").trim())},Xa=async(e,t,n)=>{if(!t||t.length===0)return!1;const r=new URL(e.url).searchParams.get("token");return r===null?!1:await Br(t,r)?!0:n?!1:qe(t,r)},Za=(e,t)=>{if(t===null||typeof t!="object"&&typeof t!="function")return;const n=t;if(typeof n.prepare=="function"&&typeof n.batch=="function"&&typeof n.dump=="function")return ir(`d1:${e}`,t);if(typeof n.list=="function"&&typeof n.head=="function"&&typeof n.createMultipartUpload=="function")return xe(`r2:${e}`,!0);if(typeof n.send=="function"&&typeof n.sendBatch=="function"&&typeof n.get!="function")return xe(`queue:${e}`,!0);if(typeof n.connectionString=="string")return xe(`hyperdrive:${e}`,!0)},qt=e=>{const t=fa(e.trustInboundTraceContext),n=pa(e.trustInboundTraceContext),r=e.defaultShardKey??"__root__",a=cr(e.resolveIdentity,e.identity),i=ct(e.shardDO,e.jurisdiction),u=e.schedulerDO===void 0?void 0:ct(e.schedulerDO,e.jurisdiction);let h=!1;const f=o=>{if(o===void 0||e.jurisdiction===void 0)return o;h||(h=!0,console.warn(`[lunora] jurisdiction "${e.jurisdiction}" pins placement, so region hints (\`shardRegion\`, replica and relay placement) are not sent. Residency wins.`))},m=async(o,s,l,c=e.shardRegion?.(s))=>we(o,s,f(c)).fetch(l);let S;const A=()=>e.adminToken??S;let T;const g=()=>e.requireEphemeralWsToken??T??!0;let y;const _=o=>{const s=o??{};if(y??=Pt(o,e.shardDO),T===void 0&&e.requireEphemeralWsToken===void 0){const c=s.LUNORA_REQUIRE_EPHEMERAL_WS_TOKEN;typeof c=="string"&&c.length>0&&(T=Dr(c,!0))}if(S!==void 0||e.adminToken!==void 0)return;const l=s.LUNORA_ADMIN_TOKEN;typeof l=="string"&&l.length>0&&(S=l)},p=new WeakSet,O=o=>Dt(o,A())||p.has(o),N=async(o,s)=>{const l=await ce(o,s,e.resolveIdentity);if(p.has(o)&&l.headers.authorization===void 0){const c=A();c!==void 0&&(l.headers.authorization=`Bearer ${c}`)}return l};let j=!1,k=!1;const F=()=>{k||(k=!0,console.warn("[lunora] `replicaReads: true` has no effect without `functions` — read eligibility is decided from the function registry."))},H=o=>{if(!e.allowUnauthenticatedShardAccess){const s=o==="fan-out"?"authorizeFanOut":"authorizeShard";throw new d(`${o} access is default-denied: configure \`${s}\` on the worker, or set \`allowUnauthenticatedShardAccess: true\` to explicitly allow unauthenticated ${o} access (relying solely on per-row RLS).`,{code:o==="fan-out"?"FORBIDDEN_FANOUT":"FORBIDDEN_SHARD",status:403})}j||(j=!0,console.warn([`[lunora] SECURITY: serving ${o} access with \`allowUnauthenticatedShardAccess: true\` and no \`authorizeShard\`/\`authorizeFanOut\` — `,"any caller (including unauthenticated ones) can target any shard / fan out across the table. ","This is safe only if every table is protected by per-row RLS. Configure `authorizeShard`/`authorizeFanOut` to gate it."].join("")))},Y=async(o,s)=>{if(e.authorizeShard){if(!await Se(e.authorizeShard({identity:o,shardKey:s})))throw new d("Forbidden shard",{code:"FORBIDDEN_SHARD",status:403})}else s!==r&&H("shard")},C=zo({defaultShard:r,forwardToShard:m,isAdmin:O,queryCoordinator:e.queryCoordinator,resolveForwardContext:N,shardDO:i}),G=async(o,s,l,c,w)=>{const b={"content-type":"application/json","x-lunora-system":"1"};return w?.userId!==void 0&&w.userId.length>0&&(b["x-lunora-userid"]=w.userId),w?.identity!==void 0&&w.identity.length>0&&(b["x-lunora-identity"]=w.identity),c!==void 0&&c.length>0&&(b["x-lunora-mutation-id"]=c),m(i,l,ye(o,s,b))},Q=async(o,s,l,c)=>{const w=l?.[o];if(!w||typeof w.create!="function")throw new d(`${c} targets workflow binding "${o}", which is not bound on env`,{code:"CRON_JOB_FAILED",status:500});if(pr(s))throw new d(`${c} params ${mr}`,{code:"BAD_REQUEST",status:400});await w.create({params:s})},J=async(o,s)=>{if(o.workflow){await Q(o.workflow,o.args??{},s,`cron job "${o.name}"`);return}if(o.functionPath===void 0)throw new d(`cron job "${o.name}" has neither a function target nor a workflow target`,{code:"CRON_JOB_FAILED",status:500});const l=await G(o.functionPath,o.args??{},o.shardKey??r);if(!l.ok)throw new d(`cron job "${o.name}" (${o.functionPath}) failed with shard status ${String(l.status)}`,{code:"CRON_JOB_FAILED",status:500})},M=o=>{if(!O(o))throw new d("admin endpoint requires a valid admin bearer",{code:"ADMIN_FORBIDDEN",status:403})},$=(o,s,l)=>{if(M(o),s===void 0)throw new d(l.message,{code:l.code,status:400});return s},oe=async(o,s,l,c)=>{const w=e.cronJobs?.[o];if(!w)return 0;for(const b of w)try{await J(b,s)}catch(I){l.push(c(I))}return w.length},z=async(o,s)=>{if(M(o),K(o,"POST","cron-jobs run"),!e.cronJobs)throw new d("cron-jobs run endpoint requires a `cronJobs` map on the worker",{code:"CRON_JOBS_NOT_CONFIGURED",status:400});const l=await Z(o),c=typeof l.name=="string"?l.name:"";if(c==="")throw new d("cron-jobs run endpoint requires a job `name`",{code:"BAD_REQUEST",status:400});const w=Object.values(e.cronJobs).flat().find(b=>b.name===c);if(!w)throw new d(`no cron job named "${c}" is registered`,{code:"CRON_JOB_NOT_FOUND",status:404});return await J(w,s),Response.json({name:c,ran:!0},{status:200})},de=async o=>{const s=typeof o.pool=="string"&&o.pool.length>0?o.pool:void 0;if(!s||!u||typeof o.id!="string")return;const l=typeof o.instanceName=="string"&&o.instanceName.length>0?o.instanceName:"default";try{await we(u,l).fetch(new Request("https://scheduler.internal/complete",{body:JSON.stringify({id:o.id,pool:s}),headers:{"content-type":"application/json"},method:"POST"}))}catch{}},ue=async(o,s)=>{K(o,"POST","Scheduler dispatch");const l=await xt(o),c=s??{},w=typeof c.LUNORA_SCHEDULER_SECRET=="string"?c.LUNORA_SCHEDULER_SECRET:void 0,b=e.adminToken??(typeof c.LUNORA_ADMIN_TOKEN=="string"?c.LUNORA_ADMIN_TOKEN:void 0),I=o.headers.get("x-lunora-scheduler-signature");let v=!1;if(I&&w?v=await Ya(w,l,I):b&&(v=Dt(o,b)),!v)throw new d("Scheduler dispatch requires a valid signature or admin bearer",{code:"DISPATCH_UNAUTHENTICATED",status:403});let E;try{E=JSON.parse(l)}catch{throw new d("Scheduler dispatch body must be valid JSON",{code:"BAD_REQUEST",status:400})}const R=E??{},U=R.args??{};if(typeof R.workflow=="string"&&R.workflow.length>0)return await Q(R.workflow,U,s,"scheduled workflow"),await de(R),Response.json({ok:!0},{status:200});if(typeof R.functionPath!="string"||R.functionPath.length===0)throw new d("Scheduler dispatch is missing `functionPath`",{code:"BAD_REQUEST",status:400});const x=typeof R.shardKey=="string"&&R.shardKey.length>0?R.shardKey:r,B=typeof R.id=="string"&&R.id.length>0?R.id:void 0,te=Ca(o),L=await G(R.functionPath,U,x,B,te);return await de(R),L},_e=Mr({assertAdmin:M,getReader:()=>e.authAuditReader}),ve=async(o,s)=>{M(o);const l=e.notifySubscriptionStore;if(l===void 0)return Response.json({result:ze({subscriptions:[]})},{headers:{"content-type":"application/json"},status:200});const c=s?.kind,w=s?.userId,b=s?.limit,I=c==="fcm"||c==="web-push"?c:void 0,v=typeof w=="string"&&w!==""?w:void 0,E=typeof b=="number"&&Number.isFinite(b)?Math.trunc(b):0,R=E>0?Math.min(E,1e3):1e3,x=(await l.list({kind:I,limit:R,userId:v})).filter(B=>I!==void 0&&B.kind!==I?!1:v===void 0||(B.userId??null)===v).map(({keys:B,token:te,...L})=>L);return Response.json({result:ze({subscriptions:x})},{headers:{"content-type":"application/json"},status:200})},ke=async(o,s)=>{if(!s.fanOut){if(s.functionPath===jr)return _e(o,s.args??{});if(s.functionPath===Ha)return ve(o,s.args)}},ae=lo({applyGlobals:e.applyGlobals,assertAdmin:M,exportCursorStore:e.exportCursorStore,exportSinks:e.exportSinks,defaultShardKey:r,knownTables:()=>[...e.listSchemaTables?.()??[]],queryCoordinator:e.queryCoordinator,requireAdminOption:$,resolveForwardContext:N,shardDO:i,streamExportRows:(o,s,l,c)=>Qt(e,o,s,l,c,i),streamingImport:(o,s)=>wo(o,e,s,i),syncGlobals:e.syncGlobals}),Ie=(o,s)=>{const l=o.searchParams.get(s);return l===null||l===""?void 0:l},Pe=o=>{const s=new URL(o.url),l=s.searchParams.get("limit"),c=s.searchParams.get("offset"),w=l===null?void 0:Number.parseInt(l,10),b=c===null?void 0:Number.parseInt(c,10);return{limit:w!==void 0&&Number.isFinite(w)&&w>=0?w:void 0,offset:b!==void 0&&Number.isFinite(b)&&b>=0?b:void 0}},Ze=()=>{if(u===void 0)throw new d("scheduled endpoints require a `schedulerDO` namespace on the worker",{code:"SCHEDULER_NOT_CONFIGURED",status:400});return u},Yt=la({checkWsAdmin:async o=>O(o)||Xa(o,A(),g()),requireSchedulerNamespace:Ze,resolveSchedulerStub:o=>(M(o),we(Ze(),e.schedulerInstanceName??"default")),schedulerInstanceName:e.schedulerInstanceName??"default"}),Xt=Sa({assertAdmin:M,resolveWorkflowsClient:e.workflowsClient??(()=>{})}),Zt=Xn({assertAdmin:M,parsePaging:Pe,queryParameter:Ie,readBodyBytes:Wn,requireAdminOption:$,storage:{storageBuckets:e.storageBuckets,storageDelete:e.storageDelete,storageDownload:e.storageDownload,storageList:e.storageList,storageSignedUrl:e.storageSignedUrl,storageUpload:e.storageUpload}}),en=Zr({options:e,readJsonBody:Z,requireAdminOption:$}),tn=ga({readJsonBody:Z,requireAdminOption:$,vectorIntrospector:e.vectorIntrospector}),nn=No({kvIntrospector:e.kvIntrospector,readJsonBody:Z,requireAdminOption:$}),rn=dr({logArchive:e.logArchive,readJsonBody:Z,requireAdminOption:$}),on=ko({assertAdmin:M,options:{cronJobs:e.cronJobs,functions:e.functions,globalIntrospector:e.globalIntrospector,openApiSpec:e.openApiSpec,openRpcSpec:e.openRpcSpec},parsePaging:Pe,queryParameter:Ie,requireAdminOption:$}),an=o=>{const s=[],l=i??o?.SHARD;if(l!==void 0&&s.push(sr("durable-object:default",l,r)),e.health?.disableBindingProbes!==!0)for(const[c,w]of Object.entries(o??{})){const b=Za(c,w);b!==void 0&&s.push(b)}for(const c of e.health?.probes??[])s.push(c);return s},sn=ar({appName:e.health?.appName,appVersion:e.health?.appVersion,auth:e.health?.auth??"public",cacheTtlMs:e.health?.cacheTtlMs,isAdmin:O,resolveProbes:an}),cn=o=>{const s=e.schedulerInstanceName??"default",l=()=>we(o,s),c=async(E,R)=>{const U=await l().fetch(new Request(`https://scheduler.internal${E}`,R));if(!U.ok)throw new d(`ctx.scheduler: SchedulerDO ${E} failed (${String(U.status)}): ${await U.text()}`,{code:"INTERNAL",status:500});return await U.json()},w=async(E,R)=>await c(E,{body:JSON.stringify(R),headers:{"content-type":"application/json"},method:"POST"}),b=E=>{const R=E;if(R==null)throw new d("ctx.scheduler: target is required — pass a reference from the generated `internal` / `workflows` / `agents`",{code:"BAD_REQUEST",status:400});if(typeof R.binding=="string"&&R.binding.length>0)return{workflow:R.binding};if(typeof R.__lunoraRef=="string")return{functionPath:R.__lunoraRef};throw new d("ctx.scheduler: expected a reference from the generated `internal` / `workflows` / `agents` — a bare function-path string is refused here, because an HTTP action can be reached unauthenticated",{code:"BAD_REQUEST",status:400})},I=async()=>await wr(async E=>c(E===void 0?"/list":`/list?cursor=${encodeURIComponent(E)}`,{method:"GET"})),v=async(E,R,U={})=>{const{id:x}=await w("/schedule",{args:U,scheduledFor:E,...b(R)});return x};return{cancel:async E=>await w("/cancel",{id:E}),get:async E=>await c(`/get?id=${encodeURIComponent(E)}`,{method:"GET"}),list:I,runAfter:async(E,R,U)=>{if(!Number.isFinite(E)||E<0)throw new d("ctx.scheduler.runAfter: `delayMs` must be a non-negative finite number",{code:"INVALID_INPUT",status:400});return await v(Date.now()+E,R,U)},runAt:async(E,R,U)=>{if(!Number.isFinite(E))throw new d("ctx.scheduler.runAt: `date` must be a non-negative finite number",{code:"INVALID_INPUT",status:400});return await v(E,R,U)}}},dn=async(o,s,l)=>{const{claims:c,headers:w,userId:b}=await ce(o,s,a),I=async(v,E={})=>{const R=v.__lunoraRef;if(typeof R!="string")throw new d("ctx.run*: expected a function reference from the generated `api`",{code:"BAD_REQUEST",status:400});const U=ye(R,E,{...w,"x-lunora-system":"1"}),x=await m(i,r,U),B=await x.json();if(B.error)throw new d(B.error.message??"shard RPC failed",{code:B.error.code??"INTERNAL",status:x.status});return B.result};return{auth:{getIdentity:()=>Promise.resolve(c),userId:b},cache:l.cache,fetch:globalThis.fetch.bind(globalThis),runAction:I,runMutation:I,runQuery:I,...u===void 0?{}:{scheduler:cn(u)},...l.waitUntil===void 0?{}:{waitUntil:l.waitUntil.bind(l)},...e.storage===void 0?{}:{storage:fr(e.storage(s))}}},un=async(o,s,l)=>{if(!e.httpRouter)return;const c=await dn(o,s,l);try{return await e.httpRouter.fetch(o,{...s,__lunoraCtx:c},l)}catch(w){return console.error("[lunora] httpRouter (SSR) handler threw:",w),new Response("Internal Server Error",{status:500})}},ln=async(o,s,l)=>{if(o.headers.get("Upgrade")!=="websocket")throw new d("WebSocket upgrade header missing",{code:"BAD_REQUEST",status:426});const c=ut(o,se);if(c)return c;const w=l.searchParams.get("shard")??r,{headers:b,identity:I}=await ce(o,s,a);await Y(I,w);const v=Nt(o,b),E=Pt(s,e.shardDO);if(E!==void 0){v.set("x-lunora-shard-binding",E);const R=await Va(i,w);if(R>0){const U=vr(w,Math.floor(Math.random()*R));return m(i,U,new Request(o,{headers:v}),lt(o))}}return m(i,w,new Request(o,{headers:v}))},hn=async(o,s,l)=>{const{voiceAgents:c}=e;if(c===void 0)return new Response("Not found",{status:404});if(o.headers.get("Upgrade")!=="websocket")return new Response("Expected a WebSocket upgrade",{headers:{allow:"GET"},status:426});const w=ut(o,se);if(w)return w;let b;try{b=decodeURIComponent(l.pathname.slice(kt.length))}catch{return new Response("Unknown voice agent",{status:404})}const I=Object.hasOwn(c,b)?c[b]:void 0;if(I===void 0)return new Response("Unknown voice agent",{status:404});const v=l.searchParams.get("threadKey");if(v===null||v.length===0)return new Response("Missing threadKey",{status:400});const{headers:E,identity:R}=await ce(o,s,a);if(e.authorizeShard){if(!await Se(e.authorizeShard({identity:R,shardKey:v})))throw new d("Forbidden shard",{code:"FORBIDDEN_SHARD",status:403})}else H("shard");const U=Nt(o,E);return m(I,v,new Request(o,{headers:U}))},fn=async(o,s,l)=>{if(e.authorizeFanOut){if(!await Se(e.authorizeFanOut(l,o.table,s)))throw new d("Forbidden fan-out",{code:"FORBIDDEN_FANOUT",status:403});return}if(s.startsWith("__lunora_relation__:"))throw new d("reverse cross-backend relation reads (`__lunora_relation__:*`) require `authorizeFanOut` to be configured on the worker",{code:"FORBIDDEN_FANOUT",status:403});if(e.authorizeShard)throw new d("Fan-out requires `authorizeFanOut` to be configured on the worker when `authorizeShard` is set",{code:"FORBIDDEN_FANOUT",status:403});H("fan-out")},Re=async(o,s)=>{if(!(!o.fanOut&&o.functionPath.startsWith("__lunora_admin__:"))){if(o.fanOut){await fn(o.fanOut,o.functionPath,s);return}await Y(s,o.shardKey??r)}},pn=(o,s,l)=>{if(e.replicaReads!==!0)return;if(e.functions===void 0){F();return}if(e.functions[s]?.kind!=="query"||l.includes($t)||l.includes(Kt))return;const c=lt(o);return c===void 0?void 0:{name:kr(l,c),region:c}},mn=async(o,s,l,c,w)=>{const b=pn(o,s,c);if(b!==void 0){const I={...w,"x-lunora-replica-read":"1",...y===void 0?{}:{"x-lunora-shard-binding":y}},v=Ir(o.headers.get("x-lunora-min-seq"));v!==void 0&&(I["x-lunora-min-seq"]=String(v));const E=await m(i,b.name,ye(s,l,I),b.region);if(E.status!==421)return E}return m(i,c,ye(s,l,w))},Ne=async(o,s,l,c,w,b)=>{const I=Date.now(),{observability:v,sampling:E}=e,R=Ge(o),{decision:U,ignoredUpstream:x,trace:B}=ea(o,{...E===void 0?{}:{sampling:E},trustInbound:t(o)});x&&n();const te={...w,"x-lunora-sample-errors":U.keepErrors?"1":"0"};ta(B,te);try{const L=await mn(o,s,l,c,te);ie(v,{...R,...vt(B),durationMs:Date.now()-I,functionPath:s,ok:L.ok,shardKey:c,...L.ok?{}:{error:{code:"SHARD_ERROR",message:`shard returned ${String(L.status)}`,status:L.status}}},b,void 0,{isTraced:B.sampled,keepErrors:U.keepErrors});const ee=new Response(L.body,{headers:L.headers,status:L.status,statusText:L.statusText});return ee.headers.set("x-lunora-shard-key",c),ee}catch(L){throw ie(v,{...R,...vt(B),...Ae(s,Date.now()-I,L,{shardKey:c})},b,void 0,{isTraced:B.sampled,keepErrors:U.keepErrors}),L}},wn=o=>{if(o.fanOut&&o.shardKey)throw new d("RPC envelope cannot set both `shardKey` and `fanOut`",{code:"BAD_REQUEST",status:400});if(!o.fanOut&&o.functionPath.startsWith("__lunora_relation__:"))throw new d("`__lunora_relation__:*` is a fan-out-only reserved RPC and cannot be dispatched to a single shard",{code:"FORBIDDEN",status:403});if(o.fanOut&&!e.queryCoordinator)throw new d("RPC envelope set `fanOut` but no `queryCoordinator` is configured on the worker",{code:"BAD_REQUEST",status:400})},gn=async(o,s,l)=>{K(o,"POST","RPC");const c=await Qa(o);Ga(s,c),wn(c);const w=await ke(o,c);if(w!==void 0)return w;const{headers:b,identity:I}=await ce(o,s,a);await Re(c,I);const v=Qe(c,e);{const E=Date.now(),{observability:R}=e,U=Ge(o),x=Ee(s,o,l&&(L=>l.waitUntil?.(L)));if(c.fanOut){const L=e.queryCoordinator;if(!L)throw new d("RPC envelope set `fanOut` but no `queryCoordinator` is configured on the worker",{code:"BAD_REQUEST",status:400});try{const ee=await L.fanOut(i,{args:c.args??{},fanOut:c.fanOut,functionPath:c.functionPath,headers:b});return ie(R,{durationMs:Date.now()-E,fanOut:{failed:ee.failed,shards:ee.ok+ee.failed,table:c.fanOut.table},functionPath:c.functionPath,...U,ok:!0},x),Response.json(ee,{headers:{"content-type":"application/json"},status:200})}catch(ee){throw ie(R,{...Ae(c.functionPath,Date.now()-E,ee,{fanOut:{table:c.fanOut.table}}),...U},x),ee}}const B=c.shardKey??r,te=()=>Ne(o,c.functionPath,c.args??{},B,b,x);return v&&e.x402Charge?e.x402Charge(o,{functionPath:c.functionPath,price:v.price},te,Fe(l)):te()}},yn=async(o,s,l)=>{K(o,"POST","RPC batch");const c=await Z(o),{calls:w}=c;if(!Array.isArray(w))throw new d("RPC batch `calls` must be an array",{code:"BAD_REQUEST",status:400});const{headers:b,identity:I}=await ce(o,s,a),v=to(w,r);for(const W of v.values())for(const V of W)if(e.functions?.[V.functionPath]?.x402)throw new d(`paid (\`.x402\`) function "${V.functionPath}" cannot be called in a batch; dispatch it individually over ${Ot}`,{code:"BAD_REQUEST",status:400});await Promise.all([...v.entries()].flatMap(([W,V])=>V.map(ne=>Re({args:ne.args,functionPath:ne.functionPath,shardKey:W},I))));const{observability:E}=e,R=Ee(s,o,l&&(W=>l.waitUntil?.(W))),U=Ge(o),x=[],B=[],te=(W,V,ne,le)=>({body:{error:{code:ne,message:le}},id:W.id,status:V}),L=(W,V,ne,le,fe)=>{for(const q of W)ie(E,fe(q),R),x.push(te(q,V,ne,le))},ee=(W,V,ne,le,fe)=>{for(const q of W){const pe=le.get(q.id)??fe,ge=pe<400;ie(E,{durationMs:ne,functionPath:q.functionPath,...U,ok:ge,shardKey:V,...ge?{}:{error:{code:"SHARD_ERROR",message:`batched call returned ${String(pe)}`,status:pe}}},R)}};await Promise.all([...v.entries()].map(async([W,V])=>{const ne=new Headers(b);ne.set("content-type","application/json");const le=new Request("https://shard.internal/rpc-batch",{body:JSON.stringify({calls:V}),headers:ne,method:"POST"}),fe=Date.now();let q;try{q=await m(i,W,le)}catch(X){const Be=Date.now()-fe,{body:ot}=Un(X,{fallbackCode:"SHARD_UNAVAILABLE",redactedMessage:"shard unavailable"});L(V,502,ot.code,ot.message,Nn=>({...Ae(Nn.functionPath,Be,X,{shardKey:W}),...U}));return}const pe=Date.now()-fe,ge=q.headers.get("x-d1-bookmark");ge&&B.push(ge);let Ue;try{Ue=await q.json()}catch{const X=`shard batch returned a non-JSON response (${String(q.status)})`;L(V,q.status,"SHARD_ERROR",X,Be=>({durationMs:pe,error:{code:"SHARD_ERROR",message:X,status:q.status},functionPath:Be.functionPath,...U,ok:!1,shardKey:W}));return}const Ce=Array.isArray(Ue.results)?Ue.results:[],In=new Map(Ce.map(X=>[X.id,X.status??q.status])),Pn=new Set(Ce.map(X=>X.id));ee(V,W,pe,In,q.status),x.push(...Ce);for(const X of V)Pn.has(X.id)||x.push(te(X,q.status,"SHARD_ERROR",`shard batch omitted result for call ${String(X.id)}`))}));const nt={"content-type":"application/json"},[rt]=B;return B.length===1&&rt!==void 0&&(nt["x-d1-bookmark"]=rt),Response.json({results:x},{headers:nt,status:200})},bn=async(o,s,l,c={},w={})=>{try{const b=l.__lunoraRef;if(typeof b!="string")throw new d("serverQuery: expected a function reference from the generated `api`",{code:"BAD_REQUEST",status:400});const{headers:I,identity:v}=await ce(o,s,a,w.context),E={args:c,functionPath:b,shardKey:w.shardKey};await Re(E,v);const R=w.shardKey??r,U=Ee(s,o,w.waitUntil),x=()=>Ne(o,b,c,R,I,U),B=Qe(E,e);return B&&e.x402Charge?await e.x402Charge(o,{functionPath:b,price:B.price},x,Fe(w.waitUntil?{waitUntil:w.waitUntil}:w.context)):await x()}catch(b){return at(b)}},et=async(o,s,l)=>{const{observability:c}=e,w=Date.now(),b=Oe(16),I=Oe(8),v=It(s);try{const E=await l();return ie(c,{durationMs:Date.now()-w,functionPath:o,ok:!0,spanId:I,traceId:b},v),E}catch(E){throw ie(c,{...Ae(o,Date.now()-w,E,{}),spanId:I,traceId:b},v),E}finally{it(c,v)}},_n=async(o,s,l)=>{_(s);const c=[],w=R=>R instanceof Error?R:new Error(String(R)),b=e.crons?.[o.cron];if(b)try{await b(o,s,l)}catch(R){c.push(w(R))}const I=await oe(o.cron,s,c,w),v=!!e.backupStore&&e.backupCron!==void 0&&e.backupCron===o.cron;if(v)try{await Jr(e,i,A(),o)}catch(R){c.push(w(R))}if(!b&&I===0&&!v){const R=[...new Set([...Object.keys(e.crons??{}),...Object.keys(e.cronJobs??{})])];console.warn(`[lunora] scheduled("${o.cron}") fired but no cron handler is registered for that expression. Registered: ${R.length===0?"(none)":R.join(", ")}. Check that \`triggers.crons\` in wrangler.jsonc matches the app's cron definitions.`)}const[E]=c;if(c.length===1&&E)throw E;if(c.length>1)throw new AggregateError(c,`scheduled("${o.cron}") had ${String(c.length)} failure(s)`)},Rn=async(o,s)=>{try{const l=o??{},c=e.adminToken??(typeof l.LUNORA_ADMIN_TOKEN=="string"?l.LUNORA_ADMIN_TOKEN:void 0);if(!c||c.length===0)return;await m(i,r,ye(xa,{outcome:s},{authorization:`Bearer ${c}`,"content-type":"application/json"}))}catch{}},En=async(o,s,l,c)=>{if(!e.authHandler)return;const w=await e.authHandler(o);if(!w)return;const b=e.authBasePath??Ba;return ja(l.pathname,b)&&c.waitUntil?.(Rn(s,w.status>=400?"fail":"ok")),w},Sn=async({args:o,env:s,functionPath:l,request:c,shardKey:w,waitUntil:b})=>{Bt(o,"REST");const I={functionPath:l,...w===void 0?{}:{shardKey:w}},{headers:v,identity:E}=await ce(c,s,a);await Re(I,E);const R=w??r,U=Ee(s,c,b),x=()=>Ne(c,l,o,R,v,U),B=Qe(I,e);return B&&e.x402Charge?e.x402Charge(c,{functionPath:l,price:B.price},x,Fe({waitUntil:b})):x()},An=zn({functions:e.functions??{},invoke:Sn,readJsonBody:Z,edgeCache:e.restEdgeCache,...e.restRateLimit?{rateLimit:e.restRateLimit}:{}}),De=e.routes!==void 0&&Object.keys(e.routes).length>0?e.routes:void 0,Tn={[Da]:o=>o.method!=="GET"&&o.method!=="HEAD"?new Response(void 0,{headers:{allow:"GET, HEAD"},status:405}):Response.json({ok:!0},{headers:{"cache-control":"no-store"}}),[Oa]:(o,s,l)=>ln(o,s,l),[Ot]:(o,s,l,c)=>gn(o,s,c),[Ta]:(o,s,l,c)=>yn(o,s,c),[va]:(o,s)=>ue(o,s),[ka]:(o,s)=>z(o,s),[Ia]:async o=>{K(o,"POST","ws-token"),M(o);const s=A();if(s===void 0)throw new d("ws-token minting requires a configured admin token",{code:"ADMIN_TOKEN_NOT_CONFIGURED",status:400});const l=await Cr(s);return Response.json(l,{headers:{"cache-control":"no-store"}})},...C,...ae,...Yt,...Xt,...Zt,...en,...tn,...nn,...rn,...on,...sn,...An,...Lr({assertAdmin:M,getAuthAdmin:()=>e.authAdmin,parsePaging:Pe,queryParameter:Ie,readJsonBody:Z})};let se=dt(e.security),tt=!1;const On=o=>{tt||(tt=!0,se=dt(e.security,o??{}))},vn=async(o,s)=>{if(!(e.adminGate===void 0||!Ua(s)))try{await Se(e.adminGate(o,We.get(o)))&&p.add(o)}catch{}},kn=async(o,s,l)=>{We.set(o,l);const c=new URL(o.url);if(o.method==="POST"||o.method==="PUT"){const v=Number(o.headers.get("content-length")??""),E=Aa[c.pathname]??Ct;if(Number.isFinite(v)&&v>E)throw new d("Body too large",{code:"PAYLOAD_TOO_LARGE",status:413})}const w=await En(o,s,c,l);if(w)return w;if(De){const v=`${o.method} ${c.pathname}`,E=De[v]??De[c.pathname];if(E)return E(o,s,l)}const b=Tn[c.pathname];if(b)return await vn(o,c.pathname),b(o,s,c,l);if(e.voiceAgents!==void 0&&c.pathname.startsWith(kt))return hn(o,s,c);const I=await un(o,s,l);return I||new Response("Not found",{status:404})};return{async fetch(o,s,l){e.passThroughOnException&&l.passThroughOnException?.(),On(s),_(s);const c=lr(o,se);if(c)return c;const w=hr(o,se);if(w)return He(w,o,se);try{const b=await kn(o,s,l);return He(b,o,se)}catch(b){return He(at(b),o,se)}finally{it(e.observability,It(l))}},async queue(o,s,l){await et(`queue:${Ka(o)}`,l,async()=>{await e.queue?.(o,s,l)})},async scheduled(o,s,l){await et(`cron:${o.cron}`,l,async()=>{await _n(o,s,l)})},serverQuery:bn}},es=e=>qt(e),ts=e=>typeof e=="function"?{fetch:e}:e,ns=e=>!!(e.crons??e.cronJobs??e.backupCron),As=(e,t)=>{const n=ts(e),r=typeof e=="object"&&typeof e.scheduled=="function"?e.scheduled:void 0,a=u=>{const h=es({...u,httpRouter:n});return r!==void 0&&!ns(u)?{...h,scheduled:async(f,m,S)=>{await r(f,m,S)}}:h};if(typeof t!="function")return a(t);const i=t;return{fetch:(u,h,f)=>a(i(h)).fetch(u,h,f),queue:(u,h,f)=>a(i(h)).queue?.(u,h,f)??Promise.resolve(),scheduled:(u,h,f)=>a(i(h)).scheduled(u,h,f),serverQuery:(u,h,f,m,S)=>a(i(h)).serverQuery(u,h,f,m,S)}},rs=(e,t)=>{if(typeof e=="function")return e(t);const n=e.shardDO??t?.SHARD;if(!n)throw new d("@lunora/runtime: no shard Durable Object namespace found. Bind `SHARD` in wrangler.jsonc, or pass `createLunoraHandler({ shardDO: env.MY_SHARD })`.");return{...e,shardDO:n}},Ts=(e={})=>(t,n,r)=>qt(rs(e,n)).fetch(t,n,r??Cn),Os=e=>e;export{jr as GET_AUTH_AUDIT_LOG_OP,Cn as NOOP_EXECUTION_CONTEXT,Is as composeIdentityResolvers,es as composeWorker,Ts as createLunoraHandler,qt as createWorker,Os as defineRpcEnvelope,Va as probeRelayCount,rs as resolveLunoraOptions,Ps as routeIdentityResolvers,As as withFrameworkWorker};
@@ -1 +1 @@
1
- import{e as c,a as u}from"./identity-header-C4Z5pldl.mjs";import{d as f}from"./wire-codec-CMVqBlcF.mjs";import{LunoraError as s}from"./LunoraError-DksAgIpa.mjs";const l="/_lunora/rpc",h=e=>{const a={"content-type":"application/json"};return e.userId!==void 0&&e.userId.length>0&&(a["x-lunora-userid"]=c(e.userId)),e.identity!==void 0&&(a["x-lunora-identity"]=u(e.identity)),a},d=async(e,a,o)=>{const t=await(e.fetch??globalThis.fetch)(new Request(`${e.origin}${l}`,{body:JSON.stringify(a),headers:h(e),method:"POST"}));if(!t.ok)throw new s(`cross-shard relation ${o} failed: worker returned ${String(t.status)}`);const r=await t.json();if(typeof r.failed=="number"&&r.failed>0){const i=(typeof r.ok=="number"?r.ok:0)+r.failed;throw new s(`cross-shard relation ${o} failed on ${String(r.failed)} of ${String(i)} shard(s) — refusing to return a partial result`)}return f(r.data)},_=e=>({crossShardCounter:async(n,t)=>{const r=await d(e,{args:{table:n,where:t},fanOut:{merge:{kind:"sum"},table:n},functionPath:"__lunora_relation__:count"},"count");return typeof r=="number"?r:0},crossShardReader:async(n,t)=>{const r=await d(e,{args:{...t,table:n},fanOut:{merge:{kind:"concat"},table:n},functionPath:"__lunora_relation__:read"},"read");return{continueCursor:null,isDone:!0,page:Array.isArray(r)?r:[]}}});export{_ as createCrossShardRelationCapabilities};
1
+ import{e as c,a as u}from"./identity-header-C4Z5pldl.mjs";import{d as f}from"./wire-codec-Du-i3W6b.mjs";import{LunoraError as s}from"./LunoraError-DksAgIpa.mjs";const l="/_lunora/rpc",h=e=>{const a={"content-type":"application/json"};return e.userId!==void 0&&e.userId.length>0&&(a["x-lunora-userid"]=c(e.userId)),e.identity!==void 0&&(a["x-lunora-identity"]=u(e.identity)),a},d=async(e,a,o)=>{const t=await(e.fetch??globalThis.fetch)(new Request(`${e.origin}${l}`,{body:JSON.stringify(a),headers:h(e),method:"POST"}));if(!t.ok)throw new s(`cross-shard relation ${o} failed: worker returned ${String(t.status)}`);const r=await t.json();if(typeof r.failed=="number"&&r.failed>0){const i=(typeof r.ok=="number"?r.ok:0)+r.failed;throw new s(`cross-shard relation ${o} failed on ${String(r.failed)} of ${String(i)} shard(s) — refusing to return a partial result`)}return f(r.data)},_=e=>({crossShardCounter:async(n,t)=>{const r=await d(e,{args:{table:n,where:t},fanOut:{merge:{kind:"sum"},table:n},functionPath:"__lunora_relation__:count"},"count");return typeof r=="number"?r:0},crossShardReader:async(n,t)=>{const r=await d(e,{args:{...t,table:n},fanOut:{merge:{kind:"concat"},table:n},functionPath:"__lunora_relation__:read"},"read");return{continueCursor:null,isDone:!0,page:Array.isArray(r)?r:[]}}});export{_ as createCrossShardRelationCapabilities};
@@ -1 +1 @@
1
- import{c as o,a as s,d as t,r as i,b as n,s as p,w as S}from"./export-tap-CGR3Xd9F.mjs";import"./portable-json-DpqTEd22.mjs";export{o as createKvCursorStore,s as createMemoryCursorStore,t as defineExportSink,i as r2Sink,n as runExportTap,p as sanitizeChange,S as webhookExportSink};
1
+ import{c as o,a as s,d as t,r as i,b as n,s as p,w as S}from"./export-tap-BLr9Lp0x.mjs";import"./portable-json-fgh98-LE.mjs";export{o as createKvCursorStore,s as createMemoryCursorStore,t as defineExportSink,i as r2Sink,n as runExportTap,p as sanitizeChange,S as webhookExportSink};
@@ -0,0 +1 @@
1
+ import{toErrorBody as v}from"@lunora/errors";import{b as E,a as I}from"./base64-Bl1_r2k1.mjs";import{LunoraError as U}from"./LunoraError-DksAgIpa.mjs";import{resolveShard as B}from"./applyJurisdiction-C0ddU7Tg.mjs";const we=r=>({listShardKeys(e){return r[e]??[]}}),F=16,D=5e3,h=r=>r!==null&&typeof r=="object"&&"result"in r?r.result:r,V=r=>{const e=r??{};return{changed:typeof e.changed=="number"?e.changed:0,processed:typeof e.processed=="number"?e.processed:0,status:typeof e.status=="string"?e.status:void 0}},L=(r,e)=>r?"failed":e?"in_progress":"completed",j=r=>{const e=[];let s=0,o=0,t=0,n=0,a=!1,c=!1;for(const i of r){if(i.kind==="err"){o+=1,e.push({error:{message:i.message,timedOut:i.timedOut},shardKey:i.shardKey});continue}s+=1;const u=h(i.value),l=V(u);t+=l.changed,n+=l.processed,a||=l.status==="in_progress",c||=l.status==="failed",e.push({result:u,shardKey:i.shardKey})}return{changed:t,failed:o,ok:s,processed:n,shards:e,status:L(c,a||o>0)}},J=r=>{const e=r??{};return{before:typeof e.before=="number"&&Number.isFinite(e.before)?e.before:0,total:typeof e.total=="number"&&Number.isFinite(e.total)?e.total:0}},$=r=>{const e=[];let s=0,o=0,t=0,n=0;for(const a of r){if(a.kind==="err"){o+=1,e.push({error:{message:a.message,timedOut:a.timedOut},shardKey:a.shardKey});continue}s+=1;const c=J(h(a.value));t+=c.before,n+=c.total,e.push({result:c,shardKey:a.shardKey})}return{failed:o,ok:s,partial:o>0,position:t+1,shards:e,total:n}},P=0,T=1,G=2,k=(r,e)=>r<e?-1:r>e?1:0,M=r=>r==null?P:typeof r=="number"?T:G,R=(r,e)=>{const s=M(r),o=M(e);return s!==o?s<o?-1:1:s===P?0:s===T?k(r,e):k(String(r),String(e))},H=(r,e,s)=>{const o=R(r.partitionKey,e.partitionKey);if(o!==0)return o;const t=Math.max(r.sortValues.length,e.sortValues.length);for(let n=0;n<t;n+=1){const a=R(r.sortValues[n],e.sortValues[n]);if(a!==0)return s[n]==="desc"?-a:a}return R(r.rowId,e.rowId)},Q=r=>I(new TextEncoder().encode(JSON.stringify(r))),Y=r=>{try{const e=JSON.parse(new TextDecoder().decode(E(r)));if(e!==null&&typeof e=="object"&&"perShard"in e){const{perShard:s}=e;if(s!==null&&typeof s=="object")return{perShard:s}}}catch{}return{perShard:{}}},W=r=>{const e=r??{},s=Array.isArray(e.rows)?e.rows:[];return{directions:Array.isArray(e.directions)?e.directions:[],hasMore:e.hasMore===!0,rows:s}},X=(r,e)=>{let s;for(const o of r){const t=o.rows[o.head];t!==void 0&&(s===void 0||H(t.key,s.row.key,e)<0)&&(s={row:t,slice:o})}return s},z=(r,e)=>{let s=!1;const o=new Set;for(const n of r)o.add(n.shardKey),(n.head<n.rows.length||n.hasMore)&&(s=!0);const t={...e};for(const n of Object.keys(e))o.has(n)||(s=!0);return s?Q({perShard:t}):null},Z=(r,e,s,o)=>{const t=[],n={...o};for(;t.length<e;){const c=X(r,s);if(c===void 0)break;t.push(c.row.doc),n[c.slice.shardKey]=c.row.key,c.slice.head+=1}const a=z(r,n);return{isDone:a===null,nextCursor:a,page:t}},q=r=>{const e=[];let s=0,o=0;for(const t of r){if(t.kind==="err"){o+=1,e.push({error:{message:t.message,timedOut:t.timedOut},shardKey:t.shardKey});continue}s+=1;const n=h(t.value),a=Array.isArray(n?.rows)?n.rows:[];e.push({rows:a,shardKey:t.shardKey})}return{failed:o,ok:s,shards:e}},ee=r=>{const e=[];let s=0,o=0;for(const{outcome:t,sinceSeq:n}of r){if(t.kind==="err"){o+=1,e.push({cursor:n,error:{message:t.message,timedOut:t.timedOut},shardKey:t.shardKey});continue}s+=1;const a=h(t.value),c=Array.isArray(a?.changes)?a.changes:[],i=typeof a?.cursor=="number"?a.cursor:n;e.push({changes:c,cursor:i,shardKey:t.shardKey})}return{failed:o,ok:s,shards:e}},re=r=>{let e=0,s=0,o=0;for(const t of r){if(t.kind==="err"){s+=1;continue}e+=1;const n=h(t.value);o+=typeof n?.applied=="number"?n.applied:0}return{applied:o,failed:s,ok:e}},te=r=>{const e=r??{};return typeof e.requests=="number"&&Number.isFinite(e.requests)&&e.requests>=0?e.requests:0},se=r=>{const e=[];let s=0,o=0;for(const t of r){if(t.kind==="err"){o+=1,e.push({requests:0,shardKey:t.shardKey});continue}s+=1,e.push({requests:te(h(t.value)),shardKey:t.shardKey})}return{failed:o,ok:s,shards:e}},oe=r=>{const e=[],s={},o=[];let t=0,n=0,a=0;for(const c of r){if(c.kind==="err"){a+=1,e.push({error:{message:c.message,timedOut:c.timedOut},shardKey:c.shardKey});continue}n+=1;const i=h(c.value),u=i?.inserted??{};for(const[f,y]of Object.entries(u))s[f]=(s[f]??0)+y;const l=i?.errors;Array.isArray(l)&&o.push(...l),t+=i?.conflicts??0,e.push({result:{conflicts:i?.conflicts??0,errors:i?.errors??[],inserted:u},shardKey:c.shardKey})}return{conflicts:t,errors:o,failed:a,inserted:s,ok:n,shards:e}},p=r=>({body:JSON.stringify({args:r.args??{},functionPath:r.functionPath}),headers:{"content-type":"application/json",...r.headers}}),g=async(r,e,s,o)=>{const t=B(r,e),n=new AbortController,a=new Request("https://shard.internal/rpc",{body:s.body,headers:s.headers,method:"POST",signal:n.signal});let c;const i=new Promise(l=>{c=setTimeout(()=>{try{n.abort()}catch{}l({code:"SHARD_TIMEOUT",kind:"err",message:`shard "${e}" timed out after ${String(o)}ms`,shardKey:e,timedOut:!0})},o)}),u=(async()=>{try{const l=await t.fetch(a);if(!l.ok)return{code:"SHARD_HTTP_ERROR",kind:"err",message:`shard "${e}" returned ${String(l.status)}`,shardKey:e,timedOut:!1};const f=await l.json();return{kind:"ok",shardKey:e,value:f}}catch(l){const{body:f}=v(l,{fallbackCode:"INTERNAL",redactedMessage:"shard call failed"});return{code:f.code,kind:"err",message:`shard "${e}" failed: ${f.message}`,shardKey:e,timedOut:!1}}})();try{return await Promise.race([u,i])}finally{c!==void 0&&clearTimeout(c)}},w=async(r,e,s)=>{if(r.length===0)return[];const o=Array.from({length:r.length});let t=0;const n=async()=>{for(;;){const c=t;t+=1;const i=r[c];if(c>=r.length||i===void 0)return;o[c]=await s(i,c)}},a=Math.min(e,r.length);return await Promise.all(Array.from({length:a},()=>n())),o},N=async(r,e)=>{const s=await Promise.all(e.map(async o=>r.listShardKeys(o)));return[...new Set(s.flat())]},O=(r,e)=>r.length>0||e===null?r:[e],m=async(r,e,s,o,t)=>{const n=p(s);return w(e,o,async a=>g(r,a,n,t))},ne=r=>{const e={};for(const s of Object.keys(r).toSorted(k))e[s]=r[s]??null;return JSON.stringify(e)},ae=r=>r.flatMap(e=>Array.isArray(e)?e:[]),ce=(r,e,s)=>{switch(s){case"max":return Math.max(r,e);case"min":return Math.min(r,e);case"sum":return r+e;default:return r}},ie=(r,e,s)=>{if(e===null||typeof e!="object")return;const o=e.key??{},t=e.value??null,n=ne(o),a=r.get(n);if(!a){r.set(n,{key:o,value:t});return}if(a.value===null){a.value=t;return}t!==null&&(a.value=ce(a.value,t,s))},ue=(r,e)=>{const s=new Map;for(const o of r)if(Array.isArray(o))for(const t of o)ie(s,t,e);return[...s.values()]},x=(r,e)=>{let s=null;for(const o of r)typeof o=="number"&&Number.isFinite(o)&&(s=s===null?o:e(s,o));return s},le=r=>{let e=0;for(const s of r)typeof s=="number"&&Number.isFinite(s)&&(e+=s);return e},de=r=>{let e=0,s=0;for(const o of r){if(o===null||typeof o!="object")continue;const t=o;typeof t.before=="number"&&Number.isFinite(t.before)&&(e+=t.before),typeof t.total=="number"&&Number.isFinite(t.total)&&(s+=t.total)}return{position:e+1,total:s}},fe=(r,e)=>{const s=[];for(const t of r)if(Array.isArray(t))for(const n of t){if(n===null||typeof n!="object")continue;const a=n[e.by],c=typeof a=="number"&&Number.isFinite(a)?a:Number.NEGATIVE_INFINITY;s.push({row:n,score:c})}const o=e.direction??"desc";return s.sort((t,n)=>o==="asc"?k(t.score,n.score):k(n.score,t.score)),s.slice(0,e.k).map(t=>t.row)},he=(r,e)=>{switch(e.kind){case"concat":return ae(r);case"first":return r[0];case"groupBy":return ue(r,e.op??"sum");case"max":return x(r,Math.max);case"min":return x(r,Math.min);case"rank":return de(r);case"sum":return le(r);case"topK":return fe(r,e);default:return r}},ke=r=>{const e=r.maxConcurrency??F,s=r.perShardTimeoutMs??D;if(e<1)throw new U("maxConcurrency must be >= 1",{code:"BAD_REQUEST",status:400});return{async fanOut(o,t){const n=await r.registry.listShardKeys(t.fanOut.table),a=await m(o,n,t,e,s),c=[],i=[];for(const u of a)u.kind==="ok"?c.push(u.value):i.push({code:u.code,message:u.message,shardKey:u.shardKey,timedOut:u.timedOut});return{data:he(c,t.fanOut.merge),errors:i,failed:i.length,ok:c.length}},async orchestrateExport(o,t){const n=await N(r.registry,t.tables),a=O(n,t.defaultShardKey),c={args:{...t.args,tables:[...t.tables]},functionPath:"__lunora_admin__:exportShard",headers:t.headers},i=await m(o,a,c,e,s);return q(i)},async orchestrateCdcSync(o,t){const n=O(await N(r.registry,t.tables),t.defaultShardKey),a=t.cursors??{},c=await w(n,e,async i=>{const u=a[i]??0;return{outcome:await g(o,i,p({args:{limit:t.limit,sinceSeq:u},functionPath:"__lunora_admin__:cdcSync",headers:t.headers}),s),sinceSeq:u}});return ee(c)},async orchestrateImport(o,t){const{batches:n}=t,a=await w(n,e,async c=>g(o,c.shardKey,p({args:{rows:[...c.rows],startLine:c.startLine??1},functionPath:"__lunora_admin__:importShard",headers:t.headers}),s));return oe(a)},async orchestrateApplyCdc(o,t){const{batches:n}=t,a=await w(n,e,async c=>g(o,c.shardKey,p({args:{changes:[...c.changes]},functionPath:"__lunora_admin__:applyCdc",headers:t.headers}),s));return re(a)},async orchestrateMigration(o,t){const n=O(await r.registry.listShardKeys(t.table),t.defaultShardKey),a=await m(o,n,t,e,s);return j(a)},async orchestrateRank(o,t){const n=await r.registry.listShardKeys(t.table),a={args:{index:t.index,partitionKey:t.partitionKey,rowId:t.rowId,sortValues:[...t.sortValues],table:t.table},functionPath:"__lunora_admin__:rankBefore",headers:t.headers},c=await m(o,n,a,e,s);return $(c)},async orchestrateRankPage(o,t){const n=await r.registry.listShardKeys(t.table),a=Math.max(1,Math.min(1e3,Math.floor(t.take??100))),c=t.directions??[],i=t.cursor?Y(t.cursor):{perShard:{}},u=await w(n,e,async d=>{const C=i.perShard[d],_={index:t.index,table:t.table,take:a};t.partitionKey!==void 0&&(_.partitionKey=t.partitionKey),C!==void 0&&(_.after=C);const b=await g(o,d,p({args:_,functionPath:"__lunora_admin__:rankPage",headers:t.headers}),s);if(b.kind==="err")return{error:{message:b.message,timedOut:b.timedOut},shardKey:d};const A=W(h(b.value));return{directions:A.directions,hasMore:A.hasMore,rows:A.rows,shardKey:d}}),l=[];let f=0,y=0,S;for(const d of u){if(d.error){y+=1;continue}f+=1,S===void 0&&d.directions&&d.directions.length>0&&(S=d.directions),l.push({hasMore:d.hasMore??!1,head:0,rows:d.rows??[],shardKey:d.shardKey})}const K=Z(l,a,S??c,i.perShard);return{continueCursor:K.nextCursor,failed:y,isDone:K.isDone,ok:f,page:K.page,partial:y>0,shards:u}},async orchestrateShardTraffic(o,t){const n=await r.registry.listShardKeys(t.table),a={functionPath:"__lunora_admin__:getMetrics",headers:t.headers},c=await m(o,n,a,e,s);return se(c)},registry:r.registry}};export{ke as createQueryCoordinator,we as createStaticShardRegistry};
@@ -1 +1 @@
1
- import{LunoraError as n}from"@lunora/errors";import{e as S,a as w}from"./identity-header-C4Z5pldl.mjs";import{e as g,d as f}from"./wire-codec-CMVqBlcF.mjs";import{applyJurisdiction as p,resolveShard as N}from"./applyJurisdiction-C0ddU7Tg.mjs";const I=e=>{if(typeof e=="string")return e;const t=e?.__lunoraRef;if(typeof t!="string"||t.length===0)throw new n("INTERNAL","createShardClient: expected a generated function reference (api.*/internal.*) or a 'namespace:fn' string");return t},x=e=>{const t=new n(e.code,e.message);return e.data!==void 0&&(t.data=f(e.data)),t},$=(e,t={})=>{const l=p(e,t.jurisdiction),m=t.system??!0,c=r=>$(e,{...t,...r});return{as:r=>c({as:r}),asSystem:()=>c({as:void 0}),call:async(r,y,o)=>{const d=I(r),h=o?.shardKey??t.shardKey;if(h===void 0||h.length===0)throw new n("INTERNAL",`createShardClient: no shard key for "${d}" — pass one to createShardClient({ shardKey }), .forShard(key), or the call's options`);const s={"content-type":"application/json"};m&&(s["x-lunora-system"]="1"),t.as&&(s["x-lunora-userid"]=S(t.as.userId),t.as.claims&&(s["x-lunora-identity"]=w(t.as.claims))),o?.mutationId!==void 0&&o.mutationId.length>0&&(s["x-lunora-mutation-id"]=o.mutationId);const a=await N(l,h).fetch(new Request("https://shard.internal/rpc",{body:JSON.stringify({args:g(y??{}),functionPath:d}),headers:s,method:"POST"})),u=a.statusText?` ${a.statusText}`:"";let i;try{i=await a.json()}catch{throw new n("INTERNAL",`createShardClient: shard response for "${d}" was not JSON (status ${String(a.status)}${u})`)}if("error"in i)throw x(i.error);if(!a.ok)throw new n("INTERNAL",`createShardClient: shard call "${d}" failed (status ${String(a.status)}${u})`);return f(i.result)},forShard:r=>c({shardKey:r})}};export{$ as createShardClient};
1
+ import{LunoraError as n}from"@lunora/errors";import{e as S,a as w}from"./identity-header-C4Z5pldl.mjs";import{e as g,d as f}from"./wire-codec-Du-i3W6b.mjs";import{applyJurisdiction as p,resolveShard as N}from"./applyJurisdiction-C0ddU7Tg.mjs";const I=e=>{if(typeof e=="string")return e;const t=e?.__lunoraRef;if(typeof t!="string"||t.length===0)throw new n("INTERNAL","createShardClient: expected a generated function reference (api.*/internal.*) or a 'namespace:fn' string");return t},x=e=>{const t=new n(e.code,e.message);return e.data!==void 0&&(t.data=f(e.data)),t},$=(e,t={})=>{const l=p(e,t.jurisdiction),m=t.system??!0,c=r=>$(e,{...t,...r});return{as:r=>c({as:r}),asSystem:()=>c({as:void 0}),call:async(r,y,o)=>{const d=I(r),h=o?.shardKey??t.shardKey;if(h===void 0||h.length===0)throw new n("INTERNAL",`createShardClient: no shard key for "${d}" — pass one to createShardClient({ shardKey }), .forShard(key), or the call's options`);const s={"content-type":"application/json"};m&&(s["x-lunora-system"]="1"),t.as&&(s["x-lunora-userid"]=S(t.as.userId),t.as.claims&&(s["x-lunora-identity"]=w(t.as.claims))),o?.mutationId!==void 0&&o.mutationId.length>0&&(s["x-lunora-mutation-id"]=o.mutationId);const a=await N(l,h).fetch(new Request("https://shard.internal/rpc",{body:JSON.stringify({args:g(y??{}),functionPath:d}),headers:s,method:"POST"})),u=a.statusText?` ${a.statusText}`:"";let i;try{i=await a.json()}catch{throw new n("INTERNAL",`createShardClient: shard response for "${d}" was not JSON (status ${String(a.status)}${u})`)}if("error"in i)throw x(i.error);if(!a.ok)throw new n("INTERNAL",`createShardClient: shard call "${d}" failed (status ${String(a.status)}${u})`);return f(i.result)},forShard:r=>c({shardKey:r})}};export{$ as createShardClient};
@@ -0,0 +1 @@
1
+ import{LunoraError as O}from"./LunoraError-DksAgIpa.mjs";const E=new Set(["0","disabled","false","no","off"]),y=new Set(["1","enabled","on","true","yes"]),d=e=>typeof e=="string"&&E.has(e.trim().toLowerCase()),S=e=>typeof e=="string"&&y.has(e.trim().toLowerCase()),L="default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'",A=e=>{const o=["base-uri 'none'","object-src 'none'"];return e==="DENY"?o.push("frame-ancestors 'none'"):e==="SAMEORIGIN"&&o.push("frame-ancestors 'self'"),o.join("; ")},b="accelerometer=(), autoplay=(), camera=(), display-capture=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()",u=["Authorization","Content-Type","X-D1-Bookmark","X-Lunora-Client-Id","X-Lunora-Client-Seq","X-Lunora-Min-Seq","X-Lunora-Mutation-Id"],f=["DELETE","GET","HEAD","PATCH","POST","PUT"],C=31536e3,v=new Set(["GET","HEAD","OPTIONS"]),R=e=>{if(e===!1)return;const o=e===void 0||e===!0?{}:e,s=o.maxAge??C,r=o.includeSubDomains??!0;return`max-age=${String(s)}${r?"; includeSubDomains":""}${o.preload?"; preload":""}`},D=(e,o)=>{if(e!==!1)return typeof e=="string"?{htmlValue:e,value:e}:{htmlValue:o,value:L}},_=e=>{if(e===!1)return{coop:void 0,csp:void 0,enabled:!1,frameOptions:void 0,hsts:void 0,permissionsPolicy:void 0,referrerPolicy:void 0};const o=e===void 0||e===!0?{}:e,s=o.frameOptions===!1?void 0:o.frameOptions??"SAMEORIGIN";return{coop:"same-origin",csp:D(o.csp,A(s)),enabled:!0,frameOptions:s,hsts:R(o.hsts),permissionsPolicy:o.permissionsPolicy===!1?void 0:o.permissionsPolicy??b,referrerPolicy:o.referrerPolicy===!1?void 0:o.referrerPolicy??"strict-origin-when-cross-origin"}},N=e=>{const o={allowCredentials:!1,allowedHeaders:u,allowedMethods:f,enabled:!1,isAllowed:()=>!1,isExplicitlyAllowed:()=>!1,maxAge:600};if(e===void 0||e===!1)return o;const s=e.allowCredentials??!1,r=e.allowedOrigins;let t,n;if(typeof r=="function"){const a=m=>r(m)===!0;t=a,n=a,console.warn(`@lunora/runtime: security.cors uses a custom \`allowedOrigins\` predicate. It is trusted by the CSRF and WebSocket origin checks${s?" AND reflects matching origins with credentials (`allowCredentials: true`)":""} — ensure it matches ONLY trusted origins by exact equality; an over-broad predicate (e.g. \`() => true\`, or \`endsWith\`/\`includes\` checks) defeats the allowlist.`)}else{const a=r;if(a.includes("*")&&s)throw new O('@lunora/runtime: security.cors cannot combine a wildcard origin ("*") with allowCredentials: true — browsers reject it and it defeats the allowlist.');t=i=>a.includes("*")||a.includes(i),n=i=>a.includes(i)}return{allowCredentials:s,allowedHeaders:e.allowedHeaders??u,allowedMethods:e.allowedMethods??f,enabled:!0,isAllowed:t,isExplicitlyAllowed:n,maxAge:e.maxAge??600}},H=e=>{if(e===!1)return{allowLoopback:!1,enabled:!1,trustedOrigins:[]};const o=e===void 0||e===!0?{}:e;return{allowLoopback:o.allowLoopback??!0,enabled:!0,trustedOrigins:o.trustedOrigins??[]}},I=e=>{const o=e?.LUNORA_ALLOWED_ORIGINS;if(typeof o!="string")return;const s=o.split(",").map(n=>n.trim()).filter(n=>n.length>0);return s.length===0?void 0:{allowCredentials:!s.includes("*")&&S(e?.LUNORA_CORS_ALLOW_CREDENTIALS),allowedOrigins:s}},j=(e,o)=>{const s=e?.headers??(d(o?.LUNORA_SECURITY_HEADERS)?!1:void 0),r=e?.csrf??(d(o?.LUNORA_SECURITY_CSRF)?!1:void 0),t=e?.cors??I(o);return{cors:N(t),csrf:H(r),headers:_(s)}},P=new Set(["127.0.0.1","::1","[::1]","localhost"]),p=e=>{try{return P.has(new URL(e).hostname)}catch{return!1}},c=e=>{if(e)try{return new URL(e).origin}catch{return}},w=(e,o,s)=>e===o||s.csrf.trustedOrigins.includes(e)||s.csrf.allowLoopback&&p(o)&&p(e)?!0:s.cors.enabled&&s.cors.isExplicitlyAllowed(e),h=(e,o,s)=>Response.json({error:{code:"FORBIDDEN_ORIGIN",expectedOrigin:s,message:`${e} rejected: Origin ${o===void 0?"was missing":`"${o}"`} is not trusted (this worker serves "${s}"). Add it to \`security.csrf.trustedOrigins\` (or LUNORA_ALLOWED_ORIGINS) if it is yours. Behind a dev proxy this usually means the proxy rewrote the host: keep both ends on loopback, or list the dev-server origin.`,receivedOrigin:o}},{headers:{"content-type":"application/json"},status:403}),F=(e,o)=>{if(!o.csrf.enabled||v.has(e.method)||!e.headers.get("cookie"))return;const s=new URL(e.url).origin,r=c(e.headers.get("origin"))??c(e.headers.get("referer"));if(!(r!==void 0&&w(r,s,o)))return h("cross-origin state-changing request",r,s)},X=(e,o)=>{if(!o.csrf.enabled||!e.headers.get("cookie"))return;const s=new URL(e.url).origin,r=c(e.headers.get("origin"));if(!(r!==void 0&&w(r,s,o)))return h("cross-origin websocket upgrade",r,s)},T=["X-D1-Bookmark","X-Lunora-Edge-Cache","X-Lunora-Shard-Key"],g=(e,o)=>{const s=new Headers;return s.set("access-control-allow-origin",e),s.set("access-control-expose-headers",T.join(", ")),s.append("vary","Origin"),o.allowCredentials&&s.set("access-control-allow-credentials","true"),s},B=(e,o)=>{if(!o.cors.enabled||e.method!=="OPTIONS")return;const s=e.headers.get("origin");if(!s||!e.headers.get("access-control-request-method")||!o.cors.isAllowed(s))return;const r=g(s,o.cors),t=e.headers.get("access-control-request-headers");r.set("access-control-allow-methods",o.cors.allowedMethods.join(", "));let n;if(t===null)n=o.cors.allowedHeaders.join(", ");else{const a=new Set(o.cors.allowedHeaders.map(i=>i.toLowerCase()));n=t.split(",").map(i=>i.trim()).filter(i=>i.length>0&&a.has(i.toLowerCase())).join(", ")}return r.set("access-control-allow-headers",n),r.set("access-control-max-age",String(o.cors.maxAge)),new Response(null,{headers:r,status:204})},x=e=>(e.headers.get("content-type")??"").toLowerCase().includes("text/html"),l=(e,o,s)=>{e.has(o)||e.set(o,s)},k=(e,o,s,r)=>{if(r.hsts!==void 0&&new URL(o.url).protocol==="https:"&&l(e,"strict-transport-security",r.hsts),l(e,"x-content-type-options","nosniff"),r.frameOptions!==void 0&&l(e,"x-frame-options",r.frameOptions),r.referrerPolicy!==void 0&&l(e,"referrer-policy",r.referrerPolicy),r.permissionsPolicy!==void 0&&l(e,"permissions-policy",r.permissionsPolicy),r.coop!==void 0&&l(e,"cross-origin-opener-policy",r.coop),r.csp!==void 0){const t=x(s)?r.csp.htmlValue:r.csp.value;t!==void 0&&l(e,"content-security-policy",t)}},U=(e,o,s)=>{const r=o.headers.get("origin");if(!(!r||!s.isAllowed(r)))for(const[t,n]of g(r,s).entries())t==="vary"?e.append("vary",n):l(e,t,n)},V=(e,o,s)=>{if(e.status===101||e.webSocket)return e;const r=new Headers(e.headers);return s.headers.enabled&&k(r,o,e,s.headers),s.cors.enabled&&U(r,o,s.cors),new Response(e.body,{headers:r,status:e.status,statusText:e.statusText})};export{V as decorateResponse,F as enforceOrigin,X as enforceWebSocketOrigin,B as handleCorsPreflight,j as resolveSecurity};
@@ -0,0 +1 @@
1
+ import{e as a,a as s,f}from"./observability-B1hLjwgx.mjs";export{a as emitLogEvent,s as emitRpcEvent,f as flushSink};
@@ -1,3 +1,3 @@
1
- import{f as K,t as j}from"./base64-Bl1_r2k1.mjs";import{t as O}from"./portable-json-DpqTEd22.mjs";const N=new TextEncoder,q=e=>j(N.encode(JSON.stringify(e))),B=e=>{const r={g:0,s:{},v:1};if(typeof e!="string"||e.length===0)return r;try{const t=JSON.parse(new TextDecoder().decode(K(e))),o=t.s&&typeof t.s=="object"?t.s:{},s={};for(const[i,n]of Object.entries(o))typeof n=="number"&&Number.isFinite(n)&&(s[i]=n);return{g:typeof t.g=="number"&&Number.isFinite(t.g)?t.g:0,s,v:1}}catch{return r}},P=e=>{const r=typeof e.table=="string"?e.table:"",t=typeof e.op=="string"?e.op:"",o=t==="delete"||t==="insert"||t==="update"?t:"upsert",s=typeof e.id=="string"?e.id:void 0;return{doc:(e.doc&&typeof e.doc=="object"?e.doc:void 0)??(s===void 0?{}:{_id:s}),op:o,table:r}},M=e=>Math.max(1,Math.min(e??1e3,1e4)),D=(e,r,t)=>{for(const o of r)e.push(P(o));return t!==void 0&&r.length>=t},R=e=>new Promise(r=>{setTimeout(r,e)}),$=e=>{const r=typeof e.table=="string"?e.table:"",t=typeof e.op=="string"?e.op:"",o=t==="delete"||t==="insert"||t==="update"?t:"upsert",s=typeof e.id=="string"?e.id:void 0,i=e.doc&&typeof e.doc=="object"?O(e.doc):void 0,n=typeof e.seq=="number"&&Number.isFinite(e.seq)?e.seq:void 0,c=typeof e.ts=="number"&&Number.isFinite(e.ts)?e.ts:void 0;return{op:o,table:r,...i===void 0?{}:{doc:i},...s===void 0?{}:{id:s},...n===void 0?{}:{seq:n},...c===void 0?{}:{ts:c}}},T=async(e,r,t,o,s,i)=>{let n=0;for(;;)try{await e.deliver(r);return}catch(c){if(n>=t)throw c instanceof Error?c:new Error(String(c));const d=Math.min(o*2**n,s);await i(d),n+=1}},I=async e=>{const{coordinator:r,cursorStore:t,defaultShardKey:o,headers:s,initialBackoffMs:i=100,limit:n,maxBackoffMs:c=5e3,maxRetries:d=3,shardDO:S,sink:p,sleep:k=R,tables:C}=e,h=await t.read(p.name),b=await r.orchestrateCdcSync(S,{cursors:h,defaultShardKey:o,headers:s,limit:n,tables:C}),l={...h},m=[];let v=0,f=!1;for(const a of b.shards){if(a.error){m.push({error:a.error.message,shardKey:a.shardKey}),f=!0;continue}const y=a.changes??[];if(y.length===0){l[a.shardKey]=a.cursor;continue}const g=y.map(u=>$(u)),E={changes:g,cursor:a.cursor,shardKey:a.shardKey,sink:p.name};try{await T(p,E,d,i,c,k),l[a.shardKey]=a.cursor,v+=g.length,y.length>=M(n)&&(f=!0)}catch(u){m.push({error:u instanceof Error?u.message:String(u),shardKey:a.shardKey}),f=!0}}return await t.write(p.name,l),{cursors:l,delivered:v,failures:m,hasMore:f,shards:b.shards.length}},x=e=>{if(typeof e.name!="string"||e.name.length===0)throw new Error("defineExportSink: `name` must be a non-empty string");if(typeof e.deliver!="function")throw new TypeError("defineExportSink: `deliver` must be a function");return{deliver:e.deliver,name:e.name}},w=e=>`${e.map(r=>JSON.stringify(r)).join(`
1
+ import{f as K,t as j}from"./base64-Bl1_r2k1.mjs";import{t as O}from"./portable-json-fgh98-LE.mjs";const N=new TextEncoder,q=e=>j(N.encode(JSON.stringify(e))),B=e=>{const r={g:0,s:{},v:1};if(typeof e!="string"||e.length===0)return r;try{const t=JSON.parse(new TextDecoder().decode(K(e))),o=t.s&&typeof t.s=="object"?t.s:{},s={};for(const[i,n]of Object.entries(o))typeof n=="number"&&Number.isFinite(n)&&(s[i]=n);return{g:typeof t.g=="number"&&Number.isFinite(t.g)?t.g:0,s,v:1}}catch{return r}},P=e=>{const r=typeof e.table=="string"?e.table:"",t=typeof e.op=="string"?e.op:"",o=t==="delete"||t==="insert"||t==="update"?t:"upsert",s=typeof e.id=="string"?e.id:void 0;return{doc:(e.doc&&typeof e.doc=="object"?e.doc:void 0)??(s===void 0?{}:{_id:s}),op:o,table:r}},M=e=>Math.max(1,Math.min(e??1e3,1e4)),D=(e,r,t)=>{for(const o of r)e.push(P(o));return t!==void 0&&r.length>=t},R=e=>new Promise(r=>{setTimeout(r,e)}),$=e=>{const r=typeof e.table=="string"?e.table:"",t=typeof e.op=="string"?e.op:"",o=t==="delete"||t==="insert"||t==="update"?t:"upsert",s=typeof e.id=="string"?e.id:void 0,i=e.doc&&typeof e.doc=="object"?O(e.doc):void 0,n=typeof e.seq=="number"&&Number.isFinite(e.seq)?e.seq:void 0,c=typeof e.ts=="number"&&Number.isFinite(e.ts)?e.ts:void 0;return{op:o,table:r,...i===void 0?{}:{doc:i},...s===void 0?{}:{id:s},...n===void 0?{}:{seq:n},...c===void 0?{}:{ts:c}}},T=async(e,r,t,o,s,i)=>{let n=0;for(;;)try{await e.deliver(r);return}catch(c){if(n>=t)throw c instanceof Error?c:new Error(String(c));const d=Math.min(o*2**n,s);await i(d),n+=1}},I=async e=>{const{coordinator:r,cursorStore:t,defaultShardKey:o,headers:s,initialBackoffMs:i=100,limit:n,maxBackoffMs:c=5e3,maxRetries:d=3,shardDO:S,sink:p,sleep:k=R,tables:C}=e,h=await t.read(p.name),b=await r.orchestrateCdcSync(S,{cursors:h,defaultShardKey:o,headers:s,limit:n,tables:C}),l={...h},m=[];let v=0,f=!1;for(const a of b.shards){if(a.error){m.push({error:a.error.message,shardKey:a.shardKey}),f=!0;continue}const y=a.changes??[];if(y.length===0){l[a.shardKey]=a.cursor;continue}const g=y.map(u=>$(u)),E={changes:g,cursor:a.cursor,shardKey:a.shardKey,sink:p.name};try{await T(p,E,d,i,c,k),l[a.shardKey]=a.cursor,v+=g.length,y.length>=M(n)&&(f=!0)}catch(u){m.push({error:u instanceof Error?u.message:String(u),shardKey:a.shardKey}),f=!0}}return await t.write(p.name,l),{cursors:l,delivered:v,failures:m,hasMore:f,shards:b.shards.length}},x=e=>{if(typeof e.name!="string"||e.name.length===0)throw new Error("defineExportSink: `name` must be a non-empty string");if(typeof e.deliver!="function")throw new TypeError("defineExportSink: `deliver` must be a function");return{deliver:e.deliver,name:e.name}},w=e=>`${e.map(r=>JSON.stringify(r)).join(`
2
2
  `)}
3
3
  `,J=e=>{const r=e.fetchImpl??((t,o)=>fetch(t,o));return x({deliver:async t=>{const o=await r(e.url,{body:w(t.changes),headers:{"content-type":"application/x-ndjson","x-lunora-cursor":String(t.cursor),"x-lunora-shard":t.shardKey,"x-lunora-sink":t.sink,...e.headers},method:"POST"});if(!o.ok)throw new Error(`webhook export sink "${e.name}" returned ${String(o.status)}`)},name:e.name})},U=e=>{let r=e.prefix??"cdc";for(;r.endsWith("/");)r=r.slice(0,-1);return x({deliver:async t=>{const o=`${r}/${t.shardKey}/${String(t.cursor)}.ndjson`;await e.bucket.put(o,w(t.changes),{httpMetadata:{contentType:"application/x-ndjson"}})},name:e.name})},z=()=>{const e={};return{read:r=>Promise.resolve({...e[r]}),snapshot:()=>structuredClone(e),write:(r,t)=>(e[r]={...t},Promise.resolve())}},W=(e,r)=>{const t=r?.keyPrefix??"__lunora_source_cursor:export",o=s=>`${t}:${s}`;return{read:async s=>{const i=await e.get(o(s),"json");if(i===null||typeof i!="object")return{};const n={};for(const[c,d]of Object.entries(i))typeof d=="number"&&Number.isFinite(d)&&(n[c]=d);return n},write:async(s,i)=>{await e.put(o(s),JSON.stringify(i))}}};export{z as a,I as b,W as c,x as d,B as e,D as f,q as g,M as h,U as r,$ as s,J as w};
@@ -0,0 +1 @@
1
+ const n=t=>{const r=Number.parseInt(t.slice(-8),16);return Number.isFinite(r)?r/4294967296:0},a=(t,r=1)=>r>=1?!0:r<=0?!1:n(t)<r,u=(t,r)=>({isTraced:a(r,t?.headRate??1),keepErrors:t?.alwaysSampleErrors??!0}),E=(t,r)=>t.isTraced||t.keepErrors&&r,i=(t,r,e,o,s)=>{if(!t?.onRpc)return;const c=s??(o!==void 0&&r.traceId!==void 0?u(o,r.traceId):void 0);if(!(c!==void 0&&!E(c,!r.ok)))try{t.onRpc(r,e)}catch{}},T=(t,r,e)=>{if(t?.onLog)try{t.onLog(r,e)}catch{}},A=(t,r)=>{if(t?.flush)try{t.flush(r)}catch{}};export{i as a,T as e,A as f,u as r};
@@ -1 +1 @@
1
- import{a as i}from"./base64-Bl1_r2k1.mjs";import{d as f,i as s}from"./wire-codec-CMVqBlcF.mjs";const o=r=>{if(typeof r=="bigint")return r.toString();if(r instanceof ArrayBuffer)return i(new Uint8Array(r));if(ArrayBuffer.isView(r))return i(new Uint8Array(r.buffer,r.byteOffset,r.byteLength));if(Array.isArray(r))return r.map(t=>o(t));if(s(r)){const t={};for(const e of Object.keys(r)){const n=o(r[e]);e==="__proto__"?Object.defineProperty(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n}return t}return r},y=r=>o(f(r));export{y as t};
1
+ import{a as i}from"./base64-Bl1_r2k1.mjs";import{d as f,i as s}from"./wire-codec-Du-i3W6b.mjs";const o=r=>{if(typeof r=="bigint")return r.toString();if(r instanceof ArrayBuffer)return i(new Uint8Array(r));if(ArrayBuffer.isView(r))return i(new Uint8Array(r.buffer,r.byteOffset,r.byteLength));if(Array.isArray(r))return r.map(t=>o(t));if(s(r)){const t={};for(const e of Object.keys(r)){const n=o(r[e]);e==="__proto__"?Object.defineProperty(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n}return t}return r},y=r=>o(f(r));export{y as t};
@@ -1 +1 @@
1
- import{t as b}from"./portable-json-DpqTEd22.mjs";const p="_id",f=(t,n=p)=>{const o=Object.create(null),s=Object.create(null),c=Object.create(null),a=Object.create(null),h=e=>typeof n=="string"?n:n[e]??p,l=(e,r)=>{const u=e[r];if(u)return u;const d=[];return e[r]=d,d};for(const e of t.changes){a[e.table]??={primary_key:[h(e.table)]};const r=b(e.doc);e.op==="delete"?l(c,e.table).push(r):e.op==="update"?l(s,e.table).push(r):l(o,e.table).push(r)}return{delete:c,hasMore:t.hasMore,insert:o,schema:a,state:{cursor:t.nextCursor},update:s}},m=(t,n=Date.now())=>{const o=[];for(const s of t.changes){const c=b(s.doc),a=s.op==="delete"?{...c,_lunora_deleted:!0}:c;o.push({record:{data:a,emitted_at:n,stream:s.table},type:"RECORD"})}return o.push({state:{data:{cursor:t.nextCursor}},type:"STATE"}),o};export{m as toAirbyteMessages,f as toFivetranResponse};
1
+ import{t as b}from"./portable-json-fgh98-LE.mjs";const p="_id",f=(t,n=p)=>{const o=Object.create(null),s=Object.create(null),c=Object.create(null),a=Object.create(null),h=e=>typeof n=="string"?n:n[e]??p,l=(e,r)=>{const u=e[r];if(u)return u;const d=[];return e[r]=d,d};for(const e of t.changes){a[e.table]??={primary_key:[h(e.table)]};const r=b(e.doc);e.op==="delete"?l(c,e.table).push(r):e.op==="update"?l(s,e.table).push(r):l(o,e.table).push(r)}return{delete:c,hasMore:t.hasMore,insert:o,schema:a,state:{cursor:t.nextCursor},update:s}},m=(t,n=Date.now())=>{const o=[];for(const s of t.changes){const c=b(s.doc),a=s.op==="delete"?{...c,_lunora_deleted:!0}:c;o.push({record:{data:a,emitted_at:n,stream:s.table},type:"RECORD"})}return o.push({state:{data:{cursor:t.nextCursor}},type:"STATE"}),o};export{m as toAirbyteMessages,f as toFivetranResponse};
@@ -0,0 +1 @@
1
+ import{a as d,b as E}from"./base64-Bl1_r2k1.mjs";const o="$lunora.wire$",w=64,p=1024,g="__proto__",A={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},l={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},O=e=>{if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype},a=(e,t=0)=>{if(t>w)throw new RangeError(`wire-codec: value nesting exceeds the ${w}-level limit`);if(e===void 0)return[o,"undefined"];if(e===null)return null;const y=typeof e;if(y==="bigint")return[o,"bigint",e.toString()];if(y==="number"){const r=e;return Number.isNaN(r)?[o,"nan"]:r===1/0?[o,"inf"]:r===-1/0?[o,"-inf"]:r}if(y!=="object")return e;if(e instanceof Date)return[o,"date",a(e.getTime(),t+1)];if(e instanceof Error){const r=e,n={};for(const c of Object.keys(r))r[c]!==void 0&&(n[c]=a(r[c],t+1));const i=[o,"error",r.name,r.message,n];return r.cause!==void 0&&i.push(a(r.cause,t+1)),i}if(e instanceof URL)return[o,"url",e.href];if(e instanceof Map)return[o,"map",[...e.entries()].map(([r,n])=>[a(r,t+1),a(n,t+1)])];if(e instanceof Set)return[o,"set",[...e].map(r=>a(r,t+1))];if(e instanceof ArrayBuffer)return[o,"bytes",d(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const r=e,n=r.constructor.name,i=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);return n==="Uint8Array"?[o,"bytes",d(i)]:[o,"bytes",d(i),n]}if(Array.isArray(e)){const r=e.map(n=>a(n,t+1));return r.length>0&&r[0]===o?[o,"arr",r]:r}if(!O(e)){const r=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${r} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const u=e,s={};for(const r of Object.keys(u)){const n=u[r];if(n===void 0)continue;const i=a(n,t+1);r===g?Object.defineProperty(s,r,{configurable:!0,enumerable:!0,value:i,writable:!0}):s[r]=i}return s},f=(e,t=0)=>{if(t>w)throw new RangeError(`wire-codec: value nesting exceeds the ${w}-level limit`);if(e===null||typeof e!="object")return e;if(Array.isArray(e)){if(e[0]===o)switch(e[1]){case"-inf":return-1/0;case"arr":return e[2].map(r=>f(r,t+1));case"bigint":{const r=e[2];if(typeof r!="string"||r.length>p||!/^-?\d+$/.test(r))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${p} digits)`);return BigInt(r)}case"date":{if(e.length<3)throw new TypeError("wire-codec: malformed date — missing payload");return new Date(f(e[2],t+1))}case"map":{const r=e[2];return new Map(r.map(n=>{if(!Array.isArray(n)||n.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[f(n[0],t+1),f(n[1],t+1)]}))}case"set":return new Set(e[2].map(r=>f(r,t+1)));case"url":return new URL(e[2]);case"error":{const r=e[2],n=e[3],i=(Object.hasOwn(l,r)?l[r]:void 0)??Error,c=new i(n);c.name!==r&&Object.defineProperty(c,"name",{configurable:!0,value:r,writable:!0});const b=f(e[4],t+1);if(b===null||typeof b!="object"||Array.isArray(b))throw new TypeError("wire-codec: malformed error — props must be an object");for(const m of Object.keys(b))m===g?Object.defineProperty(c,m,{configurable:!0,enumerable:!0,value:b[m],writable:!0}):c[m]=b[m];return e.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:f(e[5],t+1),writable:!0}),c}case"bytes":{const r=E(e[2]),n=e[3]??"Uint8Array";if(n==="ArrayBuffer")return r.buffer.byteLength===r.byteLength?r.buffer:r.slice().buffer;const i=Object.hasOwn(A,n)?A[n]:void 0;return i?new i(r.slice().buffer):r}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return e.map(r=>f(r,t+1))}return e.map(s=>f(s,t+1))}const y=e,u={};for(const s of Object.keys(y)){const r=f(y[s],t+1);s===g?Object.defineProperty(u,s,{configurable:!0,enumerable:!0,value:r,writable:!0}):u[s]=r}return u};export{f as d,a as e,O as i};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/runtime",
3
- "version": "1.0.0-alpha.87",
3
+ "version": "1.0.0-alpha.89",
4
4
  "description": "Lunora Worker runtime: the RPC router, shard resolver, and query coordinator",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,9 +46,10 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/bindings": "1.0.0-alpha.45",
50
- "@lunora/errors": "1.0.0-alpha.28",
51
- "@lunora/platform": "1.0.0-alpha.23"
49
+ "@lunora/bindings": "1.0.0-alpha.47",
50
+ "@lunora/errors": "1.0.0-alpha.30",
51
+ "@lunora/observability": "1.0.0-alpha.54",
52
+ "@lunora/platform": "1.0.0-alpha.25"
52
53
  },
53
54
  "peerDependencies": {
54
55
  "@lunora/shard-engine": ">=1.0.0-alpha.24 <2.0.0-0",
@@ -1 +0,0 @@
1
- import{e as p,L as y,o as x,c as S,O as $,f as X,g as q,h as J,w as G,i as Y,j as Z,m as Q}from"./otlp-resource-DeXhb949.mjs";const v=r=>{if(typeof r=="string")return r;try{return JSON.stringify(r)??String(r)}catch{return String(r)}},C=r=>typeof r=="boolean"||typeof r=="number"||typeof r=="string"?r:v(r),rr=512,tr=200,or=r=>{const s=r.maxItems??rr,o=r.maxDelayMs??tr;let t=[],e,a,n;const c=()=>{e!==void 0&&(clearTimeout(e),e=void 0)},h=async()=>{c();const l=t;t=[];const d=n;a=void 0,n=void 0;try{l.length>0&&await r.export(l)}catch{}finally{d?.()}},m=l=>{a===void 0&&(a=new Promise(d=>{n=d}),e=setTimeout(()=>{h()},o)),l?.(a)};return{add:(l,d)=>{for(t.push(l);t.length>s;)t.shift();m(d),t.length>=s&&h()},flush:async l=>{if(t.length===0){c();return}const d=h();return l?.(d),d},get size(){return t.length}}},sr=/["\\\u0000-\u001F\uD800-\uDFFF]/,D=r=>sr.test(r)?JSON.stringify(r):`"${r}"`,A=r=>{if(r===void 0)return"null";if(typeof r=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof r=="number"){if(Number.isNaN(r))return"nan";if(r===1/0)return"inf";if(r===-1/0)return"-inf";if(Object.is(r,-0))return"-0"}if(typeof r=="string")return D(r);if(r===null||typeof r!="object")return JSON.stringify(r);if(Array.isArray(r)){let n="[";for(let c=0;c<r.length;c++)c>0&&(n+=","),n+=A(r[c]);return n+"]"}const s=Object.getPrototypeOf(r);if(s!==null&&s!==Object.prototype){const n=r.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${n} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const o=r,t=Object.keys(o).sort();let e="{",a=!0;for(const n of t){const c=o[n];c!==void 0&&(a?a=!1:e+=",",e+=D(n),e+=":",e+=A(c))}return e+"}"},er=(r,s)=>{const o=[p(y.functionPath,r.functionPath),p(y.ok,r.ok)];r.method!==void 0&&o.push(p("http.request.method",r.method)),r.path!==void 0&&o.push(p("url.path",r.path)),o.push(p("http.route",r.functionPath)),r.scheme!==void 0&&o.push(p("url.scheme",r.scheme)),r.host!==void 0&&o.push(p("server.address",r.host)),r.port!==void 0&&o.push(p("server.port",r.port)),r.userAgent!==void 0&&o.push(p("user_agent.original",r.userAgent)),r.shardKey!==void 0&&o.push(p(y.shardKey,r.shardKey)),o.push(p("http.response.status_code",r.error?.status??200)),r.error&&o.push(p(y.errorType,r.error.code),p("lunora.error_status",r.error.status)),r.fanOut&&o.push(p("lunora.fanout.table",r.fanOut.table),p("lunora.fanout.shards",r.fanOut.shards),p("lunora.fanout.failed",r.fanOut.failed));const t={attributes:o,endTimeUnixNano:S(s),kind:$.server,name:r.functionPath,...r.parentSpanId===void 0?{}:{parentSpanId:r.parentSpanId},spanId:r.spanId??x(8),startTimeUnixNano:S(s-r.durationMs),status:r.ok?{code:1}:{code:2,message:r.error?.message??""},traceId:r.traceId??x(16)};return r.traceFlags!==void 0&&(t.flags=r.traceFlags),r.error&&(t.events=[{attributes:[p("exception.type",r.error.code),p("exception.message",r.error.message)],name:"exception",timeUnixNano:S(s)}]),t},L=(r,s)=>{const o=new Map([[y.functionPath,p(y.functionPath,r.functionPath)]]);r.shardKey!==void 0&&o.set(y.shardKey,p(y.shardKey,r.shardKey)),r.userId!==void 0&&o.set(y.userId,p(y.userId,r.userId)),r.errorType!==void 0&&o.set(y.errorType,p(y.errorType,r.errorType));for(const[t,e]of Object.entries(s??{}))o.set(t,p(t,C(e)));return[...o.values()]},nr=r=>{const s={attributes:L({errorType:r.error?.type,functionPath:r.functionPath,shardKey:r.shardKey,userId:r.userId},r.attributes),endTimeUnixNano:S(r.startTs+r.durationMs),kind:$[r.kind??"internal"],name:r.name,parentSpanId:r.parentSpanId,spanId:r.spanId,startTimeUnixNano:S(r.startTs),status:r.ok?{code:1}:{code:2,message:r.error?.message??""},traceId:r.traceId},o=t=>q(Object.fromEntries(Object.entries(t??{}).map(([e,a])=>[e,C(a)])));return r.events!==void 0&&r.events.length>0&&(s.events=r.events.map(t=>({attributes:o(t.attributes),name:t.name,timeUnixNano:S(t.ts)}))),r.links!==void 0&&r.links.length>0&&(s.links=r.links.map(t=>({attributes:o(t.attributes),spanId:t.spanId,traceId:t.traceId}))),s},ir=r=>{const s=S(r.ts),o=L({functionPath:r.functionPath,shardKey:r.shardKey},r.attributes),t={asDouble:r.value,attributes:o,timeUnixNano:s};return r.kind==="gauge"?{gauge:{dataPoints:[t]},name:r.name}:r.kind==="histogram"?{histogram:{aggregationTemporality:1,dataPoints:[{attributes:o,bucketCounts:["1"],count:"1",explicitBounds:[],max:r.value,min:r.value,sum:r.value,timeUnixNano:s}]},name:r.name}:{name:r.name,sum:{aggregationTemporality:1,dataPoints:[t],isMonotonic:!0}}},ar=r=>{const s={attributes:L({functionPath:r.functionPath,shardKey:r.shardKey,userId:r.userId},r.fields),body:{stringValue:r.message},severityNumber:X[r.level],severityText:r.level.toUpperCase(),timeUnixNano:S(r.ts)};return r.traceId!==void 0&&(s.traceId=r.traceId),r.spanId!==void 0&&(s.spanId=r.spanId),r.eventName!==void 0&&(s.eventName=r.eventName,s.attributes.push(p("event.name",r.eventName))),s},cr=1024,dr=async r=>{const s=new Blob([r]).stream().pipeThrough(new CompressionStream("gzip"));return new Response(s).arrayBuffer()},H=async(r,s,o,t)=>{try{const e=JSON.stringify(s),{byteLength:a}=new TextEncoder().encode(e),n=(a<cr?fetch(r,{body:e,headers:o,method:"POST"}):dr(e).then(c=>fetch(r,{body:c,headers:{...o,"content-encoding":"gzip"},method:"POST"}))).then(()=>{},()=>{});t?.(n),await n}catch{}},ur=(r,s,o,t)=>{H(r,s,o,t?.waitUntil).catch(()=>{})},O=(r,s)=>s===!0&&r.ok,pr=r=>r.kind==="metric"?void 0:r.event.traceId,lr=r=>{const s=Map.groupBy(r,t=>pr(t)),o=s.get(void 0)??[];return s.delete(void 0),{byTrace:s,untraced:o}},j=5,fr=(r,s,o)=>{if(s===void 0)return r;const{byTrace:t,untraced:e}=lr(r),a=[...e];let n=0,c;for(const[h,m]of t){let l;try{l=s({logs:m.filter(d=>d.kind==="log").map(d=>d.event),rpc:m.filter(d=>d.kind==="rpc").map(d=>d.event),spans:m.filter(d=>d.kind==="span").map(d=>d.event),traceId:h})}catch(d){n+=1,n===1&&(c=d),l=!0}l&&a.push(...m)}return n>0&&o(c,n),a},P=(r,s)=>{if(s===void 0)return r;try{return s(r)??void 0}catch{return}},B=(r,s)=>{if(r.kind==="rpc"){const t=P(r.event,s?.rpc);return t===void 0?void 0:{bucket:"spans",encoded:er(t,r.endMs)}}if(r.kind==="span"){const t=P(r.event,s?.span);return t===void 0?void 0:{bucket:"spans",encoded:nr(t)}}if(r.kind==="log"){const t=P(r.event,s?.log);return t===void 0?void 0:{bucket:"logs",encoded:ar(t)}}const o=P(r.event,s?.metric);return o===void 0?void 0:{bucket:"metrics",encoded:ir(o)}},mr=["fuseCloudflareTraces","instrumentDatabase","metricHistory","traceFetch"],yr=(r={})=>{const{onlyErrors:s}=r;return{onLog:o=>{o.level==="error"||o.level==="fatal"?console.error("[lunora:log]",o.functionPath,o.message):console.log("[lunora:log]",o.functionPath,o.message)},onMetric:o=>{console.log("[lunora:metric]",`${o.name}=${String(o.value)}`,o.kind,o.functionPath)},onRpc:o=>{O(o,s)||(o.ok?console.log("[lunora:rpc]",o):console.error("[lunora:rpc]",o))},onSpan:o=>{const t=o.ok?"ok":`error ${o.error?.type??""}`.trim();console.log("[lunora:span]",o.name,`${String(o.durationMs)}ms`,t,o.functionPath)}}},gr=r=>{const{headers:s,onlyErrors:o,transform:t,transformLog:e,url:a}=r,n=J({"content-type":"application/json"},s),c=(h,m)=>{try{const l=fetch(a,{body:JSON.stringify(h),headers:n,method:"POST"}).catch(()=>{});m?.waitUntil&&m.waitUntil(l)}catch{}};return{onLog:(h,m)=>{const l=P(h,e);l!==void 0&&c(l,m)},onRpc:(h,m)=>{if(O(h,o))return;const l=P(h,t);l!==void 0&&c(l,m)}}},br=r=>{const{capture:s,captureLog:o}=r,t=r.onlyErrors??!0;return{onLog:o?e=>{try{o(e)}catch{}}:void 0,onRpc:e=>{if(!O(e,t))try{s(e)}catch{}}}},kr=r=>{const{dataset:s,onlyErrors:o}=r;return{onRpc:t=>{if(!O(t,o))try{s.writeDataPoint({blobs:[t.functionPath,t.ok?"ok":"error",t.shardKey??"",t.error?.code??"",t.fanOut?.table??""],doubles:[t.durationMs,t.ok?0:1,t.fanOut?.shards??0,t.fanOut?.failed??0],indexes:[t.functionPath]})}catch{}}}},Sr=r=>{const{pipeline:s,serializeFields:o}=r;return{onLog:(t,e)=>{try{const a={functionPath:t.functionPath,level:t.level,message:t.message,ts:t.ts};t.fields&&(a.fields=o===!0?JSON.stringify(t.fields):t.fields);for(const c of["shardKey","userId","traceId","spanId"])t[c]!==void 0&&(a[c]=t[c]);const n=s.send([a]).catch(()=>{});e?.waitUntil&&e.waitUntil(n)}catch{}}}},Ir=r=>{const{batch:s,deploymentEnvironment:o,detectResources:t,endpoint:e,headers:a,onlyErrors:n,postProcessor:c,resourceAttributes:h,serviceNamespace:m,serviceVersion:l,tailSampler:d,token:z}=r,R=r.serviceName??"lunora",U={...l===void 0?{}:{"service.version":l},...m===void 0?{}:{"service.namespace":m},...o===void 0?{}:{"deployment.environment":o},...h},F=new WeakMap,k=u=>{if(t!==!0||u?.resourceAttributes===void 0)return U;const i=F.get(u);if(i!==void 0)return i;const f=Q(u.resourceAttributes(),U);return F.set(u,f),f};let I=e;for(;I.endsWith("/");)I=I.slice(0,-1);const _={logs:{url:`${I}/v1/logs`,wrap:Z},metrics:{url:`${I}/v1/metrics`,wrap:Y},spans:{url:`${I}/v1/traces`,wrap:G}},K=J({"content-type":"application/json"},a,z);let M=0;const V=(u,i)=>{if(M>=j)return;M+=1;const f=M===j?" Further tailSampler failures from this sink are silenced until the isolate restarts.":"";console.error(`[lunora:otlp] tailSampler threw for ${String(i)} trace(s) in this flush window; keeping them (fail-open), so the sampling policy did NOT apply.${f}`,u)},W=async u=>{const i=fr(u,d,V),f=new Map;for(const g of i){const b=B(g,c);if(b===void 0)continue;const E=A(g.resource);let T=f.get(E);T===void 0&&(T={logs:[],metrics:[],resource:g.resource,spans:[]},f.set(E,T)),T[b.bucket].push(b.encoded)}const w=[];for(const[,g]of f)for(const b of["spans","logs","metrics"])if(g[b].length>0){const{url:E,wrap:T}=_[b];w.push(H(E,T(g[b],"@lunora/runtime",R,g.resource),K))}await Promise.all(w)};if(s===!1){const u=(i,f)=>{const w=B(i,c);if(w!==void 0){const{url:g,wrap:b}=_[w.bucket];ur(g,b(w.encoded,"@lunora/runtime",R,i.resource),K,f)}};return{onLog:(i,f)=>{u({event:i,kind:"log",resource:k(f)},f)},onMetric:(i,f)=>{u({event:i,kind:"metric",resource:k(f)},f)},onRpc:(i,f)=>{O(i,n)||u({endMs:Date.now(),event:i,kind:"rpc",resource:k(f)},f)},onSpan:(i,f)=>{u({event:i,kind:"span",resource:k(f)},f)}}}const N=or({export:W,...s?.maxDelayMs===void 0?{}:{maxDelayMs:s.maxDelayMs},...s?.maxItems===void 0?{}:{maxItems:s.maxItems}});return{flush:u=>{N.flush(u?.waitUntil).catch(()=>{})},onLog:(u,i)=>{N.add({event:u,kind:"log",resource:k(i)},i?.waitUntil)},onMetric:(u,i)=>{N.add({event:u,kind:"metric",resource:k(i)},i?.waitUntil)},onRpc:(u,i)=>{O(u,n)||N.add({endMs:Date.now(),event:u,kind:"rpc",resource:k(i)},i?.waitUntil)},onSpan:(u,i)=>{N.add({event:u,kind:"span",resource:k(i)},i?.waitUntil)}}},wr=(...r)=>{const s=(t,e)=>{for(const a of r){const n=a[t];if(n)try{n.apply(a,e)}catch{}}},o={};for(const t of r)for(const e of mr)o[e]===void 0&&t[e]!==void 0&&(o[e]=t[e]);return{...o,flush:t=>{s("flush",[t])},onLog:(t,e)=>{s("onLog",[t,e])},onMetric:(t,e)=>{s("onMetric",[t,e])},onRpc:(t,e)=>{s("onRpc",[t,e])},onSpan:(t,e)=>{s("onSpan",[t,e])}}};export{kr as analyticsEngineSink,wr as combineSinks,yr as consoleSink,Ir as otlpSink,Sr as pipelineLogSink,br as sentrySink,gr as webhookSink};
@@ -1,6 +0,0 @@
1
- import{isLunoraError as Dn,toErrorBody as Nn}from"@lunora/errors";import{e as Nt}from"./evict-oldest-BNXsKx4s.mjs";import{NOOP_EXECUTION_CONTEXT as Un}from"./NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{t as Cn,f as Bn}from"./base64-Bl1_r2k1.mjs";import{e as xn,a as Hn}from"./identity-header-C4Z5pldl.mjs";import{o as Te,b as Ln,p as Mn,m as Kn,d as jn,a as $n,r as Fn}from"./otlp-resource-DeXhb949.mjs";import{e as Qe,d as Gn}from"./wire-codec-CMVqBlcF.mjs";import{d as Z,e as be,M as Ut,b as Qn,f as zn,g as Ct,h as Bt}from"./rest-routes-ZZES0ngM.mjs";import{LunoraError as d,toErrorResponse as ot}from"./LunoraError-DksAgIpa.mjs";import{a as j,m as me}from"./method-guard-BG_vJNTl.mjs";import{normalizeBackupPrefix as We,BACKUP_KEY_PREFIX as Ve,isBackupManifestKey as Wn,backupObjectKeyOfManifest as xt,backupObjectKey as Vn,backupManifestKey as Jn}from"./BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toHex as qn,buildStorageAdminRoutes as Yn,STORAGE_UPLOAD_MAX_BODY_BYTES as Xn,STORAGE_PATH as Zn}from"./STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{b as er,e as tr,f as at,g as nr,h as rr}from"./export-tap-CGR3Xd9F.mjs";import{buildHealthRoutes as or,durableObjectProbe as ar,d1Probe as sr,presenceProbe as Be}from"./HEALTH_PATH-jZsuCmSs.mjs";import{wrapResolverWithContract as ir}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{composeIdentityResolvers as Os,routeIdentityResolvers as vs}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{buildLogArchiveAdminRoutes as cr}from"./LOG_ARCHIVE_PATH-Hmjpz_Ko.mjs";import{r as dr,f as st,a as ie}from"./observability-vDK-rMbs.mjs";import{resolveShard as we,applyJurisdiction as it}from"./applyJurisdiction-C0ddU7Tg.mjs";import{resolveSecurity as ct,handleCorsPreflight as ur,enforceOrigin as lr,decorateResponse as xe,enforceWebSocketOrigin as dt}from"./decorateResponse-BuqVnrmc.mjs";const hr=e=>{const t=e??{};if(typeof t.bucket=="function")return t;const n={...t,bucketName:"default"};return n.bucket=()=>n,n},Ht="__lunoraBranch",fr=e=>typeof e=="object"&&e!==null&&Object.hasOwn(e,Ht),pr=`may not contain the reserved workflow branch-marker key ("${Ht}")`,Je=(e,t)=>{const n=Math.max(e.length,t.length);let o=e.length^t.length;for(let a=0;a<n;a+=1){const i=a<e.length?e.charCodeAt(a):0,u=a<t.length?t.charCodeAt(a):0;o|=i^u}return o===0},mr=(e,t,n,o)=>{const a=e.get(t);if(a!==void 0)return a;Nt(e,o);const i=n().catch(u=>{throw e.get(t)===i&&e.delete(t),u});return e.set(t,i),i},qe=new TextEncoder,wr=Array.from({length:32},(e,t)=>t);new RegExp(`[${wr.map(e=>String.fromCodePoint(e)).join("")}]`,"u");const gr=64,yr=new Map,Lt=async e=>mr(yr,e,async()=>crypto.subtle.importKey("raw",qe.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),gr),Mt=async(e,t)=>{const n=await Lt(e),o=await crypto.subtle.sign("HMAC",n,qe.encode(t));return Cn(new Uint8Array(o))},br=async(e,t,n)=>{const o=await Lt(e);return crypto.subtle.verify("HMAC",o,n,qe.encode(t))},_r=["wnam","enam","sam","weur","eeur","apac","apac-ne","apac-se","oc","afr","me"];new Set(_r);const Rr=new Set(["AE","BH","IL","IQ","IR","JO","KW","LB","OM","PS","QA","SA","SY","TR","YE"]),Er=-100,Sr=15,Ar=e=>{const t=Number(e.longitude??Number.NaN);switch(e.continent){case"AF":return"afr";case"AS":return e.country!==void 0&&Rr.has(e.country)?"me":"apac";case"EU":return Number.isFinite(t)&&t>Sr?"eeur":"weur";case"NA":return Number.isFinite(t)&&t<Er?"wnam":"enam";case"OC":return"oc";case"SA":return"sam";default:return}},ut=e=>{const t=e.cf;return t===void 0?void 0:Ar(t)},Kt="::relay::",Tr=(e,t)=>`${e}${Kt}${String(t)}`,jt="::replica::",Or=(e,t)=>`${e}${jt}${t}`,vr=e=>{if(e==null||!/^\d+$/.test(e))return;const t=Number.parseInt(e,10);return Number.isSafeInteger(t)&&t>0?t:void 0},kr=new Set(["1","enabled","on","true","yes"]),Ir=new Set(["0","disabled","false","no","off"]),Pr=(e,t)=>{const n=(e??"").trim().toLowerCase();return kr.has(n)?!0:Ir.has(n)?!1:t},$t="v1",Dr=6e4,Nr=async(e,t={})=>{const n=(t.now??Date.now())+(t.ttlMs??Dr),o=`${$t}.${String(n)}`,a=await Mt(e,o);return{expiresAtMs:n,token:`${o}.${a}`}},Ur=async(e,t,n=Date.now())=>{if(e.length===0||t.length===0)return!1;const o=t.split(".");if(o.length!==3)return!1;const[a,i,u]=o;if(a!==$t||u.length===0)return!1;const h=Number(i);if(!Number.isFinite(h)||h<=n)return!1;let f;try{f=Bn(u)}catch{return!1}return br(e,`${a}.${i}`,f)},P="/_lunora/admin/auth",Cr={INVITER_REQUIRED:400,ORG_SLUG_INVALID:400,ORG_SLUG_TAKEN:409,PASSWORD_TOO_LONG:400,PASSWORD_TOO_SHORT:400,USER_ALREADY_EXISTS:409,USER_NOT_FOUND:404},N=(e,t)=>{const n=e[t];if(typeof n!="string"||n==="")throw new d(`\`${t}\` is required`,{code:"BAD_REQUEST",status:400});return n},he=(e,t)=>{const n=e(t);if(n===void 0)throw new d(`\`${t}\` query parameter is required`,{code:"BAD_REQUEST",status:400});return n},Ft=e=>{if(typeof e=="string"||Array.isArray(e)&&e.every(t=>typeof t=="string"))return e},re=(e,t)=>typeof e[t]=="string"?e[t]:void 0,He=(e,t)=>{const n=e[t];return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:void 0},lt=e=>{const t=Ft(e.role);if(t===void 0||typeof t=="string"&&t.trim()==="")throw new d("`role` is required",{code:"BAD_REQUEST",status:400});return t},ht=e=>{const t=e.permission;if(typeof t!="object"||t===null||Array.isArray(t))throw new d("`permission` object is required",{code:"BAD_REQUEST",status:400});const n={};for(const[o,a]of Object.entries(t))Array.isArray(a)&&a.every(i=>typeof i=="string")&&(n[o]=a);return n},Br={[`${P}/capabilities`]:{build:()=>({}),http:"GET",method:"capabilities"},[`${P}/users`]:{build:({paging:e,query:t})=>{const n=t("sortDirection");return{...e,filterField:t("filterField"),filterValue:t("filterValue"),search:t("search"),searchField:t("searchField"),sortBy:t("sortBy"),sortDirection:n==="asc"||n==="desc"?n:void 0}},http:"GET",method:"listUsers"},[`${P}/sessions`]:{build:({paging:e,query:t})=>({...e,userId:t("userId")}),http:"GET",method:"listSessions"},[`${P}/accounts`]:{build:({query:e})=>({userId:he(e,"userId")}),http:"GET",method:"listAccounts"},[`${P}/passkeys`]:{build:({query:e})=>({userId:he(e,"userId")}),http:"GET",method:"listPasskeys"},[`${P}/organizations`]:{build:({paging:e})=>({...e}),http:"GET",method:"listOrganizations"},[`${P}/organizations/members`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listMembers"},[`${P}/organizations/invitations`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listInvitations"},[`${P}/config`]:{build:()=>({}),http:"GET",method:"config"},[`${P}/organizations/teams`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listTeams"},[`${P}/organizations/teams/members`]:{build:({paging:e,query:t})=>({...e,teamId:he(t,"teamId")}),http:"GET",method:"listTeamMembers"},[`${P}/organizations/roles`]:{build:({paging:e,query:t})=>({...e,organizationId:he(t,"organizationId")}),http:"GET",method:"listOrgRoles"},[`${P}/users/create`]:{build:({body:e})=>({data:He(e,"data"),email:N(e,"email"),name:N(e,"name"),password:re(e,"password"),role:Ft(e.role)}),http:"POST",method:"createUser"},[`${P}/users/update`]:{build:({body:e})=>{const{data:t}=e;if(typeof t!="object"||t===null||Array.isArray(t))throw new d("`data` object is required",{code:"BAD_REQUEST",status:400});return{data:t,userId:N(e,"userId")}},http:"POST",method:"updateUser"},[`${P}/users/role`]:{build:({body:e})=>({role:lt(e),userId:N(e,"userId")}),http:"POST",method:"setRole"},[`${P}/users/ban`]:{build:({body:e})=>({expiresInSeconds:typeof e.expiresInSeconds=="number"?e.expiresInSeconds:void 0,reason:re(e,"reason"),userId:N(e,"userId")}),http:"POST",method:"banUser"},[`${P}/users/unban`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"unbanUser"},[`${P}/users/password`]:{build:({body:e})=>({newPassword:N(e,"newPassword"),userId:N(e,"userId")}),http:"POST",method:"setUserPassword",returns:"void"},[`${P}/users/remove`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"removeUser",returns:"void"},[`${P}/users/impersonate`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"impersonateUser"},[`${P}/sessions/revoke`]:{build:({body:e})=>({sessionId:N(e,"sessionId")}),http:"POST",method:"revokeUserSession",returns:"void"},[`${P}/sessions/revoke-all`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"revokeUserSessions",returns:"void"},[`${P}/accounts/unlink`]:{build:({body:e})=>({accountId:N(e,"accountId"),userId:N(e,"userId")}),http:"POST",method:"unlinkAccount",returns:"void"},[`${P}/two-factor/disable`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"disableTwoFactor",returns:"void"},[`${P}/passkeys/delete`]:{build:({body:e})=>({passkeyId:N(e,"passkeyId")}),http:"POST",method:"deletePasskey",returns:"void"},[`${P}/organizations/members/remove`]:{build:({body:e})=>({memberId:N(e,"memberId")}),http:"POST",method:"removeMember",returns:"void"},[`${P}/organizations/invitations/cancel`]:{build:({body:e})=>({invitationId:N(e,"invitationId")}),http:"POST",method:"cancelInvitation",returns:"void"},[`${P}/organizations/create`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:He(e,"metadata"),name:N(e,"name"),ownerId:re(e,"ownerId"),slug:re(e,"slug")}),http:"POST",method:"createOrganization"},[`${P}/organizations/update`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:He(e,"metadata"),name:re(e,"name"),organizationId:N(e,"organizationId"),slug:re(e,"slug")}),http:"POST",method:"updateOrganization"},[`${P}/organizations/remove`]:{build:({body:e})=>({organizationId:N(e,"organizationId")}),http:"POST",method:"deleteOrganization",returns:"void"},[`${P}/organizations/members/add`]:{build:({body:e})=>({organizationId:N(e,"organizationId"),role:re(e,"role"),userId:N(e,"userId")}),http:"POST",method:"addMember"},[`${P}/organizations/members/invite`]:{build:({body:e})=>({email:N(e,"email"),inviterId:re(e,"inviterId"),organizationId:N(e,"organizationId"),role:re(e,"role")}),http:"POST",method:"inviteMember"},[`${P}/organizations/members/role`]:{build:({body:e})=>({memberId:N(e,"memberId"),role:lt(e)}),http:"POST",method:"updateMemberRole"},[`${P}/organizations/teams/create`]:{build:({body:e})=>({name:N(e,"name"),organizationId:N(e,"organizationId")}),http:"POST",method:"createTeam"},[`${P}/organizations/teams/update`]:{build:({body:e})=>({name:N(e,"name"),teamId:N(e,"teamId")}),http:"POST",method:"updateTeam"},[`${P}/organizations/teams/remove`]:{build:({body:e})=>({teamId:N(e,"teamId")}),http:"POST",method:"removeTeam",returns:"void"},[`${P}/organizations/teams/members/add`]:{build:({body:e})=>({teamId:N(e,"teamId"),userId:N(e,"userId")}),http:"POST",method:"addTeamMember"},[`${P}/organizations/teams/members/remove`]:{build:({body:e})=>({teamMemberId:N(e,"teamMemberId")}),http:"POST",method:"removeTeamMember",returns:"void"},[`${P}/organizations/roles/create`]:{build:({body:e})=>({organizationId:N(e,"organizationId"),permission:ht(e),role:N(e,"role")}),http:"POST",method:"createOrgRole"},[`${P}/organizations/roles/update`]:{build:({body:e})=>({permission:ht(e),roleId:N(e,"roleId")}),http:"POST",method:"updateOrgRole"},[`${P}/organizations/roles/remove`]:{build:({body:e})=>({roleId:N(e,"roleId")}),http:"POST",method:"deleteOrgRole",returns:"void"}},xr=e=>{const t=async a=>{try{return await a()}catch(i){if(i instanceof d)throw i;const u=i,h=typeof u.code=="string"?u.code:"AUTH_ADMIN_ERROR";throw console.error("[lunora] auth admin operation failed:",i),new d("auth admin operation failed",{code:h,status:Cr[h]??500})}},n=async(a,i)=>{if(e.assertAdmin(a),a.method!==i.http)throw new d(`Auth admin endpoint requires ${i.http}`,{code:"METHOD_NOT_ALLOWED",status:405});const u=e.getAuthAdmin();if(u===void 0)throw new d("auth endpoints require an `authAdmin` on the worker",{code:"AUTH_NOT_CONFIGURED",status:400});const h=u[i.method];if(h===void 0)throw new d(`auth admin does not support \`${i.method}\``,{code:"AUTH_OP_NOT_SUPPORTED",status:400});const f=new URL(a.url),w={body:i.http==="POST"?await e.readJsonBody(a):{},paging:e.parsePaging(a),query:v=>e.queryParameter(f,v)},E=i.build(w),O=await t(()=>h(E));return Response.json(i.returns==="void"?{ok:!0}:O,{headers:{"content-type":"application/json"},status:200})},o={};for(const[a,i]of Object.entries(Br))o[a]=u=>n(u,i);return o},Hr="__lunora_admin__:getAuthAuditLog",ft=e=>typeof e=="string"&&e!==""?e:void 0,pt=e=>typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0,Lr=e=>async(n,o)=>{e.assertAdmin(n);const a=e.getReader();if(a===void 0)throw new d("the auth/security audit endpoint requires an `authAuditReader` on the worker",{code:"AUTH_AUDIT_NOT_CONFIGURED",status:400});const i=ft(o.actorId),u=ft(o.event),h=pt(o.sinceSeq),f=pt(o.limit),w={...i===void 0?{}:{actorId:i},...u===void 0?{}:{event:u},...h===void 0?{}:{sinceSeq:h},...f===void 0?{}:{limit:f}};let E;try{E=await a.read(w)}catch(v){throw v instanceof d?v:(console.error("[lunora] auth audit read failed:",v),new d("auth audit read failed",{code:"AUTH_AUDIT_READ_FAILED",status:500}))}const O={entries:E};return Response.json({result:Qe(O)},{headers:{"content-type":"application/json"},status:200})},Mr=(e,t)=>{const n=[],o=[];if(t&&t.length>0)for(const a of t)e.resolveTableSharding?.(a)?.mode.kind==="global"?o.push(a):n.push(a);return{globalTables:o,shardLocalTables:n}},Kr=async(e,t,n,o,a,i,u)=>{if(n!==void 0&&o.length===0)return;const h=await e.orchestrateExport(i,{args:{tables:o},defaultShardKey:u,headers:t,tables:o});for(const f of h.shards)if(!f.error)for(const w of f.rows??[])a(w)},Gt=async(e,t,n,o,a,i)=>{const u=o??e.listSchemaTables?.();o===void 0&&e.listSchemaTables===void 0&&console.warn("[lunora] export: no table list available (`listSchemaTables` is unset and no `tables` were named), so only the default shard is reachable. A `.shardBy()` deployment's other shards will be missing from this export. Name the tables explicitly, or regenerate the worker so codegen supplies the list.");const{globalTables:h,shardLocalTables:f}=Mr(e,u);await Kr(t,n,u,f,a,i,e.defaultShardKey??"__root__");const w=e.exportGlobals;if((o===void 0||h.length>0)&&w)for await(const O of w({tables:h}))a(O)},jr=new TextEncoder,$r=1e3,Qt=10,Fr=200,mt=8,zt="lunoraBackupCron",wt=24*1048576,gt=e=>{const t=e.slice(0,Qt).map(o=>xt(o)),n=e.length-t.length;return`${t.join(", ")}${n>0?` (+${String(n)} more)`:""}`},Gr=(e,t)=>{const n=new Uint8Array(new ArrayBuffer(t));let o=0;for(const a of e)n.set(a,o),o+=a.byteLength;return n},Ye=async(e,t,n,o)=>{if(n===void 0||!Number.isInteger(n)||n<=0)return{eligible:0,stale:[]};const a=[];let i;for(let u=0;u<$r;u+=1){const h=await e.list({cursor:i,include:["customMetadata"],prefix:t});for(const f of h.objects)Wn(f.key)&&f.customMetadata?.[zt]===o&&a.push(f.key);if(!h.truncated||h.cursor===void 0)break;i=h.cursor}return{eligible:a.length,stale:a.toSorted((u,h)=>h.localeCompare(u)).slice(n)}},Qr=async(e,t,n,o,a)=>{const{stale:i}=await Ye(e,t,n,o),u=new Set(a),h=i.filter(g=>u.has(g)),f=h.slice(0,Fr),w=i.length-f.length,E=a.length-h.length;if(f.length===0)return{deleted:[],failed:[],ignored:E,remaining:w};const O=[],v=[];for(let g=0;g<f.length;g+=mt){const b=await Promise.allSettled(f.slice(g,g+mt).map(async _=>(await e.delete(xt(_)),await e.delete(_),_)));for(const[_,p]of b.entries())p.status==="fulfilled"?O.push(p.value):v.push(f[g+_])}return O.length>0&&console.info(`[lunora] backup prune kept the newest ${String(n)} and deleted ${String(O.length)}: ${gt(O)}`),v.length>0&&console.warn(`[lunora] backup prune failed to remove ${String(v.length)}: ${gt(v)}`),{deleted:O,failed:v,ignored:E,remaining:w}},zr=async e=>{const t=e.backupStore;if(!t)throw new d("backup retention preview requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const n=We(e.backupPrefix??Ve),o=e.backupCron,{eligible:a,stale:i}=o===void 0?{eligible:0,stale:[]}:await Ye(t,n,e.backupRetain,o);return{cron:o,eligible:a,keep:e.backupRetain??0,prefix:n,wouldDelete:i}},Wr=async(e,t,n,o)=>{const a=e.backupStore,i=e.queryCoordinator;if(!a)throw new d("scheduled backup requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!i)throw new d("scheduled backup requires a `queryCoordinator` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!n||n.length===0)throw new d("scheduled backup requires an `adminToken` (or `env.LUNORA_ADMIN_TOKEN`) to authenticate the per-shard export gate",{code:"BACKUP_NOT_CONFIGURED",status:500});const u={authorization:`Bearer ${n}`,"content-type":"application/json"},h=e.backupTables;let f=0,w=0,E=[];await Gt(e,i,u,h,D=>{const M=jr.encode(`${JSON.stringify(D)}
2
- `);if(f+=1,w+=M.byteLength,w>wt)throw new d(`scheduled backup reached ${String(w)} bytes of NDJSON, past the ${String(wt)}-byte limit for a snapshot assembled inside a Worker — nothing was written. Narrow it with \`backupTables\`, or take this snapshot off-platform with \`lunora backup create --bucket\`.`,{code:"BACKUP_TOO_LARGE",status:507});E.push(M)},t);const v=We(e.backupPrefix??Ve),g=new Date(o.scheduledTime).toISOString(),b=Vn(v,g),_=Gr(E,w);E=[];const p=qn(await crypto.subtle.digest("SHA-256",_));await a.put(b,_,{httpMetadata:{contentType:"application/x-ndjson"},sha256:p});const A={bytes:w,createdAt:g,cron:o.cron,file:b,id:g,rows:f,scheduledTime:o.scheduledTime,sha256:p,...h?{tables:h.join(",")}:{}};await a.put(Jn(b),`${JSON.stringify(A,void 0,2)}
3
- `,{customMetadata:{[zt]:o.cron},httpMetadata:{contentType:"application/json"}});try{const{stale:D}=await Ye(a,v,e.backupRetain,o.cron);if(D.length>0){const M=D.slice(0,Qt),I=D.length-M.length;console.info(`[lunora] backup retention: ${String(D.length)} snapshot(s) past the newest ${String(e.backupRetain)} — run \`lunora backup prune\` to remove them: ${M.join(", ")}${I>0?` (+${String(I)} more)`:""}`)}}catch(D){console.warn(`[lunora] backup ${b} was written, but the retention report failed:`,D)}},Vr=async(e,t)=>{const n=e.backupStore;if(!n)throw new d("backup prune requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const o=e.backupCron,a=e.backupRetain;if(o===void 0||a===void 0||!Number.isInteger(a)||a<=0)throw new d("backup prune needs a retention window: set `backupRetain` (and `backupCron`, which decides whose snapshots retention owns) on the worker. Without one there is nothing past the window to remove.",{code:"BACKUP_RETENTION_NOT_CONFIGURED",status:400});return Qr(n,We(e.backupPrefix??Ve),a,o,t)},Jr="/_lunora/admin/backup/retention",qr="/_lunora/admin/backup/prune",Yr=e=>{const{options:t,readJsonBody:n,requireAdminOption:o}=e,a=(h,f)=>{o(h,t.backupStore,{code:"BACKUP_NOT_CONFIGURED",message:`backup ${f} requires a \`backupStore\` on the worker`})},i=async h=>(j(h,"GET","Backup-retention"),a(h,"retention preview"),Response.json(await zr(t),{headers:{"cache-control":"no-store"}})),u=async h=>{j(h,"POST","Backup-prune"),a(h,"prune");const{confirm:f}=await n(h);if(!Array.isArray(f)||f.some(w=>typeof w!="string"))throw new d("backup prune requires a `confirm` array of the sidecar keys to remove — read them from `GET /_lunora/admin/backup/retention` and pass back the ones you mean to delete",{code:"BAD_REQUEST",status:400});return Response.json(await Vr(t,f),{headers:{"cache-control":"no-store"}})};return{[qr]:u,[Jr]:i}},yt=500,Xr=(e,t,n)=>{if(typeof e!="object"||e===null||Array.isArray(e))throw new d("each batch call must be an object",{code:"BAD_REQUEST",status:400});const o=e;if(typeof o.functionPath!="string")throw new d("each batch call needs a string `functionPath`",{code:"BAD_REQUEST",status:400});if(o.functionPath.startsWith("__lunora_relation__:")||o.functionPath.startsWith("__lunora_admin__"))throw new d("reserved function path cannot be batched",{code:"FORBIDDEN",status:403});if(o.args!==void 0&&(typeof o.args!="object"||o.args===null||Array.isArray(o.args)))throw new d("each batch call `args` must be an object",{code:"BAD_REQUEST",status:400});return{entry:{args:o.args===void 0?{}:o.args,clientId:typeof o.clientId=="string"?o.clientId:void 0,clientSeq:typeof o.clientSeq=="number"?o.clientSeq:void 0,functionPath:o.functionPath,id:typeof o.id=="number"?o.id:t,mutationId:typeof o.mutationId=="string"?o.mutationId:void 0},shardKey:typeof o.shardKey=="string"?o.shardKey:n}},Zr=(e,t)=>{if(e.length>yt)throw new d(`RPC batch exceeds the ${String(yt)}-call limit`,{code:"BAD_REQUEST",status:400});const n=new Map;for(const[o,a]of e.entries()){const{entry:i,shardKey:u}=Xr(a,o,t),h=n.get(u)??[];h.push(i),n.set(u,h)}return n},eo="/_lunora/admin/export",to="/_lunora/admin/import",no="/_lunora/admin/sync",ro="/_lunora/admin/connector/sync",oo="/_lunora/admin/apply",ao="/_lunora/admin/export-tap/run",so=new TextEncoder,io=async e=>{const n=await be(e,"Export")??{};if(n.tables===void 0)return{tables:void 0};if(!Array.isArray(n.tables))throw new d("Export `tables` must be a string array",{code:"BAD_REQUEST",status:400});const o=[];for(const a of n.tables){if(typeof a!="string"||a.length===0)throw new d("Export `tables` entries must be non-empty strings",{code:"BAD_REQUEST",status:400});o.push(a)}return{tables:o}},Le=e=>Array.isArray(e)?e.filter(t=>typeof t=="string"):void 0,co=e=>{const{applyGlobals:t,defaultShardKey:n,exportCursorStore:o,exportSinks:a,knownTables:i,queryCoordinator:u,assertAdmin:h,requireAdminOption:f,resolveForwardContext:w,shardDO:E,streamExportRows:O,streamingImport:v,syncGlobals:g}=e,b=async(I,F)=>{const H=me(I,["POST"]);if(H)return H;const Y=f(I,u,{code:"BAD_REQUEST",message:"Export endpoint requires a `queryCoordinator` on the worker"}),U=await io(I),{headers:G}=await w(I,F),Q=new ReadableStream({async pull(J){const K=$=>{J.enqueue(so.encode(`${JSON.stringify($)}
4
- `))};try{await O(Y,G,U.tables,K),J.close()}catch($){J.error($)}}});return new Response(Q,{headers:{"content-type":"application/x-ndjson"},status:200})},_=async(I,F)=>{const H=me(I,["POST"]);if(H)return H;const Y=f(I,u,{code:"BAD_REQUEST",message:"Sync endpoint requires a `queryCoordinator` on the worker"}),U=await Z(I),G=typeof U.cursors=="object"&&U.cursors!==null?U.cursors:{},Q=typeof U.limit=="number"?U.limit:void 0,J=typeof U.globalCursor=="number"?U.globalCursor:0,K=Le(U.tables),{headers:$}=await w(I,F),oe=K??i(),z=await Y.orchestrateCdcSync(E,{cursors:G,defaultShardKey:n,headers:$,limit:Q,tables:oe}),de=g?await g({limit:Q,sinceSeq:J}):void 0;return Response.json({global:de,shards:z.shards},{status:200})},p=async(I,F)=>{const H=me(I,["POST"]);if(H)return H;const Y=f(I,u,{code:"BAD_REQUEST",message:"Connector sync endpoint requires a `queryCoordinator` on the worker"}),U=await Z(I),G=tr(U.cursor),Q=typeof U.limit=="number"&&U.limit>0?U.limit:void 0,J=Le(U.tables),{headers:K}=await w(I,F),$=J??i(),oe=await Y.orchestrateCdcSync(E,{cursors:G.s,defaultShardKey:n,headers:K,limit:Q,tables:$}),z=[],de={...G.s};let ue=!1;for(const ae of oe.shards)ue=at(z,ae.changes??[],rr(Q))||ue,de[ae.shardKey]=ae.cursor;let _e=G.g;if(g){const ae=await g({limit:Q,sinceSeq:G.g});ue=at(z,ae.changes,Q)||ue,_e=ae.cursor}const Oe=nr({g:_e,s:de,v:1}),ve={changes:z,hasMore:ue,nextCursor:Oe};return Response.json(ve,{status:200})},A=async(I,F)=>{const H=me(I,["POST"]);if(H)return H;const Y=f(I,u,{code:"BAD_REQUEST",message:"Apply endpoint requires a `queryCoordinator` on the worker"}),U=await Z(I),Q=(Array.isArray(U.batches)?U.batches:[]).map(z=>z).filter(z=>z!==null&&typeof z=="object"&&typeof z.shardKey=="string"&&Array.isArray(z.changes)),J=Array.isArray(U.globalChanges)?U.globalChanges:[],{headers:K}=await w(I,F),$=await Y.orchestrateApplyCdc(E,{batches:Q,headers:K}),oe=J.length>0&&t?await t({changes:J}):0;return Response.json({applied:$.applied+oe,failed:$.failed,ok:$.ok},{status:200})},D=async(I,F)=>{const H=me(I,["POST"]);if(H)return H;h(I);const{headers:Y}=await w(I,F),U=await v(I,Y);return Response.json(U,{headers:{"content-type":"application/json"},status:U.failed.length>0?207:200})},M=async(I,F)=>{const H=me(I,["POST"]);if(H)return H;const Y=f(I,u,{code:"BAD_REQUEST",message:"Export-tap endpoint requires a `queryCoordinator` on the worker"});if(a===void 0||Object.keys(a).length===0||o===void 0)throw new d("Export-tap endpoint requires `exportSinks` + `exportCursorStore` on the worker",{code:"EXPORT_TAP_NOT_CONFIGURED",status:400});const U=await Z(I),G=typeof U.sink=="string"?U.sink:void 0,Q=typeof U.limit=="number"&&U.limit>0?U.limit:void 0,J=Le(U.tables);if(G===void 0)throw new d("Export-tap `sink` must name a configured sink",{code:"BAD_REQUEST",status:400});const K=a[G];if(K===void 0)throw new d(`Export-tap sink "${G}" is not configured`,{code:"NOT_FOUND",status:404});const{headers:$}=await w(I,F),oe=J??i(),z=await er({coordinator:Y,cursorStore:o,defaultShardKey:n,headers:$,limit:Q,shardDO:E,sink:K,tables:oe});return Response.json(z,{headers:{"content-type":"application/json"},status:200})};return{[oo]:A,[ro]:p,[eo]:b,[ao]:M,[to]:D,[no]:_}},uo=(e,t)=>{let n;try{n=JSON.parse(e)}catch{return{error:{code:"BAD_ROW",line:t,message:"line is not valid JSON",table:""},ok:!1}}if(!n||typeof n!="object"||Array.isArray(n))return{error:{code:"BAD_ROW",line:t,message:"row must be a JSON object",table:""},ok:!1};const o=n;return typeof o.table!="string"||o.table.length===0?{error:{code:"BAD_ROW",line:t,message:"row is missing `table`",table:""},ok:!1}:!o.doc||typeof o.doc!="object"||Array.isArray(o.doc)?{error:{code:"BAD_ROW",line:t,message:"row is missing or malformed `doc`",table:o.table},ok:!1}:{doc:o.doc,ok:!0,table:o.table}},lo=(e,t,n,o,a)=>{if(n?.mode.kind==="shardBy"&&typeof n.mode.field=="string"){const i=e[n.mode.field];return i==null?{error:{code:"BAD_ROW",line:a,message:`row missing shard field "${n.mode.field}" for table "${t}"`,table:t},ok:!1}:{ok:!0,shardKey:typeof i=="string"?i:JSON.stringify(i)}}return{ok:!0,shardKey:o}},ho=async(e,t,n)=>{if(!e.body)throw new d("Import endpoint requires a request body",{code:"BAD_REQUEST",status:400});const o=[],a=[],i=new Map;let u=0,h=0;const f=e.body.getReader(),w=new TextDecoder;let E="",O=0;const v=g=>{h+=1;const b=g.trim();if(b.length===0)return;u+=1;const _=uo(b,h);if(!_.ok){o.push(_.error);return}const{doc:p,table:A}=_,D=t.resolveTableSharding?.(A);if(D?.mode.kind==="global"){a.push({doc:p,line:h,table:A});return}const M=lo(p,A,D,n,h);if(!M.ok){o.push(M.error);return}const I=i.get(M.shardKey);I?I.rows.push({doc:p,table:A}):i.set(M.shardKey,{rows:[{doc:p,table:A}],shardKey:M.shardKey,startLine:h})};for(;;){const{done:g,value:b}=await f.read();if(g)break;if(b&&(O+=b.byteLength,O>Ut))throw await f.cancel().catch(()=>{}),new d("Body too large",{code:"PAYLOAD_TOO_LARGE",status:413});E+=w.decode(b,{stream:!0});let _=E.indexOf(`
5
- `);for(;_!==-1;){const p=E.slice(0,_);E=E.slice(_+1),v(p),_=E.indexOf(`
6
- `)}}return E.length>0&&v(E),{errors:o,globalRows:a,perShard:i,received:u}},fo=e=>e.flatMap(t=>t.error?[{message:t.error.message,shardKey:t.shardKey,timedOut:t.error.timedOut}]:[]),bt=(e,t)=>{for(const[n,o]of Object.entries(t.inserted))e.inserted[n]=(e.inserted[n]??0)+o;for(const n of t.errors)e.errors.push({...n});e.conflicts+=t.conflicts},po=async(e,t,n,o)=>{const a=t.defaultShardKey??"__root__",{errors:i,globalRows:u,perShard:h,received:f}=await ho(e,t,a),w={conflicts:0,errors:i,failed:[],inserted:{}},E=[];if(t.resolveTableSharding===void 0&&h.size>0&&E.push("no `resolveTableSharding` is configured, so every row was routed to the default shard and no row could be recognised as `.global()` — correct for a single-shard app, silent misplacement for a sharded one"),h.size>0){const O=t.queryCoordinator;if(!O)throw new d("Import endpoint requires a `queryCoordinator` on the worker",{code:"BAD_REQUEST",status:400});const v=await O.orchestrateImport(o,{batches:[...h.values()],headers:n});bt(w,v),w.failed.push(...fo(v.shards))}if(u.length>0)if(t.importGlobals){const O=u[0]?.line??1,v=await t.importGlobals({rows:u,startLine:O});bt(w,v)}else for(const O of u)w.errors.push({code:"GLOBAL_NOT_CONFIGURED",line:O.line,message:`row targets global table "${O.table}" but no \`importGlobals\` is configured`,table:O.table});return{conflicts:w.conflicts,errors:w.errors,failed:w.failed,inserted:w.inserted,received:f,...E.length>0?{warnings:E}:{}}},Me=e=>typeof e=="object"&&e!==null?e:{},Ke=e=>typeof e.kind=="string"?e.kind:"unknown",mo=(e,t)=>{let n=Me(t),o=!1;Ke(n)==="optional"&&(o=!0,n=Me(n._meta?.inner));const a=Ke(n),i=n._meta??{},u={kind:a,name:e,optional:o};if(a==="id"&&typeof i.tableName=="string"&&(u.table=i.tableName),a==="array"){const h=Ke(Me(i.inner));h!=="unknown"&&(u.element=h)}return u},wo=e=>typeof e!="object"||e===null?[]:Object.entries(e).map(([t,n])=>mo(t,n)).toSorted((t,n)=>t.name.localeCompare(n.name)),go="/_lunora/admin/functions",yo="/_lunora/admin/cron-jobs",bo="/_lunora/admin/openapi",_o="/_lunora/admin/openrpc",Ro="/_lunora/admin/global/tables",Eo="/_lunora/admin/global/table",So="/_lunora/admin/global/facet",_t=e=>{if(e===void 0||e==="")return;let t;try{t=Gn(JSON.parse(e))}catch{return}if(!Array.isArray(t))return;const n=t.flatMap(o=>{if(typeof o!="object"||o===null||typeof o.column!="string")return[];const{column:a,value:i}=o;return[{column:a,value:i}]});return n.length===0?void 0:n},Ao=Object.freeze({info:{description:'No OpenAPI spec is configured on this worker. Run `lunora codegen`, then wire the generated module to `createWorker`: `import { openApiSpec } from "./lunora/_generated/openapi"`.',title:"Lunora API",version:"0.0.0"},openapi:"3.1.0",paths:{}}),To=Object.freeze({info:{description:'No OpenRPC spec is configured on this worker. Run `lunora codegen --api-spec openrpc` (or `both`), then wire the generated module to `createWorker`: `import { openRpcSpec } from "./lunora/_generated/openrpc"`.',title:"Lunora RPC",version:"0.0.0"},methods:[],openrpc:"1.3.2"}),Oo=e=>{const{assertAdmin:t,options:n,parsePaging:o,queryParameter:a,requireAdminOption:i}=e,u=g=>{j(g,"GET","Functions");const b=i(g,n.functions,{code:"FUNCTIONS_NOT_CONFIGURED",message:"functions endpoint requires a `functions` registry on the worker"}),_=Object.entries(b).flatMap(([p,A])=>A.visibility==="internal"||A.kind==="stream"?[]:[{args:wo(A.args),kind:A.kind,path:p}]).toSorted((p,A)=>p.path.localeCompare(A.path));return Response.json({functions:_},{headers:{"content-type":"application/json"},status:200})},h=g=>{j(g,"GET","Cron-jobs");const b=i(g,n.cronJobs,{code:"CRON_JOBS_NOT_CONFIGURED",message:"cron-jobs endpoint requires a `cronJobs` map on the worker"}),_=Object.entries(b).flatMap(([p,A])=>A.map(D=>({args:D.args,cron:p,functionPath:D.functionPath,name:D.name,shardKey:D.shardKey,workflow:D.workflow}))).toSorted((p,A)=>p.name.localeCompare(A.name));return Response.json({jobs:_},{headers:{"content-type":"application/json"},status:200})},f=g=>(j(g,"GET","OpenAPI"),t(g),Response.json(n.openApiSpec??Ao,{headers:{"content-type":"application/json"},status:200})),w=g=>(j(g,"GET","OpenRPC"),t(g),Response.json(n.openRpcSpec??To,{headers:{"content-type":"application/json"},status:200})),E=async g=>{j(g,"GET","Global-tables");const b=i(g,n.globalIntrospector,{code:"GLOBALS_NOT_CONFIGURED",message:"global endpoints require a `globalIntrospector` on the worker"});return Response.json(await b.listTables(),{headers:{"content-type":"application/json"},status:200})},O=async g=>{j(g,"GET","Global-table");const b=i(g,n.globalIntrospector,{code:"GLOBALS_NOT_CONFIGURED",message:"global endpoints require a `globalIntrospector` on the worker"}),_=new URL(g.url),p=a(_,"table");if(p===void 0)throw new d("Global-table endpoint requires a `table` query param",{code:"BAD_REQUEST",status:400});const A=await b.readTablePage({...o(g),filters:_t(a(_,"filters")),table:p});return Response.json(A,{headers:{"content-type":"application/json"},status:200})},v=async g=>{j(g,"GET","Global-facet");const b=i(g,n.globalIntrospector,{code:"GLOBALS_NOT_CONFIGURED",message:"global endpoints require a `globalIntrospector` on the worker"}),_=new URL(g.url),p=a(_,"table"),A=a(_,"column");if(p===void 0||A===void 0)throw new d("Global-facet endpoint requires `table` and `column` query params",{code:"BAD_REQUEST",status:400});const D=a(_,"limit"),M=D===void 0?void 0:Number(D),I=await b.facetColumn({column:A,filters:_t(a(_,"filters")),limit:M!==void 0&&Number.isFinite(M)?M:void 0,table:p});return Response.json(I,{headers:{"content-type":"application/json"},status:200})};return{[yo]:h,[go]:u,[So]:v,[Eo]:O,[Ro]:E,[bo]:f,[_o]:w}},vo="/_lunora/admin/kv/namespaces",ko="/_lunora/admin/kv/keys",Wt="/_lunora/admin/kv/value",Vt=32*1048576,Rt=60,Io=e=>{const{readJsonBody:t,requireAdminOption:n}=e,o=b=>n(b,e.kvIntrospector,{code:"KV_NOT_CONFIGURED",message:"KV endpoints require a `kvIntrospector` on the worker"}),a=b=>Response.json(b,{headers:{"content-type":"application/json"},status:200}),i=(b,_)=>{const p=new URL(b.url),A=p.searchParams.get("namespace")??"",D=p.searchParams.get("key")??"";if(A==="")throw new d(`KV-value ${_} request requires a \`namespace\` query parameter`,{code:"BAD_REQUEST",status:400});if(D==="")throw new d(`KV-value ${_} request requires a \`key\` query parameter`,{code:"BAD_REQUEST",status:400});return{key:D,namespace:A}},u=async(b,_)=>{if(!(await b.listNamespaces()).some(A=>A.binding===_))throw new d(`Unknown KV namespace binding \`${_}\``,{code:"NOT_FOUND",status:404})},h=async b=>(j(b,"GET","KV-namespaces"),a({namespaces:await o(b).listNamespaces()})),f=async b=>{j(b,"GET","KV-keys");const _=o(b),p=new URL(b.url),A=p.searchParams.get("namespace")??"";if(A==="")throw new d("KV-keys request requires a `namespace` query parameter",{code:"BAD_REQUEST",status:400});const D=p.searchParams.get("prefix")??void 0,M=p.searchParams.get("cursor")??void 0,I=p.searchParams.get("limit"),F=I===null?void 0:Number.parseInt(I,10);if(F!==void 0&&(!Number.isInteger(F)||F<1))throw new d("KV-keys `limit` must be a positive integer",{code:"BAD_REQUEST",status:400});const H=F===void 0?void 0:Math.min(F,1e3);return await u(_,A),a(await _.listKeys({cursor:M,limit:H,namespace:A,prefix:D}))},v={DELETE:async b=>{const _=o(b),p=i(b,"DELETE");return await u(_,p.namespace),await _.deleteKey(p),a({deleted:!0})},GET:async b=>{const _=o(b),p=i(b,"GET");return await u(_,p.namespace),a(await _.getValue(p))},PUT:async b=>{const _=o(b),p=await t(b,Vt);if(typeof p.namespace!="string"||p.namespace==="")throw new d("KV-value PUT request requires a `namespace` string",{code:"BAD_REQUEST",status:400});if(typeof p.key!="string"||p.key==="")throw new d("KV-value PUT request requires a `key` string",{code:"BAD_REQUEST",status:400});if(typeof p.value!="string")throw new d("KV-value PUT request requires a `value` string",{code:"BAD_REQUEST",status:400});if(p.expirationTtl!==void 0&&(typeof p.expirationTtl!="number"||!Number.isInteger(p.expirationTtl)||p.expirationTtl<Rt))throw new d("KV-value PUT `expirationTtl` must be an integer ≥ 60",{code:"BAD_REQUEST",status:400});const A=Math.floor(Date.now()/1e3)+Rt;if(p.expiration!==void 0&&(typeof p.expiration!="number"||!Number.isInteger(p.expiration)||p.expiration<A))throw new d("KV-value PUT `expiration` must be a Unix-seconds timestamp at least 60 seconds in the future",{code:"BAD_REQUEST",status:400});return await u(_,p.namespace),await _.putValue({expiration:p.expiration,expirationTtl:p.expirationTtl,key:p.key,metadata:p.metadata,namespace:p.namespace,value:p.value}),a({ok:!0})}},g=b=>{const _=v[b.method];if(!_)throw new d("KV-value endpoint requires GET, PUT, or DELETE",{code:"METHOD_NOT_ALLOWED",status:405});return _(b)};return{[vo]:h,[ko]:f,[Wt]:g}},Po="/_lunora/migrate",Do="/_lunora/admin/pitr",No="/_lunora/admin/rank",Uo="/_lunora/admin/rankpage",Co="/_lunora/admin/shard-traffic",Bo=new Set(["__lunora_admin__:migrationStatus","__lunora_admin__:runMigration"]),xo=new Set(["__lunora_admin__:getPitrBookmark","__lunora_admin__:pitrRestore"]),Ho=async e=>{const n=await be(e,"Migration")??{};if(typeof n.table!="string"||n.table.length===0)throw new d("Migration request is missing `table`",{code:"BAD_REQUEST",status:400});if(typeof n.functionPath!="string"||!Bo.has(n.functionPath))throw new d("Migration request `functionPath` must be a migration admin op",{code:"BAD_REQUEST",status:400});return{args:n.args??{},functionPath:n.functionPath,table:n.table}},Lo=async e=>{const n=await be(e,"Rank")??{};if(typeof n.table!="string"||n.table.length===0)throw new d("Rank request is missing `table`",{code:"BAD_REQUEST",status:400});if(typeof n.index!="string"||n.index.length===0)throw new d("Rank request is missing `index`",{code:"BAD_REQUEST",status:400});if(typeof n.partitionKey!="string")throw new d("Rank request `partitionKey` must be a string",{code:"BAD_REQUEST",status:400});if(typeof n.rowId!="string"||n.rowId.length===0)throw new d("Rank request is missing `rowId`",{code:"BAD_REQUEST",status:400});if(!Array.isArray(n.sortValues))throw new d("Rank request `sortValues` must be an array",{code:"BAD_REQUEST",status:400});return{index:n.index,partitionKey:n.partitionKey,rowId:n.rowId,sortValues:n.sortValues,table:n.table}},Mo=e=>{if(e!==void 0){if(!Array.isArray(e)||e.some(t=>t!=="asc"&&t!=="desc"))throw new d('Rank page request `directions` must be an array of "asc"|"desc"',{code:"BAD_REQUEST",status:400});return e}},Ko=e=>{if(typeof e.table!="string"||e.table.length===0)throw new d("Rank page request is missing `table`",{code:"BAD_REQUEST",status:400});if(typeof e.index!="string"||e.index.length===0)throw new d("Rank page request is missing `index`",{code:"BAD_REQUEST",status:400});if(e.partitionKey!==void 0&&typeof e.partitionKey!="string")throw new d("Rank page request `partitionKey` must be a string",{code:"BAD_REQUEST",status:400});if(e.take!==void 0&&(typeof e.take!="number"||!Number.isFinite(e.take)))throw new d("Rank page request `take` must be a number",{code:"BAD_REQUEST",status:400});if(e.cursor!==void 0&&e.cursor!==null&&typeof e.cursor!="string")throw new d("Rank page request `cursor` must be a string or null",{code:"BAD_REQUEST",status:400})},jo=async e=>{const n=await be(e,"Rank page")??{};Ko(n);const o=Mo(n.directions);return{cursor:typeof n.cursor=="string"?n.cursor:null,directions:o,index:n.index,partitionKey:typeof n.partitionKey=="string"?n.partitionKey:void 0,table:n.table,take:typeof n.take=="number"?n.take:void 0}},$o=async e=>{const n=await be(e,"Shard-traffic")??{};if(typeof n.table!="string"||n.table.length===0)throw new d("Shard-traffic request is missing `table`",{code:"BAD_REQUEST",status:400});return{table:n.table}},Fo=async e=>{const n=await Z(e);if(typeof n.functionPath!="string"||!xo.has(n.functionPath))throw new d("PITR request `functionPath` must be a PITR admin op",{code:"BAD_REQUEST",status:400});if(n.shardKey!==void 0&&typeof n.shardKey!="string")throw new d("PITR `shardKey` must be a string",{code:"BAD_REQUEST",status:400});return{args:n.args??{},functionPath:n.functionPath,shardKey:n.shardKey}},Go=e=>{const{defaultShard:t,forwardToShard:n,isAdmin:o,queryCoordinator:a,resolveForwardContext:i,shardDO:u}=e,h=(g,b)=>{if(g.method!=="POST")throw new d(`${b} endpoint requires POST`,{code:"METHOD_NOT_ALLOWED",status:405});if(!o(g))throw new d("Admin auth required",{code:"FORBIDDEN",status:403});if(!a)throw new d(`${b} endpoint requires a \`queryCoordinator\` on the worker`,{code:"BAD_REQUEST",status:400});return a},f=async(g,b)=>{const _=h(g,"Migration"),p=await Ho(g),{headers:A}=await i(g,b),D=await _.orchestrateMigration(u,{args:p.args,defaultShardKey:t,functionPath:p.functionPath,headers:A,table:p.table});return Response.json(D,{headers:{"content-type":"application/json"},status:200})},w=async(g,b)=>{const _=h(g,"Rank"),p=await Lo(g),{headers:A}=await i(g,b),D=await _.orchestrateRank(u,{headers:A,index:p.index,partitionKey:p.partitionKey,rowId:p.rowId,sortValues:p.sortValues,table:p.table});return Response.json(D,{headers:{"content-type":"application/json"},status:200})},E=async(g,b)=>{const _=h(g,"Rank page"),p=await jo(g),{headers:A}=await i(g,b),D=await _.orchestrateRankPage(u,{...p,headers:A});return Response.json(D,{headers:{"content-type":"application/json"},status:200})},O=async(g,b)=>{const _=h(g,"Shard-traffic"),p=await $o(g),{headers:A}=await i(g,b),D=await _.orchestrateShardTraffic(u,{headers:A,table:p.table});return Response.json(D,{headers:{"content-type":"application/json"},status:200})},v=async(g,b)=>{if(j(g,"POST","PITR"),!o(g))throw new d("admin PITR endpoint requires a valid admin bearer",{code:"ADMIN_FORBIDDEN",status:403});const _=await Fo(g),{headers:p}=await i(g,b),A=new Request("https://shard.internal/rpc",{body:JSON.stringify({args:_.args,functionPath:_.functionPath}),headers:p,method:"POST"});return n(u,_.shardKey??t,A)};return{[Po]:f,[Do]:v,[No]:w,[Uo]:E,[Co]:O}},Qo=1,zo=0,Wo=32,Vo=512,Jo=/^[a-z][\d_a-z*/-]{0,255}(?:@[a-z][\d_a-z*/-]{0,13})?=[\u0020-\u002B\u002D-\u003C\u003E-\u007E]{1,256}$/,qo=e=>{if(e==null)return;const t=e.trim();if(t.length===0||t.length>Vo)return;const n=t.split(",");if(!(n.length>Wo)){for(const o of n)if(!Jo.test(o.trim()))return;return t}},Yo=e=>{const t=Mn(e.headers.get("traceparent"));if(t===void 0)return;const n=qo(e.headers.get("tracestate"));return{parentSpanId:t.parentSpanId,sampled:t.sampled,traceId:t.traceId,...n===void 0?{}:{traceState:n}}},Xo=(e,t={})=>{const n=Yo(e),o=t.trustInbound===!0?n:void 0,a=Te(8),i=o?.traceId??Te(16),u=dr(t.sampling,o===void 0?a:i),h=u.isTraced&&(o===void 0||o.sampled);return{decision:u,ignoredUpstream:n!==void 0&&o===void 0,trace:{sampled:h,spanId:a,traceFlags:h?Qo:zo,traceId:i,...o?.parentSpanId===void 0?{}:{parentSpanId:o.parentSpanId},...o?.traceState===void 0?{}:{traceState:o.traceState}}}},Zo=(e,t)=>{t.traceparent=Ln(e.traceId,e.spanId,e.sampled),e.traceState!==void 0&&(t.tracestate=e.traceState)},ea=(e,t)=>{let n;return()=>{if(n===void 0){const o=Fn(e),a=t===void 0?void 0:t.cf;n=Kn($n(o),jn(o,a))}return n}},ta="/_lunora/admin/scheduled",na="/_lunora/admin/scheduled/status",ra="/_lunora/admin/scheduled/ws",oa="/_lunora/admin/scheduled/cancel",aa="/_lunora/admin/scheduled/dead",sa="/_lunora/admin/scheduled/dead/retry",ia="/_lunora/admin/scheduled/dead/cancel",ca=e=>{const{checkWsAdmin:t,requireSchedulerNamespace:n,resolveSchedulerStub:o,schedulerInstanceName:a}=e,i=(f,w)=>E=>{if(E.method!=="GET")throw new d(`${w} endpoint requires GET`,{code:"METHOD_NOT_ALLOWED",status:405});return o(E).fetch(new Request(`https://scheduler.internal${f}`,{method:"GET"}))},u=(f,w,E=w)=>async O=>{if(O.method!=="POST")throw new d(`${E} requires POST`,{code:"METHOD_NOT_ALLOWED",status:405});const v=o(O),g=await O.json().catch(()=>{});if(typeof g?.id!="string"||g.id==="")throw new d(`${w} requires a string \`id\``,{code:"BAD_REQUEST",status:400});return v.fetch(new Request(`https://scheduler.internal${f}`,{body:JSON.stringify({id:g.id}),headers:{"content-type":"application/json"},method:"POST"}))},h=async f=>{if(f.headers.get("Upgrade")!=="websocket")throw new d("WebSocket upgrade header missing",{code:"BAD_REQUEST",status:426});if(!await t(f))throw new d("admin authorization required",{code:"ADMIN_FORBIDDEN",status:403});const w=n();return we(w,a).fetch(new Request("https://scheduler.internal/ws",{headers:{Upgrade:"websocket"}}))};return{[oa]:u("/cancel","Scheduled-cancel","Scheduled-cancel endpoint"),[ia]:u("/dead/cancel","Scheduled dead-letter action"),[aa]:i("/dead","Scheduled dead-letter"),[sa]:u("/dead/retry","Scheduled dead-letter action"),[ta]:i("/list","Scheduled-list"),[na]:i("/status","Scheduler-status"),[ra]:h}},da=(e,...t)=>{let n=e.cf;for(const o of t){if(typeof n!="object"||n===null)return;n=n[o]}return typeof n=="string"?n:void 0},Et={mtls:e=>da(e,"tlsClientAuth","certVerified")==="SUCCESS"},ua=e=>e===void 0||e===!1?()=>!1:e===!0?()=>!0:typeof e=="function"?e:(Object.hasOwn(Et,e)?Et[e]:void 0)??(()=>!1),la=e=>{if(e!==void 0)return()=>{};let t=!1;return()=>{t||(t=!0,console.warn('[lunora] Ignored an inbound `traceparent`, so this request starts a new trace instead of joining the caller\'s. That is the safe default: the header is caller-supplied, and trusting it lets any client choose which trace its spans and logs join. If this worker sits behind a gateway, service mesh, or Cloudflare Access that sets `traceparent` itself, set `trustInboundTraceContext: true` on createWorker() (or `"mtls"` to trust only edge-verified client certificates). Set it to `false` to keep this behaviour and silence this message.'))}},ha="/_lunora/admin/vector/indexes",fa="/_lunora/admin/vector/query",pa=e=>{const{readJsonBody:t,requireAdminOption:n}=e,o=async i=>{j(i,"GET","Vector-indexes");const u=n(i,e.vectorIntrospector,{code:"VECTORS_NOT_CONFIGURED",message:"vector endpoints require a `vectorIntrospector` on the worker"});return Response.json({indexes:await u.listIndexes()},{headers:{"content-type":"application/json"},status:200})},a=async i=>{j(i,"POST","Vector-query");const u=n(i,e.vectorIntrospector,{code:"VECTORS_NOT_CONFIGURED",message:"vector endpoints require a `vectorIntrospector` on the worker"});if(u.queryIndex===void 0)throw new d("vector index querying is not enabled on this worker",{code:"VECTOR_QUERY_UNSUPPORTED",status:400});const f=await t(i);if(typeof f.name!="string"||f.name==="")throw new d("Vector-query request requires a `name` string",{code:"BAD_REQUEST",status:400});if(typeof f.text!="string"||f.text==="")throw new d("Vector-query request requires a `text` string",{code:"BAD_REQUEST",status:400});if(f.topK!==void 0&&(typeof f.topK!="number"||!Number.isInteger(f.topK)||f.topK<1))throw new d("Vector-query `topK` must be a positive integer",{code:"BAD_REQUEST",status:400});const w=await u.queryIndex({name:f.name,text:f.text,topK:f.topK});return Response.json(w,{headers:{"content-type":"application/json"},status:200})};return{[ha]:o,[fa]:a}},ma="/_lunora/admin/workflows/instances",wa="/_lunora/admin/workflows/instance",ga="/_lunora/admin/workflows/status",ya={complete:!0,errored:!0,paused:!0,queued:!0,running:!0,terminated:!0,unknown:!0,waiting:!0,waitingForPause:!0},ba=e=>e!==null&&Object.hasOwn(ya,e)?e:void 0,St=(e,t)=>{const n=e.searchParams.get(t);if(n===null)return;const o=Number(n);return Number.isInteger(o)&&o>0?o:void 0},je=(e,t)=>{const n=e.searchParams.get(t);if(n===null||n==="")throw new d(`Workflows admin endpoint requires a \`${t}\` query parameter`,{code:"BAD_REQUEST",status:400});return n},At=()=>{throw new d("Workflow inspection is unconfigured. Set CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN in your .dev.vars to enable it.",{code:"WORKFLOWS_NOT_CONFIGURED",status:501})},_a=e=>{const{assertAdmin:t,resolveWorkflowsClient:n}=e,o=async(u,h,f)=>{j(u,"GET","Workflows instances"),t(u);const w=n(h);if(!w)return Response.json({configured:!1,instances:[],page:1,perPage:0,totalCount:0});const E=je(f,"name"),O=ba(f.searchParams.get("status"));return Response.json(await w.listInstances({page:St(f,"page"),perPage:St(f,"perPage"),status:O,workflowName:E}))},a=async(u,h,f)=>{j(u,"GET","Workflows instance"),t(u);const w=n(h);return w?Response.json(await w.getInstance({instanceId:je(f,"id"),workflowName:je(f,"name")})):At()},i=async(u,h)=>{j(u,"POST","Workflows status"),t(u);const f=n(h);if(!f)return At();const w=await u.json().catch(()=>{});if(typeof w?.name!="string"||w.name===""||typeof w.id!="string"||w.id==="")throw new d("Workflows status action requires string `name` and `id`",{code:"BAD_REQUEST",status:400});const{action:E}=w;if(E!=="pause"&&E!=="resume"&&E!=="terminate")throw new d("Workflows status action must be one of: pause, resume, terminate",{code:"BAD_REQUEST",status:400});return Response.json(await f.setInstanceStatus({action:E,instanceId:w.id,workflowName:w.name}))};return{[wa]:a,[ma]:o,[ga]:i}},Ra={[Wt]:Vt,[Zn]:Xn},Tt="/_lunora/rpc",Ea="/_lunora/rpc-batch",Sa="/_lunora/ws",Ee=(e,t,n)=>({resourceAttributes:ea(e,t),...n===void 0?{}:{waitUntil:n}}),$e=e=>e?.waitUntil?{waitUntil:t=>e.waitUntil?.(t)}:{},Ot=e=>({spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId,...e.parentSpanId===void 0?{}:{parentSpanId:e.parentSpanId}}),Fe=e=>{const{method:t}=e,n=e.headers.get("user-agent")??void 0;let o;try{o=new URL(e.url)}catch{return{method:t,userAgent:n}}const a=o.port===""?void 0:Number(o.port);return{host:o.hostname,method:t,path:o.pathname,port:Number.isNaN(a)?void 0:a,scheme:o.protocol.replace(":",""),userAgent:n}},vt="/_lunora/voice/",Aa="/_lunora/scheduler/dispatch",Ta="/_lunora/admin/cron-jobs/run",Oa="/_lunora/admin/ws-token",va="/_lunora/admin/",ka="/_lunora/migrate",Ia="/_lunora/status",Pa=e=>e.startsWith(va)||e===ka,Da=e=>{const t=e.headers.get("x-lunora-userid"),n=e.headers.get("x-lunora-identity");if(!(t===null&&n===null))return{...n===null?{}:{identity:n},...t===null?{}:{userId:t}}},Na="/api/auth",Ua="__lunora_admin__:recordAuthEvent",Ca="__lunora_admin__:listPushSubscriptions",Ba=["/sign-in","/sign-up","/callback"],xa=(e,t)=>{const n=t.endsWith("/")?t.slice(0,-1):t;if(!e.startsWith(`${n}/`))return!1;const o=e.slice(n.length);return Ba.some(a=>o===a||o.startsWith(`${a}/`))},Se=(e,t,n,o)=>{const a=Dn(n),i=a?n.code:"INTERNAL_SERVER_ERROR",u=a?n.status:500,h=n instanceof Error?n.message:String(n);return{durationMs:t,error:{code:i,message:h,status:u},functionPath:e,ok:!1,...o.fanOut?{fanOut:{failed:0,shards:0,table:o.fanOut.table}}:{},...o.shardKey?{shardKey:o.shardKey}:{}}},Ha=e=>{const{exp:t,expiresAtMs:n}=e;if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof t=="number"&&Number.isFinite(t))return t*1e3},kt=e=>e.waitUntil?{waitUntil:t=>{e.waitUntil?.(t)}}:void 0,La=e=>{const t=e?.queue;return typeof t=="string"&&t.length>0?t:"unknown"},ze=new WeakMap,ce=async(e,t,n,o=ze.get(e))=>{const a={"content-type":"application/json"},i=e.headers.get("authorization"),u=e.headers.get("cookie"),h=e.headers.get("x-d1-bookmark"),f=e.headers.get("x-lunora-mutation-id"),w=e.headers.get("x-lunora-client-id"),E=e.headers.get("x-lunora-client-seq");i&&(a.authorization=i),u&&(a.cookie=u),h&&(a["x-d1-bookmark"]=h),f&&(a["x-lunora-mutation-id"]=f),w&&(a["x-lunora-client-id"]=w),E&&(a["x-lunora-client-seq"]=E);const O=e.headers.get("cf-connecting-ip");if(O&&(a["x-lunora-client-ip"]=O),!n)return{claims:null,headers:a,identity:null,userId:null};const v=await n(e,t,o);if(!v||typeof v.userId!="string"||v.userId.length===0)return{claims:null,headers:a,identity:null,userId:null};a["x-lunora-userid"]=xn(v.userId);const g=Ha(v);g!==void 0&&(a["x-lunora-identity-exp"]=String(g));const{userId:b,..._}=v,p=Object.keys(_).length>0?_:null;return p&&(a["x-lunora-identity"]=Hn(p)),{claims:p,headers:a,identity:v,userId:b}},Ma=new Set(["concat","first","groupBy","max","min","rank","sum","topK"]),Ka=e=>{if(e===void 0)return;if(!e||typeof e!="object")throw new d("RPC `fanOut` must be an object",{code:"BAD_REQUEST",status:400});const t=e;if(typeof t.table!="string"||t.table.length===0)throw new d("RPC `fanOut.table` must be a non-empty string",{code:"BAD_REQUEST",status:400});if(!t.merge||typeof t.merge!="object")throw new d("RPC `fanOut.merge` must be an object",{code:"BAD_REQUEST",status:400});const n=t.merge;if(typeof n.kind!="string"||!Ma.has(n.kind))throw new d("RPC `fanOut.merge.kind` is not a recognized merge strategy",{code:"BAD_REQUEST",status:400});if(n.kind==="topK"){if(typeof n.k!="number"||!Number.isInteger(n.k)||n.k<0)throw new d("RPC `fanOut.merge.k` must be a non-negative integer",{code:"BAD_REQUEST",status:400});if(typeof n.by!="string"||n.by.length===0)throw new d("RPC `fanOut.merge.by` must be a non-empty string",{code:"BAD_REQUEST",status:400})}return t},ja=(e,t)=>{e?.LUNORA_DEBUG_RPC&&console.warn(`[lunora:rpc] ${t.fanOut?"fan-out":`shard=${t.shardKey??"(root)"}`} ${t.functionPath}`)},Ge=(e,t)=>{const n=t.functions?.[e.functionPath]?.x402;if(n){if(e.fanOut)throw new d("a paid (`.x402`) function cannot be fanned out",{code:"BAD_REQUEST",status:400});if(!t.x402Charge)throw new d(`function "${e.functionPath}" is marked paid (.x402) but no x402Charge gate is configured on the worker`,{code:"MISCONFIGURED",status:500});return n}},$a=async e=>{const t=await Bt(e);let n;try{n=JSON.parse(t)}catch{throw new d("RPC body must be valid JSON",{code:"BAD_REQUEST",status:400})}if(!n||typeof n!="object"||typeof n.functionPath!="string")throw new d("RPC envelope is missing `functionPath`",{code:"BAD_REQUEST",status:400});const o=n;if(o.args!==void 0&&Ct(o.args,"RPC"),o.shardKey!==void 0&&typeof o.shardKey!="string")throw new d("RPC `shardKey` must be a string",{code:"BAD_REQUEST",status:400});const a=n,i=Ka(a.fanOut),u=a.args??{};if(i&&a.functionPath.startsWith("__lunora_relation__:")){const h=u.table;if(typeof h=="string"&&h!==i.table)throw new d("RPC `args.table` must match the authorized `fanOut.table` for a relation fan-out",{code:"BAD_REQUEST",status:400});u.table=i.table}return{args:u,fanOut:i,functionPath:a.functionPath,shardKey:a.shardKey}},Ae=new Map,Fa=5e3,Ga=4096,Qa=async(e,t)=>{const n=Date.now(),o=Ae.get(t);if(o!==void 0&&o.expiresMs>n)return o.relayCount;o!==void 0&&Ae.delete(t);let a=0;try{const i=await we(e,t).fetch(new Request("https://shard.internal/_lunora/route"));if(i.ok){const h=(await i.json()).relayCount;typeof h=="number"&&h>0&&(a=Math.floor(h))}}catch{a=0}return Nt(Ae,Ga),Ae.set(t,{expiresMs:n+Fa,relayCount:a}),a},It=(e,t)=>{if(!(e===null||typeof e!="object"))return Object.entries(e).find(([,n])=>n===t)?.[0]},ye=(e,t,n)=>new Request("https://shard.internal/rpc",{body:JSON.stringify({args:t,functionPath:e}),headers:n,method:"POST"}),za=["x-lunora-userid","x-lunora-identity","x-lunora-identity-exp"],Wa=(e,t)=>{for(const n of za){e.delete(n);const o=t[n];o!==void 0&&e.set(n,o)}},Pt=(e,t)=>{const n=new Headers(e.headers),o=[...n.keys()];for(const a of o)a.startsWith("x-lunora-")&&n.delete(a);return Wa(n,t),n},Va=async(e,t,n)=>e.length===0||n.length===0?!1:Je(await Mt(e,t),n),Dt=(e,t)=>{if(!t||t.length===0)return!1;const n=e.headers.get("authorization");if(!n)return!1;const[o,...a]=n.split(" ");return o?.toLowerCase()!=="bearer"?!1:Je(t,a.join(" ").trim())},Ja=async(e,t,n)=>{if(!t||t.length===0)return!1;const o=new URL(e.url).searchParams.get("token");return o===null?!1:await Ur(t,o)?!0:n?!1:Je(t,o)},qa=(e,t)=>{if(t===null||typeof t!="object"&&typeof t!="function")return;const n=t;if(typeof n.prepare=="function"&&typeof n.batch=="function"&&typeof n.dump=="function")return sr(`d1:${e}`,t);if(typeof n.list=="function"&&typeof n.head=="function"&&typeof n.createMultipartUpload=="function")return Be(`r2:${e}`,!0);if(typeof n.send=="function"&&typeof n.sendBatch=="function"&&typeof n.get!="function")return Be(`queue:${e}`,!0);if(typeof n.connectionString=="string")return Be(`hyperdrive:${e}`,!0)},Jt=e=>{const t=ua(e.trustInboundTraceContext),n=la(e.trustInboundTraceContext),o=e.defaultShardKey??"__root__",a=ir(e.resolveIdentity,e.identity),i=it(e.shardDO,e.jurisdiction),u=e.schedulerDO===void 0?void 0:it(e.schedulerDO,e.jurisdiction);let h=!1;const f=r=>{if(r===void 0||e.jurisdiction===void 0)return r;h||(h=!0,console.warn(`[lunora] jurisdiction "${e.jurisdiction}" pins placement, so region hints (\`shardRegion\`, replica and relay placement) are not sent. Residency wins.`))},w=async(r,s,l,c=e.shardRegion?.(s))=>we(r,s,f(c)).fetch(l);let E;const O=()=>e.adminToken??E;let v;const g=()=>e.requireEphemeralWsToken??v??!0;let b;const _=r=>{const s=r??{};if(b??=It(r,e.shardDO),v===void 0&&e.requireEphemeralWsToken===void 0){const c=s.LUNORA_REQUIRE_EPHEMERAL_WS_TOKEN;typeof c=="string"&&c.length>0&&(v=Pr(c,!0))}if(E!==void 0||e.adminToken!==void 0)return;const l=s.LUNORA_ADMIN_TOKEN;typeof l=="string"&&l.length>0&&(E=l)},p=new WeakSet,A=r=>Dt(r,O())||p.has(r),D=async(r,s)=>{const l=await ce(r,s,e.resolveIdentity);if(p.has(r)&&l.headers.authorization===void 0){const c=O();c!==void 0&&(l.headers.authorization=`Bearer ${c}`)}return l};let M=!1,I=!1;const F=()=>{I||(I=!0,console.warn("[lunora] `replicaReads: true` has no effect without `functions` — read eligibility is decided from the function registry."))},H=r=>{if(!e.allowUnauthenticatedShardAccess){const s=r==="fan-out"?"authorizeFanOut":"authorizeShard";throw new d(`${r} access is default-denied: configure \`${s}\` on the worker, or set \`allowUnauthenticatedShardAccess: true\` to explicitly allow unauthenticated ${r} access (relying solely on per-row RLS).`,{code:r==="fan-out"?"FORBIDDEN_FANOUT":"FORBIDDEN_SHARD",status:403})}M||(M=!0,console.warn([`[lunora] SECURITY: serving ${r} access with \`allowUnauthenticatedShardAccess: true\` and no \`authorizeShard\`/\`authorizeFanOut\` — `,"any caller (including unauthenticated ones) can target any shard / fan out across the table. ","This is safe only if every table is protected by per-row RLS. Configure `authorizeShard`/`authorizeFanOut` to gate it."].join("")))},Y=async(r,s)=>{if(e.authorizeShard){if(!await e.authorizeShard({identity:r,shardKey:s}))throw new d("Forbidden shard",{code:"FORBIDDEN_SHARD",status:403})}else s!==o&&H("shard")},U=Go({defaultShard:o,forwardToShard:w,isAdmin:A,queryCoordinator:e.queryCoordinator,resolveForwardContext:D,shardDO:i}),G=async(r,s,l,c,m)=>{const R={"content-type":"application/json","x-lunora-system":"1"};return m?.userId!==void 0&&m.userId.length>0&&(R["x-lunora-userid"]=m.userId),m?.identity!==void 0&&m.identity.length>0&&(R["x-lunora-identity"]=m.identity),c!==void 0&&c.length>0&&(R["x-lunora-mutation-id"]=c),w(i,l,ye(r,s,R))},Q=async(r,s,l,c)=>{const m=l?.[r];if(!m||typeof m.create!="function")throw new d(`${c} targets workflow binding "${r}", which is not bound on env`,{code:"CRON_JOB_FAILED",status:500});if(fr(s))throw new d(`${c} params ${pr}`,{code:"BAD_REQUEST",status:400});await m.create({params:s})},J=async(r,s)=>{if(r.workflow){await Q(r.workflow,r.args??{},s,`cron job "${r.name}"`);return}if(r.functionPath===void 0)throw new d(`cron job "${r.name}" has neither a function target nor a workflow target`,{code:"CRON_JOB_FAILED",status:500});const l=await G(r.functionPath,r.args??{},r.shardKey??o);if(!l.ok)throw new d(`cron job "${r.name}" (${r.functionPath}) failed with shard status ${String(l.status)}`,{code:"CRON_JOB_FAILED",status:500})},K=r=>{if(!A(r))throw new d("admin endpoint requires a valid admin bearer",{code:"ADMIN_FORBIDDEN",status:403})},$=(r,s,l)=>{if(K(r),s===void 0)throw new d(l.message,{code:l.code,status:400});return s},oe=async(r,s,l,c)=>{const m=e.cronJobs?.[r];if(m)for(const R of m)try{await J(R,s)}catch(k){l.push(c(k))}},z=async(r,s)=>{if(K(r),j(r,"POST","cron-jobs run"),!e.cronJobs)throw new d("cron-jobs run endpoint requires a `cronJobs` map on the worker",{code:"CRON_JOBS_NOT_CONFIGURED",status:400});const l=await Z(r),c=typeof l.name=="string"?l.name:"";if(c==="")throw new d("cron-jobs run endpoint requires a job `name`",{code:"BAD_REQUEST",status:400});const m=Object.values(e.cronJobs).flat().find(R=>R.name===c);if(!m)throw new d(`no cron job named "${c}" is registered`,{code:"CRON_JOB_NOT_FOUND",status:404});return await J(m,s),Response.json({name:c,ran:!0},{status:200})},de=async r=>{const s=typeof r.pool=="string"&&r.pool.length>0?r.pool:void 0;if(!s||!u||typeof r.id!="string")return;const l=typeof r.instanceName=="string"&&r.instanceName.length>0?r.instanceName:"default";try{await we(u,l).fetch(new Request("https://scheduler.internal/complete",{body:JSON.stringify({id:r.id,pool:s}),headers:{"content-type":"application/json"},method:"POST"}))}catch{}},ue=async(r,s)=>{j(r,"POST","Scheduler dispatch");const l=await Bt(r),c=s??{},m=typeof c.LUNORA_SCHEDULER_SECRET=="string"?c.LUNORA_SCHEDULER_SECRET:void 0,R=e.adminToken??(typeof c.LUNORA_ADMIN_TOKEN=="string"?c.LUNORA_ADMIN_TOKEN:void 0),k=r.headers.get("x-lunora-scheduler-signature");let y=!1;if(k&&m?y=await Va(m,l,k):R&&(y=Dt(r,R)),!y)throw new d("Scheduler dispatch requires a valid signature or admin bearer",{code:"FORBIDDEN",status:403});let S;try{S=JSON.parse(l)}catch{throw new d("Scheduler dispatch body must be valid JSON",{code:"BAD_REQUEST",status:400})}const T=S??{},B=T.args??{};if(typeof T.workflow=="string"&&T.workflow.length>0)return await Q(T.workflow,B,s,"scheduled workflow"),await de(T),Response.json({ok:!0},{status:200});if(typeof T.functionPath!="string"||T.functionPath.length===0)throw new d("Scheduler dispatch is missing `functionPath`",{code:"BAD_REQUEST",status:400});const x=typeof T.shardKey=="string"&&T.shardKey.length>0?T.shardKey:o,C=typeof T.id=="string"&&T.id.length>0?T.id:void 0,te=Da(r),L=await G(T.functionPath,B,x,C,te);return await de(T),L},_e=Lr({assertAdmin:K,getReader:()=>e.authAuditReader}),Oe=async(r,s)=>{K(r);const l=e.notifySubscriptionStore;if(l===void 0)return Response.json({result:Qe({subscriptions:[]})},{headers:{"content-type":"application/json"},status:200});const c=s?.kind,m=s?.userId,R=s?.limit,k=c==="fcm"||c==="web-push"?c:void 0,y=typeof m=="string"&&m!==""?m:void 0,S=typeof R=="number"&&Number.isFinite(R)?Math.trunc(R):0,T=S>0?Math.min(S,1e3):1e3,x=(await l.list({kind:k,limit:T,userId:y})).filter(C=>k!==void 0&&C.kind!==k?!1:y===void 0||(C.userId??null)===y).map(({keys:C,token:te,...L})=>L);return Response.json({result:Qe({subscriptions:x})},{headers:{"content-type":"application/json"},status:200})},ve=async(r,s)=>{if(!s.fanOut){if(s.functionPath===Hr)return _e(r,s.args??{});if(s.functionPath===Ca)return Oe(r,s.args)}},ae=co({applyGlobals:e.applyGlobals,assertAdmin:K,exportCursorStore:e.exportCursorStore,exportSinks:e.exportSinks,defaultShardKey:o,knownTables:()=>[...e.listSchemaTables?.()??[]],queryCoordinator:e.queryCoordinator,requireAdminOption:$,resolveForwardContext:D,shardDO:i,streamExportRows:(r,s,l,c)=>Gt(e,r,s,l,c,i),streamingImport:(r,s)=>po(r,e,s,i),syncGlobals:e.syncGlobals}),ke=(r,s)=>{const l=r.searchParams.get(s);return l===null||l===""?void 0:l},Ie=r=>{const s=new URL(r.url),l=s.searchParams.get("limit"),c=s.searchParams.get("offset"),m=l===null?void 0:Number.parseInt(l,10),R=c===null?void 0:Number.parseInt(c,10);return{limit:m!==void 0&&Number.isFinite(m)&&m>=0?m:void 0,offset:R!==void 0&&Number.isFinite(R)&&R>=0?R:void 0}},Xe=()=>{if(u===void 0)throw new d("scheduled endpoints require a `schedulerDO` namespace on the worker",{code:"SCHEDULER_NOT_CONFIGURED",status:400});return u},qt=ca({checkWsAdmin:async r=>A(r)||Ja(r,O(),g()),requireSchedulerNamespace:Xe,resolveSchedulerStub:r=>(K(r),we(Xe(),e.schedulerInstanceName??"default")),schedulerInstanceName:e.schedulerInstanceName??"default"}),Yt=_a({assertAdmin:K,resolveWorkflowsClient:e.workflowsClient??(()=>{})}),Xt=Yn({assertAdmin:K,parsePaging:Ie,queryParameter:ke,readBodyBytes:zn,requireAdminOption:$,storage:{storageBuckets:e.storageBuckets,storageDelete:e.storageDelete,storageDownload:e.storageDownload,storageList:e.storageList,storageSignedUrl:e.storageSignedUrl,storageUpload:e.storageUpload}}),Zt=Yr({options:e,readJsonBody:Z,requireAdminOption:$}),en=pa({readJsonBody:Z,requireAdminOption:$,vectorIntrospector:e.vectorIntrospector}),tn=Io({kvIntrospector:e.kvIntrospector,readJsonBody:Z,requireAdminOption:$}),nn=cr({logArchive:e.logArchive,readJsonBody:Z,requireAdminOption:$}),rn=Oo({assertAdmin:K,options:{cronJobs:e.cronJobs,functions:e.functions,globalIntrospector:e.globalIntrospector,openApiSpec:e.openApiSpec,openRpcSpec:e.openRpcSpec},parsePaging:Ie,queryParameter:ke,requireAdminOption:$}),on=r=>{const s=[],l=i??r?.SHARD;if(l!==void 0&&s.push(ar("durable-object:default",l,o)),e.health?.disableBindingProbes!==!0)for(const[c,m]of Object.entries(r??{})){const R=qa(c,m);R!==void 0&&s.push(R)}for(const c of e.health?.probes??[])s.push(c);return s},an=or({appName:e.health?.appName,appVersion:e.health?.appVersion,auth:e.health?.auth??"public",cacheTtlMs:e.health?.cacheTtlMs,isAdmin:A,resolveProbes:on}),sn=r=>{const s=e.schedulerInstanceName??"default",l=()=>we(r,s),c=async(y,S)=>{const T=await l().fetch(new Request(`https://scheduler.internal${y}`,S));if(!T.ok)throw new d(`ctx.scheduler: SchedulerDO ${y} failed (${String(T.status)}): ${await T.text()}`,{code:"INTERNAL",status:500});return await T.json()},m=async(y,S)=>await c(y,{body:JSON.stringify(S),headers:{"content-type":"application/json"},method:"POST"}),R=y=>{const S=y;if(S==null)throw new d("ctx.scheduler: target is required — pass a reference from the generated `internal` / `workflows` / `agents`",{code:"BAD_REQUEST",status:400});if(typeof S.binding=="string"&&S.binding.length>0)return{workflow:S.binding};if(typeof S.__lunoraRef=="string")return{functionPath:S.__lunoraRef};throw new d("ctx.scheduler: expected a reference from the generated `internal` / `workflows` / `agents` — a bare function-path string is refused here, because an HTTP action can be reached unauthenticated",{code:"BAD_REQUEST",status:400})},k=async(y,S,T={})=>{const{id:B}=await m("/schedule",{args:T,scheduledFor:y,...R(S)});return B};return{cancel:async y=>await m("/cancel",{id:y}),get:async y=>await c(`/get?id=${encodeURIComponent(y)}`,{method:"GET"}),list:async()=>await c("/list",{method:"GET"}),runAfter:async(y,S,T)=>{if(!Number.isFinite(y)||y<0)throw new d("ctx.scheduler.runAfter: `delayMs` must be a non-negative finite number",{code:"BAD_REQUEST",status:400});return await k(Date.now()+y,S,T)},runAt:async(y,S,T)=>{if(!Number.isFinite(y))throw new d("ctx.scheduler.runAt: `timestampMs` must be a finite epoch-millisecond number",{code:"BAD_REQUEST",status:400});return await k(y,S,T)}}},cn=async(r,s,l)=>{const{claims:c,headers:m,userId:R}=await ce(r,s,a),k=async(y,S={})=>{const T=y.__lunoraRef;if(typeof T!="string")throw new d("ctx.run*: expected a function reference from the generated `api`",{code:"BAD_REQUEST",status:400});const B=ye(T,S,{...m,"x-lunora-system":"1"}),x=await w(i,o,B),C=await x.json();if(C.error)throw new d(C.error.message??"shard RPC failed",{code:C.error.code??"INTERNAL",status:x.status});return C.result};return{auth:{getIdentity:()=>Promise.resolve(c),userId:R},cache:l.cache,fetch:globalThis.fetch.bind(globalThis),runAction:k,runMutation:k,runQuery:k,...u===void 0?{}:{scheduler:sn(u)},...e.storage===void 0?{}:{storage:hr(e.storage(s))}}},dn=async(r,s,l)=>{if(!e.httpRouter)return;const c=await cn(r,s,l);try{return await e.httpRouter.fetch(r,{...s,__lunoraCtx:c},l)}catch(m){return console.error("[lunora] httpRouter (SSR) handler threw:",m),new Response("Internal Server Error",{status:500})}},un=async(r,s,l)=>{if(r.headers.get("Upgrade")!=="websocket")throw new d("WebSocket upgrade header missing",{code:"BAD_REQUEST",status:426});const c=dt(r,se);if(c)return c;const m=l.searchParams.get("shard")??o,{headers:R,identity:k}=await ce(r,s,a);await Y(k,m);const y=Pt(r,R),S=It(s,e.shardDO);if(S!==void 0){y.set("x-lunora-shard-binding",S);const T=await Qa(i,m);if(T>0){const B=Tr(m,Math.floor(Math.random()*T));return w(i,B,new Request(r,{headers:y}),ut(r))}}return w(i,m,new Request(r,{headers:y}))},ln=async(r,s,l)=>{const{voiceAgents:c}=e;if(c===void 0)return new Response("Not found",{status:404});if(r.headers.get("Upgrade")!=="websocket")return new Response("Expected a WebSocket upgrade",{headers:{allow:"GET"},status:426});const m=dt(r,se);if(m)return m;let R;try{R=decodeURIComponent(l.pathname.slice(vt.length))}catch{return new Response("Unknown voice agent",{status:404})}const k=Object.hasOwn(c,R)?c[R]:void 0;if(k===void 0)return new Response("Unknown voice agent",{status:404});const y=l.searchParams.get("threadKey");if(y===null||y.length===0)return new Response("Missing threadKey",{status:400});const{headers:S,identity:T}=await ce(r,s,a);if(e.authorizeShard){if(!await e.authorizeShard({identity:T,shardKey:y}))throw new d("Forbidden shard",{code:"FORBIDDEN_SHARD",status:403})}else H("shard");const B=Pt(r,S);return w(k,y,new Request(r,{headers:B}))},hn=async(r,s,l)=>{if(e.authorizeFanOut){if(!await e.authorizeFanOut(l,r.table,s))throw new d("Forbidden fan-out",{code:"FORBIDDEN_FANOUT",status:403});return}if(s.startsWith("__lunora_relation__:"))throw new d("reverse cross-backend relation reads (`__lunora_relation__:*`) require `authorizeFanOut` to be configured on the worker",{code:"FORBIDDEN_FANOUT",status:403});if(e.authorizeShard)throw new d("Fan-out requires `authorizeFanOut` to be configured on the worker when `authorizeShard` is set",{code:"FORBIDDEN_FANOUT",status:403});H("fan-out")},Re=async(r,s)=>{if(!(!r.fanOut&&r.functionPath.startsWith("__lunora_admin__:"))){if(r.fanOut){await hn(r.fanOut,r.functionPath,s);return}await Y(s,r.shardKey??o)}},fn=(r,s,l)=>{if(e.replicaReads!==!0)return;if(e.functions===void 0){F();return}if(e.functions[s]?.kind!=="query"||l.includes(jt)||l.includes(Kt))return;const c=ut(r);return c===void 0?void 0:{name:Or(l,c),region:c}},pn=async(r,s,l,c,m)=>{const R=fn(r,s,c);if(R!==void 0){const k={...m,"x-lunora-replica-read":"1",...b===void 0?{}:{"x-lunora-shard-binding":b}},y=vr(r.headers.get("x-lunora-min-seq"));y!==void 0&&(k["x-lunora-min-seq"]=String(y));const S=await w(i,R.name,ye(s,l,k),R.region);if(S.status!==421)return S}return w(i,c,ye(s,l,m))},Pe=async(r,s,l,c,m,R)=>{const k=Date.now(),{observability:y,sampling:S}=e,T=Fe(r),{decision:B,ignoredUpstream:x,trace:C}=Xo(r,{...S===void 0?{}:{sampling:S},trustInbound:t(r)});x&&n();const te={...m,"x-lunora-sample-errors":B.keepErrors?"1":"0"};Zo(C,te);try{const L=await pn(r,s,l,c,te);ie(y,{...T,...Ot(C),durationMs:Date.now()-k,functionPath:s,ok:L.ok,shardKey:c,...L.ok?{}:{error:{code:"SHARD_ERROR",message:`shard returned ${String(L.status)}`,status:L.status}}},R,void 0,{isTraced:C.sampled,keepErrors:B.keepErrors});const ee=new Response(L.body,{headers:L.headers,status:L.status,statusText:L.statusText});return ee.headers.set("x-lunora-shard-key",c),ee}catch(L){throw ie(y,{...T,...Ot(C),...Se(s,Date.now()-k,L,{shardKey:c})},R,void 0,{isTraced:C.sampled,keepErrors:B.keepErrors}),L}},mn=r=>{if(r.fanOut&&r.shardKey)throw new d("RPC envelope cannot set both `shardKey` and `fanOut`",{code:"BAD_REQUEST",status:400});if(!r.fanOut&&r.functionPath.startsWith("__lunora_relation__:"))throw new d("`__lunora_relation__:*` is a fan-out-only reserved RPC and cannot be dispatched to a single shard",{code:"FORBIDDEN",status:403});if(r.fanOut&&!e.queryCoordinator)throw new d("RPC envelope set `fanOut` but no `queryCoordinator` is configured on the worker",{code:"BAD_REQUEST",status:400})},wn=async(r,s,l)=>{j(r,"POST","RPC");const c=await $a(r);ja(s,c),mn(c);const m=await ve(r,c);if(m!==void 0)return m;const{headers:R,identity:k}=await ce(r,s,a);await Re(c,k);const y=Ge(c,e);{const S=Date.now(),{observability:T}=e,B=Fe(r),x=Ee(s,r,l&&(L=>l.waitUntil?.(L)));if(c.fanOut){const L=e.queryCoordinator;if(!L)throw new d("RPC envelope set `fanOut` but no `queryCoordinator` is configured on the worker",{code:"BAD_REQUEST",status:400});try{const ee=await L.fanOut(i,{args:c.args??{},fanOut:c.fanOut,functionPath:c.functionPath,headers:R});return ie(T,{durationMs:Date.now()-S,fanOut:{failed:ee.failed,shards:ee.ok+ee.failed,table:c.fanOut.table},functionPath:c.functionPath,...B,ok:!0},x),Response.json(ee,{headers:{"content-type":"application/json"},status:200})}catch(ee){throw ie(T,{...Se(c.functionPath,Date.now()-S,ee,{fanOut:{table:c.fanOut.table}}),...B},x),ee}}const C=c.shardKey??o,te=()=>Pe(r,c.functionPath,c.args??{},C,R,x);return y&&e.x402Charge?e.x402Charge(r,{functionPath:c.functionPath,price:y.price},te,$e(l)):te()}},gn=async(r,s,l)=>{j(r,"POST","RPC batch");const c=await Z(r),{calls:m}=c;if(!Array.isArray(m))throw new d("RPC batch `calls` must be an array",{code:"BAD_REQUEST",status:400});const{headers:R,identity:k}=await ce(r,s,a),y=Zr(m,o);for(const W of y.values())for(const V of W)if(e.functions?.[V.functionPath]?.x402)throw new d(`paid (\`.x402\`) function "${V.functionPath}" cannot be called in a batch; dispatch it individually over ${Tt}`,{code:"BAD_REQUEST",status:400});await Promise.all([...y.entries()].flatMap(([W,V])=>V.map(ne=>Re({args:ne.args,functionPath:ne.functionPath,shardKey:W},k))));const{observability:S}=e,T=Ee(s,r,l&&(W=>l.waitUntil?.(W))),B=Fe(r),x=[],C=[],te=(W,V,ne,le)=>({body:{error:{code:ne,message:le}},id:W.id,status:V}),L=(W,V,ne,le,fe)=>{for(const q of W)ie(S,fe(q),T),x.push(te(q,V,ne,le))},ee=(W,V,ne,le,fe)=>{for(const q of W){const pe=le.get(q.id)??fe,ge=pe<400;ie(S,{durationMs:ne,functionPath:q.functionPath,...B,ok:ge,shardKey:V,...ge?{}:{error:{code:"SHARD_ERROR",message:`batched call returned ${String(pe)}`,status:pe}}},T)}};await Promise.all([...y.entries()].map(async([W,V])=>{const ne=new Headers(R);ne.set("content-type","application/json");const le=new Request("https://shard.internal/rpc-batch",{body:JSON.stringify({calls:V}),headers:ne,method:"POST"}),fe=Date.now();let q;try{q=await w(i,W,le)}catch(X){const Ce=Date.now()-fe,{body:rt}=Nn(X,{fallbackCode:"SHARD_UNAVAILABLE",redactedMessage:"shard unavailable"});L(V,502,rt.code,rt.message,Pn=>({...Se(Pn.functionPath,Ce,X,{shardKey:W}),...B}));return}const pe=Date.now()-fe,ge=q.headers.get("x-d1-bookmark");ge&&C.push(ge);let Ne;try{Ne=await q.json()}catch{const X=`shard batch returned a non-JSON response (${String(q.status)})`;L(V,q.status,"SHARD_ERROR",X,Ce=>({durationMs:pe,error:{code:"SHARD_ERROR",message:X,status:q.status},functionPath:Ce.functionPath,...B,ok:!1,shardKey:W}));return}const Ue=Array.isArray(Ne.results)?Ne.results:[],kn=new Map(Ue.map(X=>[X.id,X.status??q.status])),In=new Set(Ue.map(X=>X.id));ee(V,W,pe,kn,q.status),x.push(...Ue);for(const X of V)In.has(X.id)||x.push(te(X,q.status,"SHARD_ERROR",`shard batch omitted result for call ${String(X.id)}`))}));const tt={"content-type":"application/json"},[nt]=C;return C.length===1&&nt!==void 0&&(tt["x-d1-bookmark"]=nt),Response.json({results:x},{headers:tt,status:200})},yn=async(r,s,l,c={},m={})=>{try{const R=l.__lunoraRef;if(typeof R!="string")throw new d("serverQuery: expected a function reference from the generated `api`",{code:"BAD_REQUEST",status:400});const{headers:k,identity:y}=await ce(r,s,a,m.context),S={args:c,functionPath:R,shardKey:m.shardKey};await Re(S,y);const T=m.shardKey??o,B=Ee(s,r,m.waitUntil),x=()=>Pe(r,R,c,T,k,B),C=Ge(S,e);return C&&e.x402Charge?await e.x402Charge(r,{functionPath:R,price:C.price},x,$e(m.waitUntil?{waitUntil:m.waitUntil}:m.context)):await x()}catch(R){return ot(R)}},Ze=async(r,s,l)=>{const{observability:c}=e,m=Date.now(),R=Te(16),k=Te(8),y=kt(s);try{const S=await l();return ie(c,{durationMs:Date.now()-m,functionPath:r,ok:!0,spanId:k,traceId:R},y),S}catch(S){throw ie(c,{...Se(r,Date.now()-m,S,{}),spanId:k,traceId:R},y),S}finally{st(c,y)}},bn=async(r,s,l)=>{_(s);const c=[],m=y=>y instanceof Error?y:new Error(String(y)),R=e.crons?.[r.cron];if(R)try{await R(r,s,l)}catch(y){c.push(m(y))}if(await oe(r.cron,s,c,m),e.backupStore&&e.backupCron!==void 0&&e.backupCron===r.cron)try{await Wr(e,i,O(),r)}catch(y){c.push(m(y))}const[k]=c;if(c.length===1&&k)throw k;if(c.length>1)throw new AggregateError(c,`scheduled("${r.cron}") had ${String(c.length)} failure(s)`)},_n=async(r,s)=>{try{const l=r??{},c=e.adminToken??(typeof l.LUNORA_ADMIN_TOKEN=="string"?l.LUNORA_ADMIN_TOKEN:void 0);if(!c||c.length===0)return;await w(i,o,ye(Ua,{outcome:s},{authorization:`Bearer ${c}`,"content-type":"application/json"}))}catch{}},Rn=async(r,s,l,c)=>{if(!e.authHandler)return;const m=await e.authHandler(r);if(!m)return;const R=e.authBasePath??Na;return xa(l.pathname,R)&&c.waitUntil?.(_n(s,m.status>=400?"fail":"ok")),m},En=async({args:r,env:s,functionPath:l,request:c,shardKey:m,waitUntil:R})=>{Ct(r,"REST");const k={functionPath:l,...m===void 0?{}:{shardKey:m}},{headers:y,identity:S}=await ce(c,s,a);await Re(k,S);const T=m??o,B=Ee(s,c,R),x=()=>Pe(c,l,r,T,y,B),C=Ge(k,e);return C&&e.x402Charge?e.x402Charge(c,{functionPath:l,price:C.price},x,$e({waitUntil:R})):x()},Sn=Qn({functions:e.functions??{},invoke:En,readJsonBody:Z,edgeCache:e.restEdgeCache,...e.restRateLimit?{rateLimit:e.restRateLimit}:{}}),De=e.routes!==void 0&&Object.keys(e.routes).length>0?e.routes:void 0,An={[Ia]:r=>r.method!=="GET"&&r.method!=="HEAD"?new Response(void 0,{headers:{allow:"GET, HEAD"},status:405}):Response.json({ok:!0},{headers:{"cache-control":"no-store"}}),[Sa]:(r,s,l)=>un(r,s,l),[Tt]:(r,s,l,c)=>wn(r,s,c),[Ea]:(r,s,l,c)=>gn(r,s,c),[Aa]:(r,s)=>ue(r,s),[Ta]:(r,s)=>z(r,s),[Oa]:async r=>{j(r,"POST","ws-token"),K(r);const s=O();if(s===void 0)throw new d("ws-token minting requires a configured admin token",{code:"ADMIN_TOKEN_NOT_CONFIGURED",status:400});const l=await Nr(s);return Response.json(l,{headers:{"cache-control":"no-store"}})},...U,...ae,...qt,...Yt,...Xt,...Zt,...en,...tn,...nn,...rn,...an,...Sn,...xr({assertAdmin:K,getAuthAdmin:()=>e.authAdmin,parsePaging:Ie,queryParameter:ke,readJsonBody:Z})};let se=ct(e.security),et=!1;const Tn=r=>{et||(et=!0,se=ct(e.security,r??{}))},On=async(r,s)=>{if(!(e.adminGate===void 0||!Pa(s)))try{await e.adminGate(r,ze.get(r))&&p.add(r)}catch{}},vn=async(r,s,l)=>{ze.set(r,l);const c=new URL(r.url);if(r.method==="POST"||r.method==="PUT"){const y=Number(r.headers.get("content-length")??""),S=Ra[c.pathname]??Ut;if(Number.isFinite(y)&&y>S)throw new d("Body too large",{code:"PAYLOAD_TOO_LARGE",status:413})}const m=await Rn(r,s,c,l);if(m)return m;if(De){const y=`${r.method} ${c.pathname}`,S=De[y]??De[c.pathname];if(S)return S(r,s,l)}const R=An[c.pathname];if(R)return await On(r,c.pathname),R(r,s,c,l);if(e.voiceAgents!==void 0&&c.pathname.startsWith(vt))return ln(r,s,c);const k=await dn(r,s,l);return k||new Response("Not found",{status:404})};return{async fetch(r,s,l){e.passThroughOnException&&l.passThroughOnException?.(),Tn(s),_(s);const c=ur(r,se);if(c)return c;const m=lr(r,se);if(m)return xe(m,r,se);try{const R=await vn(r,s,l);return xe(R,r,se)}catch(R){return xe(ot(R),r,se)}finally{st(e.observability,kt(l))}},async queue(r,s,l){await Ze(`queue:${La(r)}`,l,async()=>{await e.queue?.(r,s,l)})},async scheduled(r,s,l){await Ze(`cron:${r.cron}`,l,async()=>{await bn(r,s,l)})},serverQuery:yn}},Ya=e=>Jt(e),Xa=e=>typeof e=="function"?{fetch:e}:e,Za=e=>!!(e.crons??e.cronJobs??e.backupCron),Rs=(e,t)=>{const n=Xa(e),o=typeof e=="object"&&typeof e.scheduled=="function"?e.scheduled:void 0,a=u=>{const h=Ya({...u,httpRouter:n});return o!==void 0&&!Za(u)?{...h,scheduled:async(f,w,E)=>{await o(f,w,E)}}:h};if(typeof t!="function")return a(t);const i=t;return{fetch:(u,h,f)=>a(i(h)).fetch(u,h,f),queue:(u,h,f)=>a(i(h)).queue?.(u,h,f)??Promise.resolve(),scheduled:(u,h,f)=>a(i(h)).scheduled(u,h,f),serverQuery:(u,h,f,w,E)=>a(i(h)).serverQuery(u,h,f,w,E)}},es=(e,t)=>{if(typeof e=="function")return e(t);const n=e.shardDO??t?.SHARD;if(!n)throw new d("@lunora/runtime: no shard Durable Object namespace found. Bind `SHARD` in wrangler.jsonc, or pass `createLunoraHandler({ shardDO: env.MY_SHARD })`.");return{...e,shardDO:n}},Es=(e={})=>(t,n,o)=>Jt(es(e,n)).fetch(t,n,o??Un),Ss=e=>e;export{Hr as GET_AUTH_AUDIT_LOG_OP,Un as NOOP_EXECUTION_CONTEXT,Os as composeIdentityResolvers,Ya as composeWorker,Es as createLunoraHandler,Jt as createWorker,Ss as defineRpcEnvelope,Qa as probeRelayCount,es as resolveLunoraOptions,vs as routeIdentityResolvers,Rs as withFrameworkWorker};
@@ -1 +0,0 @@
1
- import{b as T,a as E}from"./base64-Bl1_r2k1.mjs";import{LunoraError as U}from"./LunoraError-DksAgIpa.mjs";import{resolveShard as I}from"./applyJurisdiction-C0ddU7Tg.mjs";const pe=r=>({listShardKeys(e){return r[e]??[]}}),F=16,B=5e3,h=r=>r!==null&&typeof r=="object"&&"result"in r?r.result:r,V=r=>{const e=r??{};return{changed:typeof e.changed=="number"?e.changed:0,processed:typeof e.processed=="number"?e.processed:0,status:typeof e.status=="string"?e.status:void 0}},D=(r,e)=>r?"failed":e?"in_progress":"completed",L=r=>{const e=[];let s=0,n=0,t=0,o=0,a=!1,c=!1;for(const i of r){if(i.kind==="err"){n+=1,e.push({error:{message:i.message,timedOut:i.timedOut},shardKey:i.shardKey});continue}s+=1;const l=h(i.value),u=V(l);t+=u.changed,o+=u.processed,a||=u.status==="in_progress",c||=u.status==="failed",e.push({result:l,shardKey:i.shardKey})}return{changed:t,failed:n,ok:s,processed:o,shards:e,status:D(c,a||n>0)}},j=r=>{const e=r??{};return{before:typeof e.before=="number"&&Number.isFinite(e.before)?e.before:0,total:typeof e.total=="number"&&Number.isFinite(e.total)?e.total:0}},J=r=>{const e=[];let s=0,n=0,t=0,o=0;for(const a of r){if(a.kind==="err"){n+=1,e.push({error:{message:a.message,timedOut:a.timedOut},shardKey:a.shardKey});continue}s+=1;const c=j(h(a.value));t+=c.before,o+=c.total,e.push({result:c,shardKey:a.shardKey})}return{failed:n,ok:s,partial:n>0,position:t+1,shards:e,total:o}},P=0,v=1,$=2,k=(r,e)=>r<e?-1:r>e?1:0,M=r=>r==null?P:typeof r=="number"?v:$,O=(r,e)=>{const s=M(r),n=M(e);return s!==n?s<n?-1:1:s===P?0:s===v?k(r,e):k(String(r),String(e))},G=(r,e,s)=>{const n=O(r.partitionKey,e.partitionKey);if(n!==0)return n;const t=Math.max(r.sortValues.length,e.sortValues.length);for(let o=0;o<t;o+=1){const a=O(r.sortValues[o],e.sortValues[o]);if(a!==0)return s[o]==="desc"?-a:a}return O(r.rowId,e.rowId)},Q=r=>E(new TextEncoder().encode(JSON.stringify(r))),Y=r=>{try{const e=JSON.parse(new TextDecoder().decode(T(r)));if(e!==null&&typeof e=="object"&&"perShard"in e){const{perShard:s}=e;if(s!==null&&typeof s=="object")return{perShard:s}}}catch{}return{perShard:{}}},H=r=>{const e=r??{},s=Array.isArray(e.rows)?e.rows:[];return{directions:Array.isArray(e.directions)?e.directions:[],hasMore:e.hasMore===!0,rows:s}},W=(r,e)=>{let s;for(const n of r){const t=n.rows[n.head];t!==void 0&&(s===void 0||G(t.key,s.row.key,e)<0)&&(s={row:t,slice:n})}return s},X=(r,e)=>{let s=!1;const n=new Set;for(const o of r)n.add(o.shardKey),(o.head<o.rows.length||o.hasMore)&&(s=!0);const t={...e};for(const o of Object.keys(e))n.has(o)||(s=!0);return s?Q({perShard:t}):null},z=(r,e,s,n)=>{const t=[],o={...n};for(;t.length<e;){const c=W(r,s);if(c===void 0)break;t.push(c.row.doc),o[c.slice.shardKey]=c.row.key,c.slice.head+=1}const a=X(r,o);return{isDone:a===null,nextCursor:a,page:t}},Z=r=>{const e=[];let s=0,n=0;for(const t of r){if(t.kind==="err"){n+=1,e.push({error:{message:t.message,timedOut:t.timedOut},shardKey:t.shardKey});continue}s+=1;const o=h(t.value),a=Array.isArray(o?.rows)?o.rows:[];e.push({rows:a,shardKey:t.shardKey})}return{failed:n,ok:s,shards:e}},q=r=>{const e=[];let s=0,n=0;for(const{outcome:t,sinceSeq:o}of r){if(t.kind==="err"){n+=1,e.push({cursor:o,error:{message:t.message,timedOut:t.timedOut},shardKey:t.shardKey});continue}s+=1;const a=h(t.value),c=Array.isArray(a?.changes)?a.changes:[],i=typeof a?.cursor=="number"?a.cursor:o;e.push({changes:c,cursor:i,shardKey:t.shardKey})}return{failed:n,ok:s,shards:e}},ee=r=>{let e=0,s=0,n=0;for(const t of r){if(t.kind==="err"){s+=1;continue}e+=1;const o=h(t.value);n+=typeof o?.applied=="number"?o.applied:0}return{applied:n,failed:s,ok:e}},re=r=>{const e=r??{};return typeof e.requests=="number"&&Number.isFinite(e.requests)&&e.requests>=0?e.requests:0},te=r=>{const e=[];let s=0,n=0;for(const t of r){if(t.kind==="err"){n+=1,e.push({requests:0,shardKey:t.shardKey});continue}s+=1,e.push({requests:re(h(t.value)),shardKey:t.shardKey})}return{failed:n,ok:s,shards:e}},se=r=>{const e=[],s={},n=[];let t=0,o=0,a=0;for(const c of r){if(c.kind==="err"){a+=1,e.push({error:{message:c.message,timedOut:c.timedOut},shardKey:c.shardKey});continue}o+=1;const i=h(c.value),l=i?.inserted??{};for(const[f,y]of Object.entries(l))s[f]=(s[f]??0)+y;const u=i?.errors;Array.isArray(u)&&n.push(...u),t+=i?.conflicts??0,e.push({result:{conflicts:i?.conflicts??0,errors:i?.errors??[],inserted:l},shardKey:c.shardKey})}return{conflicts:t,errors:n,failed:a,inserted:s,ok:o,shards:e}},p=r=>({body:JSON.stringify({args:r.args??{},functionPath:r.functionPath}),headers:{"content-type":"application/json",...r.headers}}),g=async(r,e,s,n)=>{const t=I(r,e),o=new AbortController,a=new Request("https://shard.internal/rpc",{body:s.body,headers:s.headers,method:"POST",signal:o.signal});let c;const i=new Promise(u=>{c=setTimeout(()=>{try{o.abort()}catch{}u({kind:"err",message:`shard "${e}" timed out after ${String(n)}ms`,shardKey:e,timedOut:!0})},n)}),l=(async()=>{try{const u=await t.fetch(a);if(!u.ok)return{kind:"err",message:`shard "${e}" returned ${String(u.status)}`,shardKey:e,timedOut:!1};const f=await u.json();return{kind:"ok",shardKey:e,value:f}}catch(u){const f=u instanceof Error?u.message:String(u);return{kind:"err",message:`shard "${e}" threw: ${f}`,shardKey:e,timedOut:!1}}})();try{return await Promise.race([l,i])}finally{c!==void 0&&clearTimeout(c)}},w=async(r,e,s)=>{if(r.length===0)return[];const n=Array.from({length:r.length});let t=0;const o=async()=>{for(;;){const c=t;t+=1;const i=r[c];if(c>=r.length||i===void 0)return;n[c]=await s(i,c)}},a=Math.min(e,r.length);return await Promise.all(Array.from({length:a},()=>o())),n},x=async(r,e)=>{const s=await Promise.all(e.map(async n=>r.listShardKeys(n)));return[...new Set(s.flat())]},R=(r,e)=>r.length>0||e===null?r:[e],m=async(r,e,s,n,t)=>{const o=p(s);return w(e,n,async a=>g(r,a,o,t))},ne=r=>{const e={};for(const s of Object.keys(r).toSorted(k))e[s]=r[s]??null;return JSON.stringify(e)},oe=r=>r.flatMap(e=>Array.isArray(e)?e:[]),ae=(r,e,s)=>{switch(s){case"max":return Math.max(r,e);case"min":return Math.min(r,e);case"sum":return r+e;default:return r}},ce=(r,e,s)=>{if(e===null||typeof e!="object")return;const n=e.key??{},t=e.value??null,o=ne(n),a=r.get(o);if(!a){r.set(o,{key:n,value:t});return}if(a.value===null){a.value=t;return}t!==null&&(a.value=ae(a.value,t,s))},ie=(r,e)=>{const s=new Map;for(const n of r)if(Array.isArray(n))for(const t of n)ce(s,t,e);return[...s.values()]},N=(r,e)=>{let s=null;for(const n of r)typeof n=="number"&&Number.isFinite(n)&&(s=s===null?n:e(s,n));return s},ue=r=>{let e=0;for(const s of r)typeof s=="number"&&Number.isFinite(s)&&(e+=s);return e},le=r=>{let e=0,s=0;for(const n of r){if(n===null||typeof n!="object")continue;const t=n;typeof t.before=="number"&&Number.isFinite(t.before)&&(e+=t.before),typeof t.total=="number"&&Number.isFinite(t.total)&&(s+=t.total)}return{position:e+1,total:s}},de=(r,e)=>{const s=[];for(const t of r)if(Array.isArray(t))for(const o of t){if(o===null||typeof o!="object")continue;const a=o[e.by],c=typeof a=="number"&&Number.isFinite(a)?a:Number.NEGATIVE_INFINITY;s.push({row:o,score:c})}const n=e.direction??"desc";return s.sort((t,o)=>n==="asc"?k(t.score,o.score):k(o.score,t.score)),s.slice(0,e.k).map(t=>t.row)},fe=(r,e)=>{switch(e.kind){case"concat":return oe(r);case"first":return r[0];case"groupBy":return ie(r,e.op??"sum");case"max":return N(r,Math.max);case"min":return N(r,Math.min);case"rank":return le(r);case"sum":return ue(r);case"topK":return de(r,e);default:return r}},ge=r=>{const e=r.maxConcurrency??F,s=r.perShardTimeoutMs??B;if(e<1)throw new U("maxConcurrency must be >= 1",{code:"BAD_REQUEST",status:400});return{async fanOut(n,t){const o=await r.registry.listShardKeys(t.fanOut.table),a=await m(n,o,t,e,s),c=[],i=[];for(const l of a)l.kind==="ok"?c.push(l.value):i.push({message:l.message,shardKey:l.shardKey,timedOut:l.timedOut});return{data:fe(c,t.fanOut.merge),errors:i,failed:i.length,ok:c.length}},async orchestrateExport(n,t){const o=await x(r.registry,t.tables),a=R(o,t.defaultShardKey),c={args:{...t.args,tables:[...t.tables]},functionPath:"__lunora_admin__:exportShard",headers:t.headers},i=await m(n,a,c,e,s);return Z(i)},async orchestrateCdcSync(n,t){const o=R(await x(r.registry,t.tables),t.defaultShardKey),a=t.cursors??{},c=await w(o,e,async i=>{const l=a[i]??0;return{outcome:await g(n,i,p({args:{limit:t.limit,sinceSeq:l},functionPath:"__lunora_admin__:cdcSync",headers:t.headers}),s),sinceSeq:l}});return q(c)},async orchestrateImport(n,t){const{batches:o}=t,a=await w(o,e,async c=>g(n,c.shardKey,p({args:{rows:[...c.rows],startLine:c.startLine??1},functionPath:"__lunora_admin__:importShard",headers:t.headers}),s));return se(a)},async orchestrateApplyCdc(n,t){const{batches:o}=t,a=await w(o,e,async c=>g(n,c.shardKey,p({args:{changes:[...c.changes]},functionPath:"__lunora_admin__:applyCdc",headers:t.headers}),s));return ee(a)},async orchestrateMigration(n,t){const o=R(await r.registry.listShardKeys(t.table),t.defaultShardKey),a=await m(n,o,t,e,s);return L(a)},async orchestrateRank(n,t){const o=await r.registry.listShardKeys(t.table),a={args:{index:t.index,partitionKey:t.partitionKey,rowId:t.rowId,sortValues:[...t.sortValues],table:t.table},functionPath:"__lunora_admin__:rankBefore",headers:t.headers},c=await m(n,o,a,e,s);return J(c)},async orchestrateRankPage(n,t){const o=await r.registry.listShardKeys(t.table),a=Math.max(1,Math.min(1e3,Math.floor(t.take??100))),c=t.directions??[],i=t.cursor?Y(t.cursor):{perShard:{}},l=await w(o,e,async d=>{const C=i.perShard[d],_={index:t.index,table:t.table,take:a};t.partitionKey!==void 0&&(_.partitionKey=t.partitionKey),C!==void 0&&(_.after=C);const b=await g(n,d,p({args:_,functionPath:"__lunora_admin__:rankPage",headers:t.headers}),s);if(b.kind==="err")return{error:{message:b.message,timedOut:b.timedOut},shardKey:d};const A=H(h(b.value));return{directions:A.directions,hasMore:A.hasMore,rows:A.rows,shardKey:d}}),u=[];let f=0,y=0,S;for(const d of l){if(d.error){y+=1;continue}f+=1,S===void 0&&d.directions&&d.directions.length>0&&(S=d.directions),u.push({hasMore:d.hasMore??!1,head:0,rows:d.rows??[],shardKey:d.shardKey})}const K=z(u,a,S??c,i.perShard);return{continueCursor:K.nextCursor,failed:y,isDone:K.isDone,ok:f,page:K.page,partial:y>0,shards:l}},async orchestrateShardTraffic(n,t){const o=await r.registry.listShardKeys(t.table),a={functionPath:"__lunora_admin__:getMetrics",headers:t.headers},c=await m(n,o,a,e,s);return te(c)},registry:r.registry}};export{ge as createQueryCoordinator,pe as createStaticShardRegistry};
@@ -1 +0,0 @@
1
- import{LunoraError as m}from"./LunoraError-DksAgIpa.mjs";const O="default-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'",E=e=>{const o=["base-uri 'none'","object-src 'none'"];return e==="DENY"?o.push("frame-ancestors 'none'"):e==="SAMEORIGIN"&&o.push("frame-ancestors 'self'"),o.join("; ")},y="accelerometer=(), autoplay=(), camera=(), display-capture=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()",d=["Authorization","Content-Type","X-D1-Bookmark","X-Lunora-Client-Id","X-Lunora-Client-Seq","X-Lunora-Min-Seq","X-Lunora-Mutation-Id"],u=["DELETE","GET","HEAD","PATCH","POST","PUT"],S=31536e3,L=new Set(["GET","HEAD","OPTIONS"]),A=e=>{if(e===!1)return;const o=e===void 0||e===!0?{}:e,s=o.maxAge??S,r=o.includeSubDomains??!0;return`max-age=${String(s)}${r?"; includeSubDomains":""}${o.preload?"; preload":""}`},b=(e,o)=>{if(e!==!1)return typeof e=="string"?{htmlValue:e,value:e}:{htmlValue:o,value:O}},C=e=>{if(e===!1)return{coop:void 0,csp:void 0,enabled:!1,frameOptions:void 0,hsts:void 0,permissionsPolicy:void 0,referrerPolicy:void 0};const o=e===void 0||e===!0?{}:e,s=o.frameOptions===!1?void 0:o.frameOptions??"SAMEORIGIN";return{coop:"same-origin",csp:b(o.csp,E(s)),enabled:!0,frameOptions:s,hsts:A(o.hsts),permissionsPolicy:o.permissionsPolicy===!1?void 0:o.permissionsPolicy??y,referrerPolicy:o.referrerPolicy===!1?void 0:o.referrerPolicy??"strict-origin-when-cross-origin"}},v=e=>{const o={allowCredentials:!1,allowedHeaders:d,allowedMethods:u,enabled:!1,isAllowed:()=>!1,isExplicitlyAllowed:()=>!1,maxAge:600};if(e===void 0||e===!1)return o;const s=e.allowCredentials??!1,r=e.allowedOrigins;let t,n;if(typeof r=="function")t=r,n=r,console.warn(`@lunora/runtime: security.cors uses a custom \`allowedOrigins\` predicate. It is trusted by the CSRF and WebSocket origin checks${s?" AND reflects matching origins with credentials (`allowCredentials: true`)":""} — ensure it matches ONLY trusted origins by exact equality; an over-broad predicate (e.g. \`() => true\`, or \`endsWith\`/\`includes\` checks) defeats the allowlist.`);else{const l=r;if(l.includes("*")&&s)throw new m('@lunora/runtime: security.cors cannot combine a wildcard origin ("*") with allowCredentials: true — browsers reject it and it defeats the allowlist.');t=i=>l.includes("*")||l.includes(i),n=i=>l.includes(i)}return{allowCredentials:s,allowedHeaders:e.allowedHeaders??d,allowedMethods:e.allowedMethods??u,enabled:!0,isAllowed:t,isExplicitlyAllowed:n,maxAge:e.maxAge??600}},R=e=>{if(e===!1)return{allowLoopback:!1,enabled:!1,trustedOrigins:[]};const o=e===void 0||e===!0?{}:e;return{allowLoopback:o.allowLoopback??!0,enabled:!0,trustedOrigins:o.trustedOrigins??[]}},D=new Set(["0","disabled","false","no","off"]),_=new Set(["1","enabled","on","true","yes"]),f=e=>typeof e=="string"&&D.has(e.trim().toLowerCase()),N=e=>typeof e=="string"&&_.has(e.trim().toLowerCase()),H=e=>{const o=e?.LUNORA_ALLOWED_ORIGINS;if(typeof o!="string")return;const s=o.split(",").map(n=>n.trim()).filter(n=>n.length>0);return s.length===0?void 0:{allowCredentials:!s.includes("*")&&N(e?.LUNORA_CORS_ALLOW_CREDENTIALS),allowedOrigins:s}},M=(e,o)=>{const s=e?.headers??(f(o?.LUNORA_SECURITY_HEADERS)?!1:void 0),r=e?.csrf??(f(o?.LUNORA_SECURITY_CSRF)?!1:void 0),t=e?.cors??H(o);return{cors:v(t),csrf:R(r),headers:C(s)}},I=new Set(["127.0.0.1","::1","[::1]","localhost"]),p=e=>{try{return I.has(new URL(e).hostname)}catch{return!1}},c=e=>{if(e)try{return new URL(e).origin}catch{return}},h=(e,o,s)=>e===o||s.csrf.trustedOrigins.includes(e)||s.csrf.allowLoopback&&p(o)&&p(e)?!0:s.cors.enabled&&s.cors.isExplicitlyAllowed(e),w=(e,o,s)=>Response.json({error:{code:"FORBIDDEN_ORIGIN",expectedOrigin:s,message:`${e} rejected: Origin ${o===void 0?"was missing":`"${o}"`} is not trusted (this worker serves "${s}"). Add it to \`security.csrf.trustedOrigins\` (or LUNORA_ALLOWED_ORIGINS) if it is yours. Behind a dev proxy this usually means the proxy rewrote the host: keep both ends on loopback, or list the dev-server origin.`,receivedOrigin:o}},{headers:{"content-type":"application/json"},status:403}),j=(e,o)=>{if(!o.csrf.enabled||L.has(e.method)||!e.headers.get("cookie"))return;const s=new URL(e.url).origin,r=c(e.headers.get("origin"))??c(e.headers.get("referer"));if(!(r!==void 0&&h(r,s,o)))return w("cross-origin state-changing request",r,s)},F=(e,o)=>{if(!o.csrf.enabled||!e.headers.get("cookie"))return;const s=new URL(e.url).origin,r=c(e.headers.get("origin"));if(!(r!==void 0&&h(r,s,o)))return w("cross-origin websocket upgrade",r,s)},P=["X-D1-Bookmark","X-Lunora-Edge-Cache","X-Lunora-Shard-Key"],g=(e,o)=>{const s=new Headers;return s.set("access-control-allow-origin",e),s.set("access-control-expose-headers",P.join(", ")),s.append("vary","Origin"),o.allowCredentials&&s.set("access-control-allow-credentials","true"),s},X=(e,o)=>{if(!o.cors.enabled||e.method!=="OPTIONS")return;const s=e.headers.get("origin");if(!s||!e.headers.get("access-control-request-method")||!o.cors.isAllowed(s))return;const r=g(s,o.cors),t=e.headers.get("access-control-request-headers");r.set("access-control-allow-methods",o.cors.allowedMethods.join(", "));let n;if(t===null)n=o.cors.allowedHeaders.join(", ");else{const l=new Set(o.cors.allowedHeaders.map(i=>i.toLowerCase()));n=t.split(",").map(i=>i.trim()).filter(i=>i.length>0&&l.has(i.toLowerCase())).join(", ")}return r.set("access-control-allow-headers",n),r.set("access-control-max-age",String(o.cors.maxAge)),new Response(null,{headers:r,status:204})},T=e=>(e.headers.get("content-type")??"").toLowerCase().includes("text/html"),a=(e,o,s)=>{e.has(o)||e.set(o,s)},x=(e,o,s,r)=>{if(r.hsts!==void 0&&new URL(o.url).protocol==="https:"&&a(e,"strict-transport-security",r.hsts),a(e,"x-content-type-options","nosniff"),r.frameOptions!==void 0&&a(e,"x-frame-options",r.frameOptions),r.referrerPolicy!==void 0&&a(e,"referrer-policy",r.referrerPolicy),r.permissionsPolicy!==void 0&&a(e,"permissions-policy",r.permissionsPolicy),r.coop!==void 0&&a(e,"cross-origin-opener-policy",r.coop),r.csp!==void 0){const t=T(s)?r.csp.htmlValue:r.csp.value;t!==void 0&&a(e,"content-security-policy",t)}},k=(e,o,s)=>{const r=o.headers.get("origin");if(!(!r||!s.isAllowed(r)))for(const[t,n]of g(r,s).entries())t==="vary"?e.append("vary",n):a(e,t,n)},B=(e,o,s)=>{if(e.status===101||e.webSocket)return e;const r=new Headers(e.headers);return s.headers.enabled&&x(r,o,e,s.headers),s.cors.enabled&&k(r,o,s.cors),new Response(e.body,{headers:r,status:e.status,statusText:e.statusText})};export{B as decorateResponse,j as enforceOrigin,F as enforceWebSocketOrigin,X as handleCorsPreflight,M as resolveSecurity};
@@ -1 +0,0 @@
1
- import{e as a,a as s,f}from"./observability-vDK-rMbs.mjs";export{a as emitLogEvent,s as emitRpcEvent,f as flushSink};
@@ -1 +0,0 @@
1
- const n=t=>{const r=Number.parseInt(t.slice(0,8),16);return Number.isFinite(r)?r/4294967296:0},a=(t,r=1)=>r>=1?!0:r<=0?!1:n(t)<r,u=(t,r)=>({isTraced:a(r,t?.headRate??1),keepErrors:t?.alwaysSampleErrors??!0}),E=(t,r)=>t.isTraced||t.keepErrors&&r,i=(t,r,e,o,s)=>{if(!t?.onRpc)return;const c=s??(o!==void 0&&r.traceId!==void 0?u(o,r.traceId):void 0);if(!(c!==void 0&&!E(c,!r.ok)))try{t.onRpc(r,e)}catch{}},T=(t,r,e)=>{if(t?.onLog)try{t.onLog(r,e)}catch{}},A=(t,r)=>{if(t?.flush)try{t.flush(r)}catch{}};export{i as a,T as e,A as f,u as r};
@@ -1 +0,0 @@
1
- import{a as w,b as O}from"./base64-Bl1_r2k1.mjs";const o="$lunora.wire$",m=64,A=1024,d="__proto__",p={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},E={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},l=e=>{if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype},a=(e,t=0)=>{if(t>m)throw new RangeError(`wire-codec: value nesting exceeds the ${m}-level limit`);if(e===void 0)return[o,"undefined"];if(e===null)return null;const y=typeof e;if(y==="bigint")return[o,"bigint",e.toString()];if(y==="number"){const r=e;return Number.isNaN(r)?[o,"nan"]:r===1/0?[o,"inf"]:r===-1/0?[o,"-inf"]:r}if(y!=="object")return e;if(e instanceof Date)return[o,"date",a(e.getTime(),t+1)];if(e instanceof Error){const r=e,n={};for(const c of Object.keys(r))r[c]!==void 0&&(n[c]=a(r[c],t+1));const i=[o,"error",r.name,r.message,n];return r.cause!==void 0&&i.push(a(r.cause,t+1)),i}if(e instanceof URL)return[o,"url",e.href];if(e instanceof Map)return[o,"map",[...e.entries()].map(([r,n])=>[a(r,t+1),a(n,t+1)])];if(e instanceof Set)return[o,"set",[...e].map(r=>a(r,t+1))];if(e instanceof ArrayBuffer)return[o,"bytes",w(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const r=e,n=r.constructor.name,i=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);return n==="Uint8Array"?[o,"bytes",w(i)]:[o,"bytes",w(i),n]}if(Array.isArray(e)){const r=e.map(n=>a(n,t+1));return r.length>0&&r[0]===o?[o,"arr",r]:r}if(!l(e)){const r=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${r} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const u=e,s={};for(const r of Object.keys(u)){const n=u[r];if(n===void 0)continue;const i=a(n,t+1);r===d?Object.defineProperty(s,r,{configurable:!0,enumerable:!0,value:i,writable:!0}):s[r]=i}return s},f=(e,t=0)=>{if(t>m)throw new RangeError(`wire-codec: value nesting exceeds the ${m}-level limit`);if(e===null||typeof e!="object")return e;if(Array.isArray(e)){if(e[0]===o)switch(e[1]){case"-inf":return-1/0;case"arr":return e[2].map(r=>f(r,t+1));case"bigint":{const r=e[2];if(typeof r!="string"||r.length>A||!/^-?\d+$/.test(r))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${A} digits)`);return BigInt(r)}case"date":return new Date(f(e[2],t+1));case"map":{const r=e[2];return new Map(r.map(n=>{if(!Array.isArray(n)||n.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[f(n[0],t+1),f(n[1],t+1)]}))}case"set":return new Set(e[2].map(r=>f(r,t+1)));case"url":return new URL(e[2]);case"error":{const r=e[2],n=e[3],i=(Object.hasOwn(E,r)?E[r]:void 0)??Error,c=new i(n);c.name!==r&&Object.defineProperty(c,"name",{configurable:!0,value:r,writable:!0});const g=f(e[4],t+1);for(const b of Object.keys(g))b===d?Object.defineProperty(c,b,{configurable:!0,enumerable:!0,value:g[b],writable:!0}):c[b]=g[b];return e.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:f(e[5],t+1),writable:!0}),c}case"bytes":{const r=O(e[2]),n=e[3]??"Uint8Array";if(n==="ArrayBuffer")return r.buffer.byteLength===r.byteLength?r.buffer:r.slice().buffer;const i=Object.hasOwn(p,n)?p[n]:void 0;return i?new i(r.slice().buffer):r}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return e.map(r=>f(r,t+1))}return e.map(s=>f(s,t+1))}const y=e,u={};for(const s of Object.keys(y)){const r=f(y[s],t+1);s===d?Object.defineProperty(u,s,{configurable:!0,enumerable:!0,value:r,writable:!0}):u[s]=r}return u};export{f as d,a as e,l as i};