@lunora/do 1.0.0-alpha.47 → 1.0.0-alpha.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +35 -6
- package/dist/index.d.ts +35 -6
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/ROOT_DO_SIZE_WARN_BYTES-DqqGF-jB.mjs +101 -0
- package/dist/packem_shared/context-telemetry-BQoMfXLz.mjs +1 -0
- package/dist/packem_shared/{createMetrics-ien8stle.mjs → createMetrics-BpI-Bmim.mjs} +1 -1
- package/package.json +1 -1
- package/dist/packem_shared/ROOT_DO_SIZE_WARN_BYTES-DHW1qs0Z.mjs +0 -101
- package/dist/packem_shared/context-telemetry-DBcDCBl1.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -4570,6 +4570,17 @@ declare class SessionDO {
|
|
|
4570
4570
|
* `"off"` — no database telemetry at all.
|
|
4571
4571
|
*/
|
|
4572
4572
|
type DatabaseInstrumentation = "off" | "spans" | "summary";
|
|
4573
|
+
/**
|
|
4574
|
+
* Tunable caps for {@link recordMetricHistory}, threaded from the sink's
|
|
4575
|
+
* `metricHistory` option. Each falls back to its module-constant default, so an
|
|
4576
|
+
* omitted field keeps the historical behaviour.
|
|
4577
|
+
*/
|
|
4578
|
+
interface MetricHistoryOptions {
|
|
4579
|
+
/** Distinct series tracked before a brand-new one is dropped (default {@link METRIC_HISTORY_MAX_SERIES}). */
|
|
4580
|
+
maxSeries?: number;
|
|
4581
|
+
/** Minute-buckets kept per series before older rows are trimmed (default {@link METRIC_HISTORY_BUCKET_RETENTION}). */
|
|
4582
|
+
retentionBuckets?: number;
|
|
4583
|
+
}
|
|
4573
4584
|
/** One table's resolved TTL policy, as surfaced to the DO alarm by the generated shard subclass. */
|
|
4574
4585
|
interface TtlSweepSpec {
|
|
4575
4586
|
/** Millisecond offset added to `field` to derive the expiry (`field + after`); absent ⇒ `field` is the absolute expiry. */
|
|
@@ -4668,6 +4679,16 @@ interface TelemetrySink {
|
|
|
4668
4679
|
* emits nothing extra. Mirror of `@lunora/runtime`'s `ObservabilitySink`.
|
|
4669
4680
|
*/
|
|
4670
4681
|
instrumentDatabase?: DatabaseInstrumentation;
|
|
4682
|
+
/**
|
|
4683
|
+
* **Opt-in, default off.** Durable per-minute `ctx.metrics.*` rollups written to
|
|
4684
|
+
* the reserved per-shard SQLite table (the Studio's local trend chart). Off by
|
|
4685
|
+
* default because every measurement then costs a durable SQLite write on the
|
|
4686
|
+
* request path — the live cross-instance path is `onMetric`, this is only the
|
|
4687
|
+
* local convenience. An object tunes the caps (`maxSeries` / `retentionBuckets`);
|
|
4688
|
+
* `true` uses the built-in defaults. Mirror of `@lunora/runtime`'s
|
|
4689
|
+
* `ObservabilitySink`.
|
|
4690
|
+
*/
|
|
4691
|
+
metricHistory?: boolean | MetricHistoryOptions;
|
|
4671
4692
|
onLog?: (event: LogEventInput, context?: LogSinkContext) => void;
|
|
4672
4693
|
onMetric?: (event: MetricEvent, context?: LogSinkContext) => void;
|
|
4673
4694
|
onSpan?: (event: SpanEvent, context?: LogSinkContext) => void;
|
|
@@ -5137,10 +5158,15 @@ declare abstract class ShardDO {
|
|
|
5137
5158
|
* before — when false, `ctx.trace` INTERNAL spans are held out of the live export
|
|
5138
5159
|
* and re-decided in the dispatch `finally` as a tail bias), `keepErrors` (the
|
|
5139
5160
|
* runtime's `x-lunora-sample-errors` / `alwaysSampleErrors` toggle — a sampled-out
|
|
5140
|
-
* trace that errored is still exported whole unless off),
|
|
5161
|
+
* trace that errored is still exported whole unless off), `sink` (captured
|
|
5141
5162
|
* when a sampled-out span is first held, so the `finally` can flush the trace's
|
|
5142
|
-
* held spans)
|
|
5143
|
-
*
|
|
5163
|
+
* held spans), and `held` (the sampled-out spans themselves, buffered ON THIS
|
|
5164
|
+
* ENTRY rather than read back from the shared span ring — the ring is bounded and
|
|
5165
|
+
* a concurrent trace could evict this trace's error spans before the flush, which
|
|
5166
|
+
* would silently defeat `alwaysSampleErrors`; bounded by
|
|
5167
|
+
* {@link MAX_HELD_SPANS_PER_TRACE}). Registered at dispatch entry by the
|
|
5168
|
+
* dispatch's own `traceId`, read by `span.traceId`, and deleted in the `finally`
|
|
5169
|
+
* (which drops `held` with it, so no spans leak past the dispatch).
|
|
5144
5170
|
*/
|
|
5145
5171
|
private traceSampling;
|
|
5146
5172
|
/**
|
|
@@ -6505,7 +6531,7 @@ declare abstract class ShardDO {
|
|
|
6505
6531
|
* exported whole (tail bias). Spans from a sampled-in dispatch, or from another
|
|
6506
6532
|
* trace (a subscription re-run mints its own anchor), stream immediately.
|
|
6507
6533
|
*/
|
|
6508
|
-
protected recordSpan(span: SpanEvent, sink?: TelemetrySink): void;
|
|
6534
|
+
protected recordSpan(span: SpanEvent, sink?: TelemetrySink, sampledSnapshot?: boolean): void;
|
|
6509
6535
|
/**
|
|
6510
6536
|
* Hand one span to `sink.onSpan`, swallowing sink throws. The DO's `waitUntil`
|
|
6511
6537
|
* is threaded so a network sink (otlpSink) can keep its export alive past the
|
|
@@ -6520,8 +6546,11 @@ declare abstract class ShardDO {
|
|
|
6520
6546
|
* streamed live, so this returns early for it; a sampled-out trace exports its
|
|
6521
6547
|
* held `ctx.trace` spans only when `alwaysSampleErrors` is set AND the trace
|
|
6522
6548
|
* errored (the dispatch threw, or a held span settled `ok: false`) — the tail
|
|
6523
|
-
* bias — and otherwise drops them. Held spans are
|
|
6524
|
-
* (
|
|
6549
|
+
* bias — and otherwise drops them. Held spans are drained from the per-trace
|
|
6550
|
+
* `held` array `recordSpan` accumulated (the synthetic dispatch root is never
|
|
6551
|
+
* held, since it never goes to `onSpan`) — NOT re-read from the shared span
|
|
6552
|
+
* ring, whose bound a concurrent trace could have used to evict these very
|
|
6553
|
+
* error spans before this flush ran.
|
|
6525
6554
|
*/
|
|
6526
6555
|
private flushSampledOutTrace;
|
|
6527
6556
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -4570,6 +4570,17 @@ declare class SessionDO {
|
|
|
4570
4570
|
* `"off"` — no database telemetry at all.
|
|
4571
4571
|
*/
|
|
4572
4572
|
type DatabaseInstrumentation = "off" | "spans" | "summary";
|
|
4573
|
+
/**
|
|
4574
|
+
* Tunable caps for {@link recordMetricHistory}, threaded from the sink's
|
|
4575
|
+
* `metricHistory` option. Each falls back to its module-constant default, so an
|
|
4576
|
+
* omitted field keeps the historical behaviour.
|
|
4577
|
+
*/
|
|
4578
|
+
interface MetricHistoryOptions {
|
|
4579
|
+
/** Distinct series tracked before a brand-new one is dropped (default {@link METRIC_HISTORY_MAX_SERIES}). */
|
|
4580
|
+
maxSeries?: number;
|
|
4581
|
+
/** Minute-buckets kept per series before older rows are trimmed (default {@link METRIC_HISTORY_BUCKET_RETENTION}). */
|
|
4582
|
+
retentionBuckets?: number;
|
|
4583
|
+
}
|
|
4573
4584
|
/** One table's resolved TTL policy, as surfaced to the DO alarm by the generated shard subclass. */
|
|
4574
4585
|
interface TtlSweepSpec {
|
|
4575
4586
|
/** Millisecond offset added to `field` to derive the expiry (`field + after`); absent ⇒ `field` is the absolute expiry. */
|
|
@@ -4668,6 +4679,16 @@ interface TelemetrySink {
|
|
|
4668
4679
|
* emits nothing extra. Mirror of `@lunora/runtime`'s `ObservabilitySink`.
|
|
4669
4680
|
*/
|
|
4670
4681
|
instrumentDatabase?: DatabaseInstrumentation;
|
|
4682
|
+
/**
|
|
4683
|
+
* **Opt-in, default off.** Durable per-minute `ctx.metrics.*` rollups written to
|
|
4684
|
+
* the reserved per-shard SQLite table (the Studio's local trend chart). Off by
|
|
4685
|
+
* default because every measurement then costs a durable SQLite write on the
|
|
4686
|
+
* request path — the live cross-instance path is `onMetric`, this is only the
|
|
4687
|
+
* local convenience. An object tunes the caps (`maxSeries` / `retentionBuckets`);
|
|
4688
|
+
* `true` uses the built-in defaults. Mirror of `@lunora/runtime`'s
|
|
4689
|
+
* `ObservabilitySink`.
|
|
4690
|
+
*/
|
|
4691
|
+
metricHistory?: boolean | MetricHistoryOptions;
|
|
4671
4692
|
onLog?: (event: LogEventInput, context?: LogSinkContext) => void;
|
|
4672
4693
|
onMetric?: (event: MetricEvent, context?: LogSinkContext) => void;
|
|
4673
4694
|
onSpan?: (event: SpanEvent, context?: LogSinkContext) => void;
|
|
@@ -5137,10 +5158,15 @@ declare abstract class ShardDO {
|
|
|
5137
5158
|
* before — when false, `ctx.trace` INTERNAL spans are held out of the live export
|
|
5138
5159
|
* and re-decided in the dispatch `finally` as a tail bias), `keepErrors` (the
|
|
5139
5160
|
* runtime's `x-lunora-sample-errors` / `alwaysSampleErrors` toggle — a sampled-out
|
|
5140
|
-
* trace that errored is still exported whole unless off),
|
|
5161
|
+
* trace that errored is still exported whole unless off), `sink` (captured
|
|
5141
5162
|
* when a sampled-out span is first held, so the `finally` can flush the trace's
|
|
5142
|
-
* held spans)
|
|
5143
|
-
*
|
|
5163
|
+
* held spans), and `held` (the sampled-out spans themselves, buffered ON THIS
|
|
5164
|
+
* ENTRY rather than read back from the shared span ring — the ring is bounded and
|
|
5165
|
+
* a concurrent trace could evict this trace's error spans before the flush, which
|
|
5166
|
+
* would silently defeat `alwaysSampleErrors`; bounded by
|
|
5167
|
+
* {@link MAX_HELD_SPANS_PER_TRACE}). Registered at dispatch entry by the
|
|
5168
|
+
* dispatch's own `traceId`, read by `span.traceId`, and deleted in the `finally`
|
|
5169
|
+
* (which drops `held` with it, so no spans leak past the dispatch).
|
|
5144
5170
|
*/
|
|
5145
5171
|
private traceSampling;
|
|
5146
5172
|
/**
|
|
@@ -6505,7 +6531,7 @@ declare abstract class ShardDO {
|
|
|
6505
6531
|
* exported whole (tail bias). Spans from a sampled-in dispatch, or from another
|
|
6506
6532
|
* trace (a subscription re-run mints its own anchor), stream immediately.
|
|
6507
6533
|
*/
|
|
6508
|
-
protected recordSpan(span: SpanEvent, sink?: TelemetrySink): void;
|
|
6534
|
+
protected recordSpan(span: SpanEvent, sink?: TelemetrySink, sampledSnapshot?: boolean): void;
|
|
6509
6535
|
/**
|
|
6510
6536
|
* Hand one span to `sink.onSpan`, swallowing sink throws. The DO's `waitUntil`
|
|
6511
6537
|
* is threaded so a network sink (otlpSink) can keep its export alive past the
|
|
@@ -6520,8 +6546,11 @@ declare abstract class ShardDO {
|
|
|
6520
6546
|
* streamed live, so this returns early for it; a sampled-out trace exports its
|
|
6521
6547
|
* held `ctx.trace` spans only when `alwaysSampleErrors` is set AND the trace
|
|
6522
6548
|
* errored (the dispatch threw, or a held span settled `ok: false`) — the tail
|
|
6523
|
-
* bias — and otherwise drops them. Held spans are
|
|
6524
|
-
* (
|
|
6549
|
+
* bias — and otherwise drops them. Held spans are drained from the per-trace
|
|
6550
|
+
* `held` array `recordSpan` accumulated (the synthetic dispatch root is never
|
|
6551
|
+
* held, since it never goes to `onSpan`) — NOT re-read from the shared span
|
|
6552
|
+
* ring, whose bound a concurrent trace could have used to evict these very
|
|
6553
|
+
* error spans before this flush ran.
|
|
6525
6554
|
*/
|
|
6526
6555
|
private flushSampledOutTrace;
|
|
6527
6556
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{exportShardRows as o,exportShardTable as t,importShardRows as a,parseExportShardArgs as n,parseImportShardArgs as i,selectExportTables as s,validateImportRow as l}from"./packem_shared/exportShardRows-kt42wijd.mjs";import{AGGREGATE_SQL_FUNCTION as T,aggregateSqlFunction as d,matchesStaticWhere as p,normalizeCountArgument as E,throwingScheduler as S}from"./packem_shared/AGGREGATE_SQL_FUNCTION-QYaiuty4.mjs";import{aggregateTableName as _,coerceAggregateNumber as u,encodeAggregateKey as x,foldAggregateTally as f,readAggregateValue as I}from"./packem_shared/aggregateTableName-G-eXyjcz.mjs";import{CountRlsUnsupportedError as A,mergeWhere as N,planAggregateLookup as g,selectIndexForAggregate as C,selectIndexForCount as M,selectIndexForGroupBy as h}from"./packem_shared/CountRlsUnsupportedError-Cl8XpYDL.mjs";import{AUTH_METRICS_BUCKETS_TABLE as F,AUTH_METRICS_BUCKET_MS as D,AUTH_METRICS_BUCKET_RETENTION as L,AUTH_METRICS_TABLE as U,ensureAuthMetricsTables as B,readAuthMetrics as b,recordAuthEvent as y}from"./packem_shared/AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs";import{c as K,a as G,d as P}from"./packem_shared/context-telemetry-
|
|
1
|
+
import{exportShardRows as o,exportShardTable as t,importShardRows as a,parseExportShardArgs as n,parseImportShardArgs as i,selectExportTables as s,validateImportRow as l}from"./packem_shared/exportShardRows-kt42wijd.mjs";import{AGGREGATE_SQL_FUNCTION as T,aggregateSqlFunction as d,matchesStaticWhere as p,normalizeCountArgument as E,throwingScheduler as S}from"./packem_shared/AGGREGATE_SQL_FUNCTION-QYaiuty4.mjs";import{aggregateTableName as _,coerceAggregateNumber as u,encodeAggregateKey as x,foldAggregateTally as f,readAggregateValue as I}from"./packem_shared/aggregateTableName-G-eXyjcz.mjs";import{CountRlsUnsupportedError as A,mergeWhere as N,planAggregateLookup as g,selectIndexForAggregate as C,selectIndexForCount as M,selectIndexForGroupBy as h}from"./packem_shared/CountRlsUnsupportedError-Cl8XpYDL.mjs";import{AUTH_METRICS_BUCKETS_TABLE as F,AUTH_METRICS_BUCKET_MS as D,AUTH_METRICS_BUCKET_RETENTION as L,AUTH_METRICS_TABLE as U,ensureAuthMetricsTables as B,readAuthMetrics as b,recordAuthEvent as y}from"./packem_shared/AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs";import{c as K,a as G,d as P}from"./packem_shared/context-telemetry-BQoMfXLz.mjs";import{NotUniqueError as v,assertValidClientId as H,createShardCtxDb as w,normalizeIdStructurally as q}from"./packem_shared/NotUniqueError-BcP6GOem.mjs";import{DATA_MIGRATION_STATE_TABLE as X,readMigrationStatus as Y,runDataMigration as V}from"./packem_shared/DATA_MIGRATION_STATE_TABLE-CaO6L0Ee.mjs";import{SCAN_DEP as Z,createDependencyTracker as j,depKey as J}from"./packem_shared/SCAN_DEP-D_yR9EeV.mjs";import{renderSql as ee}from"./packem_shared/renderSql-B5lF5Jd9.mjs";import{diffExternalSource as oe}from"./packem_shared/diffExternalSource-DMpkJta1.mjs";import{materializeExternalRows as ae,materializeExternalRowsIncremental as ne,readExternalSourceBaseline as ie,runExternalSourceTick as se}from"./packem_shared/materializeExternalRows-BFmT9gsw.mjs";import{isSoftDeleted as ce,isSourceDue as Te,liftSourceId as de,pullExternalSourceIncrementalTick as pe,pullExternalSourceTick as Ee}from"./packem_shared/isSoftDeleted-BvhQov04.mjs";import{FUNCTION_METRICS_BUCKETS_TABLE as me,FUNCTION_METRICS_BUCKET_MS as _e,FUNCTION_METRICS_BUCKET_RETENTION as ue,FUNCTION_METRICS_INDEX_TABLE as xe,FUNCTION_METRICS_TABLE as fe,ensureFunctionMetricsTables as Ie,readFunctionMetricBuckets as Re,readFunctionMetricIndexHits as Ae,readFunctionMetrics as Ne,readFunctionMetricsTotals as ge,recordFunctionMetric as Ce}from"./packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-BPPeqM11.mjs";import{GEO_DEFAULT_PRECISION as he,boundingBoxGeohashes as Oe,coveringGeohashes as Fe,encodeGeohash as De,haversineMeters as Le,pointInBoundingBox as Ue}from"./packem_shared/GEO_DEFAULT_PRECISION-CWAm_oYY.mjs";import{ADMIN_FUNCTIONS as be,ADMIN_FUNCTION_PREFIX as ye,FLAGS_FUNCTION_PREFIX as ke,RELATION_FUNCTION_PREFIX as Ke,facetColumn as Ge,listTables as Pe,readTablePage as We,selectMatchingIds as ve}from"./packem_shared/ADMIN_FUNCTIONS-PxZ8Lr9e.mjs";import{LogBuffer as we}from"./packem_shared/LogBuffer-bIvCelI-.mjs";import{MAIL_RETENTION as ze,MAIL_TABLE as Xe,clearCapturedMail as Ye,ensureMailTable as Ve,readCapturedMail as Qe,recordCapturedMail as Ze}from"./packem_shared/MAIL_RETENTION-KmozO2NQ.mjs";import{default as Je}from"./packem_shared/NotFoundError-J3tjf4Uo.mjs";import{armRestore as er,readBookmark as rr}from"./packem_shared/armRestore-BNzdvQ_o.mjs";import{applySelect as tr,buildSeekWhere as ar,decodeCursor as nr,encodeCursor as ir,normalizeOrderKeys as sr,softDeleteScope as lr}from"./packem_shared/applySelect-Bq2KOrkL.mjs";import{RANK_TIEBREAK as Tr,encodePartitionKey as dr,matchesRankStaticWhere as pr,rankTableName as Er,resolveRankPartition as Sr,sortColumnName as mr}from"./packem_shared/RANK_TIEBREAK-DtX8zQyc.mjs";import{ReactiveCache as ur,reactiveCacheKey as xr}from"./packem_shared/ReactiveCache-1_9Rs7J_.mjs";import{serveRelationFanout as Ir}from"./packem_shared/serveRelationFanout-Ct5D2Tbk.mjs";import{DEFAULT_MAX_RELATION_KEYS as Ar,assertFlatPredicate as Nr,assertShapeShardable as gr,containsRelationPredicate as Cr,isRelationPredicate as Mr,resolveRelationPredicates as hr}from"./packem_shared/DEFAULT_MAX_RELATION_KEYS-BRdmX7WW.mjs";import{applyOnDelete as Fr,fanOutScalarCounts as Dr,resolveWith as Lr,runRowValidators as Ur}from"./packem_shared/applyOnDelete-BvQN7pDL.mjs";import{RLS_UNWRAP_SYMBOL as br,RlsRequiredError as yr,guardWriter as kr}from"./packem_shared/RLS_UNWRAP_SYMBOL-C6_WX3dG.mjs";import{buildFtsMatch as Gr,ftsTableName as Pr,scoreDocument as Wr,stringifySearchText as vr,tokenizeSearch as Hr}from"./packem_shared/buildFtsMatch-CV0Z7PWv.mjs";import{o as qr,c as zr,_ as Xr}from"./packem_shared/security-audit-BKUOgE0x.mjs";import{SESSION_DO_TTL_DEFAULT as Vr,SessionDO as Qr}from"./packem_shared/SESSION_DO_TTL_DEFAULT-GvBy_DBz.mjs";import{ROOT_DO_SIZE_WARN_BYTES as jr,ROOT_SHARD_NAME as Jr,ShardDO as $r}from"./packem_shared/ROOT_DO_SIZE_WARN_BYTES-DqqGF-jB.mjs";import{SHARD_REGISTRY_DO_NAME as ro,ShardRegistryDO as oo}from"./packem_shared/SHARD_REGISTRY_DO_NAME-Caa0fR4N.mjs";import{MAX_SQL_ROWS as ao,assertReadonly as no,runReadonlySql as io}from"./packem_shared/MAX_SQL_ROWS-Bdu25ASB.mjs";import{createSystemReader as lo}from"./packem_shared/createSystemReader-DcDcrtM3.mjs";import{ConflictError as To}from"./packem_shared/ConflictError-C8GtJmjS.mjs";import{hasTrigger as Eo,runTriggers as So}from"./packem_shared/hasTrigger-_rexbWMO.mjs";import{selectExpiredIds as _o}from"./packem_shared/selectExpiredIds-BGVP3d8-.mjs";import{compileWhereSql as xo}from"./packem_shared/compileWhereSql-BLcfs4QW.mjs";import{CDC_LOG_TABLE as Io,applyCdcChanges as Ro,readCdcChanges as Ao,trimCdcChanges as No}from"./packem_shared/CDC_LOG_TABLE-E_J5LPoK.mjs";import{backfillAggregateIndexes as Co,backfillRankIndexes as Mo}from"./packem_shared/backfillAggregateIndexes-BAQ3Fwwh.mjs";import{runShardMigrations as Oo}from"./packem_shared/runShardMigrations-bxOHpfID.mjs";import{stableStringify as Do}from"./packem_shared/stableStringify-BjLh4gvA.mjs";import{stableWireKey as Uo}from"./packem_shared/stableWireKey-YEHLaX6X.mjs";import{subscriptionListDeltas as bo}from"./packem_shared/subscriptionListDeltas-Bs69JbA8.mjs";export{be as ADMIN_FUNCTIONS,ye as ADMIN_FUNCTION_PREFIX,T as AGGREGATE_SQL_FUNCTION,F as AUTH_METRICS_BUCKETS_TABLE,D as AUTH_METRICS_BUCKET_MS,L as AUTH_METRICS_BUCKET_RETENTION,U as AUTH_METRICS_TABLE,Io as CDC_LOG_TABLE,To as ConflictError,A as CountRlsUnsupportedError,X as DATA_MIGRATION_STATE_TABLE,Ar as DEFAULT_MAX_RELATION_KEYS,ke as FLAGS_FUNCTION_PREFIX,me as FUNCTION_METRICS_BUCKETS_TABLE,_e as FUNCTION_METRICS_BUCKET_MS,ue as FUNCTION_METRICS_BUCKET_RETENTION,xe as FUNCTION_METRICS_INDEX_TABLE,fe as FUNCTION_METRICS_TABLE,he as GEO_DEFAULT_PRECISION,we as LogBuffer,ze as MAIL_RETENTION,Xe as MAIL_TABLE,ao as MAX_SQL_ROWS,qr as MIN_ADMIN_TOKEN_LENGTH,zr as MIN_AUTH_SECRET_LENGTH,Je as NotFoundError,v as NotUniqueError,Tr as RANK_TIEBREAK,Ke as RELATION_FUNCTION_PREFIX,br as RLS_UNWRAP_SYMBOL,jr as ROOT_DO_SIZE_WARN_BYTES,Jr as ROOT_SHARD_NAME,ur as ReactiveCache,yr as RlsRequiredError,Z as SCAN_DEP,Vr as SESSION_DO_TTL_DEFAULT,ro as SHARD_REGISTRY_DO_NAME,Qr as SessionDO,$r as ShardDO,oo as ShardRegistryDO,d as aggregateSqlFunction,_ as aggregateTableName,Ro as applyCdcChanges,Fr as applyOnDelete,tr as applySelect,er as armRestore,Nr as assertFlatPredicate,no as assertReadonly,gr as assertShapeShardable,H as assertValidClientId,Co as backfillAggregateIndexes,Mo as backfillRankIndexes,Oe as boundingBoxGeohashes,Gr as buildFtsMatch,Xr as buildSecurityAudit,ar as buildSeekWhere,Ye as clearCapturedMail,u as coerceAggregateNumber,xo as compileWhereSql,Cr as containsRelationPredicate,Fe as coveringGeohashes,j as createDependencyTracker,K as createMetrics,w as createShardCtxDb,lo as createSystemReader,G as createTracer,nr as decodeCursor,J as depKey,oe as diffExternalSource,P as dispatchRootSpan,x as encodeAggregateKey,ir as encodeCursor,De as encodeGeohash,dr as encodePartitionKey,B as ensureAuthMetricsTables,Ie as ensureFunctionMetricsTables,Ve as ensureMailTable,o as exportShardRows,t as exportShardTable,Ge as facetColumn,Dr as fanOutScalarCounts,f as foldAggregateTally,Pr as ftsTableName,kr as guardWriter,Eo as hasTrigger,Le as haversineMeters,a as importShardRows,Mr as isRelationPredicate,ce as isSoftDeleted,Te as isSourceDue,de as liftSourceId,Pe as listTables,pr as matchesRankStaticWhere,p as matchesStaticWhere,ae as materializeExternalRows,ne as materializeExternalRowsIncremental,N as mergeWhere,E as normalizeCountArgument,q as normalizeIdStructurally,sr as normalizeOrderKeys,n as parseExportShardArgs,i as parseImportShardArgs,g as planAggregateLookup,Ue as pointInBoundingBox,pe as pullExternalSourceIncrementalTick,Ee as pullExternalSourceTick,Er as rankTableName,xr as reactiveCacheKey,I as readAggregateValue,b as readAuthMetrics,rr as readBookmark,Qe as readCapturedMail,Ao as readCdcChanges,ie as readExternalSourceBaseline,Re as readFunctionMetricBuckets,Ae as readFunctionMetricIndexHits,Ne as readFunctionMetrics,ge as readFunctionMetricsTotals,Y as readMigrationStatus,We as readTablePage,y as recordAuthEvent,Ze as recordCapturedMail,Ce as recordFunctionMetric,ee as renderSql,Sr as resolveRankPartition,hr as resolveRelationPredicates,Lr as resolveWith,V as runDataMigration,se as runExternalSourceTick,io as runReadonlySql,Ur as runRowValidators,Oo as runShardMigrations,So as runTriggers,Wr as scoreDocument,_o as selectExpiredIds,s as selectExportTables,C as selectIndexForAggregate,M as selectIndexForCount,h as selectIndexForGroupBy,ve as selectMatchingIds,Ir as serveRelationFanout,lr as softDeleteScope,mr as sortColumnName,Do as stableStringify,Uo as stableWireKey,vr as stringifySearchText,bo as subscriptionListDeltas,S as throwingScheduler,Hr as tokenizeSearch,No as trimCdcChanges,l as validateImportRow};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import{LunoraError as f,toErrorBody as C}from"@lunora/errors";import{drizzle as gt}from"drizzle-orm/durable-sqlite";import{c as j}from"./constant-time-equal-BVG05Guz.mjs";import{j as y}from"./json-response-wrh9TBPw.mjs";import{O as St,t as bt,n as Ie,r as K,A as Et,a as wt,b as Rt,c as Tt,d as vt,w as se,e as At}from"./context-telemetry-BQoMfXLz.mjs";import{f as w,c as O}from"./wire-codec-Ctnni0h6.mjs";import{parseExportShardArgs as It,parseImportShardArgs as _t}from"./exportShardRows-kt42wijd.mjs";import{recordAuthEvent as kt,readAuthMetrics as Mt}from"./AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs";import{DATA_MIGRATION_STATE_TABLE as Nt,readMigrationStatus as Ct}from"./DATA_MIGRATION_STATE_TABLE-CaO6L0Ee.mjs";import{SCAN_DEP as _e,createDependencyTracker as Ot,tableFromDepKey as Lt}from"./SCAN_DEP-D_yR9EeV.mjs";import{readFunctionMetricsTotals as xt,readFunctionMetricIndexHits as $t,recordFunctionMetric as Pt,mergeScanAttribution as qt,readFunctionMetrics as Dt,readFunctionMetricBuckets as Ut}from"./FUNCTION_METRICS_BUCKETS_TABLE-BPPeqM11.mjs";import{createFanoutCounters as ke,ADMIN_FUNCTION_PREFIX as k,RELATION_FUNCTION_PREFIX as Bt,selectMatchingIds as Ft,ADMIN_FUNCTIONS as h,findStorageReferences as Wt,listTables as Kt,summarizeSubscriptions as Ht,summarizeFanoutTopics as Qt,readTablePage as Gt,facetColumn as zt,FLAGS_FUNCTION_PREFIX as jt,recordFanoutPass as re,MAX_PAGE_SIZE as Jt}from"./ADMIN_FUNCTIONS-PxZ8Lr9e.mjs";import{LogBuffer as Xt}from"./LogBuffer-bIvCelI-.mjs";import{recordCapturedMail as Me,clearCapturedMail as Yt,readCapturedMail as Vt,MAIL_TABLE as Zt}from"./MAIL_RETENTION-KmozO2NQ.mjs";import{stableStringify as Ee}from"./stableStringify-BjLh4gvA.mjs";import{readBookmark as es,armRestore as ts}from"./armRestore-BNzdvQ_o.mjs";import{ReactiveCache as ss,reactiveCacheKey as Ne}from"./ReactiveCache-1_9Rs7J_.mjs";import{stableWireKey as $}from"./stableWireKey-YEHLaX6X.mjs";import{awaitWsDrain as M,trySendFrame as L,subscriptionListDeltas as rs,sendDeltaFrames as as}from"./subscriptionListDeltas-Bs69JbA8.mjs";import{fingerprintError as ns}from"@lunora/fingerprint";import{redact as is,standardRules as os}from"@visulima/redact";import{R as Ce,E as cs,_ as ds}from"./security-audit-BKUOgE0x.mjs";import{runReadonlySql as us}from"./MAX_SQL_ROWS-Bdu25ASB.mjs";import{ConflictError as ls}from"./ConflictError-C8GtJmjS.mjs";import{selectExpiredIds as hs}from"./selectExpiredIds-BGVP3d8-.mjs";import{p as ps,m as fs,T as ms,u as ys,b as ae,_ as gs,o as Ss,l as bs,d as Es,S as ws}from"./ctx-db-idempotency-wiVoGnpQ.mjs";import{CDC_LOG_TABLE as Oe,readCdcChanges as ne,readCdcCursor as Le,readCdcEpoch as xe,minCdcSeq as $e,bumpCdcEpoch as Rs}from"./CDC_LOG_TABLE-E_J5LPoK.mjs";import{a as Ts,s as vs}from"./ctx-db-shapes-DzX_H5q8.mjs";const Pe=500,J=(a,e)=>{if(a.size<e)return;const t=a.keys().next().value;t!==void 0&&a.delete(t)},at=new TextEncoder,As=a=>{const e=a.replaceAll("-","+").replaceAll("_","/")+"===".slice((a.length+3)%4),t=atob(e),s=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)s[r]=t.codePointAt(r)??0;return s},Is=64,ie=new Map,_s=async a=>{const e=ie.get(a);if(e)return e;J(ie,Is);const t=crypto.subtle.importKey("raw",at.encode(a),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]);return ie.set(a,t),t},ks=async(a,e,t)=>{const s=await _s(a);return crypto.subtle.verify("HMAC",s,t,at.encode(e))},Ms="v1",Ns=async(a,e,t=Date.now())=>{if(a.length===0||e.length===0)return!1;const s=e.split(".");if(s.length!==3)return!1;const[r,n,i]=s;if(r!==Ms||i.length===0)return!1;const o=Number(n);if(!Number.isFinite(o)||o<=t)return!1;let c;try{c=As(i)}catch{return!1}return ks(a,`${r}.${n}`,c)},q="__lunora_audit__",X=(a,e,...t)=>a.exec.call(a,e,...t),we=a=>{X(a,`CREATE TABLE IF NOT EXISTS "${q}" (
|
|
2
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
+
ts REAL NOT NULL,
|
|
4
|
+
op TEXT NOT NULL,
|
|
5
|
+
"table" TEXT,
|
|
6
|
+
id TEXT,
|
|
7
|
+
detail TEXT
|
|
8
|
+
)`)},Cs=(a,e)=>{we(a),X(a,`INSERT INTO "${q}" (ts, op, "table", id, detail) VALUES (?, ?, ?, ?, ?)`,e.ts,e.op,e.table??null,e.id??null,e.detail===void 0?null:JSON.stringify(e.detail)),X(a,`DELETE FROM "${q}" WHERE seq <= (SELECT MAX(seq) - ? FROM "${q}")`,1e3)},Os=(a,e={})=>{we(a);const t=e.sinceSeq??0,s=Math.max(1,Math.min(e.limit??1e3,1e4));return X(a,`SELECT seq, ts, op, "table", id, detail FROM "${q}" WHERE seq > ? ORDER BY seq DESC LIMIT ?`,t,s).toArray().map(r=>{const n={op:r.op,seq:r.seq,ts:r.ts};return r.table!==null&&(n.table=r.table),r.id!==null&&(n.id=r.id),r.detail!==null&&(n.detail=JSON.parse(r.detail)),n})},Ls=["x-lunora-userid","x-lunora-identity","x-d1-bookmark","x-lunora-client-ip","x-lunora-system","x-lunora-shard-binding"],xs=(a,e)=>{const t=new Headers({"content-type":"application/json"});for(const s of Ls){const r=a.headers.get(s);r!==null&&t.set(s,r)}return e.mutationId!==void 0&&t.set("x-lunora-mutation-id",e.mutationId),e.clientId!==void 0&&t.set("x-lunora-client-id",e.clientId),e.clientSeq!==void 0&&t.set("x-lunora-client-seq",String(e.clientSeq)),new Request("https://shard.internal/rpc",{body:JSON.stringify({args:e.args??{},functionPath:e.functionPath}),headers:t,method:"POST"})},$s=100,Ps=new Set(["aggregate","count","delete","deleteMany","deleteWhere","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","insertMany","insertManyUnsafe","lookupById","patch","patchMany","patchWhere","rank","rankBefore","rankPage","rankPageRows","replace","restore"]),qs=new Set(["aggregate","count","deleteWhere","findFirst","findFirstOrThrow","findMany","groupBy","insert","insertMany","insertManyUnsafe","patchWhere","rank","rankBefore","rankPage","rankPageRows"]),Ds=(a,e)=>{if(!qs.has(a))return;const t=e[0];return typeof t=="string"&&t.length>0?t:void 0},Us=a=>a instanceof Error?a.message:typeof a=="string"?a:JSON.stringify(a),Bs=a=>{const{deps:e,durationMs:t,failure:s,operation:r,startTs:n,table:i}=a;return{attributes:{"db.operation.name":r,...i===void 0?{}:{"db.collection.name":i},"db.system.name":"sqlite"},durationMs:t,...s===void 0?{}:{error:{message:Us(s),type:bt(s)}},functionPath:e.functionPath,kind:"client",name:i===void 0?`db.${r}`:`db.${r} ${i}`,ok:s===void 0,parentSpanId:e.anchor.rootSpanId,shardKey:e.shardKey,spanId:St(8),startTs:n,traceId:e.anchor.traceId,userId:e.userId()}},Fs=(a,e)=>{if(e.mode==="off")return a;const{tally:t}=e,s=new Map;return new Proxy(a,{get(r,n,i){const o=Reflect.get(r,n,i);if(typeof n!="string"||typeof o!="function"||!Ps.has(n))return o;const c=s.get(n);if(c!==void 0)return c;const d=o,u=async(...l)=>{const m=Date.now(),p=Ds(n,l);let g;try{return await d.apply(r,l)}catch(E){throw g=E,E}finally{const E=Date.now()-m;t.calls+=1,t.durationMs+=E,t.perOperation[n]=(t.perOperation[n]??0)+1,g!==void 0&&(t.errors+=1);try{e.mode==="spans"&&(t.spansEmitted>=$s?t.spansTruncated=!0:(t.spansEmitted+=1,e.record(Bs({deps:e,durationMs:E,failure:g,operation:n,startTs:m,table:p}))))}catch{}}};return s.set(n,u),u}})},Ws=()=>({calls:0,durationMs:0,errors:0,perOperation:{},spansEmitted:0,spansTruncated:!1}),Ks=a=>{const e={"db.calls":a.calls,"db.duration_ms":a.durationMs};a.errors>0&&(e["db.errors"]=a.errors),a.spansTruncated&&(e["db.spans_truncated"]=!0);for(const[t,s]of Object.entries(a.perOperation))e[`db.op.${t}`]=s;return e},B="__lunora_issue_state__",Hs=["ignored","open","resolved"],Qs=["critical","high","low","medium"],Y=(a,e,...t)=>a.exec.call(a,e,...t),H=a=>a??null,nt=a=>{Y(a,`CREATE TABLE IF NOT EXISTS "${B}" (
|
|
9
|
+
hash TEXT PRIMARY KEY,
|
|
10
|
+
status TEXT NOT NULL DEFAULT 'open',
|
|
11
|
+
assignee TEXT,
|
|
12
|
+
severity TEXT,
|
|
13
|
+
updated_at REAL NOT NULL,
|
|
14
|
+
updated_by TEXT
|
|
15
|
+
)`)},it=a=>({...a.assignee===null?{}:{assignee:a.assignee},hash:a.hash,...a.severity===null?{}:{severity:a.severity},status:a.status,updatedAt:a.updated_at,...a.updated_by===null?{}:{updatedBy:a.updated_by}}),Gs=(a,e)=>{const t=new Map;if(e.length===0)return t;nt(a);for(let s=0;s<e.length;s+=100){const r=e.slice(s,s+100),n=r.map(()=>"?").join(", "),i=Y(a,`SELECT hash, status, assignee, severity, updated_at, updated_by FROM "${B}" WHERE hash IN (${n})`,...r).toArray();for(const o of i)t.set(o.hash,it(o))}return t},zs=(a,e,t,s,r)=>{nt(a);const n=H(t.status),i=H(t.assignee),o=t.assignee===null?1:0,c=H(t.severity),d=t.severity===null?1:0,u=H(r);Y(a,`INSERT INTO "${B}" (hash, status, assignee, severity, updated_at, updated_by)
|
|
16
|
+
VALUES (?, COALESCE(?, 'open'), ?, ?, ?, ?)
|
|
17
|
+
ON CONFLICT(hash) DO UPDATE SET
|
|
18
|
+
status = COALESCE(?, status),
|
|
19
|
+
assignee = CASE WHEN ? = 1 THEN NULL ELSE COALESCE(?, assignee) END,
|
|
20
|
+
severity = CASE WHEN ? = 1 THEN NULL ELSE COALESCE(?, severity) END,
|
|
21
|
+
updated_at = ?,
|
|
22
|
+
updated_by = ?`,e,n,i,c,s,u,n,o,i,d,c,s,u);const[l]=Y(a,`SELECT hash, status, assignee, severity, updated_at, updated_by FROM "${B}" WHERE hash = ?`,e).toArray();return l===void 0?{hash:e,status:n??"open",updatedAt:s,...r===void 0?{}:{updatedBy:r}}:it(l)},qe=256,ot=a=>`${a.kind}${a.name}${Ee(a.attributes??{})}`;class js{capacity;series=new Map;constructor(e=qe){this.capacity=e>0?Math.trunc(e):qe}get size(){return this.series.size}clear(){this.series.clear()}entries(){return[...this.series.values()].toReversed().map(e=>({...e}))}push(e){const t=ot(e),s=this.series.get(t);if(s===void 0){if(this.series.size>=this.capacity){const r=this.series.keys().next().value;r!==void 0&&this.series.delete(r)}this.series.set(t,{...e.attributes===void 0?{}:{attributes:e.attributes},count:1,...e.traceId===void 0?{}:{exemplarTraceId:e.traceId},firstTs:e.ts,functionPath:e.functionPath,kind:e.kind,last:e.value,lastTs:e.ts,max:e.value,min:e.value,name:e.name,...e.shardKey===void 0?{}:{shardKey:e.shardKey},sum:e.value});return}this.series.delete(t),s.count+=1,s.sum+=e.value,s.min=Math.min(s.min,e.value),s.max=Math.max(s.max,e.value),s.last=e.value,s.lastTs=e.ts,s.functionPath=e.functionPath,e.traceId!==void 0&&(s.exemplarTraceId=e.traceId),this.series.set(t,s)}}const T="__lunora_metric_history",he=6e4,Js=1440,Xs=1e3,De=5e3,v=(a,e,...t)=>a.exec.call(a,e,...t),Ys=a=>Math.floor(a/he)*he,Ue=new WeakSet,ct=a=>{Ue.has(a)||(v(a,`CREATE TABLE IF NOT EXISTS "${T}" (
|
|
23
|
+
series_key TEXT NOT NULL,
|
|
24
|
+
bucket_ms INTEGER NOT NULL,
|
|
25
|
+
name TEXT NOT NULL,
|
|
26
|
+
kind TEXT NOT NULL,
|
|
27
|
+
attrs TEXT NOT NULL DEFAULT '{}',
|
|
28
|
+
function_path TEXT NOT NULL DEFAULT '',
|
|
29
|
+
shard_key TEXT,
|
|
30
|
+
count INTEGER NOT NULL DEFAULT 0,
|
|
31
|
+
sum REAL NOT NULL DEFAULT 0,
|
|
32
|
+
min REAL NOT NULL DEFAULT 0,
|
|
33
|
+
max REAL NOT NULL DEFAULT 0,
|
|
34
|
+
last REAL NOT NULL DEFAULT 0,
|
|
35
|
+
last_ts REAL NOT NULL DEFAULT 0,
|
|
36
|
+
exemplar_trace TEXT,
|
|
37
|
+
PRIMARY KEY (series_key, bucket_ms)
|
|
38
|
+
)`),Ue.add(a))},Vs=4096,Be=new WeakMap,Zs=a=>{let e=Be.get(a);return e===void 0&&(e=new Set,Be.set(a,e)),e},er=(a,e,t,s={})=>{const r=s.maxSeries??Xs,n=s.retentionBuckets??Js;ct(a);const i=ot(e),o=Ys(e.ts),c=Zs(a),d=`${i}\0${o.toString()}`,u=c.has(d)||v(a,`SELECT 1 AS c FROM "${T}" WHERE series_key = ? AND bucket_ms = ? LIMIT 1`,i,o).toArray().length>0;if(!u&&!(v(a,`SELECT 1 AS c FROM "${T}" WHERE series_key = ? LIMIT 1`,i).toArray().length>0)&&v(a,`SELECT COUNT(DISTINCT series_key) AS n FROM "${T}"`).one().n>=r)return;const l=t??null;v(a,`INSERT INTO "${T}"
|
|
39
|
+
(series_key, bucket_ms, name, kind, attrs, function_path, shard_key, count, sum, min, max, last, last_ts, exemplar_trace)
|
|
40
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?)
|
|
41
|
+
ON CONFLICT(series_key, bucket_ms) DO UPDATE SET
|
|
42
|
+
count = count + 1,
|
|
43
|
+
sum = sum + excluded.sum,
|
|
44
|
+
min = MIN(min, excluded.min),
|
|
45
|
+
max = MAX(max, excluded.max),
|
|
46
|
+
last = excluded.last,
|
|
47
|
+
last_ts = excluded.last_ts,
|
|
48
|
+
exemplar_trace = CASE WHEN excluded.exemplar_trace IS NULL THEN exemplar_trace ELSE excluded.exemplar_trace END`,i,o,e.name,e.kind,Ee(e.attributes??{}),e.functionPath,e.shardKey??null,e.value,e.value,e.value,e.value,e.ts,l),u||v(a,`DELETE FROM "${T}"
|
|
49
|
+
WHERE series_key = ?
|
|
50
|
+
AND bucket_ms <= (
|
|
51
|
+
SELECT MAX(bucket_ms) - ? FROM "${T}" WHERE series_key = ?
|
|
52
|
+
)`,i,n*he,i),u&&!c.has(d)&&(c.size>=Vs&&c.clear(),c.add(d))},tr=a=>{if(!(a===""||a==="{}"))try{const e=JSON.parse(a);return e!==null&&typeof e=="object"?e:void 0}catch{return}},sr=(a,e={})=>{ct(a);const t=e.sinceMs===void 0?v(a,`SELECT * FROM "${T}" ORDER BY bucket_ms DESC LIMIT ?`,De).toArray():v(a,`SELECT * FROM "${T}" WHERE bucket_ms >= ? ORDER BY bucket_ms DESC LIMIT ?`,e.sinceMs,De).toArray(),s=new Map;for(const r of t){let n=s.get(r.series_key);if(n===void 0){const i=tr(r.attrs);n={...i===void 0?{}:{attributes:i},functionPath:r.function_path,kind:r.kind,name:r.name,points:[],...r.shard_key===null?{}:{shardKey:r.shard_key}},s.set(r.series_key,n)}n.points.push({bucketMs:r.bucket_ms,count:r.count,...r.exemplar_trace===null?{}:{exemplarTraceId:r.exemplar_trace},last:r.last,max:r.max,min:r.min,sum:r.sum})}for(const r of s.values())r.points.sort((n,i)=>n.bucketMs-i.bucketMs);return{series:[...s.values()]}},D="__lunora_metrics_queries",U=(a,e,...t)=>a.exec.call(a,e,...t),rr=a=>{let e=a.replaceAll(/'(?:[^']|'')*'/g,"?").replaceAll(/\b0x[\da-f]+\b/gi,"?").replaceAll(/(?<=[=,([\s])\d+(?:\.\d+)?/g,"?").replaceAll(/\s+/g," ").trim();return e.length>512&&(e=`${e.slice(0,511)}…`),e},dt=a=>{U(a,`CREATE TABLE IF NOT EXISTS "${D}" (
|
|
53
|
+
normalized_sql TEXT PRIMARY KEY,
|
|
54
|
+
exec_count INTEGER NOT NULL DEFAULT 0,
|
|
55
|
+
total_duration_ms REAL NOT NULL DEFAULT 0,
|
|
56
|
+
rows_read INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
rows_written INTEGER NOT NULL DEFAULT 0
|
|
58
|
+
)`)},ar=(a,e,t,s,r)=>{const n=rr(e);if(n.length===0||(dt(a),U(a,`SELECT COUNT(*) AS n FROM "${D}"`).one().n>=500&&U(a,`SELECT COUNT(*) AS c FROM "${D}" WHERE normalized_sql = ?`,n).one().c===0))return;const i=`INSERT INTO "${D}" (normalized_sql, exec_count, total_duration_ms, rows_read, rows_written)
|
|
59
|
+
VALUES (?, 1, ?, ?, ?)
|
|
60
|
+
ON CONFLICT(normalized_sql) DO UPDATE SET
|
|
61
|
+
exec_count = exec_count + 1,
|
|
62
|
+
total_duration_ms = total_duration_ms + excluded.total_duration_ms,
|
|
63
|
+
rows_read = rows_read + excluded.rows_read,
|
|
64
|
+
rows_written = rows_written + excluded.rows_written`;U(a,i,n,t,s,r)},nr=a=>(dt(a),U(a,`SELECT normalized_sql, exec_count, total_duration_ms, rows_read, rows_written FROM "${D}" ORDER BY total_duration_ms DESC`).toArray().map(e=>({execCount:e.exec_count,normalizedSql:e.normalized_sql,rowsRead:e.rows_read,rowsWritten:e.rows_written,totalDurationMs:e.total_duration_ms}))),A="__lunora_queue_messages",x=(a,e,...t)=>a.exec.call(a,e,...t),Fe=a=>a??null,ut="… [truncated by the dev queue catcher]",lt="[unserializable message body]",ir=a=>{if(a===void 0)return"null";try{const e=JSON.stringify(a);return e.length>131072?JSON.stringify(`${e.slice(0,131072)}${ut}`):e}catch{return JSON.stringify(lt)}},or=a=>typeof a=="string"&&(a===lt||a.endsWith(ut)),cr=a=>{if(!(a==null||a===""))try{return JSON.parse(a)}catch{return}},ee=a=>{x(a,`CREATE TABLE IF NOT EXISTS "${A}" (
|
|
65
|
+
id TEXT PRIMARY KEY,
|
|
66
|
+
captured_at INTEGER NOT NULL,
|
|
67
|
+
message_id TEXT NOT NULL,
|
|
68
|
+
queue TEXT NOT NULL,
|
|
69
|
+
export_name TEXT,
|
|
70
|
+
body TEXT NOT NULL,
|
|
71
|
+
attempts INTEGER NOT NULL,
|
|
72
|
+
outcome TEXT NOT NULL,
|
|
73
|
+
error TEXT,
|
|
74
|
+
dead_lettered INTEGER NOT NULL,
|
|
75
|
+
message_ts INTEGER NOT NULL
|
|
76
|
+
)`)},dr=(a,e,t)=>{ee(a);for(const s of e)x(a,`INSERT INTO "${A}" (id, captured_at, message_id, queue, export_name, body, attempts, outcome, error, dead_lettered, message_ts)
|
|
77
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,crypto.randomUUID(),t,s.messageId,s.queue,Fe(s.exportName),ir(s.body),s.attempts,s.outcome,Fe(s.error),s.deadLettered===!0?1:0,s.timestamp);return x(a,`DELETE FROM "${A}"
|
|
78
|
+
WHERE id NOT IN (
|
|
79
|
+
SELECT id FROM "${A}" ORDER BY captured_at DESC, id DESC LIMIT ?
|
|
80
|
+
)`,500),{recorded:e.length}},ht=a=>({attempts:a.attempts,body:cr(a.body),capturedAt:a.captured_at,deadLettered:a.dead_lettered===1,error:a.error??void 0,exportName:a.export_name??void 0,id:a.id,messageId:a.message_id,outcome:a.outcome,queue:a.queue,timestamp:a.message_ts}),ur=(a,e={})=>{ee(a);const t=Math.min(Math.max(e.limit??100,1),500),s=typeof e.queue=="string"&&e.queue.length>0?e.queue:void 0,r=s===void 0?"":"WHERE queue = ?",n=s===void 0?[t]:[s,t];return{entries:x(a,`SELECT * FROM "${A}" ${r} ORDER BY captured_at DESC, id DESC LIMIT ?`,...n).toArray().map(i=>ht(i))}},lr=(a,e)=>{ee(a);const t=x(a,`SELECT * FROM "${A}" WHERE id = ? LIMIT 1`,e).toArray()[0];return t===void 0?void 0:ht(t)},hr=a=>(ee(a),x(a,`DELETE FROM "${A}"`),{cleared:!0}),pe="::relay::",Q=(a,e)=>`${a}${pe}${String(e)}`,pr=a=>{const e=a.lastIndexOf(pe);if(e===-1)return;const t=a.slice(0,e),s=a.slice(e+pe.length),r=Number(s);if(!(t.length===0||!Number.isInteger(r)||r<0||String(r)!==s))return{ownerKey:t,relayIndex:r}},V=(a,e)=>$({args:e??{},name:a}),fe={tDown:4e3,tUp:8e3},fr=(a,e,t=fe)=>{if(t.tDown>=t.tUp)throw new f("INTERNAL",`invalid promotion thresholds: tDown (${String(t.tDown)}) must be < tUp (${String(t.tUp)})`);return a==="owned"?e>=t.tUp?"promoted":"owned":e<t.tDown?"owned":"promoted"},mr=(a,e)=>e<a?{tDown:e,tUp:a}:{tDown:Math.min(Math.max(1,Math.floor(a/2)),a-1),tUp:a},me=(a,e)=>{if(!e)return a;const t=Object.create(null);for(const s of["_id","_creationTime",...e])Object.hasOwn(a,s)&&(t[s]=a[s]);return t},We=(a,e,t)=>{const{columns:s,table:r}=t,n=new Map,i=[];for(const{doc:o,id:c}of a){const d=me(o,s),u=JSON.stringify(w(d));n.set(c,u);const l=e.get(c);l===void 0?i.push({key:c,op:"insert",table:r,value:d}):l!==u&&i.push({key:c,op:"update",table:r,value:d})}for(const o of e.keys())n.has(o)||i.push({key:o,op:"delete",table:r});return{next:n,rowsPatch:i}},ye=a=>a.map(e=>e.value===void 0?e:{...e,value:w(e.value)}),Re=(a,e,t={})=>{const{baseCheckpoint:s,checkpoint:r,epoch:n,lastMutationId:i,pokeId:o}=e,c=[JSON.stringify({baseCheckpoint:s,epoch:n,pokeId:o,type:"pokeStart"})];for(const d of a){const u=t.preEncoded?d.rowsPatch:ye(d.rowsPatch);c.push(JSON.stringify({pokeId:o,rowsPatch:u,shapeId:d.shapeId,type:"pokePart",...i===void 0?{}:{lastMutationId:i}}))}return c.push(JSON.stringify({checkpoint:r,epoch:n,pokeId:o,type:"pokeEnd"})),c},yr=2,Te=8,gr="LUNORA_RELAY_SECRET",Ke="x-lunora-relay-sig",He=a=>{const e=a?.[gr];return typeof e=="string"&&e.length>0?e:void 0},Qe=async(a,e)=>{const t=new TextEncoder,s=await crypto.subtle.importKey("raw",t.encode(a),{hash:"SHA-256",name:"HMAC"},!1,["sign"]),r=await crypto.subtle.sign("HMAC",s,t.encode(e));return[...new Uint8Array(r)].map(n=>n.toString(16).padStart(2,"0")).join("")},P=(a,e,t)=>{const s=a?.[e];let r=Number.NaN;return typeof s=="string"?r=Number.parseInt(s,10):typeof s=="number"&&(r=s),Number.isInteger(r)&&r>0?r:t},oe={},Sr=a=>{throw new f("INTERNAL",`unhandled relay frame: ${JSON.stringify(a)}`)},br=a=>{if(a===null||typeof a!="object")return;const e=a;return typeof e.idFromName=="function"&&typeof e.get=="function"?e:void 0},Er=a=>Response.json(a,{headers:{"content-type":"application/json"}}),G=()=>new Response(null,{status:204});class pt{constructor(e,t){this.host=e,this.roleId=t}host;roleId;async handleControl(e){let t;try{t=await e.text()}catch{return new Response("bad request",{status:400})}const s=He(this.host.env());if(s!==void 0){const n=e.headers.get(Ke),i=await Qe(s,t);if(n===null||!j(n,i))return new Response("forbidden",{status:403})}let r;try{r=JSON.parse(t)}catch{return new Response("bad request",{status:400})}switch(r.type){case"relay_attach":return this.onAttach(r.relayIndex),G();case"relay_detach":return this.onDetach(r.relayIndex),G();case"relay_frame":return this.host.deliverWhisperLocal(r.topic,r.frame,void 0),await this.onWhisperFrame(r),G();case"relay_shape_poke":{const n=this.host.getWebSockets().length,i=Date.now(),o=this.onShapePoke({...r,args:O(r.args)});return this.host.recordShapePokeFanout(n,o,Date.now()-i),G()}case"relay_shape_subscribe":return Er(this.onShapeSubscribe({...r,args:O(r.args)}));default:return Sr(r)}}maxRelays(){return P(this.host.env(),"LUNORA_MAX_RELAYS",Te)}canAddressSiblings(){return this.relayNamespace()!==void 0}relayNamespace(){const e=this.host.shardBinding();if(e!==void 0)return br(this.host.env()?.[e])}async postRelayMessage(e,t){await this.requestRelayMessage(e,t)}async requestRelayMessage(e,t){const s=this.relayNamespace();if(s===void 0)return;const r=typeof s.getByName=="function"?s.getByName(e):s.get(s.idFromName(e)),n=JSON.stringify(t),i={"content-type":"application/json","x-lunora-shard-binding":this.host.shardBinding()??""},o=He(this.host.env());o!==void 0&&(i[Ke]=await Qe(o,n));try{return await r.fetch("https://relay.internal/_lunora/relay",{body:n,headers:i,method:"POST"})}catch{return}}}let wr=class extends pt{shapeUniformCache=new Map;relaySetCache;relayShapeRegistry=new Map;relayShapeProxies=new Map;promotionState="owned";constructor(e,t){super(e,{ownerKey:t})}async forwardWhisper(e,t){if(!this.canAddressSiblings())return;const s=this.ownerRelaySet();s.size!==0&&await Promise.all([...s].map(r=>this.postRelayMessage(Q(this.roleId.ownerKey,r),{frame:t,topic:e,type:"relay_frame"})))}async onFlush(e,t){await Promise.all([this.multicastShapePokes(e,t),this.proxyShapePokes(e,t)])}seedRelayShape(){return Promise.resolve(void 0)}announce(){return Promise.resolve()}announceDrain(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,t=P(this.host.env(),"LUNORA_RELAY_THRESHOLD",fe.tUp),s=P(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",fe.tDown);if(this.promotionState=fr(this.promotionState,e,mr(t,s)),this.promotionState==="owned")return 0;const r=P(this.host.env(),"LUNORA_MAX_RELAYS",Te),n=P(this.host.env(),"LUNORA_RELAY_FAN",yr);return Math.min(r,Math.max(1,n))}isShapeRelayUniform(e,t){const s=V(e,t),r=this.shapeUniformCache.get(s);if(r!==void 0)return r;const n=this.probeShapeRelayUniform(e,t);return this.shapeUniformCache.set(s,n),n}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(t=>t!==e.originRelay).map(t=>this.postRelayMessage(Q(this.roleId.ownerKey,t),{frame:e.frame,topic:e.topic,type:"relay_frame"})))}onShapeSubscribe(e){return this.buildShapeSeedFrames(e)}onShapePoke(){return 0}async multicastShapePokes(e,t){if(this.relayShapeRegistry.size===0)return;const s=this.ownerRelaySet();if(s.size===0)return;const r=this.host.currentCdcEpoch(),n=[];for(const i of this.relayShapeRegistry.values()){let o;try{o=this.host.resolveShape(i.name,i.args,oe)}catch{continue}if(o===void 0||o.global===!0||!e.has(o.table))continue;const c=i.cursor,d=this.host.buildShapeDiff(o,c,t);if(d.length===0)continue;i.cursor=t;const u={args:w(i.args),checkpoint:t,epoch:r,fromCursor:c,name:i.name,rowsPatch:ye(d),type:"relay_shape_poke"};for(const l of s)n.push(this.postRelayMessage(Q(this.roleId.ownerKey,l),u))}await Promise.all(n)}async proxyShapePokes(e,t){if(this.relayShapeProxies.size===0)return;const s=this.host.currentCdcEpoch(),r=[];for(const n of this.relayShapeProxies.values()){let i;try{i=this.host.resolveShape(n.name,n.args,n.identity)}catch{continue}if(i===void 0||i.global===!0||!e.has(i.table))continue;const o=n.cursor,c=this.host.buildShapeDiff(i,o,t);if(c.length===0)continue;n.cursor=t;const d={args:w(n.args),checkpoint:t,epoch:s,fromCursor:o,name:n.name,rowsPatch:ye(c),targetConnectionId:n.connectionId,type:"relay_shape_poke"};r.push(this.postRelayMessage(Q(this.roleId.ownerKey,n.relayIndex),d))}await Promise.all(r)}buildShapeSeedFrames(e){const t={identity:e.identity,userId:e.userId};let s;try{s=this.host.resolveShape(e.name,e.args,t)}catch(u){const{body:l}=C(u,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:l.code,message:l.message}}}if(s===void 0||s.global===!0)return{error:{code:"SHAPE_NOT_FOUND",message:`shape not relayable: ${e.name}`}};e.relayIndex!==void 0&&this.addRelayToSet(e.relayIndex);const{baseCheckpoint:r,cursor:n,epoch:i,rowsPatch:o}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},s);let c=n;if(this.isShapeRelayUniform(e.name,e.args)){const u=V(e.name,e.args);let l=this.relayShapeRegistry.get(u);l===void 0&&(l={args:e.args,cursor:n,name:e.name},this.relayShapeRegistry.set(u,l)),c=l.cursor}else e.relayIndex!==void 0&&e.connectionId!==void 0&&this.relayShapeProxies.set(`${String(e.relayIndex)}:${e.connectionId}:${e.subId}`,{args:e.args,connectionId:e.connectionId,cursor:n,epoch:i,identity:t,name:e.name,relayIndex:e.relayIndex,subId:e.subId});const d=Re([{rowsPatch:o,shapeId:e.subId}],{baseCheckpoint:r,checkpoint:n,epoch:i,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:i,frames:d}}ensureRelayTable(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)")}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTable();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(t=>Number(t.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTable(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTable(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const t=this.ownerRelaySet();t.delete(e);for(const[s,r]of this.relayShapeProxies)r.relayIndex===e&&this.relayShapeProxies.delete(s);t.size===0&&(this.relayShapeRegistry.clear(),this.shapeUniformCache.clear())}probeShapeRelayUniform(e,t){let s;try{s=this.host.resolveShape(e,t,oe)}catch{return!1}if(s===void 0||s.global===!0||this.host.rlsMetadata().policies.some(c=>c.on==="read"&&c.table===s.table)||this.tableHasAnyMask(s.table))return!1;const r=$(s.effectiveWhere),n=$(s.columns);let i=!1;const o=c=>{const d={groups:[`grp_${c}`],roles:[c],sub:`__lunora_probe_${c}__`};return{identity:new Proxy(d,{get:(u,l)=>typeof l=="symbol"||l in u?Reflect.get(u,l):`${c}:${l}`,getOwnPropertyDescriptor:(u,l)=>(i=!0,Reflect.getOwnPropertyDescriptor(u,l)),has:(u,l)=>typeof l=="symbol"?Reflect.has(u,l):!0,ownKeys:u=>(i=!0,Reflect.ownKeys(u))}),userId:`__lunora_probe_${c}__`}};return[oe,o("a"),o("b")].every(c=>{let d;try{d=this.host.resolveShape(e,t,c)}catch{return!1}return d!==void 0&&d.global!==!0&&d.table===s.table&&$(d.effectiveWhere)===r&&$(d.columns)===n})&&!i}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(t=>t.table===e)}},Rr=class extends pt{relayAnnounced=!1;shapeRelayMemos=new WeakMap;constructor(e,t,s){super(e,{ownerKey:t,relayIndex:s})}async forwardWhisper(e,t){this.canAddressSiblings()&&await this.postRelayMessage(this.roleId.ownerKey,{frame:t,originRelay:this.roleId.relayIndex,topic:e,type:"relay_frame"})}onFlush(){return Promise.resolve()}async seedRelayShape(e,t,s,r){if(!this.canAddressSiblings())return{code:"RELAY_MISCONFIGURED",message:"relay cannot address its owner"};await this.announce();const n={args:w(s.args??{}),connectionId:this.host.readAttachment(e).connectionId,identity:r.identity,name:s.name,relayIndex:this.roleId.relayIndex,sinceEpoch:s.sinceEpoch,sinceSeq:s.sinceSeq,subId:t,type:"relay_shape_subscribe",userId:r.userId},i=await this.requestRelayMessage(this.roleId.ownerKey,n);if(i===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let o;try{o=await i.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(o.error!==void 0)return o.error;if(o.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await M(e);for(const c of o.frames)L(e,c);return this.recordRelayShapeMemo(e,t,o.cursor??0,o.epoch),"ok"}async announce(){this.relayAnnounced||!this.canAddressSiblings()||(this.relayAnnounced=!0,(await this.requestRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_attach"}))?.ok||(this.relayAnnounced=!1))}async announceDrain(e){this.canAddressSiblings()&&(this.host.getWebSockets().some(t=>t!==e)||(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}relayCount(){return 0}isShapeRelayUniform(){return!1}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapePoke(e){return this.deliverShapePoke(e)}recordRelayShapeMemo(e,t,s,r){let n=this.shapeRelayMemos.get(e);n===void 0&&(n=new Map,this.shapeRelayMemos.set(e,n)),n.set(t,{cursor:s,epoch:r})}deliverShapePoke(e){const t=V(e.name,e.args);let s=0;for(const r of this.host.getWebSockets()){const n=this.host.readAttachment(r),{shapes:i}=n,o=this.shapeRelayMemos.get(r);if(!(i===void 0||o===void 0)&&!(e.targetConnectionId!==void 0&&n.connectionId!==e.targetConnectionId))for(const[c,d]of Object.entries(i)){const u=o.get(c);if(u?.cursor!==e.fromCursor||u.epoch!==e.epoch||V(d.name,d.args)!==t)continue;const l=Re([{rowsPatch:e.rowsPatch,shapeId:c}],{baseCheckpoint:void 0,checkpoint:e.checkpoint,epoch:e.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0});for(const m of l)L(r,m);o.set(c,{cursor:e.checkpoint,epoch:e.epoch}),s+=1}}return s}};const Tr=a=>{const e=a.doName();if(e===void 0)return;const t=pr(e);return t===void 0?new wr(a,e):new Rr(a,t.ownerKey,t.relayIndex)},I="__lunora_reqlog__",ve=1e3,ft="lunora",F=(a,e,...t)=>a.exec.call(a,e,...t),Z=(a,e=!1)=>e||a===null||a===void 0?a:is(a,os),W=a=>{F(a,`CREATE TABLE IF NOT EXISTS "${I}" (
|
|
81
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
82
|
+
ts REAL NOT NULL,
|
|
83
|
+
function_path TEXT NOT NULL,
|
|
84
|
+
shard_key TEXT,
|
|
85
|
+
user_id TEXT,
|
|
86
|
+
identity TEXT,
|
|
87
|
+
args TEXT,
|
|
88
|
+
outcome TEXT NOT NULL,
|
|
89
|
+
error_message TEXT,
|
|
90
|
+
duration_ms REAL NOT NULL,
|
|
91
|
+
tables_read TEXT NOT NULL DEFAULT '[]',
|
|
92
|
+
tables_written TEXT NOT NULL DEFAULT '[]',
|
|
93
|
+
cache_hit INTEGER,
|
|
94
|
+
subscriptions_rerun INTEGER NOT NULL DEFAULT 0
|
|
95
|
+
)`)},Ge=a=>JSON.stringify([...new Set(a)].toSorted((e,t)=>e.localeCompare(t))),vr=a=>a===void 0?null:a?1:0,Ar=(a,e,t={})=>{W(a);const s=t.captureRaw??!1,r=t.retention??ve;F(a,`INSERT INTO "${I}"
|
|
96
|
+
(ts, function_path, shard_key, user_id, identity, args, outcome, error_message, duration_ms, tables_read, tables_written, cache_hit, subscriptions_rerun)
|
|
97
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.ts,e.functionPath,e.shardKey??null,e.userId??null,e.identity===void 0?null:JSON.stringify(Z(e.identity,s)),e.redactedArgs===void 0?null:JSON.stringify(Z(e.redactedArgs,s)),e.outcome,e.errorMessage??null,e.durationMs,Ge(e.tablesRead),Ge(e.tablesWritten),vr(e.cacheHit),e.subscriptionsReRun??0),F(a,`DELETE FROM "${I}" WHERE seq <= (SELECT MAX(seq) - ? FROM "${I}")`,r)},Ir=(a,e={})=>{const t=e.captureRaw??!1,s={args:a.redactedArgs===void 0?void 0:Z(a.redactedArgs,t),cacheHit:a.cacheHit,durationMs:a.durationMs,error:a.errorMessage,function:a.functionPath,identity:a.identity===void 0?void 0:Z(a.identity,t),outcome:a.outcome,shard:a.shardKey,source:ft,tablesRead:a.tablesRead??[],tablesWritten:a.tablesWritten??[],ts:a.ts,type:"request",userId:a.userId},r=JSON.stringify(s);a.outcome==="error"?console.error(r):console.log(r)},_r="log",kr=a=>a.map(e=>{if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}).join(" "),Mr=a=>{if(typeof a!="object"||a===null||Array.isArray(a))return!1;const e=Object.getPrototypeOf(a);return e===Object.prototype||e===null},Nr=(a,e)=>a.length===2&&typeof a[0]=="string"&&Mr(a[1])?{fields:Ie(a[1],e),message:a[0]}:{fields:Ie(void 0,e),message:kr(a)},Cr=a=>{const e={fields:a.fields,function:a.functionPath,level:a.level,message:a.message,shard:a.shardKey,source:ft,spanId:a.spanId,traceId:a.traceId,ts:a.ts,type:_r,userId:a.userId};let t;try{t=JSON.stringify(e)}catch{t=JSON.stringify({...e,fields:void 0})}a.level==="error"||a.level==="fatal"?console.error(t):a.level==="warn"?console.warn(t):console.log(t)},ge=a=>a.replaceAll(/[\\%_]/g,e=>`\\${e}`),ze=a=>{try{const e=JSON.parse(a);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}catch{return[]}},Or=(a,e={})=>{W(a);const t=Math.max(1,Math.min(e.limit??ve,1e4)),s=["seq > ?"],r=[e.sinceSeq??0];if(e.functionPathPrefix!==void 0&&e.functionPathPrefix!==""&&(s.push(String.raw`function_path LIKE ? ESCAPE '\'`),r.push(`${ge(e.functionPathPrefix)}%`)),e.userId!==void 0&&e.userId!==""&&(s.push("user_id = ?"),r.push(e.userId)),e.shardKey!==void 0&&e.shardKey!==""&&(s.push("shard_key = ?"),r.push(e.shardKey)),e.outcome!==void 0&&(s.push("outcome = ?"),r.push(e.outcome)),e.tableTouched!==void 0&&e.tableTouched!==""){const n=`%${ge(JSON.stringify(e.tableTouched))}%`;s.push(String.raw`(tables_read LIKE ? ESCAPE '\' OR tables_written LIKE ? ESCAPE '\')`),r.push(n,n)}return r.push(t),F(a,`SELECT seq, ts, function_path, shard_key, user_id, identity, args, outcome, error_message, duration_ms, tables_read, tables_written, cache_hit, subscriptions_rerun
|
|
98
|
+
FROM "${I}" WHERE ${s.join(" AND ")} ORDER BY seq DESC LIMIT ?`,...r).toArray().map(n=>{const i={durationMs:n.duration_ms,functionPath:n.function_path,outcome:n.outcome==="error"?"error":"ok",seq:n.seq,subscriptionsReRun:n.subscriptions_rerun,tablesRead:ze(n.tables_read),tablesWritten:ze(n.tables_written),ts:n.ts};return n.shard_key!==null&&(i.shardKey=n.shard_key),n.user_id!==null&&(i.userId=n.user_id),n.identity!==null&&(i.identity=JSON.parse(n.identity)),n.args!==null&&(i.redactedArgs=JSON.parse(n.args)),n.error_message!==null&&(i.errorMessage=n.error_message),n.cache_hit!==null&&(i.cacheHit=n.cache_hit===1),i})},Lr=(a,e)=>{const t=Gs(a,[...e.keys()]);for(const s of e.values()){const r=t.get(s.hash);r!==void 0&&(s.stateUpdatedAt=r.updatedAt,r.assignee!==void 0&&(s.assignee=r.assignee),r.severity!==void 0&&(s.severity=r.severity),s.status=r.status==="resolved"&&s.lastSeen>r.updatedAt?"open":r.status)}},xr=(a,e={})=>{W(a);const t=Math.max(1,Math.min(e.limit??ve,1e4)),s=["outcome = 'error'"],r=[];e.functionPathPrefix!==void 0&&e.functionPathPrefix!==""&&(s.push(String.raw`function_path LIKE ? ESCAPE '\'`),r.push(`${ge(e.functionPathPrefix)}%`)),e.userId!==void 0&&e.userId!==""&&(s.push("user_id = ?"),r.push(e.userId)),e.shardKey!==void 0&&e.shardKey!==""&&(s.push("shard_key = ?"),r.push(e.shardKey)),r.push(t);const n=F(a,`SELECT function_path, error_message, ts
|
|
99
|
+
FROM "${I}" WHERE ${s.join(" AND ")} ORDER BY seq DESC LIMIT ?`,...r).toArray(),i=new Map,o=new Map;for(const d of n){const u=d.error_message??"",{culprit:l,hash:m,title:p}=ns({functionPath:d.function_path,message:u}),g=i.get(m);if(g===void 0){i.set(m,{count:1,culprit:l,firstSeen:d.ts,hash:m,lastSeen:d.ts,sampleMessage:u,status:"open",title:p}),o.set(m,d.ts);continue}g.count+=1,g.firstSeen=Math.min(g.firstSeen,d.ts),g.lastSeen=Math.max(g.lastSeen,d.ts),d.ts>(o.get(m)??Number.NEGATIVE_INFINITY)&&(o.set(m,d.ts),g.sampleMessage=u,g.title=p)}Lr(a,i);const c=[...i.values()];return(e.status===void 0?c:c.filter(d=>d.status===e.status)).toSorted((d,u)=>u.lastSeen-d.lastSeen)},je=async(a,e,t=8)=>{let s=0;const r=async()=>{let n=a[s];for(s+=1;n!==void 0;){try{await e(n)}catch{}n=a[s],s+=1}};await Promise.all(Array.from({length:Math.min(t,a.length)},()=>r()))};class $r{buffer=[];capacity;constructor(e=500){this.capacity=e>0?Math.trunc(e):500}get size(){return this.buffer.length}clear(){this.buffer.length=0}entries(){return[...this.buffer]}hasTrace(e){return this.buffer.some(t=>t.traceId===e)}push(e){this.buffer.push(e),this.buffer.length>this.capacity&&this.buffer.shift()}}const Pr=50,qr=a=>{const e=new Map;for(const t of a){const s=e.get(t.traceId);s===void 0?e.set(t.traceId,[t]):s.push(t)}return e},Dr=(a,e)=>{const t=a.find(r=>r.dispatch===!0);if(t!==void 0)return t;const s=a.toSorted((r,n)=>r.startTs-n.startTs);return s.find(r=>!e.has(r.parentSpanId))??s[0]},Ur=(a,e)=>{const t=new Map([[a.spanId,0]]);return s=>{const r=[],n=new Set;let i=s,o=0;for(;;){const c=t.get(i.spanId);if(c!==void 0){o=c;break}if(n.has(i.spanId))break;n.add(i.spanId),r.push(i);const d=e.get(i.parentSpanId);if(d===void 0)break;i=d}for(const[c,d]of r.toReversed().entries())t.set(d.spanId,o+c+1);return t.get(s.spanId)??o}},Br=(a,e=Pr)=>{const t=qr(a),s=[...t.entries()].map(([n,i])=>({group:i,startTs:Math.min(...i.map(o=>o.startTs)),traceId:n})).toSorted((n,i)=>i.startTs-n.startTs).slice(0,e),r=[];for(const{group:n,traceId:i}of s){const o=new Map(n.map(p=>[p.spanId,p])),c=Dr(n,o);if(c===void 0)continue;const d=Ur(c,o),{startTs:u}=c,l=Math.max(...n.map(p=>p.startTs+p.durationMs)),m=n.map(p=>({...p.attributes===void 0?{}:{attributes:p.attributes},depth:d(p),durationMs:p.durationMs,...p.error===void 0?{}:{error:p.error},name:p.name,offsetMs:Math.max(0,p.startTs-u),ok:p.ok,parentSpanId:p.parentSpanId,spanId:p.spanId})).toSorted((p,g)=>p.offsetMs-g.offsetMs||p.depth-g.depth);r.push({durationMs:l-u,functionPath:c.functionPath,ok:n.every(p=>p.ok),rootName:c.name,...c.shardKey===void 0?{}:{shardKey:c.shardKey},spans:m,startTs:u,traceId:i})}return{total:t.size,traces:r.toSorted((n,i)=>i.startTs-n.startTs)}},Je="__doc__",Fr=a=>a.startsWith("sqlite_")||a.startsWith("_cf_")||a.startsWith("__miniflare")||a.startsWith("__lunora")||a.includes("__fts_"),Se=a=>`"${a.replaceAll('"','""')}"`,Wr=(a,e)=>Fr(e)?!1:a.exec("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1",e).toArray().length>0,Kr=(a,e)=>{const t=e.includes(a),s=e.includes(Je);if(!(!t&&!s))return t?{expression:Se(a),params:[]}:{expression:`json_extract(${Se(Je)}, ?)`,params:[`$."${a.replaceAll('"','""')}"`]}},Hr=(a,e,t,s,r,n,i)=>{const o=Kr(s,r);if(o===void 0)return;const c=a.exec(`SELECT id, ${o.expression} AS ref FROM ${e} WHERE ${o.expression} IS NOT NULL AND ${o.expression} <> '' LIMIT ?`,...o.params,...o.params,...o.params,5001).toArray();c.length>5e3&&(i.truncated=!0);for(const d of c.slice(0,5e3))if(i.scanned+=1,!n.has(d.ref)){if(i.references.length>=500){i.truncated=!0;continue}i.references.push({column:s,id:d.id,key:d.ref,table:t})}},Qr=(a,e,t)=>{const s=t instanceof Set?t:new Set(t),r={references:[],scanned:0,truncated:!1};for(const[n,i]of Object.entries(e)){if(!Wr(a,n))continue;const o=Se(n),c=a.exec(`PRAGMA table_info(${o})`).toArray().map(d=>d.name);for(const d of i)Hr(a,o,n,d,c,s,r)}return r},Gr="lunora-ping",zr="lunora-pong",jr=new Set(["1","enabled","on","true","yes"]);let Xe=!1,ce;const Jr=async()=>{if(!Xe){Xe=!0;try{const a=(await import("cloudflare:workers")).tracing;ce=a!==null&&typeof a=="object"&&typeof a.enterSpan=="function"?a:void 0}catch{ce=void 0}}return ce},Xr="<undelivered>",Yr=1073741824,Ye=1e4,Vr=864e5,Zr=36e5,z="__root__",b="*",Ve=(a,e)=>(a===void 0?"":`,"cursor":${String(a)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),ea=(a,e)=>{const[t,s]=a.size<=e.size?[a,e]:[e,a];for(const r of t)if(s.has(r))return!0;return!1},ta=a=>{const e=typeof a.id=="string"?a.id:"";if(e.trim()==="")throw new f("MIGRATION_ID_REQUIRED","runMigration: `id` is required",{status:400});return{batchSize:typeof a.batchSize=="number"?a.batchSize:void 0,direction:a.direction==="down"?"down":"up",dryRun:a.dryRun===!0,id:e,maxBatches:typeof a.maxBatches=="number"?a.maxBatches:void 0}},Ze=Jt,sa=200,ra=20,aa=3e4,na=a=>{const{op:e}=a,t=typeof a.table=="string"?a.table:"";if(e!=="insert"&&e!=="patch"&&e!=="replace"&&e!=="delete")throw new f("BAD_REQUEST","writeRow: `op` must be insert|patch|replace|delete");if(t.trim()==="")throw new f("BAD_REQUEST","writeRow: `table` is required");const s=typeof a.id=="string"?a.id:void 0,r=typeof a.doc=="object"&&a.doc!==null&&!Array.isArray(a.doc)?a.doc:void 0;if(e!=="insert"&&(s===void 0||s===""))throw new f("BAD_REQUEST",`writeRow: \`id\` is required for op "${e}"`);if(e!=="delete"&&r===void 0)throw new f("BAD_REQUEST",`writeRow: \`doc\` is required for op "${e}"`);return{doc:r,id:s,op:e,table:t}},ia=a=>typeof a=="string"&&Hs.includes(a),oa=a=>typeof a=="string"&&Qs.includes(a),ca=a=>{const e=typeof a.hash=="string"?a.hash.trim():"";if(e==="")throw new f("BAD_REQUEST","issue triage: `hash` is required");return e},mt=null,da=a=>{const e=a.assignee;if(e===null)return mt;if(typeof e=="string"&&e.trim()!=="")return e;throw new f("BAD_REQUEST","assignIssue: `assignee` must be a non-empty string (assign) or null (unassign)")},ua=a=>{const e=a.severity;if(e===null)return mt;if(oa(e))return e;throw new f("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},la=a=>{const e=typeof a.exportName=="string"?a.exportName.trim():"";if(e==="")throw new f("BAD_REQUEST","createWorkflowInstance: `exportName` is required");const t=typeof a.id=="string"&&a.id!==""?a.id:void 0;return{exportName:e,id:t,params:a.params}},ha=a=>{const e=typeof a.exportName=="string"?a.exportName.trim():"",t=typeof a.id=="string"?a.id.trim():"";if(e==="")throw new f("BAD_REQUEST","getWorkflowInstanceStatus: `exportName` is required");if(t==="")throw new f("BAD_REQUEST","getWorkflowInstanceStatus: `id` is required");return{exportName:e,id:t}},pa=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),et=a=>typeof a=="string"&&pa.has(a)?a:"unknown",fa=a=>{if(typeof a!="object"||a===null)return;const{message:e,name:t}=a;return{message:typeof e=="string"?e:"",name:typeof t=="string"?t:"Error"}},ma=new Set(["contains","eq","gt","gte","lt","lte","ne"]),be=a=>{if(!Array.isArray(a))return;const e=[];for(const t of a){if(typeof t!="object"||t===null)continue;const s=t,{column:r,operator:n}=s;typeof r!="string"||r===""||typeof n!="string"||!ma.has(n)||e.push({column:r,operator:n,value:s.value})}return e.length>0?e:void 0},ya=a=>{if(typeof a!="object"||a===null)return;const{column:e,direction:t}=a;if(!(typeof e!="string"||e===""))return{column:e,direction:t==="desc"?"desc":"asc"}},ga=a=>{const e=typeof a.table=="string"?a.table:"";if(e.trim()==="")throw new f("BAD_REQUEST","deleteRows: `table` is required");return{filters:be(a.filters),limit:typeof a.limit=="number"?a.limit:void 0,search:typeof a.search=="string"?a.search:void 0,table:e}},Sa=a=>{const e=typeof a.table=="string"?a.table:"";if(e.trim()==="")throw new f("BAD_REQUEST","clearTable: `table` is required");return{limit:typeof a.limit=="number"?a.limit:void 0,table:e}},ba=a=>{const{outcome:e}=a;if(e!=="ok"&&e!=="fail")throw new f("BAD_REQUEST",'recordAuthEvent: `outcome` must be "ok" or "fail"');return{outcome:e}},Ea=/\(exit (\d+)\)/,wa=a=>{const e=a.event;if(typeof e!="object"||e===null||Array.isArray(e))throw new f("BAD_REQUEST","recordContainerEvent: `event` must be an object");const t=e,s=typeof t.container=="string"?t.container:"",r=typeof t.event=="string"?t.event:"";if(s.trim()===""||r.trim()==="")throw new f("BAD_REQUEST","recordContainerEvent: `event.container` and `event.event` are required");const n=t.level==="error"?"error":"info",i=typeof t.message=="string"?t.message:void 0,o=typeof t.ts=="number"?t.ts:Date.now(),c=typeof t.instance=="string"&&t.instance!==""?t.instance:void 0,d=i===void 0?void 0:Ea.exec(i)?.[1];return{exitCode:d===void 0?void 0:Number.parseInt(d,10),functionPath:`container:${s}`,instance:c,level:n,message:i===void 0||i===""?r:`${r}: ${i}`,timestamp:o}},Ra=a=>{const e=typeof a.functionPath=="string"?a.functionPath:"",t=typeof a.userId=="string"?a.userId:"";if(e.trim()==="")throw new f("BAD_REQUEST","runAs: `functionPath` is required");if(e.startsWith(k))throw new f("BAD_REQUEST","runAs: cannot target a reserved admin function");if(t.trim()==="")throw new f("BAD_REQUEST","runAs: `userId` is required");const s=a.args;if(s!==void 0&&(typeof s!="object"||s===null||Array.isArray(s)))throw new f("BAD_REQUEST","runAs: `args` must be an object");const r=a.identity;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new f("BAD_REQUEST","runAs: `identity` must be an object");return{args:s===void 0?{}:s,functionPath:e,userId:t,...r===void 0?{}:{identity:r}}},Ta=a=>{const e=p=>{throw new f("BAD_REQUEST",`recordMail: ${p}`)},{bcc:t,cc:s,from:r,headers:n,html:i,replyTo:o,subject:c,text:d,to:u}=a;typeof c!="string"&&e("`subject` must be a string"),typeof u=="string"||Array.isArray(u)&&u.every(p=>typeof p=="string")||e("`to` must be a string or string[]");const l=(p,g)=>{if(p!==void 0)return(!Array.isArray(p)||!p.every(E=>typeof E=="string"))&&e(`\`${g}\` must be a string[]`),p},m=(p,g)=>(p!==void 0&&typeof p!="string"&&e(`\`${g}\` must be a string`),p);return{bcc:l(t,"bcc"),cc:l(s,"cc"),from:m(r,"from"),headers:n!==void 0&&typeof n=="object"&&n!==null?n:void 0,html:m(i,"html"),replyTo:m(o,"replyTo"),subject:c,text:m(d,"text"),to:u}},va="test@lunora.sh",Aa=a=>{const{to:e}=a;if(e!==void 0&&typeof e!="string")throw new f("BAD_REQUEST","sendTestMail: `to` must be a string");const t=e??va,s="https://example.test/verify?token=demo";return{from:"Lunora <noreply@lunora.sh>",html:`<p>This is a test email from the Lunora dev mail catcher.</p><p><a href="${s}">Verify your email</a></p>`,subject:"Lunora test email",text:`This is a test email from the Lunora dev mail catcher.
|
|
100
|
+
|
|
101
|
+
Verify your email: ${s}`,to:t}},Ia=a=>{const e=r=>{throw new f("BAD_REQUEST",`recordQueueMessage: ${r}`)},t=a.messages;Array.isArray(t)||e("`messages` must be an array");const s=new Set(["ack","error","retry"]);return t.map((r,n)=>{(typeof r!="object"||r===null)&&e(`\`messages[${String(n)}]\` must be an object`);const i=r,o=typeof i.messageId=="string"?i.messageId:"",c=typeof i.queue=="string"?i.queue:"",d=typeof i.outcome=="string"?i.outcome:"";o===""&&e(`\`messages[${String(n)}].messageId\` is required`),c===""&&e(`\`messages[${String(n)}].queue\` is required`),s.has(d)||e(`\`messages[${String(n)}].outcome\` must be one of ack | error | retry`);const{attempts:u,timestamp:l}=i;return{attempts:typeof u=="number"&&Number.isFinite(u)?u:1,body:i.body,deadLettered:i.deadLettered===!0,error:typeof i.error=="string"?i.error:void 0,exportName:typeof i.exportName=="string"?i.exportName:void 0,messageId:o,outcome:d,queue:c,timestamp:typeof l=="number"&&Number.isFinite(l)?l:0}})},tt=100,R=a=>`${a.traceId}:${a.rootSpanId}`,de=256,_a=500,ue="lunora.dispatch",ka=a=>{const e=typeof a.exportName=="string"?a.exportName.trim():"";if(e==="")throw new f("BAD_REQUEST","sendQueueMessage: `exportName` is required");const t=a.delaySeconds;if(t!==void 0&&(typeof t!="number"||!Number.isFinite(t)||t<0))throw new f("BAD_REQUEST","sendQueueMessage: `delaySeconds` must be a non-negative number");const s=Array.isArray(a.batch)?a.batch:void 0;if(s!==void 0&&(s.length===0||s.length>tt))throw new f("BAD_REQUEST",`sendQueueMessage: \`batch\` must contain between 1 and ${String(tt)} messages`);return{batch:s,body:a.body,contentType:typeof a.contentType=="string"?a.contentType:void 0,delaySeconds:t,exportName:e}},Ma=a=>{const e=typeof a.id=="string"?a.id.trim():"";if(e==="")throw new f("BAD_REQUEST","replayQueueMessage: `id` is required");const t=typeof a.target=="string"&&a.target.trim()!==""?a.target.trim():void 0;return{id:e,target:t}},Na=a=>{const e=typeof a.table=="string"?a.table:"",t=typeof a.index=="string"?a.index:"",s=typeof a.rowId=="string"?a.rowId:"";if(e.trim()==="")throw new f("BAD_REQUEST","rankBefore: `table` is required");if(t.trim()==="")throw new f("BAD_REQUEST","rankBefore: `index` is required");if(typeof a.partitionKey!="string")throw new f("BAD_REQUEST","rankBefore: `partitionKey` must be a string");if(s.trim()==="")throw new f("BAD_REQUEST","rankBefore: `rowId` is required");if(!Array.isArray(a.sortValues))throw new f("BAD_REQUEST","rankBefore: `sortValues` must be an array");return{index:t,partitionKey:a.partitionKey,rowId:s,sortValues:a.sortValues,table:e}},N=a=>{throw new f("BAD_REQUEST",a)},st=(a,e)=>((typeof a!="string"||a.trim()==="")&&N(`rankPage: \`${e}\` is required`),a),Ca=a=>{if(a===void 0)return;(typeof a!="object"||a===null||Array.isArray(a))&&N("rankPage: `after` must be an object");const e=a;return(typeof e.partitionKey!="string"||typeof e.rowId!="string"||!Array.isArray(e.sortValues))&&N("rankPage: `after` must have a string partitionKey, string rowId, and array sortValues"),{partitionKey:e.partitionKey,rowId:e.rowId,sortValues:e.sortValues}},Oa=a=>{const e=st(a.table,"table"),t=st(a.index,"index");a.take!==void 0&&typeof a.take!="number"&&N("rankPage: `take` must be a number"),a.cursor!==void 0&&a.cursor!==null&&typeof a.cursor!="string"&&N("rankPage: `cursor` must be a string or null"),a.partitionKey!==void 0&&typeof a.partitionKey!="string"&&N("rankPage: `partitionKey` must be a string"),a.directions!==void 0&&!Array.isArray(a.directions)&&N("rankPage: `directions` must be an array");const s=a.directions===void 0?void 0:a.directions.map(r=>r==="desc"?"desc":"asc");return{after:Ca(a.after),cursor:typeof a.cursor=="string"?a.cursor:void 0,directions:s,index:t,partitionKey:typeof a.partitionKey=="string"?a.partitionKey:void 0,take:typeof a.take=="number"?a.take:void 0,table:e}},La=a=>{try{const e=JSON.parse(a);if(Array.isArray(e)&&typeof e[0]=="string"&&typeof e[1]=="string")return{index:e[1],table:e[0]}}catch{}},xa=a=>{const e=a.changes;if(!Array.isArray(e))throw new f("BAD_REQUEST","applyCdc: `changes` must be an array");return{changes:e.map((t,s)=>{const r=t,{op:n}=r,i=typeof r.table=="string"?r.table:"",o=typeof r.id=="string"?r.id:"";if(i===""||o===""||n!=="insert"&&n!=="update"&&n!=="delete")throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}] must have a table, id, and op of insert|update|delete`);const c=r.doc;if(c!==void 0&&(typeof c!="object"||c===null||Array.isArray(c)))throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}].doc must be an object`);const d=c;if(d!==void 0&&typeof d._id=="string"&&d._id!==o)throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}].doc._id must match the entry id`);return{doc:d,id:o,op:n,seq:typeof r.seq=="number"?r.seq:0,table:i,ts:typeof r.ts=="number"?r.ts:0}})}},$a=a=>{const e=t=>{const s=typeof t=="number"?t:Number(t);return Number.isFinite(s)&&s>=0?Math.floor(s):void 0};return{limit:e(a.limit),sinceSeq:e(a.sinceSeq)??0}},_=a=>a?{"x-d1-bookmark":a}:void 0,rt=a=>{if(a)try{const e=JSON.parse(a);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}},Pa=a=>{if(!a)return;const e=Number(a);return Number.isInteger(e)&&e>0?e:void 0},qa=a=>{const e=new Set;for(const t of a){const s=Lt(t);s!==""&&e.add(s)}return e},Da=a=>{if(a===void 0)return;const e=Number.parseInt(a,10);return Number.isFinite(e)&&e>0?e:void 0},Ua=(a,e)=>a==="1"||a==="true"?!0:a==="0"||a==="false"?!1:e,Ba=a=>{if(a===void 0)return 1;const e=Number.parseFloat(a);return Number.isFinite(e)?Math.min(1,Math.max(0,e)):1},Fa=a=>a>=1?!0:a<=0?!1:Math.random()<a,le=a=>{if(!a)return;const[e,...t]=a.split(" ");if(e?.toLowerCase()!=="bearer")return;const s=t.join(" ").trim();return s.length>0?s:void 0};class S{static MAX_STREAMS_PER_SOCKET=8;static MAX_SUBSCRIPTIONS_PER_SOCKET=32;static GLOBAL_SHAPE_POLL_INTERVAL_MS=2e3;static GLOBAL_SHAPE_MAX_ROWS=5e4;static MAX_WHISPER_TOPICS_PER_SOCKET=64;static MAX_WHISPER_BYTES=4096;static WHISPER_RATE_BURST=50;static WHISPER_RATE_PER_SEC=25;static rootSizeWarned=!1;static resetRootSizeWarning(){S.rootSizeWarned=!1}static nextPollAlarmTarget(e,t,s,r){const n=[e>0?r+S.GLOBAL_SHAPE_POLL_INTERVAL_MS:void 0,t,s].filter(i=>i!==void 0).map(i=>Math.max(i,r));return n.length>0?Math.min(...n):void 0}state;env;reactiveCache;drizzleHandle;transactionDepth=0;currentRequestBookmark;currentResponseBookmark;currentRequestUserId;currentRequestIp;currentRequestTraceparent;currentRequestTrace;traceSampling=new Map;dispatchSpans=new Map;lastTelemetrySink;currentRequestMutationId;currentRequestClientId;currentRequestClientSeq;currentMutatorClass;mutationBookkeepingCommitted=!1;lastIdempotencyTrimAt=0;currentRequestIdentity;currentRequestSystem=!1;pendingChangedTables=void 0;pendingRefreshTables=void 0;refreshInFlight=!1;subMemos=new WeakMap;shapeMemos=new WeakMap;globalShapeSnapshots=new WeakMap;globalPollScheduled=!1;pokeSequence=0;whisperBuckets=new WeakMap;streamCancellers=new WeakMap;metrics={errors:0,requests:0,sinceMs:Date.now()};fanout={shapePoke:ke(),whisper:ke()};shardBinding;relay;usedIndexes=new Set;functionStats=new Map;logs=new Xt;spans=new $r;metricSeries=new js;currentTracker;currentScannedTables;currentIndexHits;currentRequestReadTables;currentStmtSamples;currentRequestCacheHit;constructor(e,t,s={}){this.state=e,this.env=t,s.reactiveCache&&(this.reactiveCache=new ss(s.reactiveCache));const r={buildShapeDiff:(n,i,o)=>this.buildShapeDiff(this.sql,n,i,o),computeOpLogShapeSeed:(n,i)=>this.computeOpLogShapeSeed(n,i),currentCdcEpoch:()=>this.currentCdcEpoch(),deliverWhisperLocal:(n,i,o)=>this.deliverWhisperLocal(n,i,o),doName:()=>this.state.id?.name,env:()=>this.env,getWebSockets:()=>this.state.getWebSockets(),maskMetadata:()=>this.maskMetadata(),nextPokeId:()=>(this.pokeSequence+=1,`poke-${String(this.pokeSequence)}`),readAttachment:n=>this.readAttachment(n),recordShapePokeFanout:(n,i,o)=>{this.fanout.shapePoke=re(this.fanout.shapePoke,n,i,o)},resolveShape:(n,i,o)=>this.resolveShape(n,i,o),rlsMetadata:()=>this.rlsMetadata(),shardBinding:()=>this.shardBinding,sql:()=>this.sql};this.relay=Tr(r),this.armWebSocketKeepalive()}async fetch(e){const t=new URL(e.url);this.shardBinding=e.headers.get("x-lunora-shard-binding")??this.shardBinding;const s=await this.routeNonRpc(t,e);if(s!==void 0)return s;if(t.pathname!=="/rpc"||e.method!=="POST")return new Response("Not found",{status:404});let r;try{r=await e.json()}catch{return y({error:{code:"BAD_REQUEST",message:"invalid JSON body"}},400)}if(r.functionPath.startsWith(k))return this.handleAdminRpc(e,r.functionPath,r.args??{});this.currentRequestBookmark=e.headers.get("x-d1-bookmark")??void 0,this.currentResponseBookmark=void 0,this.currentRequestUserId=e.headers.get("x-lunora-userid")??void 0,this.currentRequestMutationId=e.headers.get("x-lunora-mutation-id")??void 0,this.currentRequestClientId=e.headers.get("x-lunora-client-id")??void 0,this.currentRequestClientSeq=Pa(e.headers.get("x-lunora-client-seq")),this.currentMutatorClass=void 0,this.mutationBookkeepingCommitted=!1,this.currentRequestIdentity=rt(e.headers.get("x-lunora-identity")),this.currentRequestIp=e.headers.get("x-lunora-client-ip")??void 0,this.currentRequestSystem=e.headers.get("x-lunora-system")==="1",this.currentRequestTraceparent=e.headers.get("traceparent")??void 0,this.currentRequestTrace=K(this.currentRequestTraceparent);const n=this.currentRequestTrace;this.traceSampling.set(n.traceId,{keepErrors:e.headers.get("x-lunora-sample-errors")!=="0",sampled:Et(this.currentRequestTraceparent)?.sampled??!0}),this.currentRequestReadTables=void 0,this.currentRequestCacheHit=void 0,this.metrics.requests+=1;const i=Date.now();this.currentScannedTables=new Set,this.currentIndexHits=new Set,this.currentStmtSamples=[];let o;try{if(r.functionPath.startsWith(Bt)){const E=await this.runRelationFanoutRead(r.functionPath,r.args??{});return y(E,200,_(this.currentResponseBookmark))}const c=this.isCustomMutator(r.functionPath)?this.classifyClientMutation():void 0;this.currentMutatorClass=c;const d=this.rejectNonNextMutation(r.functionPath,c,i);if(d!==void 0)return d;const u=this.readIdempotentResult(this.currentRequestMutationId);if(u!==void 0)return this.respondFromIdempotencyCache(r.functionPath,i,c,u.value);const l=await this.handleRpc(r.functionPath,O(r.args??{}));this.recordPostDispatchBookkeeping(l,c),c?.kind==="next"&&this.advanceClientMutationWatermark();const m=Date.now()-i;this.recordFunctionCall(r.functionPath,m,void 0,this.currentScannedTables,this.currentIndexHits),this.flushStmtSamples();const p=[...this.pendingChangedTables??[]];this.recordRequestLog(r.functionPath,r.args??{},m,"ok",p),this.maybeWarnRootSize();const g=this.buildDispatchResponse(c,w(l));return await this.flushChangedTables(),g}catch(c){this.metrics.errors+=1,o={thrown:c};const d=Date.now()-i,u=c instanceof Error?c.message:String(c),l=c instanceof ls&&c.kind==="occ";return c?.code!=="FUNCTION_NOT_FOUND"&&this.recordFunctionCall(r.functionPath,d,u,this.currentScannedTables,this.currentIndexHits,l),this.flushStmtSamples(),this.recordRequestLog(r.functionPath,r.args??{},d,"error",[...this.pendingChangedTables??[]],u),this.logs.push({functionPath:r.functionPath,level:"error",message:u,timestamp:Date.now()}),this.recordChangedTable(I),await this.flushChangedTables(),this.errorToResponse(c)}finally{const c=this.dispatchSpans.get(R(n));if((this.spans.hasTrace(n.traceId)||c?.collector!==void 0)&&this.recordDispatchRootSpan(r.functionPath,i,o,n),this.dispatchSpans.delete(R(n)),c?.sink?.flush)try{c.sink.flush({waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}this.flushSampledOutTrace(n,o!==void 0),this.traceSampling.delete(n.traceId),this.currentRequestTrace=void 0,this.currentRequestBookmark=void 0,this.currentResponseBookmark=void 0,this.currentRequestUserId=void 0,this.currentRequestMutationId=void 0,this.currentRequestClientId=void 0,this.currentRequestClientSeq=void 0,this.currentMutatorClass=void 0,this.mutationBookkeepingCommitted=!1,this.currentRequestIdentity=void 0,this.currentRequestIp=void 0,this.currentRequestSystem=!1,this.currentRequestTraceparent=void 0,this.currentScannedTables=void 0,this.currentIndexHits=void 0,this.currentRequestReadTables=void 0,this.currentRequestCacheHit=void 0,this.currentStmtSamples=void 0}}async webSocketMessage(e,t){return this.handleWebSocketMessage(e,t)}async webSocketClose(e,t,s,r){const n=this.readAttachment(e);n.connectionId!==void 0&&await this.dispatchLifecycle("disconnect",this.lifecycleInfo(n));const i=this.streamCancellers.get(e);if(i){for(const o of i.values())o.abort();this.streamCancellers.delete(e)}if(this.subMemos.delete(e),this.shapeMemos.delete(e),this.globalShapeSnapshots.delete(e),n.connectionId!==void 0)try{ps(this.sql,n.connectionId)}catch{}e.serializeAttachment?.(void 0),await this.relay?.announceDrain(e)}webSocketError(e,t){}async alarm(){return this.withTriggerTrace("alarm",async()=>this.handleAlarmBody())}lifecycleHookPaths(e){return[]}async dispatchLifecycle(e,t){for(const s of this.lifecycleHookPaths(e))try{await this.withRequestIdentity(t.userId,t.identity,()=>this.withSystemDispatch(()=>this.handleRpc(s,t.event)))}catch(r){this.logs.push({functionPath:s,level:"error",message:r instanceof Error?r.message:String(r),timestamp:Date.now()})}}runRelationFanoutRead(e,t){throw new f("NOT_IMPLEMENTED","__lunora_relation__: no schema bound — the base ShardDO cannot serve cross-shard relation reads",{status:500})}get sql(){const e=this.state.storage.sql,t=this.currentStmtSamples;if(t===void 0)return e;const s=e.exec;if(typeof s!="function")return e;const r=(n,...i)=>{const o=Date.now(),c=s.call(e,n,...i);if(c!==null&&typeof c=="object"){const d=c;if(typeof d.toArray=="function"){const u=d.toArray.bind(d);d.toArray=()=>{const l=u(),m=Date.now()-o;return t.push([n,m,l.length,0]),l}}if(typeof d.one=="function"){const u=d.one.bind(d);d.one=()=>{const l=u(),m=Date.now()-o;return t.push([n,m,1,0]),l}}if(typeof d.toArray!="function"&&typeof d.one!="function"){const u=Date.now()-o;t.push([n,u,0,0])}}else{const d=Date.now()-o;t.push([n,d,0,0])}return c};return new Proxy(e,{get(n,i){return i==="exec"?r:Reflect.get(n,i,n)}})}get db(){return this.drizzleHandle?this.drizzleHandle:(this.drizzleHandle=gt(this.state.storage,{logger:!1}),this.drizzleHandle)}async runInTransaction(e){if(this.transactionDepth>0)throw new f("NESTED_TRANSACTION","nested transactions are not supported in SQLite-in-DO",{status:500});const t=this.state.storage.sql;if(!t||typeof t.exec!="function")throw new f("SQL_UNAVAILABLE","storage.sql is not available on this ShardDO state",{status:500});const s=this.state.storage,r=async()=>{this.transactionDepth=1;try{return typeof s?.transaction=="function"?await s.transaction(async()=>e()):await e()}finally{this.transactionDepth=0}};return typeof this.state.blockConcurrencyWhile=="function"?this.state.blockConcurrencyWhile(r):r()}getInboundBookmark(){return this.currentRequestBookmark}setOutboundBookmark(e){this.currentResponseBookmark=e}getCurrentUserId(){return this.currentRequestUserId}getCurrentIp(){return this.currentRequestIp}getCurrentTraceparent(){return this.currentRequestTraceparent}getCurrentTrace(){return this.currentRequestTrace}getCurrentIdentity(){return this.currentRequestIdentity}isSystemDispatch(){return this.currentRequestSystem}runShardDataMigration(e){return Promise.reject(new f("MIGRATION_NOT_FOUND",`data migration "${e.id}" is not registered`,{status:404}))}ensureMigrated(){}tableRefs(e){}tableIndexes(e){return[]}tableColumns(e){return[]}storageColumns(){return{}}advisories(){return[]}rlsMetadata(){return{policies:[],roles:[]}}maskMetadata(){return{columns:[]}}storageRulesMetadata(){return{rules:[]}}studioFeatures(){return{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1}}evaluateFlags(e){return Promise.resolve({configured:!1,flags:[]})}runFlagSubscriptionRead(e,t,s){return Promise.resolve(null)}queuesMetadata(){return{queues:[]}}workflowsMetadata(){return{workflows:[]}}runtimeAdvisories(){const e=new Set([...this.usedIndexes].map(s=>s.slice(0,s.indexOf(":")))),t=[];for(const s of e)for(const r of this.tableIndexes(s))r.type==="vector"||this.usedIndexes.has(`${s}:${r.name}`)||t.push({cacheKey:`unused_index:${s}:${r.name}`,categories:["PERFORMANCE"],description:"A declared index has not been exercised by any query since this shard instance started. An unused index costs storage and is maintained on every write for no read benefit.",detail:`Index "${r.name}" on table "${s}" has not been used since this instance woke, though other indexes on "${s}" have — it may be redundant.`,facing:"INTERNAL",level:"INFO",metadata:{index:r.name,indexKind:r.type,since:"instance-woke",table:s},name:"unused_index",remediation:"Confirm over a representative window, then drop the index if no query needs it.",title:"Unused index"});return t}runShardExport(e){return Promise.resolve([])}runShardImport(e){return Promise.resolve({conflicts:0,errors:[],inserted:{}})}runShardWrite(e){return Promise.reject(new f("UNKNOWN_TABLE",`unknown table: ${e.table}`,{status:404}))}deleteRowThroughWriter(e,t){return Promise.reject(new f("UNKNOWN_TABLE",`unknown table: ${e}`,{status:404}))}async runShardBulkDelete(e){const t=Math.min(Math.max(Math.trunc(e.limit??Ze),1),Ze),{hasMore:s,ids:r}=Ft(this.sql,{filters:e.filters,limit:t,search:e.search,table:e.table});let n=0;for(const i of r)await this.deleteRowThroughWriter(e.table,i),n+=1;return{deleted:n,hasMore:s}}runShardRankBefore(e){return Promise.reject(new f("NOT_IMPLEMENTED","rankBefore is not implemented in base ShardDO",{status:500}))}runShardRankPage(e){return Promise.reject(new f("NOT_IMPLEMENTED","rankPage is not implemented in base ShardDO",{status:500}))}runShardCdcSync(e){const t=this.sql;return t.exec("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?",Oe).toArray().length>0?ne(t,{limit:e.limit,sinceSeq:e.sinceSeq}):{changes:[],cursor:e.sinceSeq}}currentCdcCursor(){return this.cdcEnabled()?Le(this.sql):void 0}currentCdcEpoch(){return this.cdcEnabled()?xe(this.sql):void 0}evaluateResume(e,t,s){const r=this.sql;if(!this.cdcEnabled())return{cursor:void 0,epoch:void 0,resumable:!1};const n=Le(r),i=xe(r);if(s!==i)return{cursor:n,epoch:i,resumable:!1};if(e>n)return{cursor:n,epoch:i,resumable:!1};if(e===n)return{cursor:n,epoch:i,resumable:!0};const o=$e(r);if(o===void 0||o>e+1)return{cursor:n,epoch:i,resumable:!1};if(t.size===0)return{cursor:n,epoch:i,resumable:!1};const{changes:c}=ne(r,{limit:Ye,sinceSeq:e});if(c.length>=Ye)return{cursor:n,epoch:i,resumable:!1};const d=c.some(u=>t.has(u.table));return{cursor:n,epoch:i,resumable:!d}}readIdempotentResult(e){if(e!==void 0)try{const t=fs(this.sql,this.currentRequestUserId??"",e);return t===void 0?void 0:{value:JSON.parse(t.resultJson)}}catch{return}}persistIdempotentResult(e){if(this.currentRequestMutationId===void 0)return;const t=Date.now();try{ms(this.sql,this.currentRequestUserId??"",this.currentRequestMutationId,JSON.stringify(w(e)),t),t-this.lastIdempotencyTrimAt>Zr&&(ys(this.sql,t-Vr),this.lastIdempotencyTrimAt=t)}catch{}}isCustomMutator(e){return!1}classifyClientMutation(){const e=this.currentRequestClientId,t=this.currentRequestClientSeq;if(e===void 0||t===void 0)return;const s=this.currentRequestUserId??"";let r;try{r=ae(this.sql,s,e)}catch{try{gs(this.sql),r=ae(this.sql,s,e)}catch{return}}const n=r+1;return t<=r?{expected:n,kind:"already"}:t===n?{expected:n,kind:"next"}:{expected:n,kind:"gap"}}rejectNonNextMutation(e,t,s){if(!(t===void 0||t.kind==="next"))return this.recordFunctionCall(e,Date.now()-s,void 0,this.currentScannedTables,this.currentIndexHits),t.kind==="already"?y({lastMutationId:t.expected-1,result:null},200,_(this.currentResponseBookmark)):y({error:{code:"OUT_OF_ORDER",expectedMutationId:t.expected,message:`out-of-order mutation; expected sequence ${String(t.expected)}`}},409,_(this.currentResponseBookmark))}respondFromIdempotencyCache(e,t,s,r){if(this.recordFunctionCall(e,Date.now()-t,void 0,this.currentScannedTables,this.currentIndexHits),s?.kind==="next")return this.advanceClientMutationWatermark(),this.buildDispatchResponse(s,r);const n=this.mutationCommitCursor();return y(n===void 0?{result:r}:{commitCursor:n,result:r},200,_(this.currentResponseBookmark))}mutationCommitCursor(){return this.currentRequestMutationId===void 0?void 0:this.currentCdcCursor()}buildDispatchResponse(e,t){if(e?.kind==="next")return y({lastMutationId:this.currentRequestClientSeq,result:t},200,_(this.currentResponseBookmark));const s=this.mutationCommitCursor();return y(s===void 0?{result:t}:{commitCursor:s,result:t},200,_(this.currentResponseBookmark))}commitMutationBookkeeping(e){this.persistIdempotentResult(e),this.currentMutatorClass?.kind==="next"&&this.advanceClientMutationWatermark({strict:!0}),this.mutationBookkeepingCommitted=!0}recordPostDispatchBookkeeping(e,t){this.mutationBookkeepingCommitted||(this.persistIdempotentResult(e),t?.kind==="next"&&this.advanceClientMutationWatermark())}advanceClientMutationWatermark(e){const t=this.currentRequestClientId,s=this.currentRequestClientSeq;if(!(t===void 0||s===void 0))try{Ss(this.sql,this.currentRequestUserId??"",t,s)}catch(r){if(e?.strict)throw r}}runShardApplyCdc(e){return Promise.reject(new f("NOT_IMPLEMENTED","applyCdc is not implemented in base ShardDO",{status:500}))}subscribe(e,t,s){const r=this.readAttachment(e);if(Object.keys(r.subs).length>=S.MAX_SUBSCRIPTIONS_PER_SOCKET)return"too_many";r.subs[t]=s;try{e.serializeAttachment?.(r)}catch{return delete r.subs[t],"serialize_failed"}return"ok"}unsubscribe(e,t){const s=this.readAttachment(e),r=s.subs[t];delete s.subs[t];try{e.serializeAttachment?.(s)}catch{r!==void 0&&(s.subs[t]=r);return}this.subMemos.get(e)?.delete(t)}shapeSubscribe(e,t,s){const r=this.readAttachment(e),n=r.shapes??{};if(Object.keys(r.subs).length+Object.keys(n).length>=S.MAX_SUBSCRIPTIONS_PER_SOCKET)return"too_many";n[t]=s,r.shapes=n;try{e.serializeAttachment?.(r)}catch{return delete r.shapes[t],"serialize_failed"}return"ok"}shapeUnsubscribe(e,t){const s=this.readAttachment(e),{shapes:r}=s;if(!r)return;const n=r[t];delete r[t];try{e.serializeAttachment?.(s)}catch{n!==void 0&&(r[t]=n);return}if(this.shapeMemos.get(e)?.delete(t),this.globalShapeSnapshots.get(e)?.delete(t),s.connectionId!==void 0)try{bs(this.sql,s.connectionId,t)}catch{}}matchesSubscription(e,t){if(e.table!==t.table)return!1;const{args:s}=e;if(!s)return!0;const{row:r}=t;if(!r)return!0;for(const[n,i]of Object.entries(s))if(r[n]!==i)return!1;return!0}broadcastDelta(e){const t=this.state.getWebSockets(),s=JSON.stringify(e);for(const r of t){const n=this.readAttachment(r);for(const[i,o]of Object.entries(n.subs))this.matchesSubscription(o,e)&&L(r,`{"type":"delta","id":${JSON.stringify(i)},"delta":${s}}`)}}executeSubscription(e,t,s){return Promise.resolve(null)}resolveShape(e,t,s){}isShapeRelayUniform(e,t){return this.relay?.isShapeRelayUniform(e,t)??!1}readGlobalShapeRows(e,t){return Promise.resolve([])}pollExternalSources(){return Promise.resolve(void 0)}scheduleSourcePoll(){return this.scheduleGlobalPoll()}ttlSweeps(){return[]}async pollTtlSweeps(){const e=this.ttlSweeps();if(e.length===0)return;const t=this.sql,s=Date.now();for(const r of e){let n=0,i=!0;for(;i&&n<ra;){const o=hs(t,r,s,sa);for(const c of o.ids)await this.deleteRowThroughWriter(r.table,c);i=o.hasMore,n+=1}}return s+aa}scheduleTtlSweep(){return this.scheduleGlobalPoll()}currentShardKey(){return this.state.id?.name??z}recordExternalSourceError(e,t){this.recordShapeError(`source:${e}`,t)}executeStream(e,t){return null}async runCachedQuery(e,t,s){if(!this.reactiveCache)return s();const r=this.currentTracker,n=Ot();this.currentTracker=n;const i=this.reactiveCache.stats().hits,o=this.getCurrentUserId(),c=this.getCurrentIdentity(),d=o===void 0&&c===void 0?null:Ee({claims:c??null,userId:o??null});try{const u=await this.reactiveCache.run(Ne(e,t,d),n.collect(),s);return this.currentRequestCacheHit=this.reactiveCache.stats().hits>i,this.currentRequestReadTables=qa(n.collect()),u}finally{this.currentTracker=r}}getCtxDbReadHook(){return(e,t)=>{this.currentTracker?.recordRead(e,t??_e),t===_e&&this.currentScannedTables?.add(e)}}getCtxDbIndexUseHook(){return(e,t)=>{this.usedIndexes.add(`${e}:${t}`),this.currentIndexHits?.add(JSON.stringify([e,t]))}}recordChangedTable(e){this.pendingChangedTables??=new Set,this.pendingChangedTables.add(e)}async flushMigrationProgress(){this.recordChangedTable(Nt),await this.flushChangedTables()}recordUserLog(e,t,s,r,n,i,o,c){const d=c??this.currentRequestTrace,u={args:s,...o===void 0?{}:{eventName:o},fields:n,functionPath:e,level:t,message:r,shardKey:this.state.id?.name,spanId:d?.rootSpanId,traceId:d?.traceId,ts:Date.now(),userId:this.getCurrentUserId()};this.logs.push({fields:n,functionPath:e,level:t,message:r,timestamp:u.ts});try{Cr(u)}catch{}if(i?.onLog)try{i.onLog(u,{waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}makeLogger(e,t,s){const r=(n,i)=>{const{fields:o,message:c}=Nr(i,s);this.recordUserLog(e,n,i,c,o,t)};return{debug:(...n)=>{r("debug",n)},error:(...n)=>{r("error",n)},event:(n,i)=>{this.recordUserLog(e,"info",[n],n,s?{...s,...i}:i,t,n)},fatal:(...n)=>{r("fatal",n)},info:(...n)=>{r("info",n)},log:(...n)=>{r("log",n)},trace:(...n)=>{r("trace",n)},warn:(...n)=>{r("warn",n)},with:n=>this.makeLogger(e,t,s?{...s,...n}:n)}}makeTracer(e,t,s){const r=s??K(void 0);return wt({anchor:r,fuseCloudflareSpans:t?.fuseCloudflareTraces===!0,functionPath:e,record:n=>{this.recordSpan(n,t,r.sampled)},resolveCloudflareTracing:Jr,shardKey:this.state.id?.name,userId:()=>this.getCurrentUserId()})}resolveDispatchAnchor(e){return(e?void 0:this.getCurrentTrace())??K(void 0)}instrumentDb(e,t,s,r){const n=r===void 0?"off":r.instrumentDatabase??"summary";return n==="off"?e:Fs(e,{anchor:s,functionPath:t,mode:n,record:i=>{this.recordSpan(i,r,s.sampled)},shardKey:this.state.id?.name,tally:this.dispatchTally(s),userId:()=>this.getCurrentUserId()})}makeFetch(e,t,s){const r=(n,i)=>globalThis.fetch(n,i);return s===void 0||s.traceFetch===!1?r:Rt({anchor:t,functionPath:e,...typeof s.traceFetch=="object"&&s.traceFetch.propagate!==void 0?{propagate:s.traceFetch.propagate}:{},record:n=>{this.recordSpan(n,s,t.sampled)},shardKey:this.state.id?.name,userId:()=>this.getCurrentUserId()},r)}makeDispatchSpan(e,t){this.lastTelemetrySink=t??this.lastTelemetrySink,t!==void 0&&(J(this.dispatchSpans,de),this.dispatchSpans.set(R(e),this.dispatchSpans.get(R(e))??{sink:t}));const s=()=>{J(this.dispatchSpans,de);const r=R(e),n=this.dispatchSpans.get(r)??{sink:t};return n.collector??=At({spanId:e.rootSpanId,traceId:e.traceId}),this.dispatchSpans.set(r,n),n.collector};return{addEvent:(r,n)=>{s().handle.addEvent(r,n)},spanContext:()=>({spanId:e.rootSpanId,traceId:e.traceId}),addLink:r=>{s().handle.addLink(r)},recordException:r=>{s().handle.recordException(r)},setAttribute:(r,n)=>{s().handle.setAttribute(r,n)},setAttributes:r=>{s().handle.setAttributes(r)}}}makeMetrics(e,t){return Tt({functionPath:e,record:s=>{this.recordMetric(s,t)},shardKey:this.state.id?.name})}recordMetric(e,t){const s=this.currentRequestTrace?.traceId,r=s===void 0?e:{...e,traceId:s},n=o=>{try{o()}catch{}};n(()=>{this.metricSeries.push(r)});const i=t?.metricHistory;if(i!==void 0&&i!==!1){const o=this.state.storage.sql,c=typeof i=="object"?i:{};n(()=>{er(o,r,s,c)})}t?.onMetric&&n(()=>t.onMetric?.(r,{waitUntil:this.state.waitUntil?.bind(this.state)}))}async handleWebSocketMessage(e,t){if(this.isSocketExpired(e)){this.dropExpiredSocket(e);return}const s=typeof t=="string"?t:new TextDecoder().decode(t);let r;try{r=JSON.parse(s)}catch{e.send(JSON.stringify({message:"invalid envelope",type:"error"}));return}if(r.type==="connect"){const n=this.readAttachment(e);if(n.connected===!0)return;r.context!==void 0&&(n.context=r.context),r.clientId!==void 0&&(n.clientId=r.clientId),n.connected=!0;try{e.serializeAttachment?.(n)}catch{}await this.dispatchLifecycle("connect",this.lifecycleInfo(n));return}if(r.type==="subscribe"&&r.query){const{functionPath:n}=r.query,i=n?.startsWith(k)===!0;if(i&&this.readAttachment(e).admin!==!0){e.send(JSON.stringify({id:r.id,message:"admin subscription requires admin authorization",type:"error"}));return}let o;try{o=r.query.args===void 0?r.query:{...r.query,args:O(r.query.args)}}catch{try{e.send(JSON.stringify({code:"BAD_SUBSCRIPTION_ARGS",error:{code:"BAD_SUBSCRIPTION_ARGS",message:"subscription args failed wire decoding"},id:r.id,type:"error"}))}catch{}return}const c=this.subscribe(e,r.id,o);if(c!=="ok"){const d=c==="too_many"?"TOO_MANY_SUBSCRIPTIONS":"SUBSCRIPTION_PERSIST_FAILED",u=c==="too_many"?`subscription cap of ${String(S.MAX_SUBSCRIPTIONS_PER_SOCKET)} reached on this socket`:"failed to persist subscription attachment";try{e.send(JSON.stringify({code:d,error:{code:d,message:u},id:r.id,type:"error"}))}catch{}return}e.send(JSON.stringify({id:r.id,type:"ack"})),n&&await this.seedSubscription(e,r.id,o,n,i);return}if(r.type==="shape_subscribe"&&r.shape){let n;try{n=r.shape.args===void 0?void 0:O(r.shape.args)}catch{this.sendShapeSubscribeError(e,r.id,"BAD_SUBSCRIPTION_ARGS","shape args failed wire decoding");return}await this.handleShapeSubscribe(e,r.id,{args:n,name:r.shape.name,sinceEpoch:r.sinceEpoch,sinceSeq:r.sinceCheckpoint});return}if(r.type==="shape_unsubscribe"){this.shapeUnsubscribe(e,r.id),e.send(JSON.stringify({id:r.id,type:"ack"}));return}if(r.type==="stream"&&r.query?.functionPath){if(r.query.functionPath.startsWith(k)){e.send(JSON.stringify({id:r.id,message:"streams must be public",type:"error"}));return}this.handleStream(e,r.id,r.query.functionPath,O(r.query.args??{})).catch(()=>{});return}if(r.type==="whisper_subscribe"||r.type==="whisper_unsubscribe"){if(typeof r.topic=="string"&&r.topic.length>0){const n=r.type==="whisper_subscribe";this.setWhisperMembership(e,r.topic,n),n&&await this.relay?.announce()}return}if(r.type==="whisper"){typeof r.topic=="string"&&r.topic.length>0&&await this.broadcastWhisper(e,r.topic,r.data);return}if(r.type==="unsubscribe"){const n=this.streamCancellers.get(e),i=n?.get(r.id);i&&(i.abort(),n?.delete(r.id)),this.unsubscribe(e,r.id),e.send(JSON.stringify({id:r.id,type:"ack"}))}}async handleAlarmBody(){this.globalPollScheduled=!1;let e;try{e=await this.pollGlobalShapes()}catch(n){this.recordShapeError("shape:poll",n),e=1}let t;try{t=await this.pollExternalSources()}catch(n){this.recordShapeError("source:poll",n),t=Date.now()+S.GLOBAL_SHAPE_POLL_INTERVAL_MS}let s;try{s=await this.pollTtlSweeps()}catch(n){this.recordShapeError("ttl:sweep",n),s=Date.now()+S.GLOBAL_SHAPE_POLL_INTERVAL_MS}await this.flushChangedTables();const r=S.nextPollAlarmTarget(e,t,s,Date.now());r!==void 0&&await this.scheduleGlobalPoll(r)}dispatchTally(e){J(this.dispatchSpans,de);const t=R(e),s=this.dispatchSpans.get(t)??{};return s.dbTally??=Ws(),this.dispatchSpans.set(t,s),s.dbTally}async withTriggerTrace(e,t){const s=K(void 0),r=Date.now(),n=this.currentRequestTrace===void 0;n&&(this.currentRequestTrace=s);let i;try{return await t()}catch(o){throw i={thrown:o},o}finally{n&&this.currentRequestTrace===s&&(this.currentRequestTrace=void 0),(this.spans.hasTrace(s.traceId)||this.dispatchSpans.get(R(s))?.collector!==void 0)&&this.recordDispatchRootSpan(e,r,i,s),this.dispatchSpans.delete(R(s)),this.flushTelemetry()}}flushTelemetry(){try{this.lastTelemetrySink?.flush?.({waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}recordDispatchRootSpan(e,t,s,r){const n=this.dispatchSpans.get(R(r)),i=Date.now()-t,o=n?.dbTally===void 0||n.dbTally.calls===0?void 0:Ks(n.dbTally),c=n?.collector===void 0?void 0:{...n.collector.collected,attributes:{...o,...n.collector.collected.attributes}};try{this.spans.push(vt({anchor:r,...c===void 0?{}:{collected:c},durationMs:i,failure:s,functionPath:e,shardKey:this.state.id?.name,startTs:t,userId:this.getCurrentUserId()}))}catch{}n?.collector!==void 0&&this.exportWideEvent(e,i,s,r,{collected:c??n.collector.collected,sink:n.sink})}exportWideEvent(e,t,s,r,n){try{const{attributes:i}=n.collected;this.recordUserLog(e,s===void 0?"info":"error",[ue],ue,{...i,[se.durationMs]:t,[se.functionPath]:e,[se.ok]:s===void 0},n.sink,ue,r)}catch{}}recordSpan(e,t,s){try{this.spans.push(e)}catch{}if(!t?.onSpan)return;const r=this.traceSampling.get(e.traceId);if(r!==void 0){if(!r.sampled){if(r.sink=t,e.dispatch!==!0){const n=r.held??(r.held=[]);n.push(e),n.length>_a&&n.shift()}return}this.emitSpan(e,t);return}s!==!1&&this.emitSpan(e,t)}emitSpan(e,t){if(t.onSpan)try{t.onSpan(e,{waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}flushSampledOutTrace(e,t){const s=this.traceSampling.get(e.traceId);if(!s||s.sampled||!s.keepErrors)return;const{held:r,sink:n}=s;if(!(!n?.onSpan||r===void 0||r.length===0||!(t||r.some(i=>!i.ok))))for(const i of r)this.emitSpan(i,n)}lifecycleInfo(e){return{event:{connectionId:e.connectionId??"",shardKey:this.state.id?.name??z,userId:e.userId??null,...e.context===void 0?{}:{context:e.context}},identity:e.identity,userId:e.userId}}async withSystemDispatch(e){const t=this.currentRequestSystem;this.currentRequestSystem=!0;try{return await e()}finally{this.currentRequestSystem=t}}collectMetrics(){const e=this.state.storage.sql?.databaseSize;let{requests:t}=this.metrics,{errors:s}=this.metrics;try{const i=xt(this.state.storage.sql);t=i.requests,s=i.errors}catch{}let r=[];try{r=$t(this.state.storage.sql)}catch{}let n=[];try{n=nr(this.state.storage.sql)}catch{}return{cache:this.reactiveCache?this.reactiveCache.stats():null,databaseSize:typeof e=="number"?e:null,errors:s,functions:this.collectFunctionStats().functions,history:this.collectFunctionMetricBuckets(),indexHits:r,queryStats:n,requests:t,shard:this.state.id?.name??z,sinceMs:this.metrics.sinceMs,uptimeMs:Date.now()-this.metrics.sinceMs}}recordFunctionCall(e,t,s,r,n,i=!1){const o=Date.now(),c=r?[...r]:[],d=n?[...n].map(m=>La(m)).filter(m=>m!==void 0):[];try{Pt(this.state.storage.sql,{conflicted:i,durationMs:t,errored:s!==void 0,errorMessage:s,indexHits:d,path:e,scannedTables:c,ts:o})}catch{}const u=this.functionStats.get(e),l=u??{calls:0,conflicts:0,errors:0,lastCalledAt:o,lastErrorAt:null,lastErrorMessage:null,maxDurationMs:0,path:e,scannedTables:[],scans:0,totalDurationMs:0};l.calls+=1,l.totalDurationMs+=t,l.maxDurationMs=Math.max(l.maxDurationMs,t),l.lastCalledAt=o,c.length>0&&(l.scans+=c.length,qt(l.scannedTables,c)),s!==void 0&&(l.errors+=1,l.lastErrorAt=o,l.lastErrorMessage=s),i&&(l.conflicts+=1),u===void 0&&this.functionStats.set(e,l)}flushStmtSamples(){const e=this.currentStmtSamples;if(!(!e||e.length===0))try{const t=this.state.storage.sql;for(const[s,r,n,i]of e)try{ar(t,s,r,n,i)}catch{}}catch{}}collectFunctionStats(){try{return{functions:Dt(this.state.storage.sql),sinceMs:this.metrics.sinceMs}}catch{return{functions:[...this.functionStats.values()].toSorted((e,t)=>t.lastCalledAt-e.lastCalledAt),sinceMs:this.metrics.sinceMs}}}collectFunctionMetricBuckets(){try{return Ut(this.state.storage.sql)}catch{return[]}}maybeWarnRootSize(){if(S.rootSizeWarned||this.state.id?.name!==z)return;const e=this.state.storage.sql?.databaseSize;typeof e!="number"||e<Yr||(S.rootSizeWarned=!0,console.warn(`[@lunora/do] __root__ Durable Object SQLite size is ${String(e)} bytes (>= 1 GiB, 10% of the 10 GiB per-DO ceiling). Plan a \`.shardBy()\` migration before you hit the wall. See https://lunora.sh/docs/concepts/sharding for guidance.`))}errorToResponse(e){const{body:t,redacted:s,status:r}=C(e,{encodeData:w,fallbackCode:"RPC_FAILED",redactedMessage:"internal error"});return s&&console.error("[@lunora/do] internal error:",e),y({error:t},r)}async handleBatchRpc(e){let t;try{t=await e.json()}catch{return y({error:{code:"BAD_REQUEST",message:"invalid JSON body"}},400)}if(!Array.isArray(t.calls))return y({error:{code:"BAD_REQUEST",message:"batch `calls` must be an array"}},400);if(t.calls.length>Pe)return y({error:{code:"BAD_REQUEST",message:`batch exceeds the ${String(Pe)}-call limit`}},400);const s=[];let r;for(const n of t.calls){const i=await this.dispatchBatchEntry(e,n);i.bookmark!==void 0&&(r=i.bookmark),s.push({body:i.body,id:i.id,status:i.status})}return y({results:s},200,_(r))}async dispatchBatchEntry(e,t){try{const s=await this.fetch(xs(e,t));return{body:await s.json(),bookmark:s.headers.get("x-d1-bookmark")??void 0,id:t.id,status:s.status}}catch(s){const{body:r,status:n}=C(s,{fallbackCode:"BATCH_ENTRY_FAILED"});return{body:{error:r},bookmark:void 0,id:t?.id,status:n}}}async handleAdminRpc(e,t,s){if(!this.isAdminAuthorized(e))return y({error:{code:"ADMIN_FORBIDDEN",message:"admin introspection is disabled or the bearer token is invalid"}},403);try{const r=this.readAdminOp(t,s);if(r)return y({result:r.result},200);if(t===h.runMigration){const i=ta(s),o=await this.runShardDataMigration(i);return await this.flushChangedTables(),this.recordAudit("runMigration",{id:i.id,detail:{changed:o.changed,direction:o.direction,dryRun:o.dryRun,processed:o.processed}}),y({result:o},200)}if(t===h.exportShard){const i=It(s),o=await this.runShardExport({batchSize:i.batchSize,tables:i.tables});return y({result:{rows:o}},200)}if(t===h.importShard){const i=_t(s),o=await this.runShardImport({rows:i.rows,startLine:i.startLine});return await this.flushChangedTables(),this.recordAudit("importShard",{detail:{conflicts:o.conflicts,errors:o.errors.length,inserted:o.inserted}}),y({result:o},200)}if(t===h.writeRow){const i=na(s),o=await this.runShardWrite(i);return await this.flushChangedTables(),this.recordAudit("writeRow",{table:i.table,id:o.id??i.id,detail:{op:o.op}}),y({result:o},200)}if(t===h.deleteRows){const i=ga(s),o=await this.runShardBulkDelete(i);return await this.flushChangedTables(),this.recordAudit("deleteRows",{table:i.table,detail:{deleted:o.deleted,hasMore:o.hasMore}}),y({result:o},200)}if(t===h.clearTable){const i=Sa(s),o=await this.runShardBulkDelete(i);return await this.flushChangedTables(),this.recordAudit("clearTable",{table:i.table,detail:{deleted:o.deleted,hasMore:o.hasMore}}),y({result:o},200)}if(t===h.rankBefore){const i=await this.runShardRankBefore(Na(s));return y({result:i},200)}if(t===h.rankPage){const i=await this.runShardRankPage(Oa(s));return y({result:i},200)}if(t===h.cdcSync){const i=this.runShardCdcSync($a(s));return y({result:i},200)}if(t===h.applyCdc){const i=await this.runShardApplyCdc(xa(s));return await this.flushChangedTables(),this.recordAudit("applyCdc",{detail:{applied:i.applied}}),y({result:i},200)}return t===h.runAs?this.handleRunAs(s):await this.handleExtraAdminOp(t,s)||y({error:{code:"UNKNOWN_ADMIN_OP",message:`unknown admin op: ${t}`}},404)}catch(r){return this.errorToResponse(r)}}async handleExtraAdminOp(e,t){if(e===h.recordAuthEvent)return this.handleRecordAuthEvent(t);if(e===h.recordContainerEvent)return this.handleRecordContainerEvent(t);if(e===h.recordMail)return this.handleRecordMail(t);if(e===h.clearCapturedMail)return this.handleClearCapturedMail();if(e===h.sendTestMail)return this.handleSendTestMail(t);if(e===h.recordQueueMessage)return this.handleRecordQueueMessage(t);if(e===h.clearQueueMessages)return this.handleClearQueueMessages();if(e===h.sendQueueMessage)return this.handleSendQueueMessage(t);if(e===h.replayQueueMessage)return this.handleReplayQueueMessage(t);if(e===h.createWorkflowInstance)return this.handleCreateWorkflowInstance(t);if(e===h.getWorkflowInstanceStatus)return this.handleGetWorkflowInstanceStatus(t);if(e===h.listFlags)return this.handleListFlags(t);const s=await this.handleIssueTriageOp(e,t);return s!==void 0?s:this.handlePitrAdminOp(e,t)}async handleIssueTriageOp(e,t){const s=this.parseIssueTriagePatch(e,t);if(s===void 0)return;const r=ca(t),n=typeof t.updatedBy=="string"?t.updatedBy:void 0,i=this.state.storage.sql,o=zs(i,r,s,Date.now(),n);return this.recordChangedTable(B),await this.flushChangedTables(),this.recordAudit(e.slice(k.length),{detail:{...s,hash:r}}),y({result:{state:o}},200)}parseIssueTriagePatch(e,t){if(e===h.resolveIssue)return{status:"resolved"};if(e===h.ignoreIssue)return{status:"ignored"};if(e===h.assignIssue)return{assignee:da(t),status:"open"};if(e===h.setIssueSeverity)return{severity:ua(t)}}handleRecordAuthEvent(e){const t=ba(e);try{kt(this.state.storage.sql,{outcome:t.outcome,ts:Date.now()})}catch{}return y({result:{recorded:!0}},200)}async handleRecordContainerEvent(e){const t=wa(e);if(this.logs.push(t),t.level==="error"||t.exitCode!==void 0&&t.exitCode!==0){const s={durationMs:0,errorMessage:t.message,functionPath:t.functionPath,outcome:"error",shardKey:this.state.id?.name,ts:t.timestamp};this.persistRequestLog(s,this.requestLogConfig()),this.recordChangedTable(I),await this.flushChangedTables()}return y({result:{recorded:!0}},200)}async handleRunAs(e){const t=Ra(e),s=await this.withRequestIdentity(t.userId,t.identity,()=>this.handleRpc(t.functionPath,t.args));return await this.flushChangedTables(),this.recordAudit("runAs",{detail:{functionPath:t.functionPath,runAsUserId:t.userId}}),y({result:s},200)}resolveWorkflowBinding(e){const t=this.workflowsMetadata().workflows.find(r=>r.exportName===e);if(!t)throw new f("BAD_REQUEST",`workflow "${e}" is not declared`);const s=this.env?.[t.binding];if(typeof s!="object"||s===null||typeof s.create!="function"||typeof s.get!="function")throw new f("BAD_REQUEST",`workflow binding "${t.binding}" is not available on this deployment`);return s}async handleCreateWorkflowInstance(e){const t=la(e),s=await this.resolveWorkflowBinding(t.exportName).create({id:t.id,params:t.params}),r=await s.status(),n={id:s.id,status:et(r.status)};return this.recordAudit("createWorkflowInstance",{id:s.id,detail:{exportName:t.exportName}}),y({result:n},200)}async handleGetWorkflowInstanceStatus(e){const t=ha(e),s=await(await this.resolveWorkflowBinding(t.exportName).get(t.id)).status(),r={error:fa(s.error),id:t.id,output:s.output,status:et(s.status)};return y({result:r},200)}async handleListFlags(e){const t=e.context,s=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0,r=await this.evaluateFlags(s);return y({result:r},200)}async withRequestIdentity(e,t,s){const r=this.currentRequestUserId,n=this.currentRequestIdentity;this.currentRequestUserId=e,this.currentRequestIdentity=t;try{return await s()}finally{this.currentRequestUserId=r,this.currentRequestIdentity=n}}handleRecordMail(e){const t=Ta(e),s=Me(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleClearCapturedMail(){const e=Yt(this.state.storage.sql);return y({result:e},200)}handleSendTestMail(e){const t=Aa(e),s=Me(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleRecordQueueMessage(e){const t=Ia(e),s=dr(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleClearQueueMessages(){const e=hr(this.state.storage.sql);return y({result:e},200)}async handleSendQueueMessage(e){const t=ka(e),{binding:s}=this.resolveQueueBinding(t.exportName);let r;return t.batch===void 0?(await s.send(t.body,{contentType:t.contentType,delaySeconds:t.delaySeconds}),r=1):(await s.sendBatch(t.batch.map(n=>({body:n,contentType:t.contentType,delaySeconds:t.delaySeconds}))),r=t.batch.length),this.recordAudit("sendQueueMessage",{detail:{count:r,exportName:t.exportName}}),y({result:{sent:r}},200)}async handleReplayQueueMessage(e){const t=Ma(e),s=lr(this.state.storage.sql,t.id);if(s===void 0)throw new f("BAD_REQUEST",`replayQueueMessage: captured message "${t.id}" was not found`,{status:404});if(or(s.body))throw new f("BAD_REQUEST",`replayQueueMessage: captured message "${t.id}" has a truncated or unserializable body and can't be replayed faithfully`,{status:422});const r=t.target??this.resolveReplayTarget(s.queue)??s.exportName;if(typeof r!="string"||r==="")throw new f("BAD_REQUEST",`replayQueueMessage: captured message "${t.id}" has no declared producer to replay onto (pass \`target\`)`);const{binding:n}=this.resolveQueueBinding(r);return await n.send(s.body),this.recordAudit("replayQueueMessage",{detail:{messageId:s.messageId,target:r},id:t.id}),y({result:{sent:1,target:r}},200)}resolveQueueBinding(e){const t=this.queuesMetadata().queues.find(r=>r.exportName===e);if(!t)throw new f("BAD_REQUEST",`queue "${e}" is not declared`);const s=this.env?.[t.binding];if(typeof s!="object"||s===null||typeof s.send!="function")throw new f("BAD_REQUEST",`queue binding "${t.binding}" is not available on this deployment`);return{binding:s,metadata:t}}resolveReplayTarget(e){const{queues:t}=this.queuesMetadata(),s=t.find(r=>r.deadLetterQueue===e);return s!==void 0?s.exportName:t.find(r=>r.name===e)?.exportName}recordAudit(e,t={}){const s=this.state.storage.sql,r=this.getCurrentUserId(),n=r===void 0?t.detail:{...t.detail,userId:r};Cs(s,{detail:n,id:t.id,op:e,table:t.table,ts:Date.now()})}recordRequestLog(e,t,s,r,n,i){const o=this.requestLogConfig();if(r==="ok"&&!Fa(o.sampleRate))return;const c={cacheHit:this.currentRequestCacheHit,durationMs:s,errorMessage:i,functionPath:e,identity:this.currentRequestIdentity,outcome:r,redactedArgs:Object.keys(t).length===0?void 0:t,shardKey:this.state.id?.name,tablesRead:this.currentRequestReadTables===void 0?[]:[...this.currentRequestReadTables],tablesWritten:n,ts:Date.now(),userId:this.getCurrentUserId()};this.persistRequestLog(c,o)}persistRequestLog(e,t){const s={captureRaw:t.captureRaw,retention:t.retention};try{Ar(this.state.storage.sql,e,s)}catch{}if(t.emit||e.outcome==="error")try{Ir(e,s)}catch{}}requestLogConfig(){const e=this.env??{};return{captureRaw:Ce(this.env),emit:Ua(e.LUNORA_REQUEST_LOG_EMIT,Ce(this.env)),retention:Da(e.LUNORA_REQUEST_LOG_RETENTION),sampleRate:Ba(e.LUNORA_REQUEST_LOG_SAMPLE)}}async handlePitrAdminOp(e,t){const s=typeof t.time=="number"||typeof t.time=="string"?t.time:void 0;if(e===h.getPitrBookmark)return y({result:await es(this.state.storage,s)},200);if(e!==h.pitrRestore)return;const r=t.restart===!0,n=typeof t.bookmark=="string"?t.bookmark:void 0,i=await ts(this.state.storage,{bookmark:n,time:s});this.cdcEnabled()&&Rs(this.sql),this.recordAudit("pitrRestore",{detail:{restart:r,restoredTo:i.restoredTo,undoBookmark:i.undoBookmark}});const o=y({result:{...i,restarted:r}},200);return r&&this.state.abort?.("lunora PITR restore"),o}readAdminOp(e,t){this.ensureMigrated();const s=this.state.storage.sql,r=this.readAdminWildcardOp(e);if(r!==void 0)return{result:r,tables:new Set([b])};if(e===h.getAuditLog)return this.readAdminAuditLog(s,t);if(e===h.getRequestLog)return this.readAdminRequestLog(s,t);if(e===h.getIssues)return this.readAdminIssues(s,t);const n=this.readAdminDurableSignal(e,s,t);if(n)return n;if(e===h.readTablePage)return this.readAdminTablePage(s,t);if(e===h.facetColumn)return this.readAdminFacetColumn(s,t);if(e===h.runSql)return this.readAdminRunSql(s,t);const i=this.readAdminTableSignal(e,s,t);return i||this.readAdminStorageSignal(e,s,t)||null}readAdminTableSignal(e,t,s){if(e===h.listTableIndexes||e===h.describeTable){const r=typeof s.table=="string"?s.table:"";return{result:e===h.describeTable?{columns:this.tableColumns(r)}:{indexes:this.tableIndexes(r)},tables:new Set([r===""?b:r])}}if(e===h.describeTables){const r=Array.isArray(s.tables)?s.tables.filter(n=>typeof n=="string"):[];return{result:{columnsByTable:Object.fromEntries(r.map(n=>[n,this.tableColumns(n)]))},tables:new Set(r.length===0?[b]:r)}}if(e===h.migrationStatus){const r=typeof s.id=="string"?s.id:void 0;return{result:{migrations:Ct(t,r)},tables:new Set([b])}}}readAdminStorageSignal(e,t,s){if(e===h.storageReferences)return this.readAdminStorageReferences(t,s);if(e===h.storageOrphans)return this.readAdminStorageOrphans(t,s)}readAdminStorageReferences(e,t){const s=Array.isArray(t.keys)?t.keys.filter(r=>typeof r=="string"):[];return{result:Wt(e,this.storageColumns(),s),tables:new Set([b])}}readAdminStorageOrphans(e,t){const s=Array.isArray(t.liveKeys)?t.liveKeys.filter(n=>typeof n=="string"):[],r=Qr(e,this.storageColumns(),s);return r.truncated&&console.warn(`[@lunora/do] storageOrphans scan truncated after checking ${String(r.scanned)} storage references; reporting the first ${String(r.references.length)} dangling reference(s).`),{result:r,tables:new Set([b])}}readAdminWildcardOp(e){if(e===h.listTables)return Kt(this.state.storage.sql);if(e===h.getMetrics)return this.collectMetrics();if(e===h.getFunctionStats)return this.collectFunctionStats();if(e===h.listSubscriptions)return this.collectSubscriptions();if(e===h.getFanoutMetrics)return this.collectFanoutMetrics();if(e===h.getLogs)return{entries:this.logs.entries()};if(e===h.getTraces){const t=Br(this.spans.entries());return{total:t.total,traces:t.traces}}if(e===h.getMetricSeries)return{series:this.metricSeries.entries()};if(e===h.getMetricHistory)return sr(this.sql);if(e===h.getSettings)return cs(this.env);if(e===h.getSecurityAudit)return ds(this.env);if(e===h.getAdvisories)return{advisories:[...this.advisories(),...this.runtimeAdvisories()]};if(e===h.rlsPolicies)return this.rlsMetadata();if(e===h.maskPolicies)return this.maskMetadata();if(e===h.storageRules)return this.storageRulesMetadata();if(e===h.studioFeatures)return this.studioFeatures();if(e===h.listWorkflows)return this.workflowsMetadata();if(e===h.listQueues)return this.queuesMetadata()}collectSubscriptions(){return Ht(this.state.getWebSockets().map(e=>this.readAttachment(e)))}collectFanoutMetrics(){const e=Qt(this.state.getWebSockets().map(s=>this.readAttachment(s))),t=this.relay?.relayCount()??0;return{...e,maxRelays:this.relay?.maxRelays()??Te,promoted:t>0,relayCount:t,shapePoke:this.fanout.shapePoke,sinceMs:this.metrics.sinceMs,whisper:this.fanout.whisper}}readAdminAuditLog(e,t){we(e);const s=typeof t.limit=="number"?t.limit:void 0,r=typeof t.sinceSeq=="number"?t.sinceSeq:void 0;return{result:{entries:Os(e,{limit:s,sinceSeq:r})},tables:new Set([b])}}readAdminRequestLog(e,t){W(e);const s=t.outcome==="ok"||t.outcome==="error"?t.outcome:void 0;return{result:{entries:Or(e,{functionPathPrefix:typeof t.functionPathPrefix=="string"?t.functionPathPrefix:void 0,limit:typeof t.limit=="number"?t.limit:void 0,outcome:s,shardKey:typeof t.shardKey=="string"?t.shardKey:void 0,sinceSeq:typeof t.sinceSeq=="number"?t.sinceSeq:void 0,tableTouched:typeof t.tableTouched=="string"?t.tableTouched:void 0,userId:typeof t.userId=="string"?t.userId:void 0})},tables:new Set([b])}}readAdminIssues(e,t){return W(e),{result:{issues:xr(e,{functionPathPrefix:typeof t.functionPathPrefix=="string"?t.functionPathPrefix:void 0,limit:typeof t.limit=="number"?t.limit:void 0,shardKey:typeof t.shardKey=="string"?t.shardKey:void 0,status:ia(t.status)?t.status:void 0,userId:typeof t.userId=="string"?t.userId:void 0})},tables:new Set([b])}}readAdminDurableSignal(e,t,s){if(e===h.getAuthMetrics)return this.readAdminAuthMetrics(t);if(e===h.getCapturedMail)return this.readAdminCapturedMail(t,s);if(e===h.getQueueMessages)return this.readAdminQueueMessages(t,s)}readAdminAuthMetrics(e){let t;try{t=Mt(e)}catch{t={attempts:0,failureRate:0,failures:0,history:[],sinceMs:0}}return{result:t,tables:new Set([b])}}readAdminCapturedMail(e,t){const s=typeof t.limit=="number"?t.limit:void 0;let r;try{r=Vt(e,{limit:s})}catch{r={entries:[]}}return{result:r,tables:new Set([Zt])}}readAdminQueueMessages(e,t){const s=typeof t.limit=="number"?t.limit:void 0,r=typeof t.queue=="string"?t.queue:void 0;let n;try{n=ur(e,{limit:s,queue:r})}catch{n={entries:[]}}return{result:n,tables:new Set([A])}}readAdminTablePage(e,t){const s=typeof t.table=="string"?t.table:"";return{result:Gt(e,{filters:be(t.filters),limit:typeof t.limit=="number"?t.limit:void 0,offset:typeof t.offset=="number"?t.offset:void 0,orderBy:ya(t.orderBy),refs:this.tableRefs(s),search:typeof t.search=="string"?t.search:void 0,skipCount:typeof t.skipCount=="boolean"?t.skipCount:void 0,table:s}),tables:new Set([s===""?b:s])}}readAdminFacetColumn(e,t){const s=typeof t.table=="string"?t.table:"";return{result:zt(e,{column:typeof t.column=="string"?t.column:"",filters:be(t.filters),limit:typeof t.limit=="number"?t.limit:void 0,search:typeof t.search=="string"?t.search:void 0,table:s}),tables:new Set([s===""?b:s])}}readAdminRunSql(e,t){const s=typeof t.sql=="string"?t.sql:"";return{result:us(e,s),tables:new Set([b])}}executeAdminSubscription(e,t){const s=this.readAdminOp(e,t);return s?{result:s.result,tables:s.tables}:null}async resolveReactiveOutcome(e,t,s,r){if(s)return this.executeAdminSubscription(e,t);if(e.startsWith(jt)){const n=await this.runFlagSubscriptionRead(e,t,r);return n===null?null:{result:n,tables:new Set([b])}}return this.executeSubscription(e,t,r)}isIdentityIndependent(e){return e.startsWith(k)}resolveReactiveOutcomeDeduped(e,t,s,r,n){if(!this.isIdentityIndependent(e))return this.resolveReactiveOutcome(e,t,s,r);const i=Ne(e,t,null),o=n.get(i);if(o!==void 0)return o;const c=this.resolveReactiveOutcome(e,t,s,r);return n.set(i,c),c}isAdminAuthorized(e){const t=(this.env??{}).LUNORA_ADMIN_TOKEN;if(!t||t.length===0)return!1;const s=le(e.headers.get("authorization"));return s!==void 0&&j(s,t)}async handleStream(e,t,s,r){const n=this.executeStream(s,r);if(!n){e.send(JSON.stringify({error:{code:"NOT_FOUND",message:`stream not registered: ${s}`},id:t,type:"error"}));return}let i=this.streamCancellers.get(e);if(i||(i=new Map,this.streamCancellers.set(e,i)),i.size>=S.MAX_STREAMS_PER_SOCKET){try{e.send(JSON.stringify({error:{code:"TOO_MANY_STREAMS",message:`stream cap of ${String(S.MAX_STREAMS_PER_SOCKET)} reached on this socket`},id:t,type:"error"}))}catch{}return}const o=new AbortController;i.set(t,o),e.send(JSON.stringify({id:t,type:"ack"}));try{for await(const c of n.iterator(o.signal)){if(o.signal.aborted)break;await M(e),e.send(JSON.stringify({data:w(c),id:t,type:"chunk"}))}o.signal.aborted||e.send(JSON.stringify({id:t,type:"complete"}))}catch(c){const{body:d,redacted:u}=C(c,{fallbackCode:"INTERNAL_SERVER_ERROR",redactedMessage:"internal error"});u&&console.error("[@lunora/do] unhandled stream error:",c),e.send(JSON.stringify({error:{code:d.code,message:d.message},id:t,type:"error"}))}finally{i.delete(t),i.size===0&&this.streamCancellers.delete(e)}}async flushChangedTables(){const e=this.pendingChangedTables;if(this.pendingChangedTables=void 0,!(!e||e.size===0)){if(this.pendingRefreshTables)for(const t of e)this.pendingRefreshTables.add(t);else this.pendingRefreshTables=e;if(!this.refreshInFlight){if(typeof this.state.waitUntil=="function"){this.state.waitUntil(this.drainSubscriptionRefreshes());return}await this.drainSubscriptionRefreshes()}}}async drainSubscriptionRefreshes(){if(!this.refreshInFlight){this.refreshInFlight=!0;try{let e=this.pendingRefreshTables;for(;e&&e.size>0;){this.pendingRefreshTables=void 0;const t=this.currentCdcCursor(),s=this.currentCdcEpoch();await Promise.all([this.refreshSubscriptions(e),this.pokeShapeSubscribers(e,t,s),this.relay?.onFlush(e,t??0)]),e=this.pendingRefreshTables}}finally{this.refreshInFlight=!1}}}async refreshSubscriptions(e){const t=[...this.state.getWebSockets()],s=this.currentCdcCursor(),r=this.currentCdcEpoch(),n=new Map;await je(t,async i=>{if(this.isSocketExpired(i)){this.dropExpiredSocket(i);return}const o=this.readAttachment(i);for(const[c,d]of Object.entries(o.subs)){const{functionPath:u}=d;if(!u)continue;const l=u.startsWith(k),m=this.subMemos.get(i)?.get(c);if(!(m&&!m.tables.has(b)&&!ea(m.tables,e)))try{const p=await this.resolveReactiveOutcomeDeduped(u,d.args??{},l,{identity:o.identity,userId:o.userId},n);if(!p)continue;await M(i),this.pushSubscriptionData(i,c,p,s,r)}catch{continue}}})}async seedSubscription(e,t,s,r,n){const i=s.args??{},o=this.readAttachment(e),c=await this.resolveReactiveOutcome(r,i,n,{identity:o.identity,userId:o.userId});if(!c)return;const{sinceEpoch:d,sinceSeq:u}=s,l=n||u===void 0?void 0:this.evaluateResume(u,c.tables,d),m=n?void 0:l?.epoch??this.currentCdcEpoch();if(l?.resumable){this.seedSubscriptionMemo(e,t,c);try{e.send(`{"type":"resume","id":${JSON.stringify(t)}${Ve(l.cursor??0,m)}}`)}catch{}return}this.pushSubscriptionData(e,t,c,l?.cursor??this.currentCdcCursor(),m)}async handleShapeSubscribe(e,t,s){const r=this.shapeSubscribe(e,t,s);if(r!=="ok"){const i=r==="too_many"?"TOO_MANY_SUBSCRIPTIONS":"SUBSCRIPTION_PERSIST_FAILED",o=r==="too_many"?`subscription cap of ${String(S.MAX_SUBSCRIPTIONS_PER_SOCKET)} reached on this socket`:"failed to persist shape subscription attachment";this.sendShapeSubscribeError(e,t,i,o);return}const n=await this.seedShapeSubscription(e,t,s);if(n!=="ok"){this.shapeUnsubscribe(e,t),this.sendShapeSubscribeError(e,t,n.code,n.message);return}try{e.send(JSON.stringify({id:t,type:"ack"}))}catch{}}sendShapeSubscribeError(e,t,s,r){try{e.send(JSON.stringify({code:s,error:{code:s,message:r},id:t,type:"error"}))}catch{}}async seedShapeSubscription(e,t,s){const r=this.readAttachment(e),n={identity:r.identity,userId:r.userId},i=await this.relay?.seedRelayShape(e,t,s,n);if(i!==void 0)return i;let o;try{o=this.resolveShape(s.name,s.args??{},n)}catch(c){this.recordShapeError(`shape:seed:${t}`,c);const{body:d}=C(c,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{code:d.code,message:d.message}}if(!o)return{code:"SHAPE_NOT_FOUND",message:`shape "${s.name}" not found or not permitted`};try{return o.global?await this.seedGlobalShape(e,t,o,n,r.connectionId??""):await this.seedOpLogShape(e,t,s,o)}catch(c){this.recordShapeError(`shape:seed:${t}`,c);const{body:d}=C(c,{fallbackCode:"SHAPE_SEED_FAILED",redactedMessage:"shape seed failed"});return{code:d.code,message:d.message}}}async seedOpLogShape(e,t,s,r){const{baseCheckpoint:n,cursor:i,epoch:o,rowsPatch:c}=this.computeOpLogShapeSeed(s,r);return await M(e),this.sendPoke(e,[{rowsPatch:c,shapeId:t}],i,o,n)&&this.recordShapeMemo(e,t,i),"ok"}computeOpLogShapeSeed(e,t){const s=this.sql,r=this.currentCdcCursor()??0,n=this.currentCdcEpoch(),i=this.cdcEnabled()?$e(s):void 0,o=this.cdcEnabled()&&e.sinceSeq!==void 0&&e.sinceEpoch===n&&e.sinceSeq<=r&&(e.sinceSeq===r||i!==void 0&&i<=e.sinceSeq+1),c=o&&e.sinceSeq!==void 0?this.buildShapeDiff(s,t,e.sinceSeq,r):this.buildShapeSeed(s,t);return{baseCheckpoint:o?e.sinceSeq:void 0,cursor:r,epoch:n,rowsPatch:c}}async pokeShapeSubscribers(e,t,s){const r=[...this.state.getWebSockets()],n=t??this.currentCdcCursor()??0,i=this.sql,o=new Map;let c=0;const d=async l=>{if(this.isSocketExpired(l)){this.dropExpiredSocket(l);return}const m=this.readAttachment(l),{shapes:p}=m;if(p)try{const g={identity:m.identity,userId:m.userId},{emptyAdvanced:E,partAdvanced:yt,parts:Ae}=this.collectShapePokeParts(l,p,g,e,n,i,o);for(const te of E)this.recordShapeMemo(l,te,n);if(Ae.length>0&&(await M(l),this.sendPoke(l,Ae,n,s,void 0))){c+=1;for(const te of yt)this.recordShapeMemo(l,te,n)}}catch{}},u=Date.now();await je(r,d),this.fanout.shapePoke=re(this.fanout.shapePoke,r.length,c,Date.now()-u)}collectShapePokeParts(e,t,s,r,n,i,o){const c=[],d=[],u=[];for(const[l,m]of Object.entries(t))try{const p=this.resolveShape(m.name,m.args??{},s);if(!p||p.global||!r.has(p.table))continue;const g=this.shapeMemos.get(e)?.get(l)?.cursor??0,E=this.buildShapeDiff(i,p,g,n,o);E.length>0?(c.push({rowsPatch:E,shapeId:l}),u.push(l)):d.push(l)}catch(p){this.recordShapeError(`shape:poke:${l}`,p)}return{emptyAdvanced:d,partAdvanced:u,parts:c}}readShapeOpRange(e,t,s,r,n){const i=`${t}\0${String(s)}\0${String(r)}`,o=n?.get(i);if(o!==void 0)return o;const c=new Map,d=new Set([t]);let u=s;for(;;){const{changes:l,cursor:m}=this.readShapeCdcPage(e,u,d);for(const p of l)c.set(p.id,p);if(l.length===0||m===u||m>=r)break;u=m}return n?.set(i,c),c}readShapeCdcPage(e,t,s){return ne(e,{sinceSeq:t,tables:s})}buildShapeDiff(e,t,s,r,n){const i=this.readShapeOpRange(e,t.table,s,r,n);if(i.size===0)return[];const o=[...i.keys()],c=Ts(e,t.table,t.effectiveWhere,o),d=[];for(const[u,l]of i){if(c.has(u)){l.doc!==void 0&&d.push({key:u,op:l.op,table:t.table,value:me(l.doc,t.columns)});continue}l.op!=="insert"&&d.push({key:u,op:"delete",table:t.table})}return d}buildShapeSeed(e,t){return vs(e,t.table,t.effectiveWhere).map(s=>({key:s.id,op:"insert",table:t.table,value:me(s.doc,t.columns)}))}async seedGlobalShape(e,t,s,r,n){const i=await this.readGlobalShapeRows(s,r);if(!this.withinGlobalShapeBound(i.length,`shape:seed:${t}`,s.table))return{code:"SHAPE_GLOBAL_TOO_LARGE",message:`global shape membership for "${s.table}" exceeds the ${String(S.GLOBAL_SHAPE_MAX_ROWS)}-row cap; narrow it with a shape predicate or an RLS read policy`};const{next:o,rowsPatch:c}=We(i,new Map,{columns:s.columns,table:s.table});return await M(e),this.sendPoke(e,[{rowsPatch:c,shapeId:t}],this.currentCdcCursor()??0,this.currentCdcEpoch(),void 0)&&(this.recordGlobalSnapshot(e,t,o),this.saveGlobalSnapshot(n,t,o)),await this.scheduleGlobalPoll(),"ok"}async refreshGlobalShape(e,t,s,r,n){const i=await this.readGlobalShapeRows(s,r);if(!this.withinGlobalShapeBound(i.length,`shape:poll:${t}`,s.table))return;const o=this.readGlobalSnapshot(e,t,n),{next:c,rowsPatch:d}=We(i,o,{columns:s.columns,table:s.table});if(d.length===0){this.recordGlobalSnapshot(e,t,c);return}await M(e),this.sendPoke(e,[{rowsPatch:d,shapeId:t}],this.currentCdcCursor()??0,this.currentCdcEpoch(),void 0)&&(this.recordGlobalSnapshot(e,t,c),this.saveGlobalSnapshot(n,t,c))}readGlobalSnapshot(e,t,s){const r=this.globalShapeSnapshots.get(e)?.get(t);if(r)return r;const n=this.loadGlobalSnapshot(s,t);return this.recordGlobalSnapshot(e,t,n),n}recordGlobalSnapshot(e,t,s){let r=this.globalShapeSnapshots.get(e);r||(r=new Map,this.globalShapeSnapshots.set(e,r)),r.set(t,s)}loadGlobalSnapshot(e,t){if(e==="")return new Map;try{return Es(this.sql,e,t)}catch{return new Map}}saveGlobalSnapshot(e,t,s){if(e!=="")try{ws(this.sql,e,t,s)}catch{}}async scheduleGlobalPoll(e){if(this.globalPollScheduled)return;const{setAlarm:t}=this.state.storage;if(t){this.globalPollScheduled=!0;try{await t.call(this.state.storage,e??Date.now()+S.GLOBAL_SHAPE_POLL_INTERVAL_MS)}catch{this.globalPollScheduled=!1}}}recordShapeError(e,t){this.logs.push({functionPath:e,level:"error",message:t instanceof Error?t.message:String(t),timestamp:Date.now()})}withinGlobalShapeBound(e,t,s){return e<=S.GLOBAL_SHAPE_MAX_ROWS?!0:(this.recordShapeError(t,new Error(`global shape membership for "${s}" (${String(e)} rows) exceeds the ${String(S.GLOBAL_SHAPE_MAX_ROWS)}-row cap; narrow it with a shape predicate or an RLS read policy`)),!1)}async pollGlobalShapes(){const e=[...this.state.getWebSockets()];let t=0;for(const s of e){if(this.isSocketExpired(s)){this.dropExpiredSocket(s);continue}const r=this.readAttachment(s),{shapes:n}=r;if(!n)continue;const i={identity:r.identity,userId:r.userId};t+=await this.pollSocketGlobalShapes(s,n,i,r.connectionId??"")}return t}async pollSocketGlobalShapes(e,t,s,r){let n=0;for(const[i,o]of Object.entries(t)){let c;try{c=this.resolveShape(o.name,o.args??{},s)}catch(d){n+=1,this.recordShapeError(`shape:poll:${i}`,d);continue}if(c?.global){n+=1;try{await this.refreshGlobalShape(e,i,c,s,r)}catch(d){this.recordShapeError(`shape:poll:${i}`,d)}}}return n}sendPoke(e,t,s,r,n){this.pokeSequence+=1;const i=`poke-${String(this.pokeSequence)}`,o=Re(t,{baseCheckpoint:n,checkpoint:s,epoch:r,lastMutationId:this.socketClientWatermark(e),pokeId:i});try{for(const c of o)e.send(c);return!0}catch{return!1}}socketClientWatermark(e){const t=this.readAttachment(e),{clientId:s}=t;if(s!==void 0)try{return ae(this.sql,t.userId??"",s)}catch{return}}recordShapeMemo(e,t,s){let r=this.shapeMemos.get(e);r||(r=new Map,this.shapeMemos.set(e,r)),r.set(t,{cursor:s})}seedSubscriptionMemo(e,t,s){let r=this.subMemos.get(e);r||(r=new Map,this.subMemos.set(e,r)),r.set(t,{lastJson:JSON.stringify(w(s.result??null)),tables:s.tables})}pushSubscriptionData(e,t,s,r,n){let i=this.subMemos.get(e);i||(i=new Map,this.subMemos.set(e,i));const o=Ve(r,n),c=JSON.stringify(w(s.result??null)),d=i.get(t);if(d?.lastJson===c){d.tables=s.tables;const m=this.socketClientWatermark(e),p=m===void 0?"":`,"lastMutationId":${String(m)}`;L(e,`{"type":"settled","id":${JSON.stringify(t)}${p}${o}}`);return}const u=[],l=(d===void 0?void 0:rs(d.lastJson,s.result,s.tables.values().next().value??"",u))===void 0?L(e,`{"type":"data","id":${JSON.stringify(t)},"data":${c}${o}}`):as(e,t,u,o);i.set(t,{lastJson:l?c:d?.lastJson??Xr,tables:s.tables})}async isUpgradeAllowed(e){const t=this.env??{},s=t.LUNORA_ALLOWED_ORIGINS;if(s&&s.trim()!==""){const n=e.headers.get("origin");if(!n||!s.split(",").map(i=>i.trim()).filter(i=>i.length>0).includes(n))return!1}const r=t.LUNORA_WS_BEARER;if(r&&r.length>0){const n=this.suppliedWsToken(e);if(!n||!j(n,r)&&!await this.isAdminSocket(e))return!1}return!0}suppliedWsToken(e){const t=le(e.headers.get("authorization"));return t!==void 0?t:new URL(e.url).searchParams.get("token")??void 0}async isAdminSocket(e){const t=this.env??{},s=t.LUNORA_ADMIN_TOKEN;if(!s||s.length===0)return!1;const r=this.suppliedWsToken(e);if(r===void 0)return!1;if(await Ns(s,r))return!0;const n=le(e.headers.get("authorization"))===void 0,i=jr.has((t.LUNORA_REQUIRE_EPHEMERAL_WS_TOKEN??"").trim().toLowerCase());return n&&i?!1:j(r,s)}armWebSocketKeepalive(){const e=this.state.setWebSocketAutoResponse;typeof e!="function"||typeof WebSocketRequestResponsePair>"u"||e.call(this.state,new WebSocketRequestResponsePair(Gr,zr))}async routeNonRpc(e,t){if(e.pathname==="/_lunora/relay"&&t.method==="POST")return this.relay?await this.relay.handleControl(t):new Response("relay tier inactive",{status:404});if(e.pathname==="/_lunora/route"&&t.method==="GET")return y({relayCount:this.relay?.relayCount()??0});if(e.pathname==="/rpc-batch"&&t.method==="POST")return this.handleBatchRpc(t);if(t.headers.get("Upgrade")==="websocket")return this.handleWebSocketUpgrade(t)}async handleWebSocketUpgrade(e){if(!await this.isUpgradeAllowed(e))return new Response("Forbidden",{status:403});const t=await this.isAdminSocket(e),s=new WebSocketPair,r=s[0],n=s[1];this.state.acceptWebSocket(n);const i=e.headers.get("x-lunora-userid")??void 0,o=rt(e.headers.get("x-lunora-identity")),c=Number(e.headers.get("x-lunora-identity-exp")),d=Number.isFinite(c)&&c>0?c:void 0;return n.serializeAttachment?.({admin:t,connectionId:crypto.randomUUID(),subs:{},...d===void 0?{}:{expiresAt:d},...o===void 0?{}:{identity:o},...i===void 0?{}:{userId:i}}),new Response(null,{status:101,webSocket:r})}cdcEnabled(){try{return this.sql.exec("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?",Oe).toArray().length>0}catch{return!1}}isSocketExpired(e){const{expiresAt:t}=this.readAttachment(e);return typeof t=="number"&&Date.now()>=t}dropExpiredSocket(e){try{e.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},type:"error"})),e.close(4001,"token_expired")}catch{}}setWhisperMembership(e,t,s){const r=this.readAttachment(e),n=r.whispers??[],i=n.includes(t);if(s){if(i||n.length>=S.MAX_WHISPER_TOPICS_PER_SOCKET)return;r.whispers=[...n,t]}else{if(!i)return;const o=n.filter(c=>c!==t);o.length===0?delete r.whispers:r.whispers=o}try{e.serializeAttachment?.(r)}catch{}}allowWhisper(e){const t=Date.now(),s=this.whisperBuckets.get(e)??{last:t,tokens:S.WHISPER_RATE_BURST},r=Math.min(S.WHISPER_RATE_BURST,s.tokens+(t-s.last)/1e3*S.WHISPER_RATE_PER_SEC);return r<1?(this.whisperBuckets.set(e,{last:t,tokens:r}),!1):(this.whisperBuckets.set(e,{last:t,tokens:r-1}),!0)}async broadcastWhisper(e,t,s){if(!this.allowWhisper(e))return;const r=JSON.stringify(s??null);if(r.length>S.MAX_WHISPER_BYTES)return;const n=this.readAttachment(e).userId,i=n===void 0?"":`,"from":${JSON.stringify(n)}`,o=`{"type":"whisper","topic":${JSON.stringify(t)},"data":${r}${i}}`;this.deliverWhisperLocal(t,o,e),await this.relay?.forwardWhisper(t,o)}deliverWhisperLocal(e,t,s){let r=0,n=0;for(const i of this.state.getWebSockets())r+=1,!(i===s||this.readAttachment(i).whispers?.includes(e)!==!0)&&(L(i,t),n+=1);return this.fanout.whisper=re(this.fanout.whisper,r,n,0),n}readAttachment(e){const t=e.deserializeAttachment?.();return t&&typeof t=="object"&&"subs"in t&&t.subs?t:{subs:{}}}}export{Yr as ROOT_DO_SIZE_WARN_BYTES,z as ROOT_SHARD_NAME,S as ShardDO,rs as subscriptionListDeltas};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isLunoraError as L}from"@lunora/errors";const x=t=>{if(typeof t=="string")return t;try{return JSON.stringify(t)??String(t)}catch{return String(t)}},E=t=>typeof t=="boolean"||typeof t=="number"||typeof t=="string"?t:x(t),b=(t,e)=>{if(t===void 0&&e===void 0)return;const n={};if(e!==void 0)for(const[r,s]of Object.entries(e))n[r]=E(s);if(t!==void 0)for(const[r,s]of Object.entries(t))n[r]=E(s);return Object.keys(n).length===0?void 0:n},T=t=>{const e=new Uint8Array(t);crypto.getRandomValues(e);let n="";for(const r of e)n+=r.toString(16).padStart(2,"0");return n},S=/^[0-9a-f]+$/,C=(t,e,n=!0)=>`00-${t}-${e}-${n?"01":"00"}`,D=t=>{if(t==null)return;const e=t.trim().toLowerCase().split("-"),[n,r,s,a]=e;if(!(e.length<4||n===void 0||n.length!==2||!S.test(n)||n==="ff"||n==="00"&&e.length!==4||r===void 0||s===void 0||a===void 0||a.length!==2||!S.test(a)||r.length!==32||s.length!==16||!S.test(r)||!S.test(s)||r==="00000000000000000000000000000000"||s==="0000000000000000"))return{parentSpanId:s,sampled:(Number.parseInt(a,16)&1)===1,traceId:r}},f=Object.freeze({durationMs:"lunora.duration_ms",errorMessage:"error.message",errorType:"error.type",functionPath:"lunora.function_path",ok:"lunora.ok",shardKey:"lunora.shard_key",userId:"lunora.user_id"}),B=t=>{const e=D(t);return{rootSpanId:e?.parentSpanId??T(8),sampled:e?.sampled??!0,traceId:e?.traceId??T(16)}},P=t=>L(t)?t.code:t instanceof Error?t.constructor.name:"Error",R=t=>{const e=Object.keys(t);return e.length>0&&e.every(n=>n==="attributes"||n==="kind"||n==="links")},_=128,F=128,U=t=>{try{const e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}`}catch{return t}},H=t=>{try{return new URL(t).host}catch{return t}},N=(t,e)=>{try{return t(new URL(e))}catch{return!1}},V=t=>t===void 0?{}:R(t)?t:{attributes:t},q=(t,e)=>{if(t.isTraced){t.setAttribute(f.functionPath,e.functionPath),t.setAttribute(f.ok,e.ok),t.setAttribute(f.durationMs,e.durationMs),e.shardKey!==void 0&&t.setAttribute(f.shardKey,e.shardKey),e.userId!==void 0&&t.setAttribute(f.userId,e.userId),e.error!==void 0&&(t.setAttribute(f.errorType,e.error.type),t.setAttribute(f.errorMessage,e.error.message));for(const[n,r]of Object.entries(e.attributes))(typeof r=="boolean"||typeof r=="number"||typeof r=="string")&&t.setAttribute(`lunora.attr.${n}`,r)}},z=t=>{const e={attributes:{},events:[],links:[]},n={spanContext:()=>t,addEvent:(r,s)=>{if(e.events.length>=_)return;const a=b(s);e.events.push({...a===void 0?{}:{attributes:a},name:r,ts:Date.now()})},addLink:r=>{if(e.links.length>=F)return;const s=b(r.attributes);e.links.push({...s===void 0?{}:{attributes:s},spanId:r.spanId,traceId:r.traceId})},recordException:r=>{n.addEvent("exception",{"exception.message":r instanceof Error?r.message:String(r),...r instanceof Error&&typeof r.stack=="string"?{"exception.stacktrace":r.stack}:{},"exception.type":P(r)})},setAttribute:(r,s)=>{Object.assign(e.attributes,b({[r]:s}))},setAttributes:r=>{Object.assign(e.attributes,b(r))}};return{collected:e,handle:n}},G=t=>{const{anchor:e,fuseCloudflareSpans:n,functionPath:r,record:s,resolveCloudflareTracing:a,shardKey:i,userId:c}=t,h=d=>async(v,m,u)=>{const l=T(8),y=Date.now(),o=V(u),M=b(o.attributes),{collected:k,handle:j}=z({spanId:l,traceId:e.traceId}),A=async g=>{let I=!0,w;try{return await m(h(l),j)}catch(p){throw I=!1,w={message:p instanceof Error?p.message:String(p),type:P(p)},p}finally{const p=Date.now()-y,K=c(),$={...M,...k.attributes},O=[...o.links??[],...k.links];try{s({...Object.keys($).length===0?{}:{attributes:$},durationMs:p,...k.events.length===0?{}:{events:k.events},...w===void 0?{}:{error:w},functionPath:r,...o.kind===void 0||o.kind==="internal"?{}:{kind:o.kind},...O.length===0?{}:{links:O},name:v,ok:I,parentSpanId:d,shardKey:i,spanId:l,startTs:y,traceId:e.traceId,userId:K})}catch{}if(g!==void 0)try{q(g,{attributes:$,durationMs:p,error:w,functionPath:r,ok:I,shardKey:i,userId:K})}catch{}}};if(n===!0&&a!==void 0){const g=await a();if(g!==void 0&&typeof g.enterSpan=="function")return await g.enterSpan(v,I=>A(I))}return await A()};return h(e.rootSpanId)},Q=(t,e)=>{const{anchor:n,functionPath:r,propagate:s=!0,record:a,shardKey:i,userId:c}=t;return async(h,d)=>{const v=T(8),m=Date.now(),u=new Request(h,d);(typeof s=="function"?N(s,u.url):s)&&u.headers.set("traceparent",C(n.traceId,v,n.sampled??!0));let l,y;try{const o=await e(u);return y=o.status,o.ok||(l={message:`HTTP ${String(o.status)}`,type:`HTTP_${String(o.status)}`}),o}catch(o){throw l={message:o instanceof Error?o.message:String(o),type:P(o)},o}finally{try{a({attributes:{"http.request.method":u.method,...y===void 0?{}:{"http.response.status_code":y},"url.full":U(u.url)},durationMs:Date.now()-m,...l===void 0?{}:{error:l},functionPath:r,kind:"client",name:`${u.method} ${H(u.url)}`,ok:l===void 0,parentSpanId:n.rootSpanId,shardKey:i,spanId:v,startTs:m,traceId:n.traceId,userId:c()})}catch{}}}},W=t=>{const{functionPath:e,record:n,shardKey:r}=t,s=(a,i,c,h)=>{if(!Number.isFinite(c))return;const d=b(h);try{n({...d===void 0?{}:{attributes:d},functionPath:e,kind:a,name:i,shardKey:r,ts:Date.now(),value:c})}catch{}};return{count:(a,i=1,c)=>{s("counter",a,i,c)},gauge:(a,i,c)=>{s("gauge",a,i,c)},record:(a,i,c)=>{s("histogram",a,i,c)}}},X=t=>{const{anchor:e,collected:n,durationMs:r,failure:s,functionPath:a,shardKey:i,startTs:c,userId:h}=t,d=n?.attributes??{};return{...Object.keys(d).length===0?{}:{attributes:d},dispatch:!0,durationMs:r,...n===void 0||n.events.length===0?{}:{events:n.events},...s===void 0?{}:{error:{message:s.thrown instanceof Error?s.thrown.message:String(s.thrown),type:P(s.thrown)}},functionPath:a,...n===void 0||n.links.length===0?{}:{links:n.links},name:a,ok:s===void 0,parentSpanId:"",shardKey:i,spanId:e.rootSpanId,startTs:c,traceId:e.traceId,userId:h}};export{D as A,T as O,G as a,Q as b,W as c,X as d,z as e,q as f,b as n,B as r,P as t,f as w};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as r,c as t,e as c,b as s,a as o,d as p}from"./context-telemetry-
|
|
1
|
+
import{f as r,c as t,e as c,b as s,a as o,d as p}from"./context-telemetry-BQoMfXLz.mjs";export{r as applyCloudflareSpanAttributes,t as createMetrics,c as createSpanCollector,s as createTracedFetch,o as createTracer,p as dispatchRootSpan};
|
package/package.json
CHANGED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import{LunoraError as f,toErrorBody as C}from"@lunora/errors";import{drizzle as yt}from"drizzle-orm/durable-sqlite";import{c as j}from"./constant-time-equal-BVG05Guz.mjs";import{j as y}from"./json-response-wrh9TBPw.mjs";import{O as gt,t as St,n as Ae,r as K,A as bt,a as Et,b as wt,c as Rt,d as Tt,e as vt}from"./context-telemetry-DBcDCBl1.mjs";import{f as w,c as O}from"./wire-codec-Ctnni0h6.mjs";import{parseExportShardArgs as At,parseImportShardArgs as It}from"./exportShardRows-kt42wijd.mjs";import{recordAuthEvent as _t,readAuthMetrics as kt}from"./AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs";import{DATA_MIGRATION_STATE_TABLE as Mt,readMigrationStatus as Nt}from"./DATA_MIGRATION_STATE_TABLE-CaO6L0Ee.mjs";import{SCAN_DEP as Ie,createDependencyTracker as Ct,tableFromDepKey as Ot}from"./SCAN_DEP-D_yR9EeV.mjs";import{readFunctionMetricsTotals as Lt,readFunctionMetricIndexHits as xt,recordFunctionMetric as $t,mergeScanAttribution as Pt,readFunctionMetrics as qt,readFunctionMetricBuckets as Dt}from"./FUNCTION_METRICS_BUCKETS_TABLE-BPPeqM11.mjs";import{createFanoutCounters as _e,ADMIN_FUNCTION_PREFIX as k,RELATION_FUNCTION_PREFIX as Ut,selectMatchingIds as Bt,ADMIN_FUNCTIONS as h,findStorageReferences as Ft,listTables as Wt,summarizeSubscriptions as Kt,summarizeFanoutTopics as Ht,readTablePage as Qt,facetColumn as zt,FLAGS_FUNCTION_PREFIX as Gt,recordFanoutPass as se,MAX_PAGE_SIZE as jt}from"./ADMIN_FUNCTIONS-PxZ8Lr9e.mjs";import{LogBuffer as Jt}from"./LogBuffer-bIvCelI-.mjs";import{recordCapturedMail as ke,clearCapturedMail as Xt,readCapturedMail as Yt,MAIL_TABLE as Vt}from"./MAIL_RETENTION-KmozO2NQ.mjs";import{stableStringify as be}from"./stableStringify-BjLh4gvA.mjs";import{readBookmark as Zt,armRestore as es}from"./armRestore-BNzdvQ_o.mjs";import{ReactiveCache as ts,reactiveCacheKey as Me}from"./ReactiveCache-1_9Rs7J_.mjs";import{stableWireKey as $}from"./stableWireKey-YEHLaX6X.mjs";import{awaitWsDrain as M,trySendFrame as L,subscriptionListDeltas as ss,sendDeltaFrames as rs}from"./subscriptionListDeltas-Bs69JbA8.mjs";import{fingerprintError as as}from"@lunora/fingerprint";import{redact as ns,standardRules as is}from"@visulima/redact";import{R as Ne,E as os,_ as cs}from"./security-audit-BKUOgE0x.mjs";import{runReadonlySql as ds}from"./MAX_SQL_ROWS-Bdu25ASB.mjs";import{ConflictError as us}from"./ConflictError-C8GtJmjS.mjs";import{selectExpiredIds as ls}from"./selectExpiredIds-BGVP3d8-.mjs";import{p as hs,m as ps,T as fs,u as ms,b as re,_ as ys,o as gs,l as Ss,d as bs,S as Es}from"./ctx-db-idempotency-wiVoGnpQ.mjs";import{CDC_LOG_TABLE as Ce,readCdcChanges as ae,readCdcCursor as Oe,readCdcEpoch as Le,minCdcSeq as xe,bumpCdcEpoch as ws}from"./CDC_LOG_TABLE-E_J5LPoK.mjs";import{a as Rs,s as Ts}from"./ctx-db-shapes-DzX_H5q8.mjs";const $e=500,J=(a,e)=>{if(a.size<e)return;const t=a.keys().next().value;t!==void 0&&a.delete(t)},rt=new TextEncoder,vs=a=>{const e=a.replaceAll("-","+").replaceAll("_","/")+"===".slice((a.length+3)%4),t=atob(e),s=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)s[r]=t.codePointAt(r)??0;return s},As=64,ne=new Map,Is=async a=>{const e=ne.get(a);if(e)return e;J(ne,As);const t=crypto.subtle.importKey("raw",rt.encode(a),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]);return ne.set(a,t),t},_s=async(a,e,t)=>{const s=await Is(a);return crypto.subtle.verify("HMAC",s,t,rt.encode(e))},ks="v1",Ms=async(a,e,t=Date.now())=>{if(a.length===0||e.length===0)return!1;const s=e.split(".");if(s.length!==3)return!1;const[r,n,i]=s;if(r!==ks||i.length===0)return!1;const o=Number(n);if(!Number.isFinite(o)||o<=t)return!1;let c;try{c=vs(i)}catch{return!1}return _s(a,`${r}.${n}`,c)},q="__lunora_audit__",X=(a,e,...t)=>a.exec.call(a,e,...t),Ee=a=>{X(a,`CREATE TABLE IF NOT EXISTS "${q}" (
|
|
2
|
-
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
-
ts REAL NOT NULL,
|
|
4
|
-
op TEXT NOT NULL,
|
|
5
|
-
"table" TEXT,
|
|
6
|
-
id TEXT,
|
|
7
|
-
detail TEXT
|
|
8
|
-
)`)},Ns=(a,e)=>{Ee(a),X(a,`INSERT INTO "${q}" (ts, op, "table", id, detail) VALUES (?, ?, ?, ?, ?)`,e.ts,e.op,e.table??null,e.id??null,e.detail===void 0?null:JSON.stringify(e.detail)),X(a,`DELETE FROM "${q}" WHERE seq <= (SELECT MAX(seq) - ? FROM "${q}")`,1e3)},Cs=(a,e={})=>{Ee(a);const t=e.sinceSeq??0,s=Math.max(1,Math.min(e.limit??1e3,1e4));return X(a,`SELECT seq, ts, op, "table", id, detail FROM "${q}" WHERE seq > ? ORDER BY seq DESC LIMIT ?`,t,s).toArray().map(r=>{const n={op:r.op,seq:r.seq,ts:r.ts};return r.table!==null&&(n.table=r.table),r.id!==null&&(n.id=r.id),r.detail!==null&&(n.detail=JSON.parse(r.detail)),n})},Os=["x-lunora-userid","x-lunora-identity","x-d1-bookmark","x-lunora-client-ip","x-lunora-system","x-lunora-shard-binding"],Ls=(a,e)=>{const t=new Headers({"content-type":"application/json"});for(const s of Os){const r=a.headers.get(s);r!==null&&t.set(s,r)}return e.mutationId!==void 0&&t.set("x-lunora-mutation-id",e.mutationId),e.clientId!==void 0&&t.set("x-lunora-client-id",e.clientId),e.clientSeq!==void 0&&t.set("x-lunora-client-seq",String(e.clientSeq)),new Request("https://shard.internal/rpc",{body:JSON.stringify({args:e.args??{},functionPath:e.functionPath}),headers:t,method:"POST"})},xs=100,$s=new Set(["aggregate","count","delete","deleteMany","deleteWhere","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","insertMany","insertManyUnsafe","lookupById","patch","patchMany","patchWhere","rank","rankBefore","rankPage","rankPageRows","replace","restore"]),Ps=new Set(["aggregate","count","deleteWhere","findFirst","findFirstOrThrow","findMany","groupBy","insert","insertMany","insertManyUnsafe","patchWhere","rank","rankBefore","rankPage","rankPageRows"]),qs=(a,e)=>{if(!Ps.has(a))return;const t=e[0];return typeof t=="string"&&t.length>0?t:void 0},Ds=a=>a instanceof Error?a.message:typeof a=="string"?a:JSON.stringify(a),Us=a=>{const{deps:e,durationMs:t,failure:s,operation:r,startTs:n,table:i}=a;return{attributes:{"db.operation.name":r,...i===void 0?{}:{"db.collection.name":i},"db.system.name":"sqlite"},durationMs:t,...s===void 0?{}:{error:{message:Ds(s),type:St(s)}},functionPath:e.functionPath,kind:"client",name:i===void 0?`db.${r}`:`db.${r} ${i}`,ok:s===void 0,parentSpanId:e.anchor.rootSpanId,shardKey:e.shardKey,spanId:gt(8),startTs:n,traceId:e.anchor.traceId,userId:e.userId()}},Bs=(a,e)=>{if(e.mode==="off")return a;const{tally:t}=e,s=new Map;return new Proxy(a,{get(r,n,i){const o=Reflect.get(r,n,i);if(typeof n!="string"||typeof o!="function"||!$s.has(n))return o;const c=s.get(n);if(c!==void 0)return c;const d=o,u=async(...l)=>{const m=Date.now(),p=qs(n,l);let g;try{return await d.apply(r,l)}catch(E){throw g=E,E}finally{const E=Date.now()-m;t.calls+=1,t.durationMs+=E,t.perOperation[n]=(t.perOperation[n]??0)+1,g!==void 0&&(t.errors+=1);try{e.mode==="spans"&&(t.spansEmitted>=xs?t.spansTruncated=!0:(t.spansEmitted+=1,e.record(Us({deps:e,durationMs:E,failure:g,operation:n,startTs:m,table:p}))))}catch{}}};return s.set(n,u),u}})},Fs=()=>({calls:0,durationMs:0,errors:0,perOperation:{},spansEmitted:0,spansTruncated:!1}),Ws=a=>{const e={"db.calls":a.calls,"db.duration_ms":a.durationMs};a.errors>0&&(e["db.errors"]=a.errors),a.spansTruncated&&(e["db.spans_truncated"]=!0);for(const[t,s]of Object.entries(a.perOperation))e[`db.op.${t}`]=s;return e},B="__lunora_issue_state__",Ks=["ignored","open","resolved"],Hs=["critical","high","low","medium"],Y=(a,e,...t)=>a.exec.call(a,e,...t),H=a=>a??null,at=a=>{Y(a,`CREATE TABLE IF NOT EXISTS "${B}" (
|
|
9
|
-
hash TEXT PRIMARY KEY,
|
|
10
|
-
status TEXT NOT NULL DEFAULT 'open',
|
|
11
|
-
assignee TEXT,
|
|
12
|
-
severity TEXT,
|
|
13
|
-
updated_at REAL NOT NULL,
|
|
14
|
-
updated_by TEXT
|
|
15
|
-
)`)},nt=a=>({...a.assignee===null?{}:{assignee:a.assignee},hash:a.hash,...a.severity===null?{}:{severity:a.severity},status:a.status,updatedAt:a.updated_at,...a.updated_by===null?{}:{updatedBy:a.updated_by}}),Qs=(a,e)=>{const t=new Map;if(e.length===0)return t;at(a);for(let s=0;s<e.length;s+=100){const r=e.slice(s,s+100),n=r.map(()=>"?").join(", "),i=Y(a,`SELECT hash, status, assignee, severity, updated_at, updated_by FROM "${B}" WHERE hash IN (${n})`,...r).toArray();for(const o of i)t.set(o.hash,nt(o))}return t},zs=(a,e,t,s,r)=>{at(a);const n=H(t.status),i=H(t.assignee),o=t.assignee===null?1:0,c=H(t.severity),d=t.severity===null?1:0,u=H(r);Y(a,`INSERT INTO "${B}" (hash, status, assignee, severity, updated_at, updated_by)
|
|
16
|
-
VALUES (?, COALESCE(?, 'open'), ?, ?, ?, ?)
|
|
17
|
-
ON CONFLICT(hash) DO UPDATE SET
|
|
18
|
-
status = COALESCE(?, status),
|
|
19
|
-
assignee = CASE WHEN ? = 1 THEN NULL ELSE COALESCE(?, assignee) END,
|
|
20
|
-
severity = CASE WHEN ? = 1 THEN NULL ELSE COALESCE(?, severity) END,
|
|
21
|
-
updated_at = ?,
|
|
22
|
-
updated_by = ?`,e,n,i,c,s,u,n,o,i,d,c,s,u);const[l]=Y(a,`SELECT hash, status, assignee, severity, updated_at, updated_by FROM "${B}" WHERE hash = ?`,e).toArray();return l===void 0?{hash:e,status:n??"open",updatedAt:s,...r===void 0?{}:{updatedBy:r}}:nt(l)},Pe=256,it=a=>`${a.kind}${a.name}${be(a.attributes??{})}`;class Gs{capacity;series=new Map;constructor(e=Pe){this.capacity=e>0?Math.trunc(e):Pe}get size(){return this.series.size}clear(){this.series.clear()}entries(){return[...this.series.values()].toReversed().map(e=>({...e}))}push(e){const t=it(e),s=this.series.get(t);if(s===void 0){if(this.series.size>=this.capacity){const r=this.series.keys().next().value;r!==void 0&&this.series.delete(r)}this.series.set(t,{...e.attributes===void 0?{}:{attributes:e.attributes},count:1,...e.traceId===void 0?{}:{exemplarTraceId:e.traceId},firstTs:e.ts,functionPath:e.functionPath,kind:e.kind,last:e.value,lastTs:e.ts,max:e.value,min:e.value,name:e.name,...e.shardKey===void 0?{}:{shardKey:e.shardKey},sum:e.value});return}this.series.delete(t),s.count+=1,s.sum+=e.value,s.min=Math.min(s.min,e.value),s.max=Math.max(s.max,e.value),s.last=e.value,s.lastTs=e.ts,s.functionPath=e.functionPath,e.traceId!==void 0&&(s.exemplarTraceId=e.traceId),this.series.set(t,s)}}const T="__lunora_metric_history",le=6e4,js=1440,Js=1e3,qe=5e3,v=(a,e,...t)=>a.exec.call(a,e,...t),Xs=a=>Math.floor(a/le)*le,De=new WeakSet,ot=a=>{De.has(a)||(v(a,`CREATE TABLE IF NOT EXISTS "${T}" (
|
|
23
|
-
series_key TEXT NOT NULL,
|
|
24
|
-
bucket_ms INTEGER NOT NULL,
|
|
25
|
-
name TEXT NOT NULL,
|
|
26
|
-
kind TEXT NOT NULL,
|
|
27
|
-
attrs TEXT NOT NULL DEFAULT '{}',
|
|
28
|
-
function_path TEXT NOT NULL DEFAULT '',
|
|
29
|
-
shard_key TEXT,
|
|
30
|
-
count INTEGER NOT NULL DEFAULT 0,
|
|
31
|
-
sum REAL NOT NULL DEFAULT 0,
|
|
32
|
-
min REAL NOT NULL DEFAULT 0,
|
|
33
|
-
max REAL NOT NULL DEFAULT 0,
|
|
34
|
-
last REAL NOT NULL DEFAULT 0,
|
|
35
|
-
last_ts REAL NOT NULL DEFAULT 0,
|
|
36
|
-
exemplar_trace TEXT,
|
|
37
|
-
PRIMARY KEY (series_key, bucket_ms)
|
|
38
|
-
)`),De.add(a))},Ys=4096,Ue=new WeakMap,Vs=a=>{let e=Ue.get(a);return e===void 0&&(e=new Set,Ue.set(a,e)),e},Zs=(a,e,t)=>{ot(a);const s=it(e),r=Xs(e.ts),n=Vs(a),i=`${s}\0${r.toString()}`,o=n.has(i)||v(a,`SELECT 1 AS c FROM "${T}" WHERE series_key = ? AND bucket_ms = ? LIMIT 1`,s,r).toArray().length>0;if(!o&&!(v(a,`SELECT 1 AS c FROM "${T}" WHERE series_key = ? LIMIT 1`,s).toArray().length>0)&&v(a,`SELECT COUNT(DISTINCT series_key) AS n FROM "${T}"`).one().n>=Js)return;const c=t??null;v(a,`INSERT INTO "${T}"
|
|
39
|
-
(series_key, bucket_ms, name, kind, attrs, function_path, shard_key, count, sum, min, max, last, last_ts, exemplar_trace)
|
|
40
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?)
|
|
41
|
-
ON CONFLICT(series_key, bucket_ms) DO UPDATE SET
|
|
42
|
-
count = count + 1,
|
|
43
|
-
sum = sum + excluded.sum,
|
|
44
|
-
min = MIN(min, excluded.min),
|
|
45
|
-
max = MAX(max, excluded.max),
|
|
46
|
-
last = excluded.last,
|
|
47
|
-
last_ts = excluded.last_ts,
|
|
48
|
-
exemplar_trace = CASE WHEN excluded.exemplar_trace IS NULL THEN exemplar_trace ELSE excluded.exemplar_trace END`,s,r,e.name,e.kind,be(e.attributes??{}),e.functionPath,e.shardKey??null,e.value,e.value,e.value,e.value,e.ts,c),o||v(a,`DELETE FROM "${T}"
|
|
49
|
-
WHERE series_key = ?
|
|
50
|
-
AND bucket_ms <= (
|
|
51
|
-
SELECT MAX(bucket_ms) - ? FROM "${T}" WHERE series_key = ?
|
|
52
|
-
)`,s,js*le,s),o&&!n.has(i)&&(n.size>=Ys&&n.clear(),n.add(i))},er=a=>{if(!(a===""||a==="{}"))try{const e=JSON.parse(a);return e!==null&&typeof e=="object"?e:void 0}catch{return}},tr=(a,e={})=>{ot(a);const t=e.sinceMs===void 0?v(a,`SELECT * FROM "${T}" ORDER BY bucket_ms DESC LIMIT ?`,qe).toArray():v(a,`SELECT * FROM "${T}" WHERE bucket_ms >= ? ORDER BY bucket_ms DESC LIMIT ?`,e.sinceMs,qe).toArray(),s=new Map;for(const r of t){let n=s.get(r.series_key);if(n===void 0){const i=er(r.attrs);n={...i===void 0?{}:{attributes:i},functionPath:r.function_path,kind:r.kind,name:r.name,points:[],...r.shard_key===null?{}:{shardKey:r.shard_key}},s.set(r.series_key,n)}n.points.push({bucketMs:r.bucket_ms,count:r.count,...r.exemplar_trace===null?{}:{exemplarTraceId:r.exemplar_trace},last:r.last,max:r.max,min:r.min,sum:r.sum})}for(const r of s.values())r.points.sort((n,i)=>n.bucketMs-i.bucketMs);return{series:[...s.values()]}},D="__lunora_metrics_queries",U=(a,e,...t)=>a.exec.call(a,e,...t),sr=a=>{let e=a.replaceAll(/'(?:[^']|'')*'/g,"?").replaceAll(/\b0x[\da-f]+\b/gi,"?").replaceAll(/(?<=[=,([\s])\d+(?:\.\d+)?/g,"?").replaceAll(/\s+/g," ").trim();return e.length>512&&(e=`${e.slice(0,511)}…`),e},ct=a=>{U(a,`CREATE TABLE IF NOT EXISTS "${D}" (
|
|
53
|
-
normalized_sql TEXT PRIMARY KEY,
|
|
54
|
-
exec_count INTEGER NOT NULL DEFAULT 0,
|
|
55
|
-
total_duration_ms REAL NOT NULL DEFAULT 0,
|
|
56
|
-
rows_read INTEGER NOT NULL DEFAULT 0,
|
|
57
|
-
rows_written INTEGER NOT NULL DEFAULT 0
|
|
58
|
-
)`)},rr=(a,e,t,s,r)=>{const n=sr(e);if(n.length===0||(ct(a),U(a,`SELECT COUNT(*) AS n FROM "${D}"`).one().n>=500&&U(a,`SELECT COUNT(*) AS c FROM "${D}" WHERE normalized_sql = ?`,n).one().c===0))return;const i=`INSERT INTO "${D}" (normalized_sql, exec_count, total_duration_ms, rows_read, rows_written)
|
|
59
|
-
VALUES (?, 1, ?, ?, ?)
|
|
60
|
-
ON CONFLICT(normalized_sql) DO UPDATE SET
|
|
61
|
-
exec_count = exec_count + 1,
|
|
62
|
-
total_duration_ms = total_duration_ms + excluded.total_duration_ms,
|
|
63
|
-
rows_read = rows_read + excluded.rows_read,
|
|
64
|
-
rows_written = rows_written + excluded.rows_written`;U(a,i,n,t,s,r)},ar=a=>(ct(a),U(a,`SELECT normalized_sql, exec_count, total_duration_ms, rows_read, rows_written FROM "${D}" ORDER BY total_duration_ms DESC`).toArray().map(e=>({execCount:e.exec_count,normalizedSql:e.normalized_sql,rowsRead:e.rows_read,rowsWritten:e.rows_written,totalDurationMs:e.total_duration_ms}))),A="__lunora_queue_messages",x=(a,e,...t)=>a.exec.call(a,e,...t),Be=a=>a??null,dt="… [truncated by the dev queue catcher]",ut="[unserializable message body]",nr=a=>{if(a===void 0)return"null";try{const e=JSON.stringify(a);return e.length>131072?JSON.stringify(`${e.slice(0,131072)}${dt}`):e}catch{return JSON.stringify(ut)}},ir=a=>typeof a=="string"&&(a===ut||a.endsWith(dt)),or=a=>{if(!(a==null||a===""))try{return JSON.parse(a)}catch{return}},ee=a=>{x(a,`CREATE TABLE IF NOT EXISTS "${A}" (
|
|
65
|
-
id TEXT PRIMARY KEY,
|
|
66
|
-
captured_at INTEGER NOT NULL,
|
|
67
|
-
message_id TEXT NOT NULL,
|
|
68
|
-
queue TEXT NOT NULL,
|
|
69
|
-
export_name TEXT,
|
|
70
|
-
body TEXT NOT NULL,
|
|
71
|
-
attempts INTEGER NOT NULL,
|
|
72
|
-
outcome TEXT NOT NULL,
|
|
73
|
-
error TEXT,
|
|
74
|
-
dead_lettered INTEGER NOT NULL,
|
|
75
|
-
message_ts INTEGER NOT NULL
|
|
76
|
-
)`)},cr=(a,e,t)=>{ee(a);for(const s of e)x(a,`INSERT INTO "${A}" (id, captured_at, message_id, queue, export_name, body, attempts, outcome, error, dead_lettered, message_ts)
|
|
77
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,crypto.randomUUID(),t,s.messageId,s.queue,Be(s.exportName),nr(s.body),s.attempts,s.outcome,Be(s.error),s.deadLettered===!0?1:0,s.timestamp);return x(a,`DELETE FROM "${A}"
|
|
78
|
-
WHERE id NOT IN (
|
|
79
|
-
SELECT id FROM "${A}" ORDER BY captured_at DESC, id DESC LIMIT ?
|
|
80
|
-
)`,500),{recorded:e.length}},lt=a=>({attempts:a.attempts,body:or(a.body),capturedAt:a.captured_at,deadLettered:a.dead_lettered===1,error:a.error??void 0,exportName:a.export_name??void 0,id:a.id,messageId:a.message_id,outcome:a.outcome,queue:a.queue,timestamp:a.message_ts}),dr=(a,e={})=>{ee(a);const t=Math.min(Math.max(e.limit??100,1),500),s=typeof e.queue=="string"&&e.queue.length>0?e.queue:void 0,r=s===void 0?"":"WHERE queue = ?",n=s===void 0?[t]:[s,t];return{entries:x(a,`SELECT * FROM "${A}" ${r} ORDER BY captured_at DESC, id DESC LIMIT ?`,...n).toArray().map(i=>lt(i))}},ur=(a,e)=>{ee(a);const t=x(a,`SELECT * FROM "${A}" WHERE id = ? LIMIT 1`,e).toArray()[0];return t===void 0?void 0:lt(t)},lr=a=>(ee(a),x(a,`DELETE FROM "${A}"`),{cleared:!0}),he="::relay::",Q=(a,e)=>`${a}${he}${String(e)}`,hr=a=>{const e=a.lastIndexOf(he);if(e===-1)return;const t=a.slice(0,e),s=a.slice(e+he.length),r=Number(s);if(!(t.length===0||!Number.isInteger(r)||r<0||String(r)!==s))return{ownerKey:t,relayIndex:r}},V=(a,e)=>$({args:e??{},name:a}),pe={tDown:4e3,tUp:8e3},pr=(a,e,t=pe)=>{if(t.tDown>=t.tUp)throw new f("INTERNAL",`invalid promotion thresholds: tDown (${String(t.tDown)}) must be < tUp (${String(t.tUp)})`);return a==="owned"?e>=t.tUp?"promoted":"owned":e<t.tDown?"owned":"promoted"},fr=(a,e)=>e<a?{tDown:e,tUp:a}:{tDown:Math.min(Math.max(1,Math.floor(a/2)),a-1),tUp:a},fe=(a,e)=>{if(!e)return a;const t=Object.create(null);for(const s of["_id","_creationTime",...e])Object.hasOwn(a,s)&&(t[s]=a[s]);return t},Fe=(a,e,t)=>{const{columns:s,table:r}=t,n=new Map,i=[];for(const{doc:o,id:c}of a){const d=fe(o,s),u=JSON.stringify(w(d));n.set(c,u);const l=e.get(c);l===void 0?i.push({key:c,op:"insert",table:r,value:d}):l!==u&&i.push({key:c,op:"update",table:r,value:d})}for(const o of e.keys())n.has(o)||i.push({key:o,op:"delete",table:r});return{next:n,rowsPatch:i}},me=a=>a.map(e=>e.value===void 0?e:{...e,value:w(e.value)}),we=(a,e,t={})=>{const{baseCheckpoint:s,checkpoint:r,epoch:n,lastMutationId:i,pokeId:o}=e,c=[JSON.stringify({baseCheckpoint:s,epoch:n,pokeId:o,type:"pokeStart"})];for(const d of a){const u=t.preEncoded?d.rowsPatch:me(d.rowsPatch);c.push(JSON.stringify({pokeId:o,rowsPatch:u,shapeId:d.shapeId,type:"pokePart",...i===void 0?{}:{lastMutationId:i}}))}return c.push(JSON.stringify({checkpoint:r,epoch:n,pokeId:o,type:"pokeEnd"})),c},mr=2,Re=8,yr="LUNORA_RELAY_SECRET",We="x-lunora-relay-sig",Ke=a=>{const e=a?.[yr];return typeof e=="string"&&e.length>0?e:void 0},He=async(a,e)=>{const t=new TextEncoder,s=await crypto.subtle.importKey("raw",t.encode(a),{hash:"SHA-256",name:"HMAC"},!1,["sign"]),r=await crypto.subtle.sign("HMAC",s,t.encode(e));return[...new Uint8Array(r)].map(n=>n.toString(16).padStart(2,"0")).join("")},P=(a,e,t)=>{const s=a?.[e];let r=Number.NaN;return typeof s=="string"?r=Number.parseInt(s,10):typeof s=="number"&&(r=s),Number.isInteger(r)&&r>0?r:t},ie={},gr=a=>{throw new f("INTERNAL",`unhandled relay frame: ${JSON.stringify(a)}`)},Sr=a=>{if(a===null||typeof a!="object")return;const e=a;return typeof e.idFromName=="function"&&typeof e.get=="function"?e:void 0},br=a=>Response.json(a,{headers:{"content-type":"application/json"}}),z=()=>new Response(null,{status:204});class ht{constructor(e,t){this.host=e,this.roleId=t}host;roleId;async handleControl(e){let t;try{t=await e.text()}catch{return new Response("bad request",{status:400})}const s=Ke(this.host.env());if(s!==void 0){const n=e.headers.get(We),i=await He(s,t);if(n===null||!j(n,i))return new Response("forbidden",{status:403})}let r;try{r=JSON.parse(t)}catch{return new Response("bad request",{status:400})}switch(r.type){case"relay_attach":return this.onAttach(r.relayIndex),z();case"relay_detach":return this.onDetach(r.relayIndex),z();case"relay_frame":return this.host.deliverWhisperLocal(r.topic,r.frame,void 0),await this.onWhisperFrame(r),z();case"relay_shape_poke":{const n=this.host.getWebSockets().length,i=Date.now(),o=this.onShapePoke({...r,args:O(r.args)});return this.host.recordShapePokeFanout(n,o,Date.now()-i),z()}case"relay_shape_subscribe":return br(this.onShapeSubscribe({...r,args:O(r.args)}));default:return gr(r)}}maxRelays(){return P(this.host.env(),"LUNORA_MAX_RELAYS",Re)}canAddressSiblings(){return this.relayNamespace()!==void 0}relayNamespace(){const e=this.host.shardBinding();if(e!==void 0)return Sr(this.host.env()?.[e])}async postRelayMessage(e,t){await this.requestRelayMessage(e,t)}async requestRelayMessage(e,t){const s=this.relayNamespace();if(s===void 0)return;const r=typeof s.getByName=="function"?s.getByName(e):s.get(s.idFromName(e)),n=JSON.stringify(t),i={"content-type":"application/json","x-lunora-shard-binding":this.host.shardBinding()??""},o=Ke(this.host.env());o!==void 0&&(i[We]=await He(o,n));try{return await r.fetch("https://relay.internal/_lunora/relay",{body:n,headers:i,method:"POST"})}catch{return}}}let Er=class extends ht{shapeUniformCache=new Map;relaySetCache;relayShapeRegistry=new Map;relayShapeProxies=new Map;promotionState="owned";constructor(e,t){super(e,{ownerKey:t})}async forwardWhisper(e,t){if(!this.canAddressSiblings())return;const s=this.ownerRelaySet();s.size!==0&&await Promise.all([...s].map(r=>this.postRelayMessage(Q(this.roleId.ownerKey,r),{frame:t,topic:e,type:"relay_frame"})))}async onFlush(e,t){await Promise.all([this.multicastShapePokes(e,t),this.proxyShapePokes(e,t)])}seedRelayShape(){return Promise.resolve(void 0)}announce(){return Promise.resolve()}announceDrain(){return Promise.resolve()}relayCount(){const e=this.host.getWebSockets().length,t=P(this.host.env(),"LUNORA_RELAY_THRESHOLD",pe.tUp),s=P(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",pe.tDown);if(this.promotionState=pr(this.promotionState,e,fr(t,s)),this.promotionState==="owned")return 0;const r=P(this.host.env(),"LUNORA_MAX_RELAYS",Re),n=P(this.host.env(),"LUNORA_RELAY_FAN",mr);return Math.min(r,Math.max(1,n))}isShapeRelayUniform(e,t){const s=V(e,t),r=this.shapeUniformCache.get(s);if(r!==void 0)return r;const n=this.probeShapeRelayUniform(e,t);return this.shapeUniformCache.set(s,n),n}onAttach(e){this.addRelayToSet(e)}onDetach(e){this.removeRelayFromSet(e)}async onWhisperFrame(e){await Promise.all([...this.ownerRelaySet()].filter(t=>t!==e.originRelay).map(t=>this.postRelayMessage(Q(this.roleId.ownerKey,t),{frame:e.frame,topic:e.topic,type:"relay_frame"})))}onShapeSubscribe(e){return this.buildShapeSeedFrames(e)}onShapePoke(){return 0}async multicastShapePokes(e,t){if(this.relayShapeRegistry.size===0)return;const s=this.ownerRelaySet();if(s.size===0)return;const r=this.host.currentCdcEpoch(),n=[];for(const i of this.relayShapeRegistry.values()){let o;try{o=this.host.resolveShape(i.name,i.args,ie)}catch{continue}if(o===void 0||o.global===!0||!e.has(o.table))continue;const c=i.cursor,d=this.host.buildShapeDiff(o,c,t);if(d.length===0)continue;i.cursor=t;const u={args:w(i.args),checkpoint:t,epoch:r,fromCursor:c,name:i.name,rowsPatch:me(d),type:"relay_shape_poke"};for(const l of s)n.push(this.postRelayMessage(Q(this.roleId.ownerKey,l),u))}await Promise.all(n)}async proxyShapePokes(e,t){if(this.relayShapeProxies.size===0)return;const s=this.host.currentCdcEpoch(),r=[];for(const n of this.relayShapeProxies.values()){let i;try{i=this.host.resolveShape(n.name,n.args,n.identity)}catch{continue}if(i===void 0||i.global===!0||!e.has(i.table))continue;const o=n.cursor,c=this.host.buildShapeDiff(i,o,t);if(c.length===0)continue;n.cursor=t;const d={args:w(n.args),checkpoint:t,epoch:s,fromCursor:o,name:n.name,rowsPatch:me(c),targetConnectionId:n.connectionId,type:"relay_shape_poke"};r.push(this.postRelayMessage(Q(this.roleId.ownerKey,n.relayIndex),d))}await Promise.all(r)}buildShapeSeedFrames(e){const t={identity:e.identity,userId:e.userId};let s;try{s=this.host.resolveShape(e.name,e.args,t)}catch(u){const{body:l}=C(u,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:l.code,message:l.message}}}if(s===void 0||s.global===!0)return{error:{code:"SHAPE_NOT_FOUND",message:`shape not relayable: ${e.name}`}};e.relayIndex!==void 0&&this.addRelayToSet(e.relayIndex);const{baseCheckpoint:r,cursor:n,epoch:i,rowsPatch:o}=this.host.computeOpLogShapeSeed({args:e.args,name:e.name,sinceEpoch:e.sinceEpoch,sinceSeq:e.sinceSeq},s);let c=n;if(this.isShapeRelayUniform(e.name,e.args)){const u=V(e.name,e.args);let l=this.relayShapeRegistry.get(u);l===void 0&&(l={args:e.args,cursor:n,name:e.name},this.relayShapeRegistry.set(u,l)),c=l.cursor}else e.relayIndex!==void 0&&e.connectionId!==void 0&&this.relayShapeProxies.set(`${String(e.relayIndex)}:${e.connectionId}:${e.subId}`,{args:e.args,connectionId:e.connectionId,cursor:n,epoch:i,identity:t,name:e.name,relayIndex:e.relayIndex,subId:e.subId});const d=we([{rowsPatch:o,shapeId:e.subId}],{baseCheckpoint:r,checkpoint:n,epoch:i,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:i,frames:d}}ensureRelayTable(){this.host.sql().exec("CREATE TABLE IF NOT EXISTS __lunora_relays (idx INTEGER PRIMARY KEY)")}ownerRelaySet(){if(this.relaySetCache===void 0){this.ensureRelayTable();const e=this.host.sql().exec("SELECT idx FROM __lunora_relays").toArray();this.relaySetCache=new Set(e.map(t=>Number(t.idx)))}return this.relaySetCache}addRelayToSet(e){this.ensureRelayTable(),this.host.sql().exec("INSERT OR IGNORE INTO __lunora_relays (idx) VALUES (?)",e),this.ownerRelaySet().add(e)}removeRelayFromSet(e){this.ensureRelayTable(),this.host.sql().exec("DELETE FROM __lunora_relays WHERE idx = ?",e);const t=this.ownerRelaySet();t.delete(e);for(const[s,r]of this.relayShapeProxies)r.relayIndex===e&&this.relayShapeProxies.delete(s);t.size===0&&(this.relayShapeRegistry.clear(),this.shapeUniformCache.clear())}probeShapeRelayUniform(e,t){let s;try{s=this.host.resolveShape(e,t,ie)}catch{return!1}if(s===void 0||s.global===!0||this.host.rlsMetadata().policies.some(c=>c.on==="read"&&c.table===s.table)||this.tableHasAnyMask(s.table))return!1;const r=$(s.effectiveWhere),n=$(s.columns);let i=!1;const o=c=>{const d={groups:[`grp_${c}`],roles:[c],sub:`__lunora_probe_${c}__`};return{identity:new Proxy(d,{get:(u,l)=>typeof l=="symbol"||l in u?Reflect.get(u,l):`${c}:${l}`,getOwnPropertyDescriptor:(u,l)=>(i=!0,Reflect.getOwnPropertyDescriptor(u,l)),has:(u,l)=>typeof l=="symbol"?Reflect.has(u,l):!0,ownKeys:u=>(i=!0,Reflect.ownKeys(u))}),userId:`__lunora_probe_${c}__`}};return[ie,o("a"),o("b")].every(c=>{let d;try{d=this.host.resolveShape(e,t,c)}catch{return!1}return d!==void 0&&d.global!==!0&&d.table===s.table&&$(d.effectiveWhere)===r&&$(d.columns)===n})&&!i}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(t=>t.table===e)}},wr=class extends ht{relayAnnounced=!1;shapeRelayMemos=new WeakMap;constructor(e,t,s){super(e,{ownerKey:t,relayIndex:s})}async forwardWhisper(e,t){this.canAddressSiblings()&&await this.postRelayMessage(this.roleId.ownerKey,{frame:t,originRelay:this.roleId.relayIndex,topic:e,type:"relay_frame"})}onFlush(){return Promise.resolve()}async seedRelayShape(e,t,s,r){if(!this.canAddressSiblings())return{code:"RELAY_MISCONFIGURED",message:"relay cannot address its owner"};await this.announce();const n={args:w(s.args??{}),connectionId:this.host.readAttachment(e).connectionId,identity:r.identity,name:s.name,relayIndex:this.roleId.relayIndex,sinceEpoch:s.sinceEpoch,sinceSeq:s.sinceSeq,subId:t,type:"relay_shape_subscribe",userId:r.userId},i=await this.requestRelayMessage(this.roleId.ownerKey,n);if(i===void 0)return{code:"RELAY_SEED_FAILED",message:"owner did not answer the shape seed"};let o;try{o=await i.json()}catch{return{code:"RELAY_SEED_FAILED",message:"malformed shape seed from owner"}}if(o.error!==void 0)return o.error;if(o.frames===void 0)return{code:"RELAY_SEED_FAILED",message:"owner returned no shape frames"};await M(e);for(const c of o.frames)L(e,c);return this.recordRelayShapeMemo(e,t,o.cursor??0,o.epoch),"ok"}async announce(){this.relayAnnounced||!this.canAddressSiblings()||(this.relayAnnounced=!0,(await this.requestRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_attach"}))?.ok||(this.relayAnnounced=!1))}async announceDrain(e){this.canAddressSiblings()&&(this.host.getWebSockets().some(t=>t!==e)||(this.relayAnnounced=!1,await this.postRelayMessage(this.roleId.ownerKey,{relayIndex:this.roleId.relayIndex,type:"relay_detach"})))}relayCount(){return 0}isShapeRelayUniform(){return!1}onAttach(){}onDetach(){}onWhisperFrame(){return Promise.resolve()}onShapeSubscribe(){return{error:{code:"RELAY_CANNOT_SEED",message:"a relay has no op-log to seed from"}}}onShapePoke(e){return this.deliverShapePoke(e)}recordRelayShapeMemo(e,t,s,r){let n=this.shapeRelayMemos.get(e);n===void 0&&(n=new Map,this.shapeRelayMemos.set(e,n)),n.set(t,{cursor:s,epoch:r})}deliverShapePoke(e){const t=V(e.name,e.args);let s=0;for(const r of this.host.getWebSockets()){const n=this.host.readAttachment(r),{shapes:i}=n,o=this.shapeRelayMemos.get(r);if(!(i===void 0||o===void 0)&&!(e.targetConnectionId!==void 0&&n.connectionId!==e.targetConnectionId))for(const[c,d]of Object.entries(i)){const u=o.get(c);if(u?.cursor!==e.fromCursor||u.epoch!==e.epoch||V(d.name,d.args)!==t)continue;const l=we([{rowsPatch:e.rowsPatch,shapeId:c}],{baseCheckpoint:void 0,checkpoint:e.checkpoint,epoch:e.epoch,lastMutationId:void 0,pokeId:this.host.nextPokeId()},{preEncoded:!0});for(const m of l)L(r,m);o.set(c,{cursor:e.checkpoint,epoch:e.epoch}),s+=1}}return s}};const Rr=a=>{const e=a.doName();if(e===void 0)return;const t=hr(e);return t===void 0?new Er(a,e):new wr(a,t.ownerKey,t.relayIndex)},I="__lunora_reqlog__",Te=1e3,pt="lunora",F=(a,e,...t)=>a.exec.call(a,e,...t),Z=(a,e=!1)=>e||a===null||a===void 0?a:ns(a,is),W=a=>{F(a,`CREATE TABLE IF NOT EXISTS "${I}" (
|
|
81
|
-
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
82
|
-
ts REAL NOT NULL,
|
|
83
|
-
function_path TEXT NOT NULL,
|
|
84
|
-
shard_key TEXT,
|
|
85
|
-
user_id TEXT,
|
|
86
|
-
identity TEXT,
|
|
87
|
-
args TEXT,
|
|
88
|
-
outcome TEXT NOT NULL,
|
|
89
|
-
error_message TEXT,
|
|
90
|
-
duration_ms REAL NOT NULL,
|
|
91
|
-
tables_read TEXT NOT NULL DEFAULT '[]',
|
|
92
|
-
tables_written TEXT NOT NULL DEFAULT '[]',
|
|
93
|
-
cache_hit INTEGER,
|
|
94
|
-
subscriptions_rerun INTEGER NOT NULL DEFAULT 0
|
|
95
|
-
)`)},Qe=a=>JSON.stringify([...new Set(a)].toSorted((e,t)=>e.localeCompare(t))),Tr=a=>a===void 0?null:a?1:0,vr=(a,e,t={})=>{W(a);const s=t.captureRaw??!1,r=t.retention??Te;F(a,`INSERT INTO "${I}"
|
|
96
|
-
(ts, function_path, shard_key, user_id, identity, args, outcome, error_message, duration_ms, tables_read, tables_written, cache_hit, subscriptions_rerun)
|
|
97
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,e.ts,e.functionPath,e.shardKey??null,e.userId??null,e.identity===void 0?null:JSON.stringify(Z(e.identity,s)),e.redactedArgs===void 0?null:JSON.stringify(Z(e.redactedArgs,s)),e.outcome,e.errorMessage??null,e.durationMs,Qe(e.tablesRead),Qe(e.tablesWritten),Tr(e.cacheHit),e.subscriptionsReRun??0),F(a,`DELETE FROM "${I}" WHERE seq <= (SELECT MAX(seq) - ? FROM "${I}")`,r)},Ar=(a,e={})=>{const t=e.captureRaw??!1,s={args:a.redactedArgs===void 0?void 0:Z(a.redactedArgs,t),cacheHit:a.cacheHit,durationMs:a.durationMs,error:a.errorMessage,function:a.functionPath,identity:a.identity===void 0?void 0:Z(a.identity,t),outcome:a.outcome,shard:a.shardKey,source:pt,tablesRead:a.tablesRead??[],tablesWritten:a.tablesWritten??[],ts:a.ts,type:"request",userId:a.userId},r=JSON.stringify(s);a.outcome==="error"?console.error(r):console.log(r)},Ir="log",_r=a=>a.map(e=>{if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}).join(" "),kr=a=>{if(typeof a!="object"||a===null||Array.isArray(a))return!1;const e=Object.getPrototypeOf(a);return e===Object.prototype||e===null},Mr=(a,e)=>a.length===2&&typeof a[0]=="string"&&kr(a[1])?{fields:Ae(a[1],e),message:a[0]}:{fields:Ae(void 0,e),message:_r(a)},Nr=a=>{const e={fields:a.fields,function:a.functionPath,level:a.level,message:a.message,shard:a.shardKey,source:pt,spanId:a.spanId,traceId:a.traceId,ts:a.ts,type:Ir,userId:a.userId};let t;try{t=JSON.stringify(e)}catch{t=JSON.stringify({...e,fields:void 0})}a.level==="error"||a.level==="fatal"?console.error(t):a.level==="warn"?console.warn(t):console.log(t)},ye=a=>a.replaceAll(/[\\%_]/g,e=>`\\${e}`),ze=a=>{try{const e=JSON.parse(a);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}catch{return[]}},Cr=(a,e={})=>{W(a);const t=Math.max(1,Math.min(e.limit??Te,1e4)),s=["seq > ?"],r=[e.sinceSeq??0];if(e.functionPathPrefix!==void 0&&e.functionPathPrefix!==""&&(s.push(String.raw`function_path LIKE ? ESCAPE '\'`),r.push(`${ye(e.functionPathPrefix)}%`)),e.userId!==void 0&&e.userId!==""&&(s.push("user_id = ?"),r.push(e.userId)),e.shardKey!==void 0&&e.shardKey!==""&&(s.push("shard_key = ?"),r.push(e.shardKey)),e.outcome!==void 0&&(s.push("outcome = ?"),r.push(e.outcome)),e.tableTouched!==void 0&&e.tableTouched!==""){const n=`%${ye(JSON.stringify(e.tableTouched))}%`;s.push(String.raw`(tables_read LIKE ? ESCAPE '\' OR tables_written LIKE ? ESCAPE '\')`),r.push(n,n)}return r.push(t),F(a,`SELECT seq, ts, function_path, shard_key, user_id, identity, args, outcome, error_message, duration_ms, tables_read, tables_written, cache_hit, subscriptions_rerun
|
|
98
|
-
FROM "${I}" WHERE ${s.join(" AND ")} ORDER BY seq DESC LIMIT ?`,...r).toArray().map(n=>{const i={durationMs:n.duration_ms,functionPath:n.function_path,outcome:n.outcome==="error"?"error":"ok",seq:n.seq,subscriptionsReRun:n.subscriptions_rerun,tablesRead:ze(n.tables_read),tablesWritten:ze(n.tables_written),ts:n.ts};return n.shard_key!==null&&(i.shardKey=n.shard_key),n.user_id!==null&&(i.userId=n.user_id),n.identity!==null&&(i.identity=JSON.parse(n.identity)),n.args!==null&&(i.redactedArgs=JSON.parse(n.args)),n.error_message!==null&&(i.errorMessage=n.error_message),n.cache_hit!==null&&(i.cacheHit=n.cache_hit===1),i})},Or=(a,e)=>{const t=Qs(a,[...e.keys()]);for(const s of e.values()){const r=t.get(s.hash);r!==void 0&&(s.stateUpdatedAt=r.updatedAt,r.assignee!==void 0&&(s.assignee=r.assignee),r.severity!==void 0&&(s.severity=r.severity),s.status=r.status==="resolved"&&s.lastSeen>r.updatedAt?"open":r.status)}},Lr=(a,e={})=>{W(a);const t=Math.max(1,Math.min(e.limit??Te,1e4)),s=["outcome = 'error'"],r=[];e.functionPathPrefix!==void 0&&e.functionPathPrefix!==""&&(s.push(String.raw`function_path LIKE ? ESCAPE '\'`),r.push(`${ye(e.functionPathPrefix)}%`)),e.userId!==void 0&&e.userId!==""&&(s.push("user_id = ?"),r.push(e.userId)),e.shardKey!==void 0&&e.shardKey!==""&&(s.push("shard_key = ?"),r.push(e.shardKey)),r.push(t);const n=F(a,`SELECT function_path, error_message, ts
|
|
99
|
-
FROM "${I}" WHERE ${s.join(" AND ")} ORDER BY seq DESC LIMIT ?`,...r).toArray(),i=new Map,o=new Map;for(const d of n){const u=d.error_message??"",{culprit:l,hash:m,title:p}=as({functionPath:d.function_path,message:u}),g=i.get(m);if(g===void 0){i.set(m,{count:1,culprit:l,firstSeen:d.ts,hash:m,lastSeen:d.ts,sampleMessage:u,status:"open",title:p}),o.set(m,d.ts);continue}g.count+=1,g.firstSeen=Math.min(g.firstSeen,d.ts),g.lastSeen=Math.max(g.lastSeen,d.ts),d.ts>(o.get(m)??Number.NEGATIVE_INFINITY)&&(o.set(m,d.ts),g.sampleMessage=u,g.title=p)}Or(a,i);const c=[...i.values()];return(e.status===void 0?c:c.filter(d=>d.status===e.status)).toSorted((d,u)=>u.lastSeen-d.lastSeen)},Ge=async(a,e,t=8)=>{let s=0;const r=async()=>{let n=a[s];for(s+=1;n!==void 0;){try{await e(n)}catch{}n=a[s],s+=1}};await Promise.all(Array.from({length:Math.min(t,a.length)},()=>r()))};class xr{buffer=[];capacity;constructor(e=500){this.capacity=e>0?Math.trunc(e):500}get size(){return this.buffer.length}clear(){this.buffer.length=0}entries(){return[...this.buffer]}hasTrace(e){return this.buffer.some(t=>t.traceId===e)}push(e){this.buffer.push(e),this.buffer.length>this.capacity&&this.buffer.shift()}}const $r=50,Pr=a=>{const e=new Map;for(const t of a){const s=e.get(t.traceId);s===void 0?e.set(t.traceId,[t]):s.push(t)}return e},qr=(a,e)=>{const t=a.find(r=>r.dispatch===!0);if(t!==void 0)return t;const s=a.toSorted((r,n)=>r.startTs-n.startTs);return s.find(r=>!e.has(r.parentSpanId))??s[0]},Dr=(a,e)=>{const t=new Map([[a.spanId,0]]);return s=>{const r=[],n=new Set;let i=s,o=0;for(;;){const c=t.get(i.spanId);if(c!==void 0){o=c;break}if(n.has(i.spanId))break;n.add(i.spanId),r.push(i);const d=e.get(i.parentSpanId);if(d===void 0)break;i=d}for(const[c,d]of r.toReversed().entries())t.set(d.spanId,o+c+1);return t.get(s.spanId)??o}},Ur=(a,e=$r)=>{const t=Pr(a),s=[...t.entries()].map(([n,i])=>({group:i,startTs:Math.min(...i.map(o=>o.startTs)),traceId:n})).toSorted((n,i)=>i.startTs-n.startTs).slice(0,e),r=[];for(const{group:n,traceId:i}of s){const o=new Map(n.map(p=>[p.spanId,p])),c=qr(n,o);if(c===void 0)continue;const d=Dr(c,o),{startTs:u}=c,l=Math.max(...n.map(p=>p.startTs+p.durationMs)),m=n.map(p=>({...p.attributes===void 0?{}:{attributes:p.attributes},depth:d(p),durationMs:p.durationMs,...p.error===void 0?{}:{error:p.error},name:p.name,offsetMs:Math.max(0,p.startTs-u),ok:p.ok,parentSpanId:p.parentSpanId,spanId:p.spanId})).toSorted((p,g)=>p.offsetMs-g.offsetMs||p.depth-g.depth);r.push({durationMs:l-u,functionPath:c.functionPath,ok:n.every(p=>p.ok),rootName:c.name,...c.shardKey===void 0?{}:{shardKey:c.shardKey},spans:m,startTs:u,traceId:i})}return{total:t.size,traces:r.toSorted((n,i)=>i.startTs-n.startTs)}},je="__doc__",Br=a=>a.startsWith("sqlite_")||a.startsWith("_cf_")||a.startsWith("__miniflare")||a.startsWith("__lunora")||a.includes("__fts_"),ge=a=>`"${a.replaceAll('"','""')}"`,Fr=(a,e)=>Br(e)?!1:a.exec("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1",e).toArray().length>0,Wr=(a,e)=>{const t=e.includes(a),s=e.includes(je);if(!(!t&&!s))return t?{expression:ge(a),params:[]}:{expression:`json_extract(${ge(je)}, ?)`,params:[`$."${a.replaceAll('"','""')}"`]}},Kr=(a,e,t,s,r,n,i)=>{const o=Wr(s,r);if(o===void 0)return;const c=a.exec(`SELECT id, ${o.expression} AS ref FROM ${e} WHERE ${o.expression} IS NOT NULL AND ${o.expression} <> '' LIMIT ?`,...o.params,...o.params,...o.params,5001).toArray();c.length>5e3&&(i.truncated=!0);for(const d of c.slice(0,5e3))if(i.scanned+=1,!n.has(d.ref)){if(i.references.length>=500){i.truncated=!0;continue}i.references.push({column:s,id:d.id,key:d.ref,table:t})}},Hr=(a,e,t)=>{const s=t instanceof Set?t:new Set(t),r={references:[],scanned:0,truncated:!1};for(const[n,i]of Object.entries(e)){if(!Fr(a,n))continue;const o=ge(n),c=a.exec(`PRAGMA table_info(${o})`).toArray().map(d=>d.name);for(const d of i)Kr(a,o,n,d,c,s,r)}return r},Qr="lunora-ping",zr="lunora-pong",Gr=new Set(["1","enabled","on","true","yes"]);let Je=!1,oe;const jr=async()=>{if(!Je){Je=!0;try{const a=(await import("cloudflare:workers")).tracing;oe=a!==null&&typeof a=="object"&&typeof a.enterSpan=="function"?a:void 0}catch{oe=void 0}}return oe},Jr="<undelivered>",Xr=1073741824,Xe=1e4,Yr=864e5,Vr=36e5,G="__root__",b="*",Ye=(a,e)=>(a===void 0?"":`,"cursor":${String(a)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),Zr=(a,e)=>{const[t,s]=a.size<=e.size?[a,e]:[e,a];for(const r of t)if(s.has(r))return!0;return!1},ea=a=>{const e=typeof a.id=="string"?a.id:"";if(e.trim()==="")throw new f("MIGRATION_ID_REQUIRED","runMigration: `id` is required",{status:400});return{batchSize:typeof a.batchSize=="number"?a.batchSize:void 0,direction:a.direction==="down"?"down":"up",dryRun:a.dryRun===!0,id:e,maxBatches:typeof a.maxBatches=="number"?a.maxBatches:void 0}},Ve=jt,ta=200,sa=20,ra=3e4,aa=a=>{const{op:e}=a,t=typeof a.table=="string"?a.table:"";if(e!=="insert"&&e!=="patch"&&e!=="replace"&&e!=="delete")throw new f("BAD_REQUEST","writeRow: `op` must be insert|patch|replace|delete");if(t.trim()==="")throw new f("BAD_REQUEST","writeRow: `table` is required");const s=typeof a.id=="string"?a.id:void 0,r=typeof a.doc=="object"&&a.doc!==null&&!Array.isArray(a.doc)?a.doc:void 0;if(e!=="insert"&&(s===void 0||s===""))throw new f("BAD_REQUEST",`writeRow: \`id\` is required for op "${e}"`);if(e!=="delete"&&r===void 0)throw new f("BAD_REQUEST",`writeRow: \`doc\` is required for op "${e}"`);return{doc:r,id:s,op:e,table:t}},na=a=>typeof a=="string"&&Ks.includes(a),ia=a=>typeof a=="string"&&Hs.includes(a),oa=a=>{const e=typeof a.hash=="string"?a.hash.trim():"";if(e==="")throw new f("BAD_REQUEST","issue triage: `hash` is required");return e},ft=null,ca=a=>{const e=a.assignee;if(e===null)return ft;if(typeof e=="string"&&e.trim()!=="")return e;throw new f("BAD_REQUEST","assignIssue: `assignee` must be a non-empty string (assign) or null (unassign)")},da=a=>{const e=a.severity;if(e===null)return ft;if(ia(e))return e;throw new f("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},ua=a=>{const e=typeof a.exportName=="string"?a.exportName.trim():"";if(e==="")throw new f("BAD_REQUEST","createWorkflowInstance: `exportName` is required");const t=typeof a.id=="string"&&a.id!==""?a.id:void 0;return{exportName:e,id:t,params:a.params}},la=a=>{const e=typeof a.exportName=="string"?a.exportName.trim():"",t=typeof a.id=="string"?a.id.trim():"";if(e==="")throw new f("BAD_REQUEST","getWorkflowInstanceStatus: `exportName` is required");if(t==="")throw new f("BAD_REQUEST","getWorkflowInstanceStatus: `id` is required");return{exportName:e,id:t}},ha=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),Ze=a=>typeof a=="string"&&ha.has(a)?a:"unknown",pa=a=>{if(typeof a!="object"||a===null)return;const{message:e,name:t}=a;return{message:typeof e=="string"?e:"",name:typeof t=="string"?t:"Error"}},fa=new Set(["contains","eq","gt","gte","lt","lte","ne"]),Se=a=>{if(!Array.isArray(a))return;const e=[];for(const t of a){if(typeof t!="object"||t===null)continue;const s=t,{column:r,operator:n}=s;typeof r!="string"||r===""||typeof n!="string"||!fa.has(n)||e.push({column:r,operator:n,value:s.value})}return e.length>0?e:void 0},ma=a=>{if(typeof a!="object"||a===null)return;const{column:e,direction:t}=a;if(!(typeof e!="string"||e===""))return{column:e,direction:t==="desc"?"desc":"asc"}},ya=a=>{const e=typeof a.table=="string"?a.table:"";if(e.trim()==="")throw new f("BAD_REQUEST","deleteRows: `table` is required");return{filters:Se(a.filters),limit:typeof a.limit=="number"?a.limit:void 0,search:typeof a.search=="string"?a.search:void 0,table:e}},ga=a=>{const e=typeof a.table=="string"?a.table:"";if(e.trim()==="")throw new f("BAD_REQUEST","clearTable: `table` is required");return{limit:typeof a.limit=="number"?a.limit:void 0,table:e}},Sa=a=>{const{outcome:e}=a;if(e!=="ok"&&e!=="fail")throw new f("BAD_REQUEST",'recordAuthEvent: `outcome` must be "ok" or "fail"');return{outcome:e}},ba=/\(exit (\d+)\)/,Ea=a=>{const e=a.event;if(typeof e!="object"||e===null||Array.isArray(e))throw new f("BAD_REQUEST","recordContainerEvent: `event` must be an object");const t=e,s=typeof t.container=="string"?t.container:"",r=typeof t.event=="string"?t.event:"";if(s.trim()===""||r.trim()==="")throw new f("BAD_REQUEST","recordContainerEvent: `event.container` and `event.event` are required");const n=t.level==="error"?"error":"info",i=typeof t.message=="string"?t.message:void 0,o=typeof t.ts=="number"?t.ts:Date.now(),c=typeof t.instance=="string"&&t.instance!==""?t.instance:void 0,d=i===void 0?void 0:ba.exec(i)?.[1];return{exitCode:d===void 0?void 0:Number.parseInt(d,10),functionPath:`container:${s}`,instance:c,level:n,message:i===void 0||i===""?r:`${r}: ${i}`,timestamp:o}},wa=a=>{const e=typeof a.functionPath=="string"?a.functionPath:"",t=typeof a.userId=="string"?a.userId:"";if(e.trim()==="")throw new f("BAD_REQUEST","runAs: `functionPath` is required");if(e.startsWith(k))throw new f("BAD_REQUEST","runAs: cannot target a reserved admin function");if(t.trim()==="")throw new f("BAD_REQUEST","runAs: `userId` is required");const s=a.args;if(s!==void 0&&(typeof s!="object"||s===null||Array.isArray(s)))throw new f("BAD_REQUEST","runAs: `args` must be an object");const r=a.identity;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new f("BAD_REQUEST","runAs: `identity` must be an object");return{args:s===void 0?{}:s,functionPath:e,userId:t,...r===void 0?{}:{identity:r}}},Ra=a=>{const e=p=>{throw new f("BAD_REQUEST",`recordMail: ${p}`)},{bcc:t,cc:s,from:r,headers:n,html:i,replyTo:o,subject:c,text:d,to:u}=a;typeof c!="string"&&e("`subject` must be a string"),typeof u=="string"||Array.isArray(u)&&u.every(p=>typeof p=="string")||e("`to` must be a string or string[]");const l=(p,g)=>{if(p!==void 0)return(!Array.isArray(p)||!p.every(E=>typeof E=="string"))&&e(`\`${g}\` must be a string[]`),p},m=(p,g)=>(p!==void 0&&typeof p!="string"&&e(`\`${g}\` must be a string`),p);return{bcc:l(t,"bcc"),cc:l(s,"cc"),from:m(r,"from"),headers:n!==void 0&&typeof n=="object"&&n!==null?n:void 0,html:m(i,"html"),replyTo:m(o,"replyTo"),subject:c,text:m(d,"text"),to:u}},Ta="test@lunora.sh",va=a=>{const{to:e}=a;if(e!==void 0&&typeof e!="string")throw new f("BAD_REQUEST","sendTestMail: `to` must be a string");const t=e??Ta,s="https://example.test/verify?token=demo";return{from:"Lunora <noreply@lunora.sh>",html:`<p>This is a test email from the Lunora dev mail catcher.</p><p><a href="${s}">Verify your email</a></p>`,subject:"Lunora test email",text:`This is a test email from the Lunora dev mail catcher.
|
|
100
|
-
|
|
101
|
-
Verify your email: ${s}`,to:t}},Aa=a=>{const e=r=>{throw new f("BAD_REQUEST",`recordQueueMessage: ${r}`)},t=a.messages;Array.isArray(t)||e("`messages` must be an array");const s=new Set(["ack","error","retry"]);return t.map((r,n)=>{(typeof r!="object"||r===null)&&e(`\`messages[${String(n)}]\` must be an object`);const i=r,o=typeof i.messageId=="string"?i.messageId:"",c=typeof i.queue=="string"?i.queue:"",d=typeof i.outcome=="string"?i.outcome:"";o===""&&e(`\`messages[${String(n)}].messageId\` is required`),c===""&&e(`\`messages[${String(n)}].queue\` is required`),s.has(d)||e(`\`messages[${String(n)}].outcome\` must be one of ack | error | retry`);const{attempts:u,timestamp:l}=i;return{attempts:typeof u=="number"&&Number.isFinite(u)?u:1,body:i.body,deadLettered:i.deadLettered===!0,error:typeof i.error=="string"?i.error:void 0,exportName:typeof i.exportName=="string"?i.exportName:void 0,messageId:o,outcome:d,queue:c,timestamp:typeof l=="number"&&Number.isFinite(l)?l:0}})},et=100,R=a=>`${a.traceId}:${a.rootSpanId}`,ce=256,de="lunora.dispatch",Ia=a=>{const e=typeof a.exportName=="string"?a.exportName.trim():"";if(e==="")throw new f("BAD_REQUEST","sendQueueMessage: `exportName` is required");const t=a.delaySeconds;if(t!==void 0&&(typeof t!="number"||!Number.isFinite(t)||t<0))throw new f("BAD_REQUEST","sendQueueMessage: `delaySeconds` must be a non-negative number");const s=Array.isArray(a.batch)?a.batch:void 0;if(s!==void 0&&(s.length===0||s.length>et))throw new f("BAD_REQUEST",`sendQueueMessage: \`batch\` must contain between 1 and ${String(et)} messages`);return{batch:s,body:a.body,contentType:typeof a.contentType=="string"?a.contentType:void 0,delaySeconds:t,exportName:e}},_a=a=>{const e=typeof a.id=="string"?a.id.trim():"";if(e==="")throw new f("BAD_REQUEST","replayQueueMessage: `id` is required");const t=typeof a.target=="string"&&a.target.trim()!==""?a.target.trim():void 0;return{id:e,target:t}},ka=a=>{const e=typeof a.table=="string"?a.table:"",t=typeof a.index=="string"?a.index:"",s=typeof a.rowId=="string"?a.rowId:"";if(e.trim()==="")throw new f("BAD_REQUEST","rankBefore: `table` is required");if(t.trim()==="")throw new f("BAD_REQUEST","rankBefore: `index` is required");if(typeof a.partitionKey!="string")throw new f("BAD_REQUEST","rankBefore: `partitionKey` must be a string");if(s.trim()==="")throw new f("BAD_REQUEST","rankBefore: `rowId` is required");if(!Array.isArray(a.sortValues))throw new f("BAD_REQUEST","rankBefore: `sortValues` must be an array");return{index:t,partitionKey:a.partitionKey,rowId:s,sortValues:a.sortValues,table:e}},N=a=>{throw new f("BAD_REQUEST",a)},tt=(a,e)=>((typeof a!="string"||a.trim()==="")&&N(`rankPage: \`${e}\` is required`),a),Ma=a=>{if(a===void 0)return;(typeof a!="object"||a===null||Array.isArray(a))&&N("rankPage: `after` must be an object");const e=a;return(typeof e.partitionKey!="string"||typeof e.rowId!="string"||!Array.isArray(e.sortValues))&&N("rankPage: `after` must have a string partitionKey, string rowId, and array sortValues"),{partitionKey:e.partitionKey,rowId:e.rowId,sortValues:e.sortValues}},Na=a=>{const e=tt(a.table,"table"),t=tt(a.index,"index");a.take!==void 0&&typeof a.take!="number"&&N("rankPage: `take` must be a number"),a.cursor!==void 0&&a.cursor!==null&&typeof a.cursor!="string"&&N("rankPage: `cursor` must be a string or null"),a.partitionKey!==void 0&&typeof a.partitionKey!="string"&&N("rankPage: `partitionKey` must be a string"),a.directions!==void 0&&!Array.isArray(a.directions)&&N("rankPage: `directions` must be an array");const s=a.directions===void 0?void 0:a.directions.map(r=>r==="desc"?"desc":"asc");return{after:Ma(a.after),cursor:typeof a.cursor=="string"?a.cursor:void 0,directions:s,index:t,partitionKey:typeof a.partitionKey=="string"?a.partitionKey:void 0,take:typeof a.take=="number"?a.take:void 0,table:e}},Ca=a=>{try{const e=JSON.parse(a);if(Array.isArray(e)&&typeof e[0]=="string"&&typeof e[1]=="string")return{index:e[1],table:e[0]}}catch{}},Oa=a=>{const e=a.changes;if(!Array.isArray(e))throw new f("BAD_REQUEST","applyCdc: `changes` must be an array");return{changes:e.map((t,s)=>{const r=t,{op:n}=r,i=typeof r.table=="string"?r.table:"",o=typeof r.id=="string"?r.id:"";if(i===""||o===""||n!=="insert"&&n!=="update"&&n!=="delete")throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}] must have a table, id, and op of insert|update|delete`);const c=r.doc;if(c!==void 0&&(typeof c!="object"||c===null||Array.isArray(c)))throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}].doc must be an object`);const d=c;if(d!==void 0&&typeof d._id=="string"&&d._id!==o)throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}].doc._id must match the entry id`);return{doc:d,id:o,op:n,seq:typeof r.seq=="number"?r.seq:0,table:i,ts:typeof r.ts=="number"?r.ts:0}})}},La=a=>{const e=t=>{const s=typeof t=="number"?t:Number(t);return Number.isFinite(s)&&s>=0?Math.floor(s):void 0};return{limit:e(a.limit),sinceSeq:e(a.sinceSeq)??0}},_=a=>a?{"x-d1-bookmark":a}:void 0,st=a=>{if(a)try{const e=JSON.parse(a);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}},xa=a=>{if(!a)return;const e=Number(a);return Number.isInteger(e)&&e>0?e:void 0},$a=a=>{const e=new Set;for(const t of a){const s=Ot(t);s!==""&&e.add(s)}return e},Pa=a=>{if(a===void 0)return;const e=Number.parseInt(a,10);return Number.isFinite(e)&&e>0?e:void 0},qa=(a,e)=>a==="1"||a==="true"?!0:a==="0"||a==="false"?!1:e,Da=a=>{if(a===void 0)return 1;const e=Number.parseFloat(a);return Number.isFinite(e)?Math.min(1,Math.max(0,e)):1},Ua=a=>a>=1?!0:a<=0?!1:Math.random()<a,ue=a=>{if(!a)return;const[e,...t]=a.split(" ");if(e?.toLowerCase()!=="bearer")return;const s=t.join(" ").trim();return s.length>0?s:void 0};class S{static MAX_STREAMS_PER_SOCKET=8;static MAX_SUBSCRIPTIONS_PER_SOCKET=32;static GLOBAL_SHAPE_POLL_INTERVAL_MS=2e3;static GLOBAL_SHAPE_MAX_ROWS=5e4;static MAX_WHISPER_TOPICS_PER_SOCKET=64;static MAX_WHISPER_BYTES=4096;static WHISPER_RATE_BURST=50;static WHISPER_RATE_PER_SEC=25;static rootSizeWarned=!1;static resetRootSizeWarning(){S.rootSizeWarned=!1}static nextPollAlarmTarget(e,t,s,r){const n=[e>0?r+S.GLOBAL_SHAPE_POLL_INTERVAL_MS:void 0,t,s].filter(i=>i!==void 0).map(i=>Math.max(i,r));return n.length>0?Math.min(...n):void 0}state;env;reactiveCache;drizzleHandle;transactionDepth=0;currentRequestBookmark;currentResponseBookmark;currentRequestUserId;currentRequestIp;currentRequestTraceparent;currentRequestTrace;traceSampling=new Map;dispatchSpans=new Map;lastTelemetrySink;currentRequestMutationId;currentRequestClientId;currentRequestClientSeq;currentMutatorClass;mutationBookkeepingCommitted=!1;lastIdempotencyTrimAt=0;currentRequestIdentity;currentRequestSystem=!1;pendingChangedTables=void 0;pendingRefreshTables=void 0;refreshInFlight=!1;subMemos=new WeakMap;shapeMemos=new WeakMap;globalShapeSnapshots=new WeakMap;globalPollScheduled=!1;pokeSequence=0;whisperBuckets=new WeakMap;streamCancellers=new WeakMap;metrics={errors:0,requests:0,sinceMs:Date.now()};fanout={shapePoke:_e(),whisper:_e()};shardBinding;relay;usedIndexes=new Set;functionStats=new Map;logs=new Jt;spans=new xr;metricSeries=new Gs;currentTracker;currentScannedTables;currentIndexHits;currentRequestReadTables;currentStmtSamples;currentRequestCacheHit;constructor(e,t,s={}){this.state=e,this.env=t,s.reactiveCache&&(this.reactiveCache=new ts(s.reactiveCache));const r={buildShapeDiff:(n,i,o)=>this.buildShapeDiff(this.sql,n,i,o),computeOpLogShapeSeed:(n,i)=>this.computeOpLogShapeSeed(n,i),currentCdcEpoch:()=>this.currentCdcEpoch(),deliverWhisperLocal:(n,i,o)=>this.deliverWhisperLocal(n,i,o),doName:()=>this.state.id?.name,env:()=>this.env,getWebSockets:()=>this.state.getWebSockets(),maskMetadata:()=>this.maskMetadata(),nextPokeId:()=>(this.pokeSequence+=1,`poke-${String(this.pokeSequence)}`),readAttachment:n=>this.readAttachment(n),recordShapePokeFanout:(n,i,o)=>{this.fanout.shapePoke=se(this.fanout.shapePoke,n,i,o)},resolveShape:(n,i,o)=>this.resolveShape(n,i,o),rlsMetadata:()=>this.rlsMetadata(),shardBinding:()=>this.shardBinding,sql:()=>this.sql};this.relay=Rr(r),this.armWebSocketKeepalive()}async fetch(e){const t=new URL(e.url);this.shardBinding=e.headers.get("x-lunora-shard-binding")??this.shardBinding;const s=await this.routeNonRpc(t,e);if(s!==void 0)return s;if(t.pathname!=="/rpc"||e.method!=="POST")return new Response("Not found",{status:404});let r;try{r=await e.json()}catch{return y({error:{code:"BAD_REQUEST",message:"invalid JSON body"}},400)}if(r.functionPath.startsWith(k))return this.handleAdminRpc(e,r.functionPath,r.args??{});this.currentRequestBookmark=e.headers.get("x-d1-bookmark")??void 0,this.currentResponseBookmark=void 0,this.currentRequestUserId=e.headers.get("x-lunora-userid")??void 0,this.currentRequestMutationId=e.headers.get("x-lunora-mutation-id")??void 0,this.currentRequestClientId=e.headers.get("x-lunora-client-id")??void 0,this.currentRequestClientSeq=xa(e.headers.get("x-lunora-client-seq")),this.currentMutatorClass=void 0,this.mutationBookkeepingCommitted=!1,this.currentRequestIdentity=st(e.headers.get("x-lunora-identity")),this.currentRequestIp=e.headers.get("x-lunora-client-ip")??void 0,this.currentRequestSystem=e.headers.get("x-lunora-system")==="1",this.currentRequestTraceparent=e.headers.get("traceparent")??void 0,this.currentRequestTrace=K(this.currentRequestTraceparent);const n=this.currentRequestTrace;this.traceSampling.set(n.traceId,{keepErrors:e.headers.get("x-lunora-sample-errors")!=="0",sampled:bt(this.currentRequestTraceparent)?.sampled??!0}),this.currentRequestReadTables=void 0,this.currentRequestCacheHit=void 0,this.metrics.requests+=1;const i=Date.now();this.currentScannedTables=new Set,this.currentIndexHits=new Set,this.currentStmtSamples=[];let o;try{if(r.functionPath.startsWith(Ut)){const E=await this.runRelationFanoutRead(r.functionPath,r.args??{});return y(E,200,_(this.currentResponseBookmark))}const c=this.isCustomMutator(r.functionPath)?this.classifyClientMutation():void 0;this.currentMutatorClass=c;const d=this.rejectNonNextMutation(r.functionPath,c,i);if(d!==void 0)return d;const u=this.readIdempotentResult(this.currentRequestMutationId);if(u!==void 0)return this.respondFromIdempotencyCache(r.functionPath,i,c,u.value);const l=await this.handleRpc(r.functionPath,O(r.args??{}));this.recordPostDispatchBookkeeping(l,c),c?.kind==="next"&&this.advanceClientMutationWatermark();const m=Date.now()-i;this.recordFunctionCall(r.functionPath,m,void 0,this.currentScannedTables,this.currentIndexHits),this.flushStmtSamples();const p=[...this.pendingChangedTables??[]];this.recordRequestLog(r.functionPath,r.args??{},m,"ok",p),this.maybeWarnRootSize();const g=this.buildDispatchResponse(c,w(l));return await this.flushChangedTables(),g}catch(c){this.metrics.errors+=1,o={thrown:c};const d=Date.now()-i,u=c instanceof Error?c.message:String(c),l=c instanceof us&&c.kind==="occ";return c?.code!=="FUNCTION_NOT_FOUND"&&this.recordFunctionCall(r.functionPath,d,u,this.currentScannedTables,this.currentIndexHits,l),this.flushStmtSamples(),this.recordRequestLog(r.functionPath,r.args??{},d,"error",[...this.pendingChangedTables??[]],u),this.logs.push({functionPath:r.functionPath,level:"error",message:u,timestamp:Date.now()}),this.recordChangedTable(I),await this.flushChangedTables(),this.errorToResponse(c)}finally{const c=this.dispatchSpans.get(R(n));if((this.spans.hasTrace(n.traceId)||c?.collector!==void 0)&&this.recordDispatchRootSpan(r.functionPath,i,o,n),this.dispatchSpans.delete(R(n)),c?.sink?.flush)try{c.sink.flush({waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}this.flushSampledOutTrace(n,o!==void 0),this.traceSampling.delete(n.traceId),this.currentRequestTrace=void 0,this.currentRequestBookmark=void 0,this.currentResponseBookmark=void 0,this.currentRequestUserId=void 0,this.currentRequestMutationId=void 0,this.currentRequestClientId=void 0,this.currentRequestClientSeq=void 0,this.currentMutatorClass=void 0,this.mutationBookkeepingCommitted=!1,this.currentRequestIdentity=void 0,this.currentRequestIp=void 0,this.currentRequestSystem=!1,this.currentRequestTraceparent=void 0,this.currentScannedTables=void 0,this.currentIndexHits=void 0,this.currentRequestReadTables=void 0,this.currentRequestCacheHit=void 0,this.currentStmtSamples=void 0}}async webSocketMessage(e,t){return this.handleWebSocketMessage(e,t)}async webSocketClose(e,t,s,r){const n=this.readAttachment(e);n.connectionId!==void 0&&await this.dispatchLifecycle("disconnect",this.lifecycleInfo(n));const i=this.streamCancellers.get(e);if(i){for(const o of i.values())o.abort();this.streamCancellers.delete(e)}if(this.subMemos.delete(e),this.shapeMemos.delete(e),this.globalShapeSnapshots.delete(e),n.connectionId!==void 0)try{hs(this.sql,n.connectionId)}catch{}e.serializeAttachment?.(void 0),await this.relay?.announceDrain(e)}webSocketError(e,t){}async alarm(){return this.withTriggerTrace("alarm",async()=>this.handleAlarmBody())}lifecycleHookPaths(e){return[]}async dispatchLifecycle(e,t){for(const s of this.lifecycleHookPaths(e))try{await this.withRequestIdentity(t.userId,t.identity,()=>this.withSystemDispatch(()=>this.handleRpc(s,t.event)))}catch(r){this.logs.push({functionPath:s,level:"error",message:r instanceof Error?r.message:String(r),timestamp:Date.now()})}}runRelationFanoutRead(e,t){throw new f("NOT_IMPLEMENTED","__lunora_relation__: no schema bound — the base ShardDO cannot serve cross-shard relation reads",{status:500})}get sql(){const e=this.state.storage.sql,t=this.currentStmtSamples;if(t===void 0)return e;const s=e.exec;if(typeof s!="function")return e;const r=(n,...i)=>{const o=Date.now(),c=s.call(e,n,...i);if(c!==null&&typeof c=="object"){const d=c;if(typeof d.toArray=="function"){const u=d.toArray.bind(d);d.toArray=()=>{const l=u(),m=Date.now()-o;return t.push([n,m,l.length,0]),l}}if(typeof d.one=="function"){const u=d.one.bind(d);d.one=()=>{const l=u(),m=Date.now()-o;return t.push([n,m,1,0]),l}}if(typeof d.toArray!="function"&&typeof d.one!="function"){const u=Date.now()-o;t.push([n,u,0,0])}}else{const d=Date.now()-o;t.push([n,d,0,0])}return c};return new Proxy(e,{get(n,i){return i==="exec"?r:Reflect.get(n,i,n)}})}get db(){return this.drizzleHandle?this.drizzleHandle:(this.drizzleHandle=yt(this.state.storage,{logger:!1}),this.drizzleHandle)}async runInTransaction(e){if(this.transactionDepth>0)throw new f("NESTED_TRANSACTION","nested transactions are not supported in SQLite-in-DO",{status:500});const t=this.state.storage.sql;if(!t||typeof t.exec!="function")throw new f("SQL_UNAVAILABLE","storage.sql is not available on this ShardDO state",{status:500});const s=this.state.storage,r=async()=>{this.transactionDepth=1;try{return typeof s?.transaction=="function"?await s.transaction(async()=>e()):await e()}finally{this.transactionDepth=0}};return typeof this.state.blockConcurrencyWhile=="function"?this.state.blockConcurrencyWhile(r):r()}getInboundBookmark(){return this.currentRequestBookmark}setOutboundBookmark(e){this.currentResponseBookmark=e}getCurrentUserId(){return this.currentRequestUserId}getCurrentIp(){return this.currentRequestIp}getCurrentTraceparent(){return this.currentRequestTraceparent}getCurrentTrace(){return this.currentRequestTrace}getCurrentIdentity(){return this.currentRequestIdentity}isSystemDispatch(){return this.currentRequestSystem}runShardDataMigration(e){return Promise.reject(new f("MIGRATION_NOT_FOUND",`data migration "${e.id}" is not registered`,{status:404}))}ensureMigrated(){}tableRefs(e){}tableIndexes(e){return[]}tableColumns(e){return[]}storageColumns(){return{}}advisories(){return[]}rlsMetadata(){return{policies:[],roles:[]}}maskMetadata(){return{columns:[]}}storageRulesMetadata(){return{rules:[]}}studioFeatures(){return{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1}}evaluateFlags(e){return Promise.resolve({configured:!1,flags:[]})}runFlagSubscriptionRead(e,t,s){return Promise.resolve(null)}queuesMetadata(){return{queues:[]}}workflowsMetadata(){return{workflows:[]}}runtimeAdvisories(){const e=new Set([...this.usedIndexes].map(s=>s.slice(0,s.indexOf(":")))),t=[];for(const s of e)for(const r of this.tableIndexes(s))r.type==="vector"||this.usedIndexes.has(`${s}:${r.name}`)||t.push({cacheKey:`unused_index:${s}:${r.name}`,categories:["PERFORMANCE"],description:"A declared index has not been exercised by any query since this shard instance started. An unused index costs storage and is maintained on every write for no read benefit.",detail:`Index "${r.name}" on table "${s}" has not been used since this instance woke, though other indexes on "${s}" have — it may be redundant.`,facing:"INTERNAL",level:"INFO",metadata:{index:r.name,indexKind:r.type,since:"instance-woke",table:s},name:"unused_index",remediation:"Confirm over a representative window, then drop the index if no query needs it.",title:"Unused index"});return t}runShardExport(e){return Promise.resolve([])}runShardImport(e){return Promise.resolve({conflicts:0,errors:[],inserted:{}})}runShardWrite(e){return Promise.reject(new f("UNKNOWN_TABLE",`unknown table: ${e.table}`,{status:404}))}deleteRowThroughWriter(e,t){return Promise.reject(new f("UNKNOWN_TABLE",`unknown table: ${e}`,{status:404}))}async runShardBulkDelete(e){const t=Math.min(Math.max(Math.trunc(e.limit??Ve),1),Ve),{hasMore:s,ids:r}=Bt(this.sql,{filters:e.filters,limit:t,search:e.search,table:e.table});let n=0;for(const i of r)await this.deleteRowThroughWriter(e.table,i),n+=1;return{deleted:n,hasMore:s}}runShardRankBefore(e){return Promise.reject(new f("NOT_IMPLEMENTED","rankBefore is not implemented in base ShardDO",{status:500}))}runShardRankPage(e){return Promise.reject(new f("NOT_IMPLEMENTED","rankPage is not implemented in base ShardDO",{status:500}))}runShardCdcSync(e){const t=this.sql;return t.exec("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?",Ce).toArray().length>0?ae(t,{limit:e.limit,sinceSeq:e.sinceSeq}):{changes:[],cursor:e.sinceSeq}}currentCdcCursor(){return this.cdcEnabled()?Oe(this.sql):void 0}currentCdcEpoch(){return this.cdcEnabled()?Le(this.sql):void 0}evaluateResume(e,t,s){const r=this.sql;if(!this.cdcEnabled())return{cursor:void 0,epoch:void 0,resumable:!1};const n=Oe(r),i=Le(r);if(s!==i)return{cursor:n,epoch:i,resumable:!1};if(e>n)return{cursor:n,epoch:i,resumable:!1};if(e===n)return{cursor:n,epoch:i,resumable:!0};const o=xe(r);if(o===void 0||o>e+1)return{cursor:n,epoch:i,resumable:!1};if(t.size===0)return{cursor:n,epoch:i,resumable:!1};const{changes:c}=ae(r,{limit:Xe,sinceSeq:e});if(c.length>=Xe)return{cursor:n,epoch:i,resumable:!1};const d=c.some(u=>t.has(u.table));return{cursor:n,epoch:i,resumable:!d}}readIdempotentResult(e){if(e!==void 0)try{const t=ps(this.sql,this.currentRequestUserId??"",e);return t===void 0?void 0:{value:JSON.parse(t.resultJson)}}catch{return}}persistIdempotentResult(e){if(this.currentRequestMutationId===void 0)return;const t=Date.now();try{fs(this.sql,this.currentRequestUserId??"",this.currentRequestMutationId,JSON.stringify(w(e)),t),t-this.lastIdempotencyTrimAt>Vr&&(ms(this.sql,t-Yr),this.lastIdempotencyTrimAt=t)}catch{}}isCustomMutator(e){return!1}classifyClientMutation(){const e=this.currentRequestClientId,t=this.currentRequestClientSeq;if(e===void 0||t===void 0)return;const s=this.currentRequestUserId??"";let r;try{r=re(this.sql,s,e)}catch{try{ys(this.sql),r=re(this.sql,s,e)}catch{return}}const n=r+1;return t<=r?{expected:n,kind:"already"}:t===n?{expected:n,kind:"next"}:{expected:n,kind:"gap"}}rejectNonNextMutation(e,t,s){if(!(t===void 0||t.kind==="next"))return this.recordFunctionCall(e,Date.now()-s,void 0,this.currentScannedTables,this.currentIndexHits),t.kind==="already"?y({lastMutationId:t.expected-1,result:null},200,_(this.currentResponseBookmark)):y({error:{code:"OUT_OF_ORDER",expectedMutationId:t.expected,message:`out-of-order mutation; expected sequence ${String(t.expected)}`}},409,_(this.currentResponseBookmark))}respondFromIdempotencyCache(e,t,s,r){if(this.recordFunctionCall(e,Date.now()-t,void 0,this.currentScannedTables,this.currentIndexHits),s?.kind==="next")return this.advanceClientMutationWatermark(),this.buildDispatchResponse(s,r);const n=this.mutationCommitCursor();return y(n===void 0?{result:r}:{commitCursor:n,result:r},200,_(this.currentResponseBookmark))}mutationCommitCursor(){return this.currentRequestMutationId===void 0?void 0:this.currentCdcCursor()}buildDispatchResponse(e,t){if(e?.kind==="next")return y({lastMutationId:this.currentRequestClientSeq,result:t},200,_(this.currentResponseBookmark));const s=this.mutationCommitCursor();return y(s===void 0?{result:t}:{commitCursor:s,result:t},200,_(this.currentResponseBookmark))}commitMutationBookkeeping(e){this.persistIdempotentResult(e),this.currentMutatorClass?.kind==="next"&&this.advanceClientMutationWatermark({strict:!0}),this.mutationBookkeepingCommitted=!0}recordPostDispatchBookkeeping(e,t){this.mutationBookkeepingCommitted||(this.persistIdempotentResult(e),t?.kind==="next"&&this.advanceClientMutationWatermark())}advanceClientMutationWatermark(e){const t=this.currentRequestClientId,s=this.currentRequestClientSeq;if(!(t===void 0||s===void 0))try{gs(this.sql,this.currentRequestUserId??"",t,s)}catch(r){if(e?.strict)throw r}}runShardApplyCdc(e){return Promise.reject(new f("NOT_IMPLEMENTED","applyCdc is not implemented in base ShardDO",{status:500}))}subscribe(e,t,s){const r=this.readAttachment(e);if(Object.keys(r.subs).length>=S.MAX_SUBSCRIPTIONS_PER_SOCKET)return"too_many";r.subs[t]=s;try{e.serializeAttachment?.(r)}catch{return delete r.subs[t],"serialize_failed"}return"ok"}unsubscribe(e,t){const s=this.readAttachment(e),r=s.subs[t];delete s.subs[t];try{e.serializeAttachment?.(s)}catch{r!==void 0&&(s.subs[t]=r);return}this.subMemos.get(e)?.delete(t)}shapeSubscribe(e,t,s){const r=this.readAttachment(e),n=r.shapes??{};if(Object.keys(r.subs).length+Object.keys(n).length>=S.MAX_SUBSCRIPTIONS_PER_SOCKET)return"too_many";n[t]=s,r.shapes=n;try{e.serializeAttachment?.(r)}catch{return delete r.shapes[t],"serialize_failed"}return"ok"}shapeUnsubscribe(e,t){const s=this.readAttachment(e),{shapes:r}=s;if(!r)return;const n=r[t];delete r[t];try{e.serializeAttachment?.(s)}catch{n!==void 0&&(r[t]=n);return}if(this.shapeMemos.get(e)?.delete(t),this.globalShapeSnapshots.get(e)?.delete(t),s.connectionId!==void 0)try{Ss(this.sql,s.connectionId,t)}catch{}}matchesSubscription(e,t){if(e.table!==t.table)return!1;const{args:s}=e;if(!s)return!0;const{row:r}=t;if(!r)return!0;for(const[n,i]of Object.entries(s))if(r[n]!==i)return!1;return!0}broadcastDelta(e){const t=this.state.getWebSockets(),s=JSON.stringify(e);for(const r of t){const n=this.readAttachment(r);for(const[i,o]of Object.entries(n.subs))this.matchesSubscription(o,e)&&L(r,`{"type":"delta","id":${JSON.stringify(i)},"delta":${s}}`)}}executeSubscription(e,t,s){return Promise.resolve(null)}resolveShape(e,t,s){}isShapeRelayUniform(e,t){return this.relay?.isShapeRelayUniform(e,t)??!1}readGlobalShapeRows(e,t){return Promise.resolve([])}pollExternalSources(){return Promise.resolve(void 0)}scheduleSourcePoll(){return this.scheduleGlobalPoll()}ttlSweeps(){return[]}async pollTtlSweeps(){const e=this.ttlSweeps();if(e.length===0)return;const t=this.sql,s=Date.now();for(const r of e){let n=0,i=!0;for(;i&&n<sa;){const o=ls(t,r,s,ta);for(const c of o.ids)await this.deleteRowThroughWriter(r.table,c);i=o.hasMore,n+=1}}return s+ra}scheduleTtlSweep(){return this.scheduleGlobalPoll()}currentShardKey(){return this.state.id?.name??G}recordExternalSourceError(e,t){this.recordShapeError(`source:${e}`,t)}executeStream(e,t){return null}async runCachedQuery(e,t,s){if(!this.reactiveCache)return s();const r=this.currentTracker,n=Ct();this.currentTracker=n;const i=this.reactiveCache.stats().hits,o=this.getCurrentUserId(),c=this.getCurrentIdentity(),d=o===void 0&&c===void 0?null:be({claims:c??null,userId:o??null});try{const u=await this.reactiveCache.run(Me(e,t,d),n.collect(),s);return this.currentRequestCacheHit=this.reactiveCache.stats().hits>i,this.currentRequestReadTables=$a(n.collect()),u}finally{this.currentTracker=r}}getCtxDbReadHook(){return(e,t)=>{this.currentTracker?.recordRead(e,t??Ie),t===Ie&&this.currentScannedTables?.add(e)}}getCtxDbIndexUseHook(){return(e,t)=>{this.usedIndexes.add(`${e}:${t}`),this.currentIndexHits?.add(JSON.stringify([e,t]))}}recordChangedTable(e){this.pendingChangedTables??=new Set,this.pendingChangedTables.add(e)}async flushMigrationProgress(){this.recordChangedTable(Mt),await this.flushChangedTables()}recordUserLog(e,t,s,r,n,i,o,c){const d=c??this.currentRequestTrace,u={args:s,...o===void 0?{}:{eventName:o},fields:n,functionPath:e,level:t,message:r,shardKey:this.state.id?.name,spanId:d?.rootSpanId,traceId:d?.traceId,ts:Date.now(),userId:this.getCurrentUserId()};this.logs.push({fields:n,functionPath:e,level:t,message:r,timestamp:u.ts});try{Nr(u)}catch{}if(i?.onLog)try{i.onLog(u,{waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}makeLogger(e,t,s){const r=(n,i)=>{const{fields:o,message:c}=Mr(i,s);this.recordUserLog(e,n,i,c,o,t)};return{debug:(...n)=>{r("debug",n)},error:(...n)=>{r("error",n)},event:(n,i)=>{this.recordUserLog(e,"info",[n],n,s?{...s,...i}:i,t,n)},fatal:(...n)=>{r("fatal",n)},info:(...n)=>{r("info",n)},log:(...n)=>{r("log",n)},trace:(...n)=>{r("trace",n)},warn:(...n)=>{r("warn",n)},with:n=>this.makeLogger(e,t,s?{...s,...n}:n)}}makeTracer(e,t,s){return Et({anchor:s??K(void 0),fuseCloudflareSpans:t?.fuseCloudflareTraces===!0,functionPath:e,record:r=>{this.recordSpan(r,t)},resolveCloudflareTracing:jr,shardKey:this.state.id?.name,userId:()=>this.getCurrentUserId()})}resolveDispatchAnchor(e){return(e?void 0:this.getCurrentTrace())??K(void 0)}instrumentDb(e,t,s,r){const n=r===void 0?"off":r.instrumentDatabase??"summary";return n==="off"?e:Bs(e,{anchor:s,functionPath:t,mode:n,record:i=>{this.recordSpan(i,r)},shardKey:this.state.id?.name,tally:this.dispatchTally(s),userId:()=>this.getCurrentUserId()})}makeFetch(e,t,s){const r=(n,i)=>globalThis.fetch(n,i);return s===void 0||s.traceFetch===!1?r:wt({anchor:t,functionPath:e,...typeof s.traceFetch=="object"&&s.traceFetch.propagate!==void 0?{propagate:s.traceFetch.propagate}:{},record:n=>{this.recordSpan(n,s)},shardKey:this.state.id?.name,userId:()=>this.getCurrentUserId()},r)}makeDispatchSpan(e,t){this.lastTelemetrySink=t??this.lastTelemetrySink,t!==void 0&&(J(this.dispatchSpans,ce),this.dispatchSpans.set(R(e),this.dispatchSpans.get(R(e))??{sink:t}));const s=()=>{J(this.dispatchSpans,ce);const r=R(e),n=this.dispatchSpans.get(r)??{sink:t};return n.collector??=vt({spanId:e.rootSpanId,traceId:e.traceId}),this.dispatchSpans.set(r,n),n.collector};return{addEvent:(r,n)=>{s().handle.addEvent(r,n)},spanContext:()=>({spanId:e.rootSpanId,traceId:e.traceId}),addLink:r=>{s().handle.addLink(r)},recordException:r=>{s().handle.recordException(r)},setAttribute:(r,n)=>{s().handle.setAttribute(r,n)},setAttributes:r=>{s().handle.setAttributes(r)}}}makeMetrics(e,t){return Rt({functionPath:e,record:s=>{this.recordMetric(s,t)},shardKey:this.state.id?.name})}recordMetric(e,t){const s=this.currentRequestTrace?.traceId,r=s===void 0?e:{...e,traceId:s},n=o=>{try{o()}catch{}};n(()=>{this.metricSeries.push(r)});const i=this.state.storage.sql;n(()=>{Zs(i,r,s)}),t?.onMetric&&n(()=>t.onMetric?.(r,{waitUntil:this.state.waitUntil?.bind(this.state)}))}async handleWebSocketMessage(e,t){if(this.isSocketExpired(e)){this.dropExpiredSocket(e);return}const s=typeof t=="string"?t:new TextDecoder().decode(t);let r;try{r=JSON.parse(s)}catch{e.send(JSON.stringify({message:"invalid envelope",type:"error"}));return}if(r.type==="connect"){const n=this.readAttachment(e);if(n.connected===!0)return;r.context!==void 0&&(n.context=r.context),r.clientId!==void 0&&(n.clientId=r.clientId),n.connected=!0;try{e.serializeAttachment?.(n)}catch{}await this.dispatchLifecycle("connect",this.lifecycleInfo(n));return}if(r.type==="subscribe"&&r.query){const{functionPath:n}=r.query,i=n?.startsWith(k)===!0;if(i&&this.readAttachment(e).admin!==!0){e.send(JSON.stringify({id:r.id,message:"admin subscription requires admin authorization",type:"error"}));return}let o;try{o=r.query.args===void 0?r.query:{...r.query,args:O(r.query.args)}}catch{try{e.send(JSON.stringify({code:"BAD_SUBSCRIPTION_ARGS",error:{code:"BAD_SUBSCRIPTION_ARGS",message:"subscription args failed wire decoding"},id:r.id,type:"error"}))}catch{}return}const c=this.subscribe(e,r.id,o);if(c!=="ok"){const d=c==="too_many"?"TOO_MANY_SUBSCRIPTIONS":"SUBSCRIPTION_PERSIST_FAILED",u=c==="too_many"?`subscription cap of ${String(S.MAX_SUBSCRIPTIONS_PER_SOCKET)} reached on this socket`:"failed to persist subscription attachment";try{e.send(JSON.stringify({code:d,error:{code:d,message:u},id:r.id,type:"error"}))}catch{}return}e.send(JSON.stringify({id:r.id,type:"ack"})),n&&await this.seedSubscription(e,r.id,o,n,i);return}if(r.type==="shape_subscribe"&&r.shape){let n;try{n=r.shape.args===void 0?void 0:O(r.shape.args)}catch{this.sendShapeSubscribeError(e,r.id,"BAD_SUBSCRIPTION_ARGS","shape args failed wire decoding");return}await this.handleShapeSubscribe(e,r.id,{args:n,name:r.shape.name,sinceEpoch:r.sinceEpoch,sinceSeq:r.sinceCheckpoint});return}if(r.type==="shape_unsubscribe"){this.shapeUnsubscribe(e,r.id),e.send(JSON.stringify({id:r.id,type:"ack"}));return}if(r.type==="stream"&&r.query?.functionPath){if(r.query.functionPath.startsWith(k)){e.send(JSON.stringify({id:r.id,message:"streams must be public",type:"error"}));return}this.handleStream(e,r.id,r.query.functionPath,O(r.query.args??{})).catch(()=>{});return}if(r.type==="whisper_subscribe"||r.type==="whisper_unsubscribe"){if(typeof r.topic=="string"&&r.topic.length>0){const n=r.type==="whisper_subscribe";this.setWhisperMembership(e,r.topic,n),n&&await this.relay?.announce()}return}if(r.type==="whisper"){typeof r.topic=="string"&&r.topic.length>0&&await this.broadcastWhisper(e,r.topic,r.data);return}if(r.type==="unsubscribe"){const n=this.streamCancellers.get(e),i=n?.get(r.id);i&&(i.abort(),n?.delete(r.id)),this.unsubscribe(e,r.id),e.send(JSON.stringify({id:r.id,type:"ack"}))}}async handleAlarmBody(){this.globalPollScheduled=!1;let e;try{e=await this.pollGlobalShapes()}catch(n){this.recordShapeError("shape:poll",n),e=1}let t;try{t=await this.pollExternalSources()}catch(n){this.recordShapeError("source:poll",n),t=Date.now()+S.GLOBAL_SHAPE_POLL_INTERVAL_MS}let s;try{s=await this.pollTtlSweeps()}catch(n){this.recordShapeError("ttl:sweep",n),s=Date.now()+S.GLOBAL_SHAPE_POLL_INTERVAL_MS}await this.flushChangedTables();const r=S.nextPollAlarmTarget(e,t,s,Date.now());r!==void 0&&await this.scheduleGlobalPoll(r)}dispatchTally(e){J(this.dispatchSpans,ce);const t=R(e),s=this.dispatchSpans.get(t)??{};return s.dbTally??=Fs(),this.dispatchSpans.set(t,s),s.dbTally}async withTriggerTrace(e,t){const s=K(void 0),r=Date.now(),n=this.currentRequestTrace===void 0;n&&(this.currentRequestTrace=s);let i;try{return await t()}catch(o){throw i={thrown:o},o}finally{n&&this.currentRequestTrace===s&&(this.currentRequestTrace=void 0),(this.spans.hasTrace(s.traceId)||this.dispatchSpans.get(R(s))?.collector!==void 0)&&this.recordDispatchRootSpan(e,r,i,s),this.dispatchSpans.delete(R(s)),this.flushTelemetry()}}flushTelemetry(){try{this.lastTelemetrySink?.flush?.({waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}recordDispatchRootSpan(e,t,s,r){const n=this.dispatchSpans.get(R(r)),i=Date.now()-t,o=n?.dbTally===void 0||n.dbTally.calls===0?void 0:Ws(n.dbTally),c=n?.collector===void 0?void 0:{...n.collector.collected,attributes:{...o,...n.collector.collected.attributes}};try{this.spans.push(Tt({anchor:r,...c===void 0?{}:{collected:c},durationMs:i,failure:s,functionPath:e,shardKey:this.state.id?.name,startTs:t,userId:this.getCurrentUserId()}))}catch{}n?.collector!==void 0&&this.exportWideEvent(e,i,s,r,{collected:c??n.collector.collected,sink:n.sink})}exportWideEvent(e,t,s,r,n){try{const{attributes:i}=n.collected;this.recordUserLog(e,s===void 0?"info":"error",[de],de,{...i,"lunora.duration_ms":t,"lunora.function_path":e,"lunora.ok":s===void 0},n.sink,de,r)}catch{}}recordSpan(e,t){try{this.spans.push(e)}catch{}if(!t?.onSpan)return;const s=this.traceSampling.get(e.traceId);if(s&&!s.sampled){s.sink=t;return}this.emitSpan(e,t)}emitSpan(e,t){if(t.onSpan)try{t.onSpan(e,{waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}flushSampledOutTrace(e,t){const s=this.traceSampling.get(e.traceId);if(!s||s.sampled||!s.keepErrors)return;const{sink:r}=s;if(!r?.onSpan)return;const n=this.spans.entries().filter(i=>i.traceId===e.traceId&&i.dispatch!==!0);if(t||n.some(i=>!i.ok))for(const i of n)this.emitSpan(i,r)}lifecycleInfo(e){return{event:{connectionId:e.connectionId??"",shardKey:this.state.id?.name??G,userId:e.userId??null,...e.context===void 0?{}:{context:e.context}},identity:e.identity,userId:e.userId}}async withSystemDispatch(e){const t=this.currentRequestSystem;this.currentRequestSystem=!0;try{return await e()}finally{this.currentRequestSystem=t}}collectMetrics(){const e=this.state.storage.sql?.databaseSize;let{requests:t}=this.metrics,{errors:s}=this.metrics;try{const i=Lt(this.state.storage.sql);t=i.requests,s=i.errors}catch{}let r=[];try{r=xt(this.state.storage.sql)}catch{}let n=[];try{n=ar(this.state.storage.sql)}catch{}return{cache:this.reactiveCache?this.reactiveCache.stats():null,databaseSize:typeof e=="number"?e:null,errors:s,functions:this.collectFunctionStats().functions,history:this.collectFunctionMetricBuckets(),indexHits:r,queryStats:n,requests:t,shard:this.state.id?.name??G,sinceMs:this.metrics.sinceMs,uptimeMs:Date.now()-this.metrics.sinceMs}}recordFunctionCall(e,t,s,r,n,i=!1){const o=Date.now(),c=r?[...r]:[],d=n?[...n].map(m=>Ca(m)).filter(m=>m!==void 0):[];try{$t(this.state.storage.sql,{conflicted:i,durationMs:t,errored:s!==void 0,errorMessage:s,indexHits:d,path:e,scannedTables:c,ts:o})}catch{}const u=this.functionStats.get(e),l=u??{calls:0,conflicts:0,errors:0,lastCalledAt:o,lastErrorAt:null,lastErrorMessage:null,maxDurationMs:0,path:e,scannedTables:[],scans:0,totalDurationMs:0};l.calls+=1,l.totalDurationMs+=t,l.maxDurationMs=Math.max(l.maxDurationMs,t),l.lastCalledAt=o,c.length>0&&(l.scans+=c.length,Pt(l.scannedTables,c)),s!==void 0&&(l.errors+=1,l.lastErrorAt=o,l.lastErrorMessage=s),i&&(l.conflicts+=1),u===void 0&&this.functionStats.set(e,l)}flushStmtSamples(){const e=this.currentStmtSamples;if(!(!e||e.length===0))try{const t=this.state.storage.sql;for(const[s,r,n,i]of e)try{rr(t,s,r,n,i)}catch{}}catch{}}collectFunctionStats(){try{return{functions:qt(this.state.storage.sql),sinceMs:this.metrics.sinceMs}}catch{return{functions:[...this.functionStats.values()].toSorted((e,t)=>t.lastCalledAt-e.lastCalledAt),sinceMs:this.metrics.sinceMs}}}collectFunctionMetricBuckets(){try{return Dt(this.state.storage.sql)}catch{return[]}}maybeWarnRootSize(){if(S.rootSizeWarned||this.state.id?.name!==G)return;const e=this.state.storage.sql?.databaseSize;typeof e!="number"||e<Xr||(S.rootSizeWarned=!0,console.warn(`[@lunora/do] __root__ Durable Object SQLite size is ${String(e)} bytes (>= 1 GiB, 10% of the 10 GiB per-DO ceiling). Plan a \`.shardBy()\` migration before you hit the wall. See https://lunora.sh/docs/concepts/sharding for guidance.`))}errorToResponse(e){const{body:t,redacted:s,status:r}=C(e,{encodeData:w,fallbackCode:"RPC_FAILED",redactedMessage:"internal error"});return s&&console.error("[@lunora/do] internal error:",e),y({error:t},r)}async handleBatchRpc(e){let t;try{t=await e.json()}catch{return y({error:{code:"BAD_REQUEST",message:"invalid JSON body"}},400)}if(!Array.isArray(t.calls))return y({error:{code:"BAD_REQUEST",message:"batch `calls` must be an array"}},400);if(t.calls.length>$e)return y({error:{code:"BAD_REQUEST",message:`batch exceeds the ${String($e)}-call limit`}},400);const s=[];let r;for(const n of t.calls){const i=await this.dispatchBatchEntry(e,n);i.bookmark!==void 0&&(r=i.bookmark),s.push({body:i.body,id:i.id,status:i.status})}return y({results:s},200,_(r))}async dispatchBatchEntry(e,t){try{const s=await this.fetch(Ls(e,t));return{body:await s.json(),bookmark:s.headers.get("x-d1-bookmark")??void 0,id:t.id,status:s.status}}catch(s){const{body:r,status:n}=C(s,{fallbackCode:"BATCH_ENTRY_FAILED"});return{body:{error:r},bookmark:void 0,id:t?.id,status:n}}}async handleAdminRpc(e,t,s){if(!this.isAdminAuthorized(e))return y({error:{code:"ADMIN_FORBIDDEN",message:"admin introspection is disabled or the bearer token is invalid"}},403);try{const r=this.readAdminOp(t,s);if(r)return y({result:r.result},200);if(t===h.runMigration){const i=ea(s),o=await this.runShardDataMigration(i);return await this.flushChangedTables(),this.recordAudit("runMigration",{id:i.id,detail:{changed:o.changed,direction:o.direction,dryRun:o.dryRun,processed:o.processed}}),y({result:o},200)}if(t===h.exportShard){const i=At(s),o=await this.runShardExport({batchSize:i.batchSize,tables:i.tables});return y({result:{rows:o}},200)}if(t===h.importShard){const i=It(s),o=await this.runShardImport({rows:i.rows,startLine:i.startLine});return await this.flushChangedTables(),this.recordAudit("importShard",{detail:{conflicts:o.conflicts,errors:o.errors.length,inserted:o.inserted}}),y({result:o},200)}if(t===h.writeRow){const i=aa(s),o=await this.runShardWrite(i);return await this.flushChangedTables(),this.recordAudit("writeRow",{table:i.table,id:o.id??i.id,detail:{op:o.op}}),y({result:o},200)}if(t===h.deleteRows){const i=ya(s),o=await this.runShardBulkDelete(i);return await this.flushChangedTables(),this.recordAudit("deleteRows",{table:i.table,detail:{deleted:o.deleted,hasMore:o.hasMore}}),y({result:o},200)}if(t===h.clearTable){const i=ga(s),o=await this.runShardBulkDelete(i);return await this.flushChangedTables(),this.recordAudit("clearTable",{table:i.table,detail:{deleted:o.deleted,hasMore:o.hasMore}}),y({result:o},200)}if(t===h.rankBefore){const i=await this.runShardRankBefore(ka(s));return y({result:i},200)}if(t===h.rankPage){const i=await this.runShardRankPage(Na(s));return y({result:i},200)}if(t===h.cdcSync){const i=this.runShardCdcSync(La(s));return y({result:i},200)}if(t===h.applyCdc){const i=await this.runShardApplyCdc(Oa(s));return await this.flushChangedTables(),this.recordAudit("applyCdc",{detail:{applied:i.applied}}),y({result:i},200)}return t===h.runAs?this.handleRunAs(s):await this.handleExtraAdminOp(t,s)||y({error:{code:"UNKNOWN_ADMIN_OP",message:`unknown admin op: ${t}`}},404)}catch(r){return this.errorToResponse(r)}}async handleExtraAdminOp(e,t){if(e===h.recordAuthEvent)return this.handleRecordAuthEvent(t);if(e===h.recordContainerEvent)return this.handleRecordContainerEvent(t);if(e===h.recordMail)return this.handleRecordMail(t);if(e===h.clearCapturedMail)return this.handleClearCapturedMail();if(e===h.sendTestMail)return this.handleSendTestMail(t);if(e===h.recordQueueMessage)return this.handleRecordQueueMessage(t);if(e===h.clearQueueMessages)return this.handleClearQueueMessages();if(e===h.sendQueueMessage)return this.handleSendQueueMessage(t);if(e===h.replayQueueMessage)return this.handleReplayQueueMessage(t);if(e===h.createWorkflowInstance)return this.handleCreateWorkflowInstance(t);if(e===h.getWorkflowInstanceStatus)return this.handleGetWorkflowInstanceStatus(t);if(e===h.listFlags)return this.handleListFlags(t);const s=await this.handleIssueTriageOp(e,t);return s!==void 0?s:this.handlePitrAdminOp(e,t)}async handleIssueTriageOp(e,t){const s=this.parseIssueTriagePatch(e,t);if(s===void 0)return;const r=oa(t),n=typeof t.updatedBy=="string"?t.updatedBy:void 0,i=this.state.storage.sql,o=zs(i,r,s,Date.now(),n);return this.recordChangedTable(B),await this.flushChangedTables(),this.recordAudit(e.slice(k.length),{detail:{...s,hash:r}}),y({result:{state:o}},200)}parseIssueTriagePatch(e,t){if(e===h.resolveIssue)return{status:"resolved"};if(e===h.ignoreIssue)return{status:"ignored"};if(e===h.assignIssue)return{assignee:ca(t),status:"open"};if(e===h.setIssueSeverity)return{severity:da(t)}}handleRecordAuthEvent(e){const t=Sa(e);try{_t(this.state.storage.sql,{outcome:t.outcome,ts:Date.now()})}catch{}return y({result:{recorded:!0}},200)}async handleRecordContainerEvent(e){const t=Ea(e);if(this.logs.push(t),t.level==="error"||t.exitCode!==void 0&&t.exitCode!==0){const s={durationMs:0,errorMessage:t.message,functionPath:t.functionPath,outcome:"error",shardKey:this.state.id?.name,ts:t.timestamp};this.persistRequestLog(s,this.requestLogConfig()),this.recordChangedTable(I),await this.flushChangedTables()}return y({result:{recorded:!0}},200)}async handleRunAs(e){const t=wa(e),s=await this.withRequestIdentity(t.userId,t.identity,()=>this.handleRpc(t.functionPath,t.args));return await this.flushChangedTables(),this.recordAudit("runAs",{detail:{functionPath:t.functionPath,runAsUserId:t.userId}}),y({result:s},200)}resolveWorkflowBinding(e){const t=this.workflowsMetadata().workflows.find(r=>r.exportName===e);if(!t)throw new f("BAD_REQUEST",`workflow "${e}" is not declared`);const s=this.env?.[t.binding];if(typeof s!="object"||s===null||typeof s.create!="function"||typeof s.get!="function")throw new f("BAD_REQUEST",`workflow binding "${t.binding}" is not available on this deployment`);return s}async handleCreateWorkflowInstance(e){const t=ua(e),s=await this.resolveWorkflowBinding(t.exportName).create({id:t.id,params:t.params}),r=await s.status(),n={id:s.id,status:Ze(r.status)};return this.recordAudit("createWorkflowInstance",{id:s.id,detail:{exportName:t.exportName}}),y({result:n},200)}async handleGetWorkflowInstanceStatus(e){const t=la(e),s=await(await this.resolveWorkflowBinding(t.exportName).get(t.id)).status(),r={error:pa(s.error),id:t.id,output:s.output,status:Ze(s.status)};return y({result:r},200)}async handleListFlags(e){const t=e.context,s=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0,r=await this.evaluateFlags(s);return y({result:r},200)}async withRequestIdentity(e,t,s){const r=this.currentRequestUserId,n=this.currentRequestIdentity;this.currentRequestUserId=e,this.currentRequestIdentity=t;try{return await s()}finally{this.currentRequestUserId=r,this.currentRequestIdentity=n}}handleRecordMail(e){const t=Ra(e),s=ke(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleClearCapturedMail(){const e=Xt(this.state.storage.sql);return y({result:e},200)}handleSendTestMail(e){const t=va(e),s=ke(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleRecordQueueMessage(e){const t=Aa(e),s=cr(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleClearQueueMessages(){const e=lr(this.state.storage.sql);return y({result:e},200)}async handleSendQueueMessage(e){const t=Ia(e),{binding:s}=this.resolveQueueBinding(t.exportName);let r;return t.batch===void 0?(await s.send(t.body,{contentType:t.contentType,delaySeconds:t.delaySeconds}),r=1):(await s.sendBatch(t.batch.map(n=>({body:n,contentType:t.contentType,delaySeconds:t.delaySeconds}))),r=t.batch.length),this.recordAudit("sendQueueMessage",{detail:{count:r,exportName:t.exportName}}),y({result:{sent:r}},200)}async handleReplayQueueMessage(e){const t=_a(e),s=ur(this.state.storage.sql,t.id);if(s===void 0)throw new f("BAD_REQUEST",`replayQueueMessage: captured message "${t.id}" was not found`,{status:404});if(ir(s.body))throw new f("BAD_REQUEST",`replayQueueMessage: captured message "${t.id}" has a truncated or unserializable body and can't be replayed faithfully`,{status:422});const r=t.target??this.resolveReplayTarget(s.queue)??s.exportName;if(typeof r!="string"||r==="")throw new f("BAD_REQUEST",`replayQueueMessage: captured message "${t.id}" has no declared producer to replay onto (pass \`target\`)`);const{binding:n}=this.resolveQueueBinding(r);return await n.send(s.body),this.recordAudit("replayQueueMessage",{detail:{messageId:s.messageId,target:r},id:t.id}),y({result:{sent:1,target:r}},200)}resolveQueueBinding(e){const t=this.queuesMetadata().queues.find(r=>r.exportName===e);if(!t)throw new f("BAD_REQUEST",`queue "${e}" is not declared`);const s=this.env?.[t.binding];if(typeof s!="object"||s===null||typeof s.send!="function")throw new f("BAD_REQUEST",`queue binding "${t.binding}" is not available on this deployment`);return{binding:s,metadata:t}}resolveReplayTarget(e){const{queues:t}=this.queuesMetadata(),s=t.find(r=>r.deadLetterQueue===e);return s!==void 0?s.exportName:t.find(r=>r.name===e)?.exportName}recordAudit(e,t={}){const s=this.state.storage.sql,r=this.getCurrentUserId(),n=r===void 0?t.detail:{...t.detail,userId:r};Ns(s,{detail:n,id:t.id,op:e,table:t.table,ts:Date.now()})}recordRequestLog(e,t,s,r,n,i){const o=this.requestLogConfig();if(r==="ok"&&!Ua(o.sampleRate))return;const c={cacheHit:this.currentRequestCacheHit,durationMs:s,errorMessage:i,functionPath:e,identity:this.currentRequestIdentity,outcome:r,redactedArgs:Object.keys(t).length===0?void 0:t,shardKey:this.state.id?.name,tablesRead:this.currentRequestReadTables===void 0?[]:[...this.currentRequestReadTables],tablesWritten:n,ts:Date.now(),userId:this.getCurrentUserId()};this.persistRequestLog(c,o)}persistRequestLog(e,t){const s={captureRaw:t.captureRaw,retention:t.retention};try{vr(this.state.storage.sql,e,s)}catch{}if(t.emit||e.outcome==="error")try{Ar(e,s)}catch{}}requestLogConfig(){const e=this.env??{};return{captureRaw:Ne(this.env),emit:qa(e.LUNORA_REQUEST_LOG_EMIT,Ne(this.env)),retention:Pa(e.LUNORA_REQUEST_LOG_RETENTION),sampleRate:Da(e.LUNORA_REQUEST_LOG_SAMPLE)}}async handlePitrAdminOp(e,t){const s=typeof t.time=="number"||typeof t.time=="string"?t.time:void 0;if(e===h.getPitrBookmark)return y({result:await Zt(this.state.storage,s)},200);if(e!==h.pitrRestore)return;const r=t.restart===!0,n=typeof t.bookmark=="string"?t.bookmark:void 0,i=await es(this.state.storage,{bookmark:n,time:s});this.cdcEnabled()&&ws(this.sql),this.recordAudit("pitrRestore",{detail:{restart:r,restoredTo:i.restoredTo,undoBookmark:i.undoBookmark}});const o=y({result:{...i,restarted:r}},200);return r&&this.state.abort?.("lunora PITR restore"),o}readAdminOp(e,t){this.ensureMigrated();const s=this.state.storage.sql,r=this.readAdminWildcardOp(e);if(r!==void 0)return{result:r,tables:new Set([b])};if(e===h.getAuditLog)return this.readAdminAuditLog(s,t);if(e===h.getRequestLog)return this.readAdminRequestLog(s,t);if(e===h.getIssues)return this.readAdminIssues(s,t);const n=this.readAdminDurableSignal(e,s,t);if(n)return n;if(e===h.readTablePage)return this.readAdminTablePage(s,t);if(e===h.facetColumn)return this.readAdminFacetColumn(s,t);if(e===h.runSql)return this.readAdminRunSql(s,t);const i=this.readAdminTableSignal(e,s,t);return i||this.readAdminStorageSignal(e,s,t)||null}readAdminTableSignal(e,t,s){if(e===h.listTableIndexes||e===h.describeTable){const r=typeof s.table=="string"?s.table:"";return{result:e===h.describeTable?{columns:this.tableColumns(r)}:{indexes:this.tableIndexes(r)},tables:new Set([r===""?b:r])}}if(e===h.describeTables){const r=Array.isArray(s.tables)?s.tables.filter(n=>typeof n=="string"):[];return{result:{columnsByTable:Object.fromEntries(r.map(n=>[n,this.tableColumns(n)]))},tables:new Set(r.length===0?[b]:r)}}if(e===h.migrationStatus){const r=typeof s.id=="string"?s.id:void 0;return{result:{migrations:Nt(t,r)},tables:new Set([b])}}}readAdminStorageSignal(e,t,s){if(e===h.storageReferences)return this.readAdminStorageReferences(t,s);if(e===h.storageOrphans)return this.readAdminStorageOrphans(t,s)}readAdminStorageReferences(e,t){const s=Array.isArray(t.keys)?t.keys.filter(r=>typeof r=="string"):[];return{result:Ft(e,this.storageColumns(),s),tables:new Set([b])}}readAdminStorageOrphans(e,t){const s=Array.isArray(t.liveKeys)?t.liveKeys.filter(n=>typeof n=="string"):[],r=Hr(e,this.storageColumns(),s);return r.truncated&&console.warn(`[@lunora/do] storageOrphans scan truncated after checking ${String(r.scanned)} storage references; reporting the first ${String(r.references.length)} dangling reference(s).`),{result:r,tables:new Set([b])}}readAdminWildcardOp(e){if(e===h.listTables)return Wt(this.state.storage.sql);if(e===h.getMetrics)return this.collectMetrics();if(e===h.getFunctionStats)return this.collectFunctionStats();if(e===h.listSubscriptions)return this.collectSubscriptions();if(e===h.getFanoutMetrics)return this.collectFanoutMetrics();if(e===h.getLogs)return{entries:this.logs.entries()};if(e===h.getTraces){const t=Ur(this.spans.entries());return{total:t.total,traces:t.traces}}if(e===h.getMetricSeries)return{series:this.metricSeries.entries()};if(e===h.getMetricHistory)return tr(this.sql);if(e===h.getSettings)return os(this.env);if(e===h.getSecurityAudit)return cs(this.env);if(e===h.getAdvisories)return{advisories:[...this.advisories(),...this.runtimeAdvisories()]};if(e===h.rlsPolicies)return this.rlsMetadata();if(e===h.maskPolicies)return this.maskMetadata();if(e===h.storageRules)return this.storageRulesMetadata();if(e===h.studioFeatures)return this.studioFeatures();if(e===h.listWorkflows)return this.workflowsMetadata();if(e===h.listQueues)return this.queuesMetadata()}collectSubscriptions(){return Kt(this.state.getWebSockets().map(e=>this.readAttachment(e)))}collectFanoutMetrics(){const e=Ht(this.state.getWebSockets().map(s=>this.readAttachment(s))),t=this.relay?.relayCount()??0;return{...e,maxRelays:this.relay?.maxRelays()??Re,promoted:t>0,relayCount:t,shapePoke:this.fanout.shapePoke,sinceMs:this.metrics.sinceMs,whisper:this.fanout.whisper}}readAdminAuditLog(e,t){Ee(e);const s=typeof t.limit=="number"?t.limit:void 0,r=typeof t.sinceSeq=="number"?t.sinceSeq:void 0;return{result:{entries:Cs(e,{limit:s,sinceSeq:r})},tables:new Set([b])}}readAdminRequestLog(e,t){W(e);const s=t.outcome==="ok"||t.outcome==="error"?t.outcome:void 0;return{result:{entries:Cr(e,{functionPathPrefix:typeof t.functionPathPrefix=="string"?t.functionPathPrefix:void 0,limit:typeof t.limit=="number"?t.limit:void 0,outcome:s,shardKey:typeof t.shardKey=="string"?t.shardKey:void 0,sinceSeq:typeof t.sinceSeq=="number"?t.sinceSeq:void 0,tableTouched:typeof t.tableTouched=="string"?t.tableTouched:void 0,userId:typeof t.userId=="string"?t.userId:void 0})},tables:new Set([b])}}readAdminIssues(e,t){return W(e),{result:{issues:Lr(e,{functionPathPrefix:typeof t.functionPathPrefix=="string"?t.functionPathPrefix:void 0,limit:typeof t.limit=="number"?t.limit:void 0,shardKey:typeof t.shardKey=="string"?t.shardKey:void 0,status:na(t.status)?t.status:void 0,userId:typeof t.userId=="string"?t.userId:void 0})},tables:new Set([b])}}readAdminDurableSignal(e,t,s){if(e===h.getAuthMetrics)return this.readAdminAuthMetrics(t);if(e===h.getCapturedMail)return this.readAdminCapturedMail(t,s);if(e===h.getQueueMessages)return this.readAdminQueueMessages(t,s)}readAdminAuthMetrics(e){let t;try{t=kt(e)}catch{t={attempts:0,failureRate:0,failures:0,history:[],sinceMs:0}}return{result:t,tables:new Set([b])}}readAdminCapturedMail(e,t){const s=typeof t.limit=="number"?t.limit:void 0;let r;try{r=Yt(e,{limit:s})}catch{r={entries:[]}}return{result:r,tables:new Set([Vt])}}readAdminQueueMessages(e,t){const s=typeof t.limit=="number"?t.limit:void 0,r=typeof t.queue=="string"?t.queue:void 0;let n;try{n=dr(e,{limit:s,queue:r})}catch{n={entries:[]}}return{result:n,tables:new Set([A])}}readAdminTablePage(e,t){const s=typeof t.table=="string"?t.table:"";return{result:Qt(e,{filters:Se(t.filters),limit:typeof t.limit=="number"?t.limit:void 0,offset:typeof t.offset=="number"?t.offset:void 0,orderBy:ma(t.orderBy),refs:this.tableRefs(s),search:typeof t.search=="string"?t.search:void 0,skipCount:typeof t.skipCount=="boolean"?t.skipCount:void 0,table:s}),tables:new Set([s===""?b:s])}}readAdminFacetColumn(e,t){const s=typeof t.table=="string"?t.table:"";return{result:zt(e,{column:typeof t.column=="string"?t.column:"",filters:Se(t.filters),limit:typeof t.limit=="number"?t.limit:void 0,search:typeof t.search=="string"?t.search:void 0,table:s}),tables:new Set([s===""?b:s])}}readAdminRunSql(e,t){const s=typeof t.sql=="string"?t.sql:"";return{result:ds(e,s),tables:new Set([b])}}executeAdminSubscription(e,t){const s=this.readAdminOp(e,t);return s?{result:s.result,tables:s.tables}:null}async resolveReactiveOutcome(e,t,s,r){if(s)return this.executeAdminSubscription(e,t);if(e.startsWith(Gt)){const n=await this.runFlagSubscriptionRead(e,t,r);return n===null?null:{result:n,tables:new Set([b])}}return this.executeSubscription(e,t,r)}isIdentityIndependent(e){return e.startsWith(k)}resolveReactiveOutcomeDeduped(e,t,s,r,n){if(!this.isIdentityIndependent(e))return this.resolveReactiveOutcome(e,t,s,r);const i=Me(e,t,null),o=n.get(i);if(o!==void 0)return o;const c=this.resolveReactiveOutcome(e,t,s,r);return n.set(i,c),c}isAdminAuthorized(e){const t=(this.env??{}).LUNORA_ADMIN_TOKEN;if(!t||t.length===0)return!1;const s=ue(e.headers.get("authorization"));return s!==void 0&&j(s,t)}async handleStream(e,t,s,r){const n=this.executeStream(s,r);if(!n){e.send(JSON.stringify({error:{code:"NOT_FOUND",message:`stream not registered: ${s}`},id:t,type:"error"}));return}let i=this.streamCancellers.get(e);if(i||(i=new Map,this.streamCancellers.set(e,i)),i.size>=S.MAX_STREAMS_PER_SOCKET){try{e.send(JSON.stringify({error:{code:"TOO_MANY_STREAMS",message:`stream cap of ${String(S.MAX_STREAMS_PER_SOCKET)} reached on this socket`},id:t,type:"error"}))}catch{}return}const o=new AbortController;i.set(t,o),e.send(JSON.stringify({id:t,type:"ack"}));try{for await(const c of n.iterator(o.signal)){if(o.signal.aborted)break;await M(e),e.send(JSON.stringify({data:w(c),id:t,type:"chunk"}))}o.signal.aborted||e.send(JSON.stringify({id:t,type:"complete"}))}catch(c){const{body:d,redacted:u}=C(c,{fallbackCode:"INTERNAL_SERVER_ERROR",redactedMessage:"internal error"});u&&console.error("[@lunora/do] unhandled stream error:",c),e.send(JSON.stringify({error:{code:d.code,message:d.message},id:t,type:"error"}))}finally{i.delete(t),i.size===0&&this.streamCancellers.delete(e)}}async flushChangedTables(){const e=this.pendingChangedTables;if(this.pendingChangedTables=void 0,!(!e||e.size===0)){if(this.pendingRefreshTables)for(const t of e)this.pendingRefreshTables.add(t);else this.pendingRefreshTables=e;if(!this.refreshInFlight){if(typeof this.state.waitUntil=="function"){this.state.waitUntil(this.drainSubscriptionRefreshes());return}await this.drainSubscriptionRefreshes()}}}async drainSubscriptionRefreshes(){if(!this.refreshInFlight){this.refreshInFlight=!0;try{let e=this.pendingRefreshTables;for(;e&&e.size>0;){this.pendingRefreshTables=void 0;const t=this.currentCdcCursor(),s=this.currentCdcEpoch();await Promise.all([this.refreshSubscriptions(e),this.pokeShapeSubscribers(e,t,s),this.relay?.onFlush(e,t??0)]),e=this.pendingRefreshTables}}finally{this.refreshInFlight=!1}}}async refreshSubscriptions(e){const t=[...this.state.getWebSockets()],s=this.currentCdcCursor(),r=this.currentCdcEpoch(),n=new Map;await Ge(t,async i=>{if(this.isSocketExpired(i)){this.dropExpiredSocket(i);return}const o=this.readAttachment(i);for(const[c,d]of Object.entries(o.subs)){const{functionPath:u}=d;if(!u)continue;const l=u.startsWith(k),m=this.subMemos.get(i)?.get(c);if(!(m&&!m.tables.has(b)&&!Zr(m.tables,e)))try{const p=await this.resolveReactiveOutcomeDeduped(u,d.args??{},l,{identity:o.identity,userId:o.userId},n);if(!p)continue;await M(i),this.pushSubscriptionData(i,c,p,s,r)}catch{continue}}})}async seedSubscription(e,t,s,r,n){const i=s.args??{},o=this.readAttachment(e),c=await this.resolveReactiveOutcome(r,i,n,{identity:o.identity,userId:o.userId});if(!c)return;const{sinceEpoch:d,sinceSeq:u}=s,l=n||u===void 0?void 0:this.evaluateResume(u,c.tables,d),m=n?void 0:l?.epoch??this.currentCdcEpoch();if(l?.resumable){this.seedSubscriptionMemo(e,t,c);try{e.send(`{"type":"resume","id":${JSON.stringify(t)}${Ye(l.cursor??0,m)}}`)}catch{}return}this.pushSubscriptionData(e,t,c,l?.cursor??this.currentCdcCursor(),m)}async handleShapeSubscribe(e,t,s){const r=this.shapeSubscribe(e,t,s);if(r!=="ok"){const i=r==="too_many"?"TOO_MANY_SUBSCRIPTIONS":"SUBSCRIPTION_PERSIST_FAILED",o=r==="too_many"?`subscription cap of ${String(S.MAX_SUBSCRIPTIONS_PER_SOCKET)} reached on this socket`:"failed to persist shape subscription attachment";this.sendShapeSubscribeError(e,t,i,o);return}const n=await this.seedShapeSubscription(e,t,s);if(n!=="ok"){this.shapeUnsubscribe(e,t),this.sendShapeSubscribeError(e,t,n.code,n.message);return}try{e.send(JSON.stringify({id:t,type:"ack"}))}catch{}}sendShapeSubscribeError(e,t,s,r){try{e.send(JSON.stringify({code:s,error:{code:s,message:r},id:t,type:"error"}))}catch{}}async seedShapeSubscription(e,t,s){const r=this.readAttachment(e),n={identity:r.identity,userId:r.userId},i=await this.relay?.seedRelayShape(e,t,s,n);if(i!==void 0)return i;let o;try{o=this.resolveShape(s.name,s.args??{},n)}catch(c){this.recordShapeError(`shape:seed:${t}`,c);const{body:d}=C(c,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{code:d.code,message:d.message}}if(!o)return{code:"SHAPE_NOT_FOUND",message:`shape "${s.name}" not found or not permitted`};try{return o.global?await this.seedGlobalShape(e,t,o,n,r.connectionId??""):await this.seedOpLogShape(e,t,s,o)}catch(c){this.recordShapeError(`shape:seed:${t}`,c);const{body:d}=C(c,{fallbackCode:"SHAPE_SEED_FAILED",redactedMessage:"shape seed failed"});return{code:d.code,message:d.message}}}async seedOpLogShape(e,t,s,r){const{baseCheckpoint:n,cursor:i,epoch:o,rowsPatch:c}=this.computeOpLogShapeSeed(s,r);return await M(e),this.sendPoke(e,[{rowsPatch:c,shapeId:t}],i,o,n)&&this.recordShapeMemo(e,t,i),"ok"}computeOpLogShapeSeed(e,t){const s=this.sql,r=this.currentCdcCursor()??0,n=this.currentCdcEpoch(),i=this.cdcEnabled()?xe(s):void 0,o=this.cdcEnabled()&&e.sinceSeq!==void 0&&e.sinceEpoch===n&&e.sinceSeq<=r&&(e.sinceSeq===r||i!==void 0&&i<=e.sinceSeq+1),c=o&&e.sinceSeq!==void 0?this.buildShapeDiff(s,t,e.sinceSeq,r):this.buildShapeSeed(s,t);return{baseCheckpoint:o?e.sinceSeq:void 0,cursor:r,epoch:n,rowsPatch:c}}async pokeShapeSubscribers(e,t,s){const r=[...this.state.getWebSockets()],n=t??this.currentCdcCursor()??0,i=this.sql,o=new Map;let c=0;const d=async l=>{if(this.isSocketExpired(l)){this.dropExpiredSocket(l);return}const m=this.readAttachment(l),{shapes:p}=m;if(p)try{const g={identity:m.identity,userId:m.userId},{emptyAdvanced:E,partAdvanced:mt,parts:ve}=this.collectShapePokeParts(l,p,g,e,n,i,o);for(const te of E)this.recordShapeMemo(l,te,n);if(ve.length>0&&(await M(l),this.sendPoke(l,ve,n,s,void 0))){c+=1;for(const te of mt)this.recordShapeMemo(l,te,n)}}catch{}},u=Date.now();await Ge(r,d),this.fanout.shapePoke=se(this.fanout.shapePoke,r.length,c,Date.now()-u)}collectShapePokeParts(e,t,s,r,n,i,o){const c=[],d=[],u=[];for(const[l,m]of Object.entries(t))try{const p=this.resolveShape(m.name,m.args??{},s);if(!p||p.global||!r.has(p.table))continue;const g=this.shapeMemos.get(e)?.get(l)?.cursor??0,E=this.buildShapeDiff(i,p,g,n,o);E.length>0?(c.push({rowsPatch:E,shapeId:l}),u.push(l)):d.push(l)}catch(p){this.recordShapeError(`shape:poke:${l}`,p)}return{emptyAdvanced:d,partAdvanced:u,parts:c}}readShapeOpRange(e,t,s,r,n){const i=`${t}\0${String(s)}\0${String(r)}`,o=n?.get(i);if(o!==void 0)return o;const c=new Map,d=new Set([t]);let u=s;for(;;){const{changes:l,cursor:m}=this.readShapeCdcPage(e,u,d);for(const p of l)c.set(p.id,p);if(l.length===0||m===u||m>=r)break;u=m}return n?.set(i,c),c}readShapeCdcPage(e,t,s){return ae(e,{sinceSeq:t,tables:s})}buildShapeDiff(e,t,s,r,n){const i=this.readShapeOpRange(e,t.table,s,r,n);if(i.size===0)return[];const o=[...i.keys()],c=Rs(e,t.table,t.effectiveWhere,o),d=[];for(const[u,l]of i){if(c.has(u)){l.doc!==void 0&&d.push({key:u,op:l.op,table:t.table,value:fe(l.doc,t.columns)});continue}l.op!=="insert"&&d.push({key:u,op:"delete",table:t.table})}return d}buildShapeSeed(e,t){return Ts(e,t.table,t.effectiveWhere).map(s=>({key:s.id,op:"insert",table:t.table,value:fe(s.doc,t.columns)}))}async seedGlobalShape(e,t,s,r,n){const i=await this.readGlobalShapeRows(s,r);if(!this.withinGlobalShapeBound(i.length,`shape:seed:${t}`,s.table))return{code:"SHAPE_GLOBAL_TOO_LARGE",message:`global shape membership for "${s.table}" exceeds the ${String(S.GLOBAL_SHAPE_MAX_ROWS)}-row cap; narrow it with a shape predicate or an RLS read policy`};const{next:o,rowsPatch:c}=Fe(i,new Map,{columns:s.columns,table:s.table});return await M(e),this.sendPoke(e,[{rowsPatch:c,shapeId:t}],this.currentCdcCursor()??0,this.currentCdcEpoch(),void 0)&&(this.recordGlobalSnapshot(e,t,o),this.saveGlobalSnapshot(n,t,o)),await this.scheduleGlobalPoll(),"ok"}async refreshGlobalShape(e,t,s,r,n){const i=await this.readGlobalShapeRows(s,r);if(!this.withinGlobalShapeBound(i.length,`shape:poll:${t}`,s.table))return;const o=this.readGlobalSnapshot(e,t,n),{next:c,rowsPatch:d}=Fe(i,o,{columns:s.columns,table:s.table});if(d.length===0){this.recordGlobalSnapshot(e,t,c);return}await M(e),this.sendPoke(e,[{rowsPatch:d,shapeId:t}],this.currentCdcCursor()??0,this.currentCdcEpoch(),void 0)&&(this.recordGlobalSnapshot(e,t,c),this.saveGlobalSnapshot(n,t,c))}readGlobalSnapshot(e,t,s){const r=this.globalShapeSnapshots.get(e)?.get(t);if(r)return r;const n=this.loadGlobalSnapshot(s,t);return this.recordGlobalSnapshot(e,t,n),n}recordGlobalSnapshot(e,t,s){let r=this.globalShapeSnapshots.get(e);r||(r=new Map,this.globalShapeSnapshots.set(e,r)),r.set(t,s)}loadGlobalSnapshot(e,t){if(e==="")return new Map;try{return bs(this.sql,e,t)}catch{return new Map}}saveGlobalSnapshot(e,t,s){if(e!=="")try{Es(this.sql,e,t,s)}catch{}}async scheduleGlobalPoll(e){if(this.globalPollScheduled)return;const{setAlarm:t}=this.state.storage;if(t){this.globalPollScheduled=!0;try{await t.call(this.state.storage,e??Date.now()+S.GLOBAL_SHAPE_POLL_INTERVAL_MS)}catch{this.globalPollScheduled=!1}}}recordShapeError(e,t){this.logs.push({functionPath:e,level:"error",message:t instanceof Error?t.message:String(t),timestamp:Date.now()})}withinGlobalShapeBound(e,t,s){return e<=S.GLOBAL_SHAPE_MAX_ROWS?!0:(this.recordShapeError(t,new Error(`global shape membership for "${s}" (${String(e)} rows) exceeds the ${String(S.GLOBAL_SHAPE_MAX_ROWS)}-row cap; narrow it with a shape predicate or an RLS read policy`)),!1)}async pollGlobalShapes(){const e=[...this.state.getWebSockets()];let t=0;for(const s of e){if(this.isSocketExpired(s)){this.dropExpiredSocket(s);continue}const r=this.readAttachment(s),{shapes:n}=r;if(!n)continue;const i={identity:r.identity,userId:r.userId};t+=await this.pollSocketGlobalShapes(s,n,i,r.connectionId??"")}return t}async pollSocketGlobalShapes(e,t,s,r){let n=0;for(const[i,o]of Object.entries(t)){let c;try{c=this.resolveShape(o.name,o.args??{},s)}catch(d){n+=1,this.recordShapeError(`shape:poll:${i}`,d);continue}if(c?.global){n+=1;try{await this.refreshGlobalShape(e,i,c,s,r)}catch(d){this.recordShapeError(`shape:poll:${i}`,d)}}}return n}sendPoke(e,t,s,r,n){this.pokeSequence+=1;const i=`poke-${String(this.pokeSequence)}`,o=we(t,{baseCheckpoint:n,checkpoint:s,epoch:r,lastMutationId:this.socketClientWatermark(e),pokeId:i});try{for(const c of o)e.send(c);return!0}catch{return!1}}socketClientWatermark(e){const t=this.readAttachment(e),{clientId:s}=t;if(s!==void 0)try{return re(this.sql,t.userId??"",s)}catch{return}}recordShapeMemo(e,t,s){let r=this.shapeMemos.get(e);r||(r=new Map,this.shapeMemos.set(e,r)),r.set(t,{cursor:s})}seedSubscriptionMemo(e,t,s){let r=this.subMemos.get(e);r||(r=new Map,this.subMemos.set(e,r)),r.set(t,{lastJson:JSON.stringify(w(s.result??null)),tables:s.tables})}pushSubscriptionData(e,t,s,r,n){let i=this.subMemos.get(e);i||(i=new Map,this.subMemos.set(e,i));const o=Ye(r,n),c=JSON.stringify(w(s.result??null)),d=i.get(t);if(d?.lastJson===c){d.tables=s.tables;const m=this.socketClientWatermark(e),p=m===void 0?"":`,"lastMutationId":${String(m)}`;L(e,`{"type":"settled","id":${JSON.stringify(t)}${p}${o}}`);return}const u=[],l=(d===void 0?void 0:ss(d.lastJson,s.result,s.tables.values().next().value??"",u))===void 0?L(e,`{"type":"data","id":${JSON.stringify(t)},"data":${c}${o}}`):rs(e,t,u,o);i.set(t,{lastJson:l?c:d?.lastJson??Jr,tables:s.tables})}async isUpgradeAllowed(e){const t=this.env??{},s=t.LUNORA_ALLOWED_ORIGINS;if(s&&s.trim()!==""){const n=e.headers.get("origin");if(!n||!s.split(",").map(i=>i.trim()).filter(i=>i.length>0).includes(n))return!1}const r=t.LUNORA_WS_BEARER;if(r&&r.length>0){const n=this.suppliedWsToken(e);if(!n||!j(n,r)&&!await this.isAdminSocket(e))return!1}return!0}suppliedWsToken(e){const t=ue(e.headers.get("authorization"));return t!==void 0?t:new URL(e.url).searchParams.get("token")??void 0}async isAdminSocket(e){const t=this.env??{},s=t.LUNORA_ADMIN_TOKEN;if(!s||s.length===0)return!1;const r=this.suppliedWsToken(e);if(r===void 0)return!1;if(await Ms(s,r))return!0;const n=ue(e.headers.get("authorization"))===void 0,i=Gr.has((t.LUNORA_REQUIRE_EPHEMERAL_WS_TOKEN??"").trim().toLowerCase());return n&&i?!1:j(r,s)}armWebSocketKeepalive(){const e=this.state.setWebSocketAutoResponse;typeof e!="function"||typeof WebSocketRequestResponsePair>"u"||e.call(this.state,new WebSocketRequestResponsePair(Qr,zr))}async routeNonRpc(e,t){if(e.pathname==="/_lunora/relay"&&t.method==="POST")return this.relay?await this.relay.handleControl(t):new Response("relay tier inactive",{status:404});if(e.pathname==="/_lunora/route"&&t.method==="GET")return y({relayCount:this.relay?.relayCount()??0});if(e.pathname==="/rpc-batch"&&t.method==="POST")return this.handleBatchRpc(t);if(t.headers.get("Upgrade")==="websocket")return this.handleWebSocketUpgrade(t)}async handleWebSocketUpgrade(e){if(!await this.isUpgradeAllowed(e))return new Response("Forbidden",{status:403});const t=await this.isAdminSocket(e),s=new WebSocketPair,r=s[0],n=s[1];this.state.acceptWebSocket(n);const i=e.headers.get("x-lunora-userid")??void 0,o=st(e.headers.get("x-lunora-identity")),c=Number(e.headers.get("x-lunora-identity-exp")),d=Number.isFinite(c)&&c>0?c:void 0;return n.serializeAttachment?.({admin:t,connectionId:crypto.randomUUID(),subs:{},...d===void 0?{}:{expiresAt:d},...o===void 0?{}:{identity:o},...i===void 0?{}:{userId:i}}),new Response(null,{status:101,webSocket:r})}cdcEnabled(){try{return this.sql.exec("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?",Ce).toArray().length>0}catch{return!1}}isSocketExpired(e){const{expiresAt:t}=this.readAttachment(e);return typeof t=="number"&&Date.now()>=t}dropExpiredSocket(e){try{e.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},type:"error"})),e.close(4001,"token_expired")}catch{}}setWhisperMembership(e,t,s){const r=this.readAttachment(e),n=r.whispers??[],i=n.includes(t);if(s){if(i||n.length>=S.MAX_WHISPER_TOPICS_PER_SOCKET)return;r.whispers=[...n,t]}else{if(!i)return;const o=n.filter(c=>c!==t);o.length===0?delete r.whispers:r.whispers=o}try{e.serializeAttachment?.(r)}catch{}}allowWhisper(e){const t=Date.now(),s=this.whisperBuckets.get(e)??{last:t,tokens:S.WHISPER_RATE_BURST},r=Math.min(S.WHISPER_RATE_BURST,s.tokens+(t-s.last)/1e3*S.WHISPER_RATE_PER_SEC);return r<1?(this.whisperBuckets.set(e,{last:t,tokens:r}),!1):(this.whisperBuckets.set(e,{last:t,tokens:r-1}),!0)}async broadcastWhisper(e,t,s){if(!this.allowWhisper(e))return;const r=JSON.stringify(s??null);if(r.length>S.MAX_WHISPER_BYTES)return;const n=this.readAttachment(e).userId,i=n===void 0?"":`,"from":${JSON.stringify(n)}`,o=`{"type":"whisper","topic":${JSON.stringify(t)},"data":${r}${i}}`;this.deliverWhisperLocal(t,o,e),await this.relay?.forwardWhisper(t,o)}deliverWhisperLocal(e,t,s){let r=0,n=0;for(const i of this.state.getWebSockets())r+=1,!(i===s||this.readAttachment(i).whispers?.includes(e)!==!0)&&(L(i,t),n+=1);return this.fanout.whisper=se(this.fanout.whisper,r,n,0),n}readAttachment(e){const t=e.deserializeAttachment?.();return t&&typeof t=="object"&&"subs"in t&&t.subs?t:{subs:{}}}}export{Xr as ROOT_DO_SIZE_WARN_BYTES,G as ROOT_SHARD_NAME,S as ShardDO,ss as subscriptionListDeltas};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{isLunoraError as x}from"@lunora/errors";const L=t=>{if(typeof t=="string")return t;try{return JSON.stringify(t)??String(t)}catch{return String(t)}},E=t=>typeof t=="boolean"||typeof t=="number"||typeof t=="string"?t:L(t),g=(t,e)=>{if(t===void 0&&e===void 0)return;const n={};if(e!==void 0)for(const[r,a]of Object.entries(e))n[r]=E(a);if(t!==void 0)for(const[r,a]of Object.entries(t))n[r]=E(a);return Object.keys(n).length===0?void 0:n},w=t=>{const e=new Uint8Array(t);crypto.getRandomValues(e);let n="";for(const r of e)n+=r.toString(16).padStart(2,"0");return n},S=/^[0-9a-f]+$/,M=(t,e,n=!0)=>`00-${t}-${e}-${n?"01":"00"}`,C=t=>{if(t==null)return;const e=t.trim().toLowerCase().split("-"),[n,r,a,s]=e;if(!(e.length<4||n===void 0||n.length!==2||!S.test(n)||n==="ff"||n==="00"&&e.length!==4||r===void 0||a===void 0||s===void 0||s.length!==2||!S.test(s)||r.length!==32||a.length!==16||!S.test(r)||!S.test(a)||r==="00000000000000000000000000000000"||a==="0000000000000000"))return{parentSpanId:a,sampled:(Number.parseInt(s,16)&1)===1,traceId:r}},J=t=>{const e=C(t);return{rootSpanId:e?.parentSpanId??w(8),sampled:e?.sampled??!0,traceId:e?.traceId??w(16)}},A=t=>x(t)?t.code:t instanceof Error?t.constructor.name:"Error",D=t=>{const e=Object.keys(t);return e.length>0&&e.every(n=>n==="attributes"||n==="kind"||n==="links")},R=128,_=128,F=t=>{try{const e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}`}catch{return t}},U=t=>{try{return new URL(t).host}catch{return t}},N=(t,e)=>{try{return t(new URL(e))}catch{return!1}},V=t=>t===void 0?{}:D(t)?t:{attributes:t},q=(t,e)=>{if(t.isTraced){t.setAttribute("lunora.function_path",e.functionPath),t.setAttribute("lunora.ok",e.ok),t.setAttribute("lunora.duration_ms",e.durationMs),e.shardKey!==void 0&&t.setAttribute("lunora.shard_key",e.shardKey),e.userId!==void 0&&t.setAttribute("lunora.user_id",e.userId),e.error!==void 0&&(t.setAttribute("lunora.error.type",e.error.type),t.setAttribute("lunora.error.message",e.error.message));for(const[n,r]of Object.entries(e.attributes))(typeof r=="boolean"||typeof r=="number"||typeof r=="string")&&t.setAttribute(`lunora.attr.${n}`,r)}},H=t=>{const e={attributes:{},events:[],links:[]},n={spanContext:()=>t,addEvent:(r,a)=>{if(e.events.length>=R)return;const s=g(a);e.events.push({...s===void 0?{}:{attributes:s},name:r,ts:Date.now()})},addLink:r=>{if(e.links.length>=_)return;const a=g(r.attributes);e.links.push({...a===void 0?{}:{attributes:a},spanId:r.spanId,traceId:r.traceId})},recordException:r=>{n.addEvent("exception",{"exception.message":r instanceof Error?r.message:String(r),...r instanceof Error&&typeof r.stack=="string"?{"exception.stacktrace":r.stack}:{},"exception.type":A(r)})},setAttribute:(r,a)=>{Object.assign(e.attributes,g({[r]:a}))},setAttributes:r=>{Object.assign(e.attributes,g(r))}};return{collected:e,handle:n}},B=t=>{const{anchor:e,fuseCloudflareSpans:n,functionPath:r,record:a,resolveCloudflareTracing:s,shardKey:i,userId:c}=t,p=d=>async(b,I,u)=>{const l=w(8),f=Date.now(),o=V(u),K=g(o.attributes),{collected:m,handle:j}=H({spanId:l,traceId:e.traceId}),$=async y=>{let v=!0,k;try{return await I(p(l),j)}catch(h){throw v=!1,k={message:h instanceof Error?h.message:String(h),type:A(h)},h}finally{const h=Date.now()-f,O=c(),T={...K,...m.attributes},P=[...o.links??[],...m.links];try{a({...Object.keys(T).length===0?{}:{attributes:T},durationMs:h,...m.events.length===0?{}:{events:m.events},...k===void 0?{}:{error:k},functionPath:r,...o.kind===void 0||o.kind==="internal"?{}:{kind:o.kind},...P.length===0?{}:{links:P},name:b,ok:v,parentSpanId:d,shardKey:i,spanId:l,startTs:f,traceId:e.traceId,userId:O})}catch{}if(y!==void 0)try{q(y,{attributes:T,durationMs:h,error:k,functionPath:r,ok:v,shardKey:i,userId:O})}catch{}}};if(n===!0&&s!==void 0){const y=await s();if(y!==void 0&&typeof y.enterSpan=="function")return await y.enterSpan(b,v=>$(v))}return await $()};return p(e.rootSpanId)},G=(t,e)=>{const{anchor:n,functionPath:r,propagate:a=!0,record:s,shardKey:i,userId:c}=t;return async(p,d)=>{const b=w(8),I=Date.now(),u=new Request(p,d);(typeof a=="function"?N(a,u.url):a)&&u.headers.set("traceparent",M(n.traceId,b,n.sampled??!0));let l,f;try{const o=await e(u);return f=o.status,o.ok||(l={message:`HTTP ${String(o.status)}`,type:`HTTP_${String(o.status)}`}),o}catch(o){throw l={message:o instanceof Error?o.message:String(o),type:A(o)},o}finally{try{s({attributes:{"http.request.method":u.method,...f===void 0?{}:{"http.response.status_code":f},"url.full":F(u.url)},durationMs:Date.now()-I,...l===void 0?{}:{error:l},functionPath:r,kind:"client",name:`${u.method} ${U(u.url)}`,ok:l===void 0,parentSpanId:n.rootSpanId,shardKey:i,spanId:b,startTs:I,traceId:n.traceId,userId:c()})}catch{}}}},Q=t=>{const{functionPath:e,record:n,shardKey:r}=t,a=(s,i,c,p)=>{if(!Number.isFinite(c))return;const d=g(p);try{n({...d===void 0?{}:{attributes:d},functionPath:e,kind:s,name:i,shardKey:r,ts:Date.now(),value:c})}catch{}};return{count:(s,i=1,c)=>{a("counter",s,i,c)},gauge:(s,i,c)=>{a("gauge",s,i,c)},record:(s,i,c)=>{a("histogram",s,i,c)}}},W=t=>{const{anchor:e,collected:n,durationMs:r,failure:a,functionPath:s,shardKey:i,startTs:c,userId:p}=t,d=n?.attributes??{};return{...Object.keys(d).length===0?{}:{attributes:d},dispatch:!0,durationMs:r,...n===void 0||n.events.length===0?{}:{events:n.events},...a===void 0?{}:{error:{message:a.thrown instanceof Error?a.thrown.message:String(a.thrown),type:A(a.thrown)}},functionPath:s,...n===void 0||n.links.length===0?{}:{links:n.links},name:s,ok:a===void 0,parentSpanId:"",shardKey:i,spanId:e.rootSpanId,startTs:c,traceId:e.traceId,userId:p}};export{C as A,w as O,B as a,G as b,Q as c,W as d,H as e,q as f,g as n,J as r,A as t};
|