@lunora/do 1.0.0-alpha.44 → 1.0.0-alpha.45
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 +55 -1
- package/dist/index.d.ts +55 -1
- package/dist/index.mjs +1 -44
- package/dist/packem_shared/ADMIN_FUNCTIONS-PxZ8Lr9e.mjs +1 -0
- package/dist/packem_shared/AGGREGATE_SQL_FUNCTION-QYaiuty4.mjs +1 -0
- package/dist/packem_shared/AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs +22 -0
- package/dist/packem_shared/CDC_LOG_TABLE-E_J5LPoK.mjs +8 -0
- package/dist/packem_shared/ConflictError-C8GtJmjS.mjs +1 -0
- package/dist/packem_shared/CountRlsUnsupportedError-Cl8XpYDL.mjs +1 -0
- package/dist/packem_shared/DATA_MIGRATION_STATE_TABLE-CaO6L0Ee.mjs +31 -0
- package/dist/packem_shared/DEFAULT_MAX_RELATION_KEYS-BRdmX7WW.mjs +1 -0
- package/dist/packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-BPPeqM11.mjs +56 -0
- package/dist/packem_shared/GEO_DEFAULT_PRECISION-CWAm_oYY.mjs +1 -0
- package/dist/packem_shared/LogBuffer-bIvCelI-.mjs +1 -0
- package/dist/packem_shared/MAIL_RETENTION-KmozO2NQ.mjs +18 -0
- package/dist/packem_shared/MAX_SQL_ROWS-Bdu25ASB.mjs +2 -0
- package/dist/packem_shared/MIN_ADMIN_TOKEN_LENGTH-Ch6OW6_3.mjs +1 -0
- package/dist/packem_shared/NotFoundError-J3tjf4Uo.mjs +1 -0
- package/dist/packem_shared/NotUniqueError-BcP6GOem.mjs +1 -0
- package/dist/packem_shared/RANK_TIEBREAK-DtX8zQyc.mjs +1 -0
- package/dist/packem_shared/RLS_UNWRAP_SYMBOL-C6_WX3dG.mjs +1 -0
- package/dist/packem_shared/ROOT_DO_SIZE_WARN_BYTES-CP5wvJOW.mjs +101 -0
- package/dist/packem_shared/ReactiveCache-1_9Rs7J_.mjs +1 -0
- package/dist/packem_shared/SCAN_DEP-D_yR9EeV.mjs +1 -0
- package/dist/packem_shared/SESSION_DO_TTL_DEFAULT-GvBy_DBz.mjs +1 -0
- package/dist/packem_shared/SHARD_REGISTRY_DO_NAME-Caa0fR4N.mjs +1 -0
- package/dist/packem_shared/aggregateTableName-G-eXyjcz.mjs +1 -0
- package/dist/packem_shared/applyOnDelete-BvQN7pDL.mjs +1 -0
- package/dist/packem_shared/applySelect-Bq2KOrkL.mjs +1 -0
- package/dist/packem_shared/armRestore-BNzdvQ_o.mjs +1 -0
- package/dist/packem_shared/backfillAggregateIndexes-BAQ3Fwwh.mjs +1 -0
- package/dist/packem_shared/buildFtsMatch-CV0Z7PWv.mjs +1 -0
- package/dist/packem_shared/compileWhereSql-BLcfs4QW.mjs +1 -0
- package/dist/packem_shared/constant-time-equal-BVG05Guz.mjs +1 -0
- package/dist/packem_shared/context-telemetry-8eigmiNQ.mjs +1 -0
- package/dist/packem_shared/createMetrics-CyjLFXtA.mjs +1 -0
- package/dist/packem_shared/createSystemReader-DcDcrtM3.mjs +1 -0
- package/dist/packem_shared/ctx-db-idempotency-wiVoGnpQ.mjs +19 -0
- package/dist/packem_shared/ctx-db-shapes-DzX_H5q8.mjs +1 -0
- package/dist/packem_shared/diffExternalSource-DMpkJta1.mjs +1 -0
- package/dist/packem_shared/do-exec-BLe9lLrN.mjs +1 -0
- package/dist/packem_shared/do-sql-BYIQTG3z.mjs +1 -0
- package/dist/packem_shared/exportShardRows-kt42wijd.mjs +1 -0
- package/dist/packem_shared/hasTrigger-_rexbWMO.mjs +1 -0
- package/dist/packem_shared/isSoftDeleted-BvhQov04.mjs +9 -0
- package/dist/packem_shared/json-response-wrh9TBPw.mjs +1 -0
- package/dist/packem_shared/materializeExternalRows-BFmT9gsw.mjs +1 -0
- package/dist/packem_shared/renderSql-B5lF5Jd9.mjs +1 -0
- package/dist/packem_shared/runShardMigrations-bxOHpfID.mjs +5 -0
- package/dist/packem_shared/security-audit-BKUOgE0x.mjs +1 -0
- package/dist/packem_shared/selectExpiredIds-BGVP3d8-.mjs +1 -0
- package/dist/packem_shared/serialize-sql-DiRzL7A4.mjs +1 -0
- package/dist/packem_shared/serveRelationFanout-Ct5D2Tbk.mjs +1 -0
- package/dist/packem_shared/stableStringify-BjLh4gvA.mjs +1 -0
- package/dist/packem_shared/stableWireKey-YEHLaX6X.mjs +1 -0
- package/dist/packem_shared/subscriptionListDeltas-Bs69JbA8.mjs +1 -0
- package/dist/packem_shared/wire-codec-Ctnni0h6.mjs +1 -0
- package/package.json +1 -1
- package/dist/packem_shared/ADMIN_FUNCTIONS-CnZkbXH_.mjs +0 -374
- package/dist/packem_shared/AGGREGATE_SQL_FUNCTION-CQsu2Xga.mjs +0 -56
- package/dist/packem_shared/AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs +0 -84
- package/dist/packem_shared/CDC_LOG_TABLE-uwOJxJJZ.mjs +0 -107
- package/dist/packem_shared/ConflictError-CLoq37xH.mjs +0 -12
- package/dist/packem_shared/CountRlsUnsupportedError-BGxj0pgS.mjs +0 -133
- package/dist/packem_shared/DATA_MIGRATION_STATE_TABLE-CYwBpyTr.mjs +0 -245
- package/dist/packem_shared/DEFAULT_MAX_RELATION_KEYS-BEan1CRD.mjs +0 -211
- package/dist/packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-UDNVD7FS.mjs +0 -248
- package/dist/packem_shared/GEO_DEFAULT_PRECISION-BWnsNmpP.mjs +0 -114
- package/dist/packem_shared/LogBuffer-B_Ezju_N.mjs +0 -37
- package/dist/packem_shared/MAIL_RETENTION-CPpgl-dX.mjs +0 -104
- package/dist/packem_shared/MAX_SQL_ROWS-iFAA8FbD.mjs +0 -61
- package/dist/packem_shared/MIN_ADMIN_TOKEN_LENGTH-CCAvoFlr.mjs +0 -1
- package/dist/packem_shared/NotFoundError-C70b9hLw.mjs +0 -9
- package/dist/packem_shared/NotUniqueError-DbtlWwcG.mjs +0 -2031
- package/dist/packem_shared/RANK_TIEBREAK-CXhdcA1o.mjs +0 -91
- package/dist/packem_shared/RLS_UNWRAP_SYMBOL-DTvHvRzY.mjs +0 -141
- package/dist/packem_shared/ROOT_DO_SIZE_WARN_BYTES-B_zt4RQE.mjs +0 -7676
- package/dist/packem_shared/ReactiveCache-DnSvbjil.mjs +0 -233
- package/dist/packem_shared/SCAN_DEP-DLJF8dsj.mjs +0 -19
- package/dist/packem_shared/SESSION_DO_TTL_DEFAULT-BnSKgVO4.mjs +0 -169
- package/dist/packem_shared/SHARD_REGISTRY_DO_NAME-D99roc-r.mjs +0 -144
- package/dist/packem_shared/aggregateTableName-CxNqY1Sl.mjs +0 -64
- package/dist/packem_shared/applyOnDelete-BXSq3S70.mjs +0 -176
- package/dist/packem_shared/applySelect-WQY8m62C.mjs +0 -103
- package/dist/packem_shared/armRestore-4Px61hHS.mjs +0 -49
- package/dist/packem_shared/backfillAggregateIndexes-BGTwynwh.mjs +0 -81
- package/dist/packem_shared/buildFtsMatch-BLEMawrp.mjs +0 -38
- package/dist/packem_shared/compileWhereSql-DE6yfRcQ.mjs +0 -129
- package/dist/packem_shared/constant-time-equal-BVRWZgES.mjs +0 -12
- package/dist/packem_shared/context-telemetry-CDpyil58.mjs +0 -223
- package/dist/packem_shared/createMetrics-C4I2Yanj.mjs +0 -1
- package/dist/packem_shared/createSystemReader-D12eNH13.mjs +0 -82
- package/dist/packem_shared/ctx-db-idempotency-BdcNpvY4.mjs +0 -108
- package/dist/packem_shared/ctx-db-shapes-DTeFiHYS.mjs +0 -53
- package/dist/packem_shared/diffExternalSource-CovHfdyo.mjs +0 -44
- package/dist/packem_shared/do-exec-5eQy5cEi.mjs +0 -12
- package/dist/packem_shared/do-sql-CGAgiQUz.mjs +0 -88
- package/dist/packem_shared/exportShardRows-Dy3oFZ26.mjs +0 -157
- package/dist/packem_shared/hasTrigger-5N6_Fx0A.mjs +0 -20
- package/dist/packem_shared/isSoftDeleted-CFJmhjFP.mjs +0 -217
- package/dist/packem_shared/json-response-BdbtpOhm.mjs +0 -3
- package/dist/packem_shared/materializeExternalRows-BtEGs1Fv.mjs +0 -45
- package/dist/packem_shared/renderSql-D6eUcn2N.mjs +0 -16
- package/dist/packem_shared/runShardMigrations-BVax6rYu.mjs +0 -120
- package/dist/packem_shared/security-audit-CucgBice.mjs +0 -158
- package/dist/packem_shared/selectExpiredIds-C5W29Upb.mjs +0 -18
- package/dist/packem_shared/serialize-sql-BlRUoiQe.mjs +0 -14
- package/dist/packem_shared/serveRelationFanout-k7HTh3CC.mjs +0 -21
- package/dist/packem_shared/stableStringify-mC40mZts.mjs +0 -40
- package/dist/packem_shared/stableWireKey-DKuXO7T5.mjs +0 -6
- package/dist/packem_shared/subscriptionListDeltas-CT76bYny.mjs +0 -126
- package/dist/packem_shared/wire-codec-CzQc1pvf.mjs +0 -225
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as p}from"@lunora/errors";const y=Symbol.for("lunora.ctxdb.rls-unwrap");class f extends p{table;constructor(i){super("RLS_REQUIRED",`ctx.db access to "${i}" is denied: the schema is marked .rls("required"), so this table is protected. Apply RLS with .use(rls(policies)) in the procedure, or mark the table .public() to opt it out.`,{name:"RlsRequiredError"}),this.table=i}}const w=n=>Object.entries(n.tables).filter(([,i])=>i.shardMode?.kind!=="global").map(([i])=>i),g=(n,i,c)=>{const t=i?.tables,d=new Set(i?.exclude);for(const s of n)(t===void 0||t.includes(s))&&!d.has(s)&&c(s)},b=(n,i,c)=>{const t={},{deleteAll:d,wipeShard:s}=n;return d&&(t.deleteAll=(o,u)=>(c(o),d(o,u))),s&&(t.wipeShard=o=>(g(w(i),o,c),s(o))),t},k=(n,i,c)=>{if(i.rlsMode!=="required")return n;const t=n,d=e=>{const r=i.tables[e];return r!==void 0&&r.isPublic!==!0},s=e=>{if(d(e))throw new f(e)},o=async(e,r)=>{if(r!==void 0){s(r);return}const a=await c(e);a!==void 0&&s(a)},u=t.rankBefore,h={...n,...b(t,i,s),[y]:n,aggregate:(e,r)=>(s(e),t.aggregate(e,r)),count:(e,r)=>(s(e),t.count(e,r)),delete:async(e,r,a)=>(await o(e,r),t.delete(e,r,a)),deleteMany:async(e,r,a)=>{for(const l of e)await o(l,a);return t.deleteMany(e,r,a)},deleteWhere:t.deleteWhere?async(e,r,a)=>(s(e),await t.deleteWhere?.(e,r,a)):void 0,findFirst:(e,r)=>(s(e),t.findFirst(e,r)),findFirstOrThrow:(e,r)=>(s(e),t.findFirstOrThrow(e,r)),findMany:(e,r)=>(s(e),t.findMany(e,r)),get:async(e,r)=>(await o(e,r),t.get(e,r)),groupBy:(e,r)=>(s(e),t.groupBy(e,r)),insert:(e,r,a)=>(s(e),t.insert(e,r,a)),insertMany:(e,r,a)=>(s(e),t.insertMany(e,r,a)),insertManyUnsafe:(e,r,a)=>(s(e),t.insertManyUnsafe(e,r,a)),patch:async(e,r,a)=>(await o(e,a),t.patch(e,r,a)),patchMany:async(e,r,a)=>{for(const l of e)await o(l.id,a);return t.patchMany(e,r,a)},patchWhere:t.patchWhere?async(e,r,a)=>(s(e),await t.patchWhere?.(e,r,a)):void 0,query:e=>(s(e),t.query(e)),rank:(e,r,a)=>(s(e),t.rank(e,r,a)),rankPage:(e,r,a)=>(s(e),t.rankPage(e,r,a)),replace:async(e,r,a,l)=>(await o(e,a),t.replace(e,r,a,l)),restore:async(e,r)=>(await o(e,r),t.restore?.(e,r))};return u&&(h.rankBefore=(e,r,a)=>(s(e),u(e,r,a))),h};export{y as RLS_UNWRAP_SYMBOL,f as RlsRequiredError,k as guardWriter};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import{LunoraError as f,toErrorBody as N}from"@lunora/errors";import{drizzle as ht}from"drizzle-orm/durable-sqlite";import{c as z}from"./constant-time-equal-BVG05Guz.mjs";import{j as y}from"./json-response-wrh9TBPw.mjs";import{n as Ee,r as Re,m as pt,a as ft,c as mt,d as yt}from"./context-telemetry-8eigmiNQ.mjs";import{f as E,c as C}from"./wire-codec-Ctnni0h6.mjs";import{parseExportShardArgs as gt,parseImportShardArgs as St}from"./exportShardRows-kt42wijd.mjs";import{recordAuthEvent as bt,readAuthMetrics as Et}from"./AUTH_METRICS_BUCKETS_TABLE-D0wNaez7.mjs";import{DATA_MIGRATION_STATE_TABLE as Rt,readMigrationStatus as wt}from"./DATA_MIGRATION_STATE_TABLE-CaO6L0Ee.mjs";import{SCAN_DEP as we,createDependencyTracker as Tt,tableFromDepKey as At}from"./SCAN_DEP-D_yR9EeV.mjs";import{readFunctionMetricsTotals as vt,readFunctionMetricIndexHits as It,recordFunctionMetric as _t,mergeScanAttribution as kt,readFunctionMetrics as Mt,readFunctionMetricBuckets as Nt}from"./FUNCTION_METRICS_BUCKETS_TABLE-BPPeqM11.mjs";import{createFanoutCounters as Te,ADMIN_FUNCTION_PREFIX as _,RELATION_FUNCTION_PREFIX as Ct,selectMatchingIds as Ot,ADMIN_FUNCTIONS as h,findStorageReferences as Lt,listTables as xt,summarizeSubscriptions as qt,summarizeFanoutTopics as Pt,readTablePage as $t,facetColumn as Dt,FLAGS_FUNCTION_PREFIX as Ut,recordFanoutPass as Z,MAX_PAGE_SIZE as Bt}from"./ADMIN_FUNCTIONS-PxZ8Lr9e.mjs";import{LogBuffer as Ft}from"./LogBuffer-bIvCelI-.mjs";import{recordCapturedMail as Ae,clearCapturedMail as Wt,readCapturedMail as Kt,MAIL_TABLE as Ht}from"./MAIL_RETENTION-KmozO2NQ.mjs";import{stableStringify as fe}from"./stableStringify-BjLh4gvA.mjs";import{readBookmark as Qt,armRestore as zt}from"./armRestore-BNzdvQ_o.mjs";import{ReactiveCache as Gt,reactiveCacheKey as ve}from"./ReactiveCache-1_9Rs7J_.mjs";import{stableWireKey as x}from"./stableWireKey-YEHLaX6X.mjs";import{awaitWsDrain as k,trySendFrame as O,subscriptionListDeltas as jt,sendDeltaFrames as Jt}from"./subscriptionListDeltas-Bs69JbA8.mjs";import{fingerprintError as Xt}from"@lunora/fingerprint";import{redact as Yt,standardRules as Vt}from"@visulima/redact";import{R as Ie,E as Zt,_ as es}from"./security-audit-BKUOgE0x.mjs";import{runReadonlySql as ts}from"./MAX_SQL_ROWS-Bdu25ASB.mjs";import{ConflictError as ss}from"./ConflictError-C8GtJmjS.mjs";import{selectExpiredIds as rs}from"./selectExpiredIds-BGVP3d8-.mjs";import{p as as,m as ns,T as is,u as os,b as ee,_ as cs,o as us,l as ds,d as ls,S as hs}from"./ctx-db-idempotency-wiVoGnpQ.mjs";import{CDC_LOG_TABLE as _e,readCdcChanges as te,readCdcCursor as ke,readCdcEpoch as Me,minCdcSeq as Ne,bumpCdcEpoch as ps}from"./CDC_LOG_TABLE-E_J5LPoK.mjs";import{a as fs,s as ms}from"./ctx-db-shapes-DzX_H5q8.mjs";const Ce=500,ys=(a,e)=>{if(a.size<e)return;const t=a.keys().next().value;t!==void 0&&a.delete(t)},Ze=new TextEncoder,gs=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},Ss=64,se=new Map,bs=async a=>{const e=se.get(a);if(e)return e;ys(se,Ss);const t=crypto.subtle.importKey("raw",Ze.encode(a),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]);return se.set(a,t),t},Es=async(a,e,t)=>{const s=await bs(a);return crypto.subtle.verify("HMAC",s,t,Ze.encode(e))},Rs="v1",ws=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!==Rs||i.length===0)return!1;const o=Number(n);if(!Number.isFinite(o)||o<=t)return!1;let c;try{c=gs(i)}catch{return!1}return Es(a,`${r}.${n}`,c)},P="__lunora_audit__",G=(a,e,...t)=>a.exec.call(a,e,...t),me=a=>{G(a,`CREATE TABLE IF NOT EXISTS "${P}" (
|
|
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
|
+
)`)},Ts=(a,e)=>{me(a),G(a,`INSERT INTO "${P}" (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)),G(a,`DELETE FROM "${P}" WHERE seq <= (SELECT MAX(seq) - ? FROM "${P}")`,1e3)},As=(a,e={})=>{me(a);const t=e.sinceSeq??0,s=Math.max(1,Math.min(e.limit??1e3,1e4));return G(a,`SELECT seq, ts, op, "table", id, detail FROM "${P}" 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})},vs=["x-lunora-userid","x-lunora-identity","x-d1-bookmark","x-lunora-client-ip","x-lunora-system","x-lunora-shard-binding"],Is=(a,e)=>{const t=new Headers({"content-type":"application/json"});for(const s of vs){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"})},U="__lunora_issue_state__",_s=["ignored","open","resolved"],ks=["critical","high","low","medium"],j=(a,e,...t)=>a.exec.call(a,e,...t),W=a=>a??null,et=a=>{j(a,`CREATE TABLE IF NOT EXISTS "${U}" (
|
|
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
|
+
)`)},tt=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}}),Ms=(a,e)=>{const t=new Map;if(e.length===0)return t;et(a);for(let s=0;s<e.length;s+=100){const r=e.slice(s,s+100),n=r.map(()=>"?").join(", "),i=j(a,`SELECT hash, status, assignee, severity, updated_at, updated_by FROM "${U}" WHERE hash IN (${n})`,...r).toArray();for(const o of i)t.set(o.hash,tt(o))}return t},Ns=(a,e,t,s,r)=>{et(a);const n=W(t.status),i=W(t.assignee),o=t.assignee===null?1:0,c=W(t.severity),u=t.severity===null?1:0,l=W(r);j(a,`INSERT INTO "${U}" (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,l,n,o,i,u,c,s,l);const[d]=j(a,`SELECT hash, status, assignee, severity, updated_at, updated_by FROM "${U}" WHERE hash = ?`,e).toArray();return d===void 0?{hash:e,status:n??"open",updatedAt:s,...r===void 0?{}:{updatedBy:r}}:tt(d)},Oe=256,st=a=>`${a.kind}${a.name}${fe(a.attributes??{})}`;class Cs{capacity;series=new Map;constructor(e=Oe){this.capacity=e>0?Math.trunc(e):Oe}get size(){return this.series.size}clear(){this.series.clear()}entries(){return[...this.series.values()].toReversed().map(e=>({...e}))}push(e){const t=st(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 R="__lunora_metric_history",ie=6e4,Os=1440,Ls=1e3,Le=5e3,T=(a,e,...t)=>a.exec.call(a,e,...t),xs=a=>Math.floor(a/ie)*ie,xe=new WeakSet,rt=a=>{xe.has(a)||(T(a,`CREATE TABLE IF NOT EXISTS "${R}" (
|
|
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
|
+
)`),xe.add(a))},qs=4096,qe=new WeakMap,Ps=a=>{let e=qe.get(a);return e===void 0&&(e=new Set,qe.set(a,e)),e},$s=(a,e,t)=>{rt(a);const s=st(e),r=xs(e.ts),n=Ps(a),i=`${s}\0${r.toString()}`,o=n.has(i)||T(a,`SELECT 1 AS c FROM "${R}" WHERE series_key = ? AND bucket_ms = ? LIMIT 1`,s,r).toArray().length>0;if(!o&&!(T(a,`SELECT 1 AS c FROM "${R}" WHERE series_key = ? LIMIT 1`,s).toArray().length>0)&&T(a,`SELECT COUNT(DISTINCT series_key) AS n FROM "${R}"`).one().n>=Ls)return;const c=t??null;T(a,`INSERT INTO "${R}"
|
|
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,fe(e.attributes??{}),e.functionPath,e.shardKey??null,e.value,e.value,e.value,e.value,e.ts,c),o||T(a,`DELETE FROM "${R}"
|
|
49
|
+
WHERE series_key = ?
|
|
50
|
+
AND bucket_ms <= (
|
|
51
|
+
SELECT MAX(bucket_ms) - ? FROM "${R}" WHERE series_key = ?
|
|
52
|
+
)`,s,Os*ie,s),o&&!n.has(i)&&(n.size>=qs&&n.clear(),n.add(i))},Ds=a=>{if(!(a===""||a==="{}"))try{const e=JSON.parse(a);return e!==null&&typeof e=="object"?e:void 0}catch{return}},Us=(a,e={})=>{rt(a);const t=e.sinceMs===void 0?T(a,`SELECT * FROM "${R}" ORDER BY bucket_ms DESC LIMIT ?`,Le).toArray():T(a,`SELECT * FROM "${R}" WHERE bucket_ms >= ? ORDER BY bucket_ms DESC LIMIT ?`,e.sinceMs,Le).toArray(),s=new Map;for(const r of t){let n=s.get(r.series_key);if(n===void 0){const i=Ds(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()]}},$="__lunora_metrics_queries",D=(a,e,...t)=>a.exec.call(a,e,...t),Bs=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},at=a=>{D(a,`CREATE TABLE IF NOT EXISTS "${$}" (
|
|
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
|
+
)`)},Fs=(a,e,t,s,r)=>{const n=Bs(e);if(n.length===0||(at(a),D(a,`SELECT COUNT(*) AS n FROM "${$}"`).one().n>=500&&D(a,`SELECT COUNT(*) AS c FROM "${$}" WHERE normalized_sql = ?`,n).one().c===0))return;const i=`INSERT INTO "${$}" (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`;D(a,i,n,t,s,r)},Ws=a=>(at(a),D(a,`SELECT normalized_sql, exec_count, total_duration_ms, rows_read, rows_written FROM "${$}" 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",L=(a,e,...t)=>a.exec.call(a,e,...t),Pe=a=>a??null,nt="… [truncated by the dev queue catcher]",it="[unserializable message body]",Ks=a=>{if(a===void 0)return"null";try{const e=JSON.stringify(a);return e.length>131072?JSON.stringify(`${e.slice(0,131072)}${nt}`):e}catch{return JSON.stringify(it)}},Hs=a=>typeof a=="string"&&(a===it||a.endsWith(nt)),Qs=a=>{if(!(a==null||a===""))try{return JSON.parse(a)}catch{return}},Y=a=>{L(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
|
+
)`)},zs=(a,e,t)=>{Y(a);for(const s of e)L(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,Pe(s.exportName),Ks(s.body),s.attempts,s.outcome,Pe(s.error),s.deadLettered===!0?1:0,s.timestamp);return L(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}},ot=a=>({attempts:a.attempts,body:Qs(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}),Gs=(a,e={})=>{Y(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:L(a,`SELECT * FROM "${A}" ${r} ORDER BY captured_at DESC, id DESC LIMIT ?`,...n).toArray().map(i=>ot(i))}},js=(a,e)=>{Y(a);const t=L(a,`SELECT * FROM "${A}" WHERE id = ? LIMIT 1`,e).toArray()[0];return t===void 0?void 0:ot(t)},Js=a=>(Y(a),L(a,`DELETE FROM "${A}"`),{cleared:!0}),oe="::relay::",K=(a,e)=>`${a}${oe}${String(e)}`,Xs=a=>{const e=a.lastIndexOf(oe);if(e===-1)return;const t=a.slice(0,e),s=a.slice(e+oe.length),r=Number(s);if(!(t.length===0||!Number.isInteger(r)||r<0||String(r)!==s))return{ownerKey:t,relayIndex:r}},J=(a,e)=>x({args:e??{},name:a}),ce={tDown:4e3,tUp:8e3},Ys=(a,e,t=ce)=>{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"},Vs=(a,e)=>e<a?{tDown:e,tUp:a}:{tDown:Math.min(Math.max(1,Math.floor(a/2)),a-1),tUp:a},ue=(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},$e=(a,e,t)=>{const{columns:s,table:r}=t,n=new Map,i=[];for(const{doc:o,id:c}of a){const u=ue(o,s),l=JSON.stringify(E(u));n.set(c,l);const d=e.get(c);d===void 0?i.push({key:c,op:"insert",table:r,value:u}):d!==l&&i.push({key:c,op:"update",table:r,value:u})}for(const o of e.keys())n.has(o)||i.push({key:o,op:"delete",table:r});return{next:n,rowsPatch:i}},de=a=>a.map(e=>e.value===void 0?e:{...e,value:E(e.value)}),ye=(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 u of a){const l=t.preEncoded?u.rowsPatch:de(u.rowsPatch);c.push(JSON.stringify({pokeId:o,rowsPatch:l,shapeId:u.shapeId,type:"pokePart",...i===void 0?{}:{lastMutationId:i}}))}return c.push(JSON.stringify({checkpoint:r,epoch:n,pokeId:o,type:"pokeEnd"})),c},Zs=2,ge=8,er="LUNORA_RELAY_SECRET",De="x-lunora-relay-sig",Ue=a=>{const e=a?.[er];return typeof e=="string"&&e.length>0?e:void 0},Be=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("")},q=(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},re={},tr=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},rr=a=>Response.json(a,{headers:{"content-type":"application/json"}}),H=()=>new Response(null,{status:204});class ct{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=Ue(this.host.env());if(s!==void 0){const n=e.headers.get(De),i=await Be(s,t);if(n===null||!z(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),H();case"relay_detach":return this.onDetach(r.relayIndex),H();case"relay_frame":return this.host.deliverWhisperLocal(r.topic,r.frame,void 0),await this.onWhisperFrame(r),H();case"relay_shape_poke":{const n=this.host.getWebSockets().length,i=Date.now(),o=this.onShapePoke({...r,args:C(r.args)});return this.host.recordShapePokeFanout(n,o,Date.now()-i),H()}case"relay_shape_subscribe":return rr(this.onShapeSubscribe({...r,args:C(r.args)}));default:return tr(r)}}maxRelays(){return q(this.host.env(),"LUNORA_MAX_RELAYS",ge)}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=Ue(this.host.env());o!==void 0&&(i[De]=await Be(o,n));try{return await r.fetch("https://relay.internal/_lunora/relay",{body:n,headers:i,method:"POST"})}catch{return}}}let ar=class extends ct{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(K(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=q(this.host.env(),"LUNORA_RELAY_THRESHOLD",ce.tUp),s=q(this.host.env(),"LUNORA_RELAY_COLLAPSE_THRESHOLD",ce.tDown);if(this.promotionState=Ys(this.promotionState,e,Vs(t,s)),this.promotionState==="owned")return 0;const r=q(this.host.env(),"LUNORA_MAX_RELAYS",ge),n=q(this.host.env(),"LUNORA_RELAY_FAN",Zs);return Math.min(r,Math.max(1,n))}isShapeRelayUniform(e,t){const s=J(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(K(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,re)}catch{continue}if(o===void 0||o.global===!0||!e.has(o.table))continue;const c=i.cursor,u=this.host.buildShapeDiff(o,c,t);if(u.length===0)continue;i.cursor=t;const l={args:E(i.args),checkpoint:t,epoch:r,fromCursor:c,name:i.name,rowsPatch:de(u),type:"relay_shape_poke"};for(const d of s)n.push(this.postRelayMessage(K(this.roleId.ownerKey,d),l))}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 u={args:E(n.args),checkpoint:t,epoch:s,fromCursor:o,name:n.name,rowsPatch:de(c),targetConnectionId:n.connectionId,type:"relay_shape_poke"};r.push(this.postRelayMessage(K(this.roleId.ownerKey,n.relayIndex),u))}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(l){const{body:d}=N(l,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{error:{code:d.code,message:d.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 l=J(e.name,e.args);let d=this.relayShapeRegistry.get(l);d===void 0&&(d={args:e.args,cursor:n,name:e.name},this.relayShapeRegistry.set(l,d)),c=d.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 u=ye([{rowsPatch:o,shapeId:e.subId}],{baseCheckpoint:r,checkpoint:n,epoch:i,lastMutationId:void 0,pokeId:this.host.nextPokeId()});return{cursor:c,epoch:i,frames:u}}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,re)}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=x(s.effectiveWhere),n=x(s.columns);let i=!1;const o=c=>{const u={groups:[`grp_${c}`],roles:[c],sub:`__lunora_probe_${c}__`};return{identity:new Proxy(u,{get:(l,d)=>typeof d=="symbol"||d in l?Reflect.get(l,d):`${c}:${d}`,getOwnPropertyDescriptor:(l,d)=>(i=!0,Reflect.getOwnPropertyDescriptor(l,d)),has:(l,d)=>typeof d=="symbol"?Reflect.has(l,d):!0,ownKeys:l=>(i=!0,Reflect.ownKeys(l))}),userId:`__lunora_probe_${c}__`}};return[re,o("a"),o("b")].every(c=>{let u;try{u=this.host.resolveShape(e,t,c)}catch{return!1}return u!==void 0&&u.global!==!0&&u.table===s.table&&x(u.effectiveWhere)===r&&x(u.columns)===n})&&!i}tableHasAnyMask(e){return this.host.maskMetadata().columns.some(t=>t.table===e)}},nr=class extends ct{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:E(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 k(e);for(const c of o.frames)O(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=J(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,u]of Object.entries(i)){const l=o.get(c);if(l?.cursor!==e.fromCursor||l.epoch!==e.epoch||J(u.name,u.args)!==t)continue;const d=ye([{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 d)O(r,m);o.set(c,{cursor:e.checkpoint,epoch:e.epoch}),s+=1}}return s}};const ir=a=>{const e=a.doName();if(e===void 0)return;const t=Xs(e);return t===void 0?new ar(a,e):new nr(a,t.ownerKey,t.relayIndex)},v="__lunora_reqlog__",Se=1e3,ut="lunora",B=(a,e,...t)=>a.exec.call(a,e,...t),X=(a,e=!1)=>e||a===null||a===void 0?a:Yt(a,Vt),F=a=>{B(a,`CREATE TABLE IF NOT EXISTS "${v}" (
|
|
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
|
+
)`)},Fe=a=>JSON.stringify([...new Set(a)].toSorted((e,t)=>e.localeCompare(t))),or=a=>a===void 0?null:a?1:0,cr=(a,e,t={})=>{F(a);const s=t.captureRaw??!1,r=t.retention??Se;B(a,`INSERT INTO "${v}"
|
|
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(X(e.identity,s)),e.redactedArgs===void 0?null:JSON.stringify(X(e.redactedArgs,s)),e.outcome,e.errorMessage??null,e.durationMs,Fe(e.tablesRead),Fe(e.tablesWritten),or(e.cacheHit),e.subscriptionsReRun??0),B(a,`DELETE FROM "${v}" WHERE seq <= (SELECT MAX(seq) - ? FROM "${v}")`,r)},ur=(a,e={})=>{const t=e.captureRaw??!1,s={args:a.redactedArgs===void 0?void 0:X(a.redactedArgs,t),cacheHit:a.cacheHit,durationMs:a.durationMs,error:a.errorMessage,function:a.functionPath,identity:a.identity===void 0?void 0:X(a.identity,t),outcome:a.outcome,shard:a.shardKey,source:ut,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)},dr="log",lr=a=>a.map(e=>{if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}).join(" "),hr=a=>{if(typeof a!="object"||a===null||Array.isArray(a))return!1;const e=Object.getPrototypeOf(a);return e===Object.prototype||e===null},pr=(a,e)=>a.length===2&&typeof a[0]=="string"&&hr(a[1])?{fields:Ee(a[1],e),message:a[0]}:{fields:Ee(void 0,e),message:lr(a)},fr=a=>{const e={fields:a.fields,function:a.functionPath,level:a.level,message:a.message,shard:a.shardKey,source:ut,spanId:a.spanId,traceId:a.traceId,ts:a.ts,type:dr,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)},le=a=>a.replaceAll(/[\\%_]/g,e=>`\\${e}`),We=a=>{try{const e=JSON.parse(a);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}catch{return[]}},mr=(a,e={})=>{F(a);const t=Math.max(1,Math.min(e.limit??Se,1e4)),s=["seq > ?"],r=[e.sinceSeq??0];if(e.functionPathPrefix!==void 0&&e.functionPathPrefix!==""&&(s.push(String.raw`function_path LIKE ? ESCAPE '\'`),r.push(`${le(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=`%${le(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),B(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 "${v}" 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:We(n.tables_read),tablesWritten:We(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})},yr=(a,e)=>{const t=Ms(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)}},gr=(a,e={})=>{F(a);const t=Math.max(1,Math.min(e.limit??Se,1e4)),s=["outcome = 'error'"],r=[];e.functionPathPrefix!==void 0&&e.functionPathPrefix!==""&&(s.push(String.raw`function_path LIKE ? ESCAPE '\'`),r.push(`${le(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=B(a,`SELECT function_path, error_message, ts
|
|
99
|
+
FROM "${v}" WHERE ${s.join(" AND ")} ORDER BY seq DESC LIMIT ?`,...r).toArray(),i=new Map,o=new Map;for(const u of n){const l=u.error_message??"",{culprit:d,hash:m,title:p}=Xt({functionPath:u.function_path,message:l}),S=i.get(m);if(S===void 0){i.set(m,{count:1,culprit:d,firstSeen:u.ts,hash:m,lastSeen:u.ts,sampleMessage:l,status:"open",title:p}),o.set(m,u.ts);continue}S.count+=1,S.firstSeen=Math.min(S.firstSeen,u.ts),S.lastSeen=Math.max(S.lastSeen,u.ts),u.ts>(o.get(m)??Number.NEGATIVE_INFINITY)&&(o.set(m,u.ts),S.sampleMessage=l,S.title=p)}yr(a,i);const c=[...i.values()];return(e.status===void 0?c:c.filter(u=>u.status===e.status)).toSorted((u,l)=>l.lastSeen-u.lastSeen)},Ke=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 Sr{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 br=50,Er=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},Rr=(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]},wr=(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 u=e.get(i.parentSpanId);if(u===void 0)break;i=u}for(const[c,u]of r.toReversed().entries())t.set(u.spanId,o+c+1);return t.get(s.spanId)??o}},Tr=(a,e=br)=>{const t=Er(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=Rr(n,o);if(c===void 0)continue;const u=wr(c,o),{startTs:l}=c,d=Math.max(...n.map(p=>p.startTs+p.durationMs)),m=n.map(p=>({...p.attributes===void 0?{}:{attributes:p.attributes},depth:u(p),durationMs:p.durationMs,...p.error===void 0?{}:{error:p.error},name:p.name,offsetMs:Math.max(0,p.startTs-l),ok:p.ok,parentSpanId:p.parentSpanId,spanId:p.spanId})).toSorted((p,S)=>p.offsetMs-S.offsetMs||p.depth-S.depth);r.push({durationMs:d-l,functionPath:c.functionPath,ok:n.every(p=>p.ok),rootName:c.name,...c.shardKey===void 0?{}:{shardKey:c.shardKey},spans:m,startTs:l,traceId:i})}return{total:t.size,traces:r.toSorted((n,i)=>i.startTs-n.startTs)}},He="__doc__",Ar=a=>a.startsWith("sqlite_")||a.startsWith("_cf_")||a.startsWith("__miniflare")||a.startsWith("__lunora")||a.includes("__fts_"),he=a=>`"${a.replaceAll('"','""')}"`,vr=(a,e)=>Ar(e)?!1:a.exec("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1",e).toArray().length>0,Ir=(a,e)=>{const t=e.includes(a),s=e.includes(He);if(!(!t&&!s))return t?{expression:he(a),params:[]}:{expression:`json_extract(${he(He)}, ?)`,params:[`$."${a.replaceAll('"','""')}"`]}},_r=(a,e,t,s,r,n,i)=>{const o=Ir(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 u of c.slice(0,5e3))if(i.scanned+=1,!n.has(u.ref)){if(i.references.length>=500){i.truncated=!0;continue}i.references.push({column:s,id:u.id,key:u.ref,table:t})}},kr=(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(!vr(a,n))continue;const o=he(n),c=a.exec(`PRAGMA table_info(${o})`).toArray().map(u=>u.name);for(const u of i)_r(a,o,n,u,c,s,r)}return r},Mr="lunora-ping",Nr="lunora-pong",Cr=new Set(["1","enabled","on","true","yes"]);let Qe=!1,ae;const Or=async()=>{if(!Qe){Qe=!0;try{const a=(await import("cloudflare:workers")).tracing;ae=a!==null&&typeof a=="object"&&typeof a.enterSpan=="function"?a:void 0}catch{ae=void 0}}return ae},Lr="<undelivered>",xr=1073741824,ze=1e4,qr=864e5,Pr=36e5,Q="__root__",b="*",Ge=(a,e)=>(a===void 0?"":`,"cursor":${String(a)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),$r=(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},Dr=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}},je=Bt,Ur=200,Br=20,Fr=3e4,Wr=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}},Kr=a=>typeof a=="string"&&_s.includes(a),Hr=a=>typeof a=="string"&&ks.includes(a),Qr=a=>{const e=typeof a.hash=="string"?a.hash.trim():"";if(e==="")throw new f("BAD_REQUEST","issue triage: `hash` is required");return e},dt=null,zr=a=>{const e=a.assignee;if(e===null)return dt;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)")},Gr=a=>{const e=a.severity;if(e===null)return dt;if(Hr(e))return e;throw new f("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},jr=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}},Jr=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}},Xr=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),Je=a=>typeof a=="string"&&Xr.has(a)?a:"unknown",Yr=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"}},Vr=new Set(["contains","eq","gt","gte","lt","lte","ne"]),pe=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"||!Vr.has(n)||e.push({column:r,operator:n,value:s.value})}return e.length>0?e:void 0},Zr=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"}},ea=a=>{const e=typeof a.table=="string"?a.table:"";if(e.trim()==="")throw new f("BAD_REQUEST","deleteRows: `table` is required");return{filters:pe(a.filters),limit:typeof a.limit=="number"?a.limit:void 0,search:typeof a.search=="string"?a.search:void 0,table:e}},ta=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}},ra=/\(exit (\d+)\)/,aa=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,u=i===void 0?void 0:ra.exec(i)?.[1];return{exitCode:u===void 0?void 0:Number.parseInt(u,10),functionPath:`container:${s}`,instance:c,level:n,message:i===void 0||i===""?r:`${r}: ${i}`,timestamp:o}},na=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(_))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}}},ia=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:u,to:l}=a;typeof c!="string"&&e("`subject` must be a string"),typeof l=="string"||Array.isArray(l)&&l.every(p=>typeof p=="string")||e("`to` must be a string or string[]");const d=(p,S)=>{if(p!==void 0)return(!Array.isArray(p)||!p.every(w=>typeof w=="string"))&&e(`\`${S}\` must be a string[]`),p},m=(p,S)=>(p!==void 0&&typeof p!="string"&&e(`\`${S}\` must be a string`),p);return{bcc:d(t,"bcc"),cc:d(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(u,"text"),to:l}},oa="test@lunora.sh",ca=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??oa,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}},ua=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:"",u=typeof i.outcome=="string"?i.outcome:"";o===""&&e(`\`messages[${String(n)}].messageId\` is required`),c===""&&e(`\`messages[${String(n)}].queue\` is required`),s.has(u)||e(`\`messages[${String(n)}].outcome\` must be one of ack | error | retry`);const{attempts:l,timestamp:d}=i;return{attempts:typeof l=="number"&&Number.isFinite(l)?l: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:u,queue:c,timestamp:typeof d=="number"&&Number.isFinite(d)?d:0}})},Xe=100,da=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>Xe))throw new f("BAD_REQUEST",`sendQueueMessage: \`batch\` must contain between 1 and ${String(Xe)} messages`);return{batch:s,body:a.body,contentType:typeof a.contentType=="string"?a.contentType:void 0,delaySeconds:t,exportName:e}},la=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}},ha=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}},M=a=>{throw new f("BAD_REQUEST",a)},Ye=(a,e)=>((typeof a!="string"||a.trim()==="")&&M(`rankPage: \`${e}\` is required`),a),pa=a=>{if(a===void 0)return;(typeof a!="object"||a===null||Array.isArray(a))&&M("rankPage: `after` must be an object");const e=a;return(typeof e.partitionKey!="string"||typeof e.rowId!="string"||!Array.isArray(e.sortValues))&&M("rankPage: `after` must have a string partitionKey, string rowId, and array sortValues"),{partitionKey:e.partitionKey,rowId:e.rowId,sortValues:e.sortValues}},fa=a=>{const e=Ye(a.table,"table"),t=Ye(a.index,"index");a.take!==void 0&&typeof a.take!="number"&&M("rankPage: `take` must be a number"),a.cursor!==void 0&&a.cursor!==null&&typeof a.cursor!="string"&&M("rankPage: `cursor` must be a string or null"),a.partitionKey!==void 0&&typeof a.partitionKey!="string"&&M("rankPage: `partitionKey` must be a string"),a.directions!==void 0&&!Array.isArray(a.directions)&&M("rankPage: `directions` must be an array");const s=a.directions===void 0?void 0:a.directions.map(r=>r==="desc"?"desc":"asc");return{after:pa(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}},ma=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{}},ya=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 u=c;if(u!==void 0&&typeof u._id=="string"&&u._id!==o)throw new f("BAD_REQUEST",`applyCdc: changes[${String(s)}].doc._id must match the entry id`);return{doc:u,id:o,op:n,seq:typeof r.seq=="number"?r.seq:0,table:i,ts:typeof r.ts=="number"?r.ts:0}})}},ga=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}},I=a=>a?{"x-d1-bookmark":a}:void 0,Ve=a=>{if(a)try{const e=JSON.parse(a);if(e&&typeof e=="object"&&!Array.isArray(e))return e}catch{}},Sa=a=>{if(!a)return;const e=Number(a);return Number.isInteger(e)&&e>0?e:void 0},ba=a=>{const e=new Set;for(const t of a){const s=At(t);s!==""&&e.add(s)}return e},Ea=a=>{if(a===void 0)return;const e=Number.parseInt(a,10);return Number.isFinite(e)&&e>0?e:void 0},Ra=(a,e)=>a==="1"||a==="true"?!0:a==="0"||a==="false"?!1:e,wa=a=>{if(a===void 0)return 1;const e=Number.parseFloat(a);return Number.isFinite(e)?Math.min(1,Math.max(0,e)):1},Ta=a=>a>=1?!0:a<=0?!1:Math.random()<a,ne=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 g{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(){g.rootSizeWarned=!1}static nextPollAlarmTarget(e,t,s,r){const n=[e>0?r+g.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;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:Te(),whisper:Te()};shardBinding;relay;usedIndexes=new Set;functionStats=new Map;logs=new Ft;spans=new Sr;metricSeries=new Cs;currentTracker;currentScannedTables;currentIndexHits;currentRequestReadTables;currentStmtSamples;currentRequestCacheHit;constructor(e,t,s={}){this.state=e,this.env=t,s.reactiveCache&&(this.reactiveCache=new Gt(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=Z(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=ir(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(_))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=Sa(e.headers.get("x-lunora-client-seq")),this.currentMutatorClass=void 0,this.mutationBookkeepingCommitted=!1,this.currentRequestIdentity=Ve(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=Re(this.currentRequestTraceparent);const n=this.currentRequestTrace;this.traceSampling.set(n.traceId,{keepErrors:e.headers.get("x-lunora-sample-errors")!=="0",sampled:pt(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(Ct)){const w=await this.runRelationFanoutRead(r.functionPath,r.args??{});return y(w,200,I(this.currentResponseBookmark))}const c=this.isCustomMutator(r.functionPath)?this.classifyClientMutation():void 0;this.currentMutatorClass=c;const u=this.rejectNonNextMutation(r.functionPath,c,i);if(u!==void 0)return u;const l=this.readIdempotentResult(this.currentRequestMutationId);if(l!==void 0)return this.respondFromIdempotencyCache(r.functionPath,i,c,l.value);const d=await this.handleRpc(r.functionPath,C(r.args??{}));this.recordPostDispatchBookkeeping(d,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 S=this.buildDispatchResponse(c,E(d));return await this.flushChangedTables(),S}catch(c){this.metrics.errors+=1,o={thrown:c};const u=Date.now()-i,l=c instanceof Error?c.message:String(c),d=c instanceof ss&&c.kind==="occ";return c?.code!=="FUNCTION_NOT_FOUND"&&this.recordFunctionCall(r.functionPath,u,l,this.currentScannedTables,this.currentIndexHits,d),this.flushStmtSamples(),this.recordRequestLog(r.functionPath,r.args??{},u,"error",[...this.pendingChangedTables??[]],l),this.logs.push({functionPath:r.functionPath,level:"error",message:l,timestamp:Date.now()}),this.recordChangedTable(v),await this.flushChangedTables(),this.errorToResponse(c)}finally{this.spans.hasTrace(n.traceId)&&this.recordDispatchRootSpan(r.functionPath,i,o,n),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){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(_)===!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:C(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 u=c==="too_many"?"TOO_MANY_SUBSCRIPTIONS":"SUBSCRIPTION_PERSIST_FAILED",l=c==="too_many"?`subscription cap of ${String(g.MAX_SUBSCRIPTIONS_PER_SOCKET)} reached on this socket`:"failed to persist subscription attachment";try{e.send(JSON.stringify({code:u,error:{code:u,message:l},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:C(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(_)){e.send(JSON.stringify({id:r.id,message:"streams must be public",type:"error"}));return}this.handleStream(e,r.id,r.query.functionPath,C(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 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{as(this.sql,n.connectionId)}catch{}e.serializeAttachment?.(void 0),await this.relay?.announceDrain(e)}webSocketError(e,t){}async alarm(){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()+g.GLOBAL_SHAPE_POLL_INTERVAL_MS}let s;try{s=await this.pollTtlSweeps()}catch(n){this.recordShapeError("ttl:sweep",n),s=Date.now()+g.GLOBAL_SHAPE_POLL_INTERVAL_MS}await this.flushChangedTables();const r=g.nextPollAlarmTarget(e,t,s,Date.now());r!==void 0&&await this.scheduleGlobalPoll(r)}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 u=c;if(typeof u.toArray=="function"){const l=u.toArray.bind(u);u.toArray=()=>{const d=l(),m=Date.now()-o;return t.push([n,m,d.length,0]),d}}if(typeof u.one=="function"){const l=u.one.bind(u);u.one=()=>{const d=l(),m=Date.now()-o;return t.push([n,m,1,0]),d}}if(typeof u.toArray!="function"&&typeof u.one!="function"){const l=Date.now()-o;t.push([n,l,0,0])}}else{const u=Date.now()-o;t.push([n,u,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=ht(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??je),1),je),{hasMore:s,ids:r}=Ot(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 = ?",_e).toArray().length>0?te(t,{limit:e.limit,sinceSeq:e.sinceSeq}):{changes:[],cursor:e.sinceSeq}}currentCdcCursor(){return this.cdcEnabled()?ke(this.sql):void 0}currentCdcEpoch(){return this.cdcEnabled()?Me(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=ke(r),i=Me(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=Ne(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}=te(r,{limit:ze,sinceSeq:e});if(c.length>=ze)return{cursor:n,epoch:i,resumable:!1};const u=c.some(l=>t.has(l.table));return{cursor:n,epoch:i,resumable:!u}}readIdempotentResult(e){if(e!==void 0)try{const t=ns(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{is(this.sql,this.currentRequestUserId??"",this.currentRequestMutationId,JSON.stringify(E(e)),t),t-this.lastIdempotencyTrimAt>Pr&&(os(this.sql,t-qr),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=ee(this.sql,s,e)}catch{try{cs(this.sql),r=ee(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,I(this.currentResponseBookmark)):y({error:{code:"OUT_OF_ORDER",expectedMutationId:t.expected,message:`out-of-order mutation; expected sequence ${String(t.expected)}`}},409,I(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,I(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,I(this.currentResponseBookmark));const s=this.mutationCommitCursor();return y(s===void 0?{result:t}:{commitCursor:s,result:t},200,I(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{us(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>=g.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>=g.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{ds(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)&&O(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<Br;){const o=rs(t,r,s,Ur);for(const c of o.ids)await this.deleteRowThroughWriter(r.table,c);i=o.hasMore,n+=1}}return s+Fr}scheduleTtlSweep(){return this.scheduleGlobalPoll()}currentShardKey(){return this.state.id?.name??Q}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=Tt();this.currentTracker=n;const i=this.reactiveCache.stats().hits,o=this.getCurrentUserId(),c=this.getCurrentIdentity(),u=o===void 0&&c===void 0?null:fe({claims:c??null,userId:o??null});try{const l=await this.reactiveCache.run(ve(e,t,u),n.collect(),s);return this.currentRequestCacheHit=this.reactiveCache.stats().hits>i,this.currentRequestReadTables=ba(n.collect()),l}finally{this.currentTracker=r}}getCtxDbReadHook(){return(e,t)=>{this.currentTracker?.recordRead(e,t??we),t===we&&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(Rt),await this.flushChangedTables()}recordUserLog(e,t,s,r,n,i){const o=this.currentRequestTrace,c={args:s,fields:n,functionPath:e,level:t,message:r,shardKey:this.state.id?.name,spanId:o?.rootSpanId,traceId:o?.traceId,ts:Date.now(),userId:this.getCurrentUserId()};this.logs.push({fields:n,functionPath:e,level:t,message:r,timestamp:c.ts});try{fr(c)}catch{}if(i?.onLog)try{i.onLog(c,{waitUntil:this.state.waitUntil?.bind(this.state)})}catch{}}makeLogger(e,t,s){const r=(n,i)=>{const{fields:o,message:c}=pr(i,s);this.recordUserLog(e,n,i,c,o,t)};return{debug:(...n)=>{r("debug",n)},error:(...n)=>{r("error",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 ft({anchor:s??Re(void 0),fuseCloudflareSpans:t?.fuseCloudflareTraces===!0,functionPath:e,record:r=>{this.recordSpan(r,t)},resolveCloudflareTracing:Or,shardKey:this.state.id?.name,userId:()=>this.getCurrentUserId()})}makeMetrics(e,t){return mt({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(()=>{$s(i,r,s)}),t?.onMetric&&n(()=>t.onMetric?.(r,{waitUntil:this.state.waitUntil?.bind(this.state)}))}recordDispatchRootSpan(e,t,s,r){try{this.spans.push(yt({anchor:r,durationMs:Date.now()-t,failure:s,functionPath:e,shardKey:this.state.id?.name,startTs:t,userId:this.getCurrentUserId()}))}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??Q,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=vt(this.state.storage.sql);t=i.requests,s=i.errors}catch{}let r=[];try{r=It(this.state.storage.sql)}catch{}let n=[];try{n=Ws(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??Q,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]:[],u=n?[...n].map(m=>ma(m)).filter(m=>m!==void 0):[];try{_t(this.state.storage.sql,{conflicted:i,durationMs:t,errored:s!==void 0,errorMessage:s,indexHits:u,path:e,scannedTables:c,ts:o})}catch{}const l=this.functionStats.get(e),d=l??{calls:0,conflicts:0,errors:0,lastCalledAt:o,lastErrorAt:null,lastErrorMessage:null,maxDurationMs:0,path:e,scannedTables:[],scans:0,totalDurationMs:0};d.calls+=1,d.totalDurationMs+=t,d.maxDurationMs=Math.max(d.maxDurationMs,t),d.lastCalledAt=o,c.length>0&&(d.scans+=c.length,kt(d.scannedTables,c)),s!==void 0&&(d.errors+=1,d.lastErrorAt=o,d.lastErrorMessage=s),i&&(d.conflicts+=1),l===void 0&&this.functionStats.set(e,d)}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{Fs(t,s,r,n,i)}catch{}}catch{}}collectFunctionStats(){try{return{functions:Mt(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 Nt(this.state.storage.sql)}catch{return[]}}maybeWarnRootSize(){if(g.rootSizeWarned||this.state.id?.name!==Q)return;const e=this.state.storage.sql?.databaseSize;typeof e!="number"||e<xr||(g.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}=N(e,{encodeData:E,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>Ce)return y({error:{code:"BAD_REQUEST",message:`batch exceeds the ${String(Ce)}-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,I(r))}async dispatchBatchEntry(e,t){try{const s=await this.fetch(Is(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}=N(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=Dr(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=gt(s),o=await this.runShardExport({batchSize:i.batchSize,tables:i.tables});return y({result:{rows:o}},200)}if(t===h.importShard){const i=St(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=Wr(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=ea(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=ta(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(ha(s));return y({result:i},200)}if(t===h.rankPage){const i=await this.runShardRankPage(fa(s));return y({result:i},200)}if(t===h.cdcSync){const i=this.runShardCdcSync(ga(s));return y({result:i},200)}if(t===h.applyCdc){const i=await this.runShardApplyCdc(ya(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=Qr(t),n=typeof t.updatedBy=="string"?t.updatedBy:void 0,i=this.state.storage.sql,o=Ns(i,r,s,Date.now(),n);return this.recordChangedTable(U),await this.flushChangedTables(),this.recordAudit(e.slice(_.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:zr(t),status:"open"};if(e===h.setIssueSeverity)return{severity:Gr(t)}}handleRecordAuthEvent(e){const t=sa(e);try{bt(this.state.storage.sql,{outcome:t.outcome,ts:Date.now()})}catch{}return y({result:{recorded:!0}},200)}async handleRecordContainerEvent(e){const t=aa(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(v),await this.flushChangedTables()}return y({result:{recorded:!0}},200)}async handleRunAs(e){const t=na(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=jr(e),s=await this.resolveWorkflowBinding(t.exportName).create({id:t.id,params:t.params}),r=await s.status(),n={id:s.id,status:Je(r.status)};return this.recordAudit("createWorkflowInstance",{id:s.id,detail:{exportName:t.exportName}}),y({result:n},200)}async handleGetWorkflowInstanceStatus(e){const t=Jr(e),s=await(await this.resolveWorkflowBinding(t.exportName).get(t.id)).status(),r={error:Yr(s.error),id:t.id,output:s.output,status:Je(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=ia(e),s=Ae(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleClearCapturedMail(){const e=Wt(this.state.storage.sql);return y({result:e},200)}handleSendTestMail(e){const t=ca(e),s=Ae(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleRecordQueueMessage(e){const t=ua(e),s=zs(this.state.storage.sql,t,Date.now());return y({result:s},200)}handleClearQueueMessages(){const e=Js(this.state.storage.sql);return y({result:e},200)}async handleSendQueueMessage(e){const t=da(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=la(e),s=js(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(Hs(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};Ts(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"&&!Ta(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{cr(this.state.storage.sql,e,s)}catch{}if(t.emit||e.outcome==="error")try{ur(e,s)}catch{}}requestLogConfig(){const e=this.env??{};return{captureRaw:Ie(this.env),emit:Ra(e.LUNORA_REQUEST_LOG_EMIT,Ie(this.env)),retention:Ea(e.LUNORA_REQUEST_LOG_RETENTION),sampleRate:wa(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 Qt(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 zt(this.state.storage,{bookmark:n,time:s});this.cdcEnabled()&&ps(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:wt(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:Lt(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=kr(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 xt(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=Tr(this.spans.entries());return{total:t.total,traces:t.traces}}if(e===h.getMetricSeries)return{series:this.metricSeries.entries()};if(e===h.getMetricHistory)return Us(this.sql);if(e===h.getSettings)return Zt(this.env);if(e===h.getSecurityAudit)return es(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 qt(this.state.getWebSockets().map(e=>this.readAttachment(e)))}collectFanoutMetrics(){const e=Pt(this.state.getWebSockets().map(s=>this.readAttachment(s))),t=this.relay?.relayCount()??0;return{...e,maxRelays:this.relay?.maxRelays()??ge,promoted:t>0,relayCount:t,shapePoke:this.fanout.shapePoke,sinceMs:this.metrics.sinceMs,whisper:this.fanout.whisper}}readAdminAuditLog(e,t){me(e);const s=typeof t.limit=="number"?t.limit:void 0,r=typeof t.sinceSeq=="number"?t.sinceSeq:void 0;return{result:{entries:As(e,{limit:s,sinceSeq:r})},tables:new Set([b])}}readAdminRequestLog(e,t){F(e);const s=t.outcome==="ok"||t.outcome==="error"?t.outcome:void 0;return{result:{entries:mr(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 F(e),{result:{issues:gr(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:Kr(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=Et(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=Kt(e,{limit:s})}catch{r={entries:[]}}return{result:r,tables:new Set([Ht])}}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=Gs(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:$t(e,{filters:pe(t.filters),limit:typeof t.limit=="number"?t.limit:void 0,offset:typeof t.offset=="number"?t.offset:void 0,orderBy:Zr(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:Dt(e,{column:typeof t.column=="string"?t.column:"",filters:pe(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:ts(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(Ut)){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(_)}resolveReactiveOutcomeDeduped(e,t,s,r,n){if(!this.isIdentityIndependent(e))return this.resolveReactiveOutcome(e,t,s,r);const i=ve(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=ne(e.headers.get("authorization"));return s!==void 0&&z(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>=g.MAX_STREAMS_PER_SOCKET){try{e.send(JSON.stringify({error:{code:"TOO_MANY_STREAMS",message:`stream cap of ${String(g.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 k(e),e.send(JSON.stringify({data:E(c),id:t,type:"chunk"}))}o.signal.aborted||e.send(JSON.stringify({id:t,type:"complete"}))}catch(c){const{body:u,redacted:l}=N(c,{fallbackCode:"INTERNAL_SERVER_ERROR",redactedMessage:"internal error"});l&&console.error("[@lunora/do] unhandled stream error:",c),e.send(JSON.stringify({error:{code:u.code,message:u.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 Ke(t,async i=>{if(this.isSocketExpired(i)){this.dropExpiredSocket(i);return}const o=this.readAttachment(i);for(const[c,u]of Object.entries(o.subs)){const{functionPath:l}=u;if(!l)continue;const d=l.startsWith(_),m=this.subMemos.get(i)?.get(c);if(!(m&&!m.tables.has(b)&&!$r(m.tables,e)))try{const p=await this.resolveReactiveOutcomeDeduped(l,u.args??{},d,{identity:o.identity,userId:o.userId},n);if(!p)continue;await k(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:u,sinceSeq:l}=s,d=n||l===void 0?void 0:this.evaluateResume(l,c.tables,u),m=n?void 0:d?.epoch??this.currentCdcEpoch();if(d?.resumable){this.seedSubscriptionMemo(e,t,c);try{e.send(`{"type":"resume","id":${JSON.stringify(t)}${Ge(d.cursor??0,m)}}`)}catch{}return}this.pushSubscriptionData(e,t,c,d?.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(g.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:u}=N(c,{fallbackCode:"SHAPE_RESOLVE_FAILED",redactedMessage:"shape resolution failed"});return{code:u.code,message:u.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:u}=N(c,{fallbackCode:"SHAPE_SEED_FAILED",redactedMessage:"shape seed failed"});return{code:u.code,message:u.message}}}async seedOpLogShape(e,t,s,r){const{baseCheckpoint:n,cursor:i,epoch:o,rowsPatch:c}=this.computeOpLogShapeSeed(s,r);return await k(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()?Ne(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 u=async d=>{if(this.isSocketExpired(d)){this.dropExpiredSocket(d);return}const m=this.readAttachment(d),{shapes:p}=m;if(p)try{const S={identity:m.identity,userId:m.userId},{emptyAdvanced:w,partAdvanced:lt,parts:be}=this.collectShapePokeParts(d,p,S,e,n,i,o);for(const V of w)this.recordShapeMemo(d,V,n);if(be.length>0&&(await k(d),this.sendPoke(d,be,n,s,void 0))){c+=1;for(const V of lt)this.recordShapeMemo(d,V,n)}}catch{}},l=Date.now();await Ke(r,u),this.fanout.shapePoke=Z(this.fanout.shapePoke,r.length,c,Date.now()-l)}collectShapePokeParts(e,t,s,r,n,i,o){const c=[],u=[],l=[];for(const[d,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 S=this.shapeMemos.get(e)?.get(d)?.cursor??0,w=this.buildShapeDiff(i,p,S,n,o);w.length>0?(c.push({rowsPatch:w,shapeId:d}),l.push(d)):u.push(d)}catch(p){this.recordShapeError(`shape:poke:${d}`,p)}return{emptyAdvanced:u,partAdvanced:l,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,u=new Set([t]);let l=s;for(;;){const{changes:d,cursor:m}=this.readShapeCdcPage(e,l,u);for(const p of d)c.set(p.id,p);if(d.length===0||m===l||m>=r)break;l=m}return n?.set(i,c),c}readShapeCdcPage(e,t,s){return te(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=fs(e,t.table,t.effectiveWhere,o),u=[];for(const[l,d]of i){if(c.has(l)){d.doc!==void 0&&u.push({key:l,op:d.op,table:t.table,value:ue(d.doc,t.columns)});continue}d.op!=="insert"&&u.push({key:l,op:"delete",table:t.table})}return u}buildShapeSeed(e,t){return ms(e,t.table,t.effectiveWhere).map(s=>({key:s.id,op:"insert",table:t.table,value:ue(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(g.GLOBAL_SHAPE_MAX_ROWS)}-row cap; narrow it with a shape predicate or an RLS read policy`};const{next:o,rowsPatch:c}=$e(i,new Map,{columns:s.columns,table:s.table});return await k(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:u}=$e(i,o,{columns:s.columns,table:s.table});if(u.length===0){this.recordGlobalSnapshot(e,t,c);return}await k(e),this.sendPoke(e,[{rowsPatch:u,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 ls(this.sql,e,t)}catch{return new Map}}saveGlobalSnapshot(e,t,s){if(e!=="")try{hs(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()+g.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<=g.GLOBAL_SHAPE_MAX_ROWS?!0:(this.recordShapeError(t,new Error(`global shape membership for "${s}" (${String(e)} rows) exceeds the ${String(g.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(u){n+=1,this.recordShapeError(`shape:poll:${i}`,u);continue}if(c?.global){n+=1;try{await this.refreshGlobalShape(e,i,c,s,r)}catch(u){this.recordShapeError(`shape:poll:${i}`,u)}}}return n}sendPoke(e,t,s,r,n){this.pokeSequence+=1;const i=`poke-${String(this.pokeSequence)}`,o=ye(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 ee(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(E(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=Ge(r,n),c=JSON.stringify(E(s.result??null)),u=i.get(t);if(u?.lastJson===c){u.tables=s.tables;const m=this.socketClientWatermark(e),p=m===void 0?"":`,"lastMutationId":${String(m)}`;O(e,`{"type":"settled","id":${JSON.stringify(t)}${p}${o}}`);return}const l=[],d=(u===void 0?void 0:jt(u.lastJson,s.result,s.tables.values().next().value??"",l))===void 0?O(e,`{"type":"data","id":${JSON.stringify(t)},"data":${c}${o}}`):Jt(e,t,l,o);i.set(t,{lastJson:d?c:u?.lastJson??Lr,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||!z(n,r)&&!await this.isAdminSocket(e))return!1}return!0}suppliedWsToken(e){const t=ne(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 ws(s,r))return!0;const n=ne(e.headers.get("authorization"))===void 0,i=Cr.has((t.LUNORA_REQUIRE_EPHEMERAL_WS_TOKEN??"").trim().toLowerCase());return n&&i?!1:z(r,s)}armWebSocketKeepalive(){const e=this.state.setWebSocketAutoResponse;typeof e!="function"||typeof WebSocketRequestResponsePair>"u"||e.call(this.state,new WebSocketRequestResponsePair(Mr,Nr))}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=Ve(e.headers.get("x-lunora-identity")),c=Number(e.headers.get("x-lunora-identity-exp")),u=Number.isFinite(c)&&c>0?c:void 0;return n.serializeAttachment?.({admin:t,connectionId:crypto.randomUUID(),subs:{},...u===void 0?{}:{expiresAt:u},...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 = ?",_e).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>=g.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:g.WHISPER_RATE_BURST},r=Math.min(g.WHISPER_RATE_BURST,s.tokens+(t-s.last)/1e3*g.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>g.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)&&(O(i,t),n+=1);return this.fanout.whisper=Z(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,Q as ROOT_SHARD_NAME,g as ShardDO,jt as subscriptionListDeltas};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{stableWireKey as d}from"./stableWireKey-YEHLaX6X.mjs";import{depKey as c,SCAN_DEP as y}from"./SCAN_DEP-D_yR9EeV.mjs";import{stableStringify as w}from"./stableStringify-BjLh4gvA.mjs";const u=1e3,l=4*1024*1024,m=r=>{if(r==null)return 0;try{return JSON.stringify(r).length}catch{return l}};class p{entries=new Map;tableIndex=new Map;totalBytes=0;hits=0;misses=0;evictions=0;maxEntries;maxBytes;now;monotonic=0;constructor(t={}){this.maxEntries=t.maxEntries??u,this.maxBytes=t.maxBytes??l,this.now=t.now??(()=>(this.monotonic+=1,this.monotonic))}async run(t,s,e){const i=this.entries.get(t);if(i)return this.hits+=1,i.lastUsed=this.now(),this.entries.delete(t),this.entries.set(t,i),i.result;this.misses+=1;const n=await e(),h=m(n),b={bytes:h,deps:s,lastUsed:this.now(),result:n,subscribers:new Set};this.entries.set(t,b),this.totalBytes+=h;for(const a of s){let o=this.tableIndex.get(a);o||(o=new Set,this.tableIndex.set(a,o)),o.add(t)}return this.evict(),n}invalidate(t,s){const e=[];return this.collectAndDrop(c(t,s),e),this.collectAndDrop(c(t,y),e),e}invalidateTable(t){const s=[],e=`${t}:`;for(const i of this.tableIndex.keys())i.startsWith(e)&&this.collectAndDrop(i,s);return s}subscribe(t,s){const e=this.entries.get(t);e&&e.subscribers.add(s)}unsubscribe(t,s){const e=this.entries.get(t);e&&e.subscribers.delete(s)}size(){return{bytes:this.totalBytes,entries:this.entries.size}}clear(){this.entries.clear(),this.tableIndex.clear(),this.totalBytes=0}subscribers(t){const s=this.entries.get(t);return s?[...s.subscribers]:[]}stats(){return{bytes:this.totalBytes,entries:this.entries.size,evictions:this.evictions,hits:this.hits,misses:this.misses}}collectAndDrop(t,s){const e=this.tableIndex.get(t);if(e)for(const i of e){const n=this.entries.get(i);n&&(this.dropEntry(i,n),s.push(i))}}dropEntry(t,s){this.entries.delete(t),this.totalBytes-=s.bytes;for(const e of s.deps){const i=this.tableIndex.get(e);i&&(i.delete(t),i.size===0&&this.tableIndex.delete(e))}}evict(){if(!(this.entries.size<=this.maxEntries&&this.totalBytes<=this.maxBytes))for(const[t,s]of this.entries){if(this.entries.size<=this.maxEntries&&this.totalBytes<=this.maxBytes)return;s.subscribers.size>0||(this.dropEntry(t,s),this.evictions+=1)}}}const B=(r,t,s)=>`${s??"\0anon"}\0${r}:${d(t)}`;export{p as ReactiveCache,B as reactiveCacheKey,w as stableStringify,d as stableWireKey};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t="*scan",n=(e,r)=>`${e}:${r}`,d=e=>{const r=e.indexOf(":");return r===-1?e:e.slice(0,r)},o=()=>{const e=new Set;return{collect(){return e},recordRead(r,c){e.add(n(r,c))}}};export{t as SCAN_DEP,o as createDependencyTracker,n as depKey,d as tableFromDepKey};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as h}from"./constant-time-equal-BVG05Guz.mjs";import{j as s}from"./json-response-wrh9TBPw.mjs";const d=10080*60,m=2160*60*60,c=1440*60*1e3,g="x-lunora-session-do-secret",u="x-lunora-session-token",f=/^[\w-]+$/,p=32,w=256,A=256,D=(n,e)=>{const t=e.SESSION_DO_SECRET;if(typeof t!="string"||t.length===0)return!1;const r=n.headers.get(g);return typeof r!="string"||r.length===0?!1:h(t,r)},_=n=>{let e;if(n==null)e=d;else if(typeof n=="number")e=n;else return;if(!(!Number.isFinite(e)||!Number.isInteger(e)||e<=0||e>m))return e},T=n=>{if(typeof n=="string"&&!(n.length<p||n.length>w)&&f.test(n))return n};class O{state;env;constructor(e,t){this.state=e,this.env=t}async fetch(e){const t=this.env??{};if(!D(e,t))return s({error:{code:"UNAUTHORIZED",message:"missing or invalid SessionDO secret"}},401);const r=new URL(e.url);return e.method==="POST"&&r.pathname==="/create"?this.handleCreate(e):e.method==="GET"&&r.pathname==="/get"?this.handleGet(e):e.method==="DELETE"&&r.pathname==="/revoke"?this.handleRevoke(e):s({error:{code:"NOT_FOUND",message:"no such session route"}},404)}async alarm(){const{storage:e}=this.state;if(!e.list)return;const t=Date.now(),r=await e.list({prefix:"s:"}),a=[];let i=0;for(const[o,l]of r)l.expiresAt<t?a.push(o):i+=1;for(const o of a)await e.delete(o);i>0&&e.setAlarm&&await e.setAlarm(t+c)}async handleCreate(e){let t;try{t=await e.json()}catch{return s({error:"invalid_request"},400)}const r=T(t.token);if(r===void 0)return s({error:"invalid_request"},400);const{userId:a}=t;if(typeof a!="string"||a.length===0||a.length>A)return s({error:"invalid_request"},400);const i=_(t.ttlSeconds);if(i===void 0)return s({error:"invalid_request"},400);const o=Date.now(),l={createdAt:o,expiresAt:o+i*1e3,userId:a};return await this.state.storage.put(`s:${r}`,l),await this.armGcAlarm(),s({token:r,...l},201)}async armGcAlarm(){const{storage:e}=this.state;!e.getAlarm||!e.setAlarm||await e.getAlarm()===null&&await e.setAlarm(Date.now()+c)}async handleGet(e){const t=e.headers.get(u);if(!t)return s({error:{code:"INVALID_INPUT",message:"token required"}},400);const r=await this.state.storage.get(`s:${t}`);return r?r.expiresAt<Date.now()?(await this.state.storage.delete(`s:${t}`),s({error:{code:"EXPIRED",message:"session expired"}},404)):s({token:t,...r},200):s({error:{code:"NOT_FOUND",message:"session not found"}},404)}async handleRevoke(e){const t=e.headers.get(u);return t?(await this.state.storage.delete(`s:${t}`),s({ok:!0},200)):s({error:{code:"INVALID_INPUT",message:"token required"}},400)}}export{d as SESSION_DO_TTL_DEFAULT,m as SESSION_DO_TTL_MAX,O as SessionDO};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as a}from"./json-response-wrh9TBPw.mjs";const l="__lunora_shard_registry__",i="__tables__",h=async o=>{let e;try{e=await o.json()}catch{return{kind:"error",response:a({error:{code:"BAD_REQUEST",message:"invalid JSON body"}},400)}}const t=typeof e.table=="string"?e.table.trim():"",s=typeof e.shardKey=="string"?e.shardKey.trim():"";return!t||!s?{kind:"error",response:a({error:{code:"BAD_REQUEST",message:"table and shardKey required"}},400)}:{kind:"ok",value:{shardKey:s,table:t}}};class c{env;state;tables=new Map;loaded=!1;constructor(e,t){this.state=e,this.env=t}async fetch(e){await this.ensureLoaded();const t=new URL(e.url);return e.method==="POST"&&t.pathname==="/register"?this.handleRegister(e):e.method==="POST"&&t.pathname==="/unregister"?this.handleUnregister(e):e.method==="GET"&&t.pathname==="/list"?this.handleList(t):e.method==="GET"&&t.pathname==="/snapshot"?this.handleSnapshot():a({error:{code:"NOT_FOUND",message:`unknown shard-registry route ${e.method} ${t.pathname}`}},404)}async ensureLoaded(){this.loaded||await this.state.blockConcurrencyWhile(async()=>{if(this.loaded)return;const e=await this.state.storage.get(i);if(e)for(const[t,s]of Object.entries(e))this.tables.set(t,new Set(s));this.loaded=!0})}handleList(e){const t=e.searchParams.get("table");return t?a({shardKeys:[...this.tables.get(t)??[]]},200):a({error:{code:"BAD_REQUEST",message:"missing required query parameter: table"}},400)}async handleRegister(e){const t=await h(e);if(t.kind==="error")return t.response;const{shardKey:s,table:n}=t.value;return this.state.blockConcurrencyWhile(async()=>{let r=this.tables.get(n);return r||(r=new Set,this.tables.set(n,r)),r.has(s)?a({changed:!1,ok:!0},200):(r.add(s),await this.persist(),a({changed:!0,ok:!0},200))})}handleSnapshot(){const e={};for(const[t,s]of this.tables)e[t]=[...s];return a({tables:e},200)}async handleUnregister(e){const t=await h(e);if(t.kind==="error")return t.response;const{shardKey:s,table:n}=t.value;return this.state.blockConcurrencyWhile(async()=>{const r=this.tables.get(n);return r?.has(s)?(r.delete(s),r.size===0&&this.tables.delete(n),await this.persist(),a({changed:!0,ok:!0},200)):a({changed:!1,ok:!0},200)})}async persist(){const e={};for(const[t,s]of this.tables)e[t]=[...s];await this.state.storage.put(i,e)}}export{l as SHARD_REGISTRY_DO_NAME,c as ShardRegistryDO};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const g=(e,t)=>e<t?-1:e>t?1:0,r=(e,t)=>`${e}__agg_${t}`,n=e=>{if(typeof e=="number")return Number.isFinite(e)?e:void 0},c=(e,t,l,a)=>{const u=e.get(t)??{count:0,value:null};if(l.op==="count"){u.count+=1,u.value=u.count,e.set(t,u);return}const o=n(a[l.field??""]);if(l.op==="sum"||l.op==="avg"){o!==void 0&&(u.value=(u.value??0)+o,u.count+=1),e.set(t,u);return}u.count+=1,o!==void 0&&(u.value===null?u.value=o:u.value=l.op==="min"?Math.min(u.value,o):Math.max(u.value,o)),e.set(t,u)},v=(e,t)=>e==="count"?t?.value??0:!t||t.count===0?null:e==="avg"?t.value===null?null:t.value/t.count:t.value,i=(e,t)=>{if(e.length===0)return"";const l={};for(const a of[...e].toSorted(g))l[a]=t[a]??null;return JSON.stringify(l)};export{r as aggregateTableName,n as coerceAggregateNumber,i as encodeAggregateKey,c as foldAggregateTally,v as readAggregateValue};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as D}from"@lunora/errors";import{applySelect as A}from"./applySelect-Bq2KOrkL.mjs";const v=(r,o)=>o.select?A(r,o.select,o.with):r,_=async(r,o,t,a,s)=>{const w=await Promise.all(a.map(async l=>{const m=s?{AND:[{[t]:l},s]}:{[t]:l};return[l,await r(o,m)]}));return new Map(w)},W=(r,o)=>{const t=new Set;for(const a of r){const s=a[o];s!=null&&t.add(s)}return[...t]},C=async r=>{const{groupedCounter:o,fetcher:t,parents:a,relationBaseWhere:s,schema:w,tableName:l,with:m}=r;if(a.length===0)return;const k=w.tables[l];if(!k)throw new D("INTERNAL",`unknown table: ${l}`);const O=k.relationMap??{},g=c=>{const e=O[c];if(!e)throw new D("INTERNAL",`unknown relation "${c}" on table "${l}"`);return e},M=async(c,e,n)=>{const u=W(a,e.field);if(u.length===0){for(const i of a)i[c]=null;return}const{page:p}=await t(e.table,{baseWhere:s?.(e.table),relationBaseWhere:s,where:{[e.references]:{in:u}},with:n.with}),b=new Map;for(const i of p)b.set(i[e.references],i);for(const i of a){const d=b.get(i[e.field]);i[c]=d?v([d],n)[0]??null:null}},R=async(c,e,n)=>{const u=W(a,e.references);if(u.length===0){for(const f of a)f[c]=[];return}const p={[e.field]:{in:u}},b=n.where?{AND:[n.where,p]}:p,{page:i}=await t(e.table,{baseWhere:s?.(e.table),orderBy:n.orderBy,relationBaseWhere:s,where:b,with:n.with}),d=new Map;for(const f of i){const h=f[e.field],$=d.get(h);$?$.push(f):d.set(h,[f])}const y=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;for(const f of a){const h=d.get(f[e.references])??[];f[c]=v(y===void 0?h:h.slice(0,y),n)}},N=async c=>{for(const e of Object.keys(c)){const n=g(e),[u,p]=n.kind==="many"?[n.field,n.references]:[n.references,n.field],b=s?.(n.table),i=W(a,p),d=i.length===0?new Map:await o(n.table,u,i,b);for(const y of a){const f=y._count??{},h=y[p];f[e]=h==null?0:d.get(h)??0,y._count=f}}};for(const[c,e]of Object.entries(m)){if(e===void 0||e===!1)continue;if(c==="_count"){await N(e);continue}const n=g(c),u=e===!0?{}:e;await(n.kind==="one"?M(c,n,u):R(c,n,u))}},B=async(r,o,t)=>{const{deletedId:a,deletedReference:s,findHolders:w,onCascade:l,onRestrict:m,onSetNull:k,tableName:O}=r,g=t.references==="_id"?a:s(t.references);if(g==null)return;const M=await w(o,t.field,g);if(M.length!==0){t.onDelete==="restrict"&&m(`cannot delete "${O}" row: "${o}.${t.field}" still references it`);for(const R of M){const N=R._id;typeof N=="string"&&await(t.onDelete==="cascade"?l(o,N):k(o,N,t.field))}}},E=async r=>{const{schema:o,tableName:t}=r;if(!o.tables[t])throw new D("INTERNAL",`unknown table: ${t}`);for(const[a,s]of Object.entries(o.tables)){const w=s.relationMap;if(w)for(const l of Object.values(w))l.kind!=="one"||l.table!==t||!l.onDelete||await B(r,a,l)}},I=(r,o)=>{for(const[t,a]of Object.entries(r.shape))t in o&&typeof a.parse=="function"&&a.parse(o[t])};export{E as applyOnDelete,W as distinctValues,_ as fanOutScalarCounts,C as resolveWith,I as runRowValidators};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as m}from"@lunora/errors";const a="id",h=new Set(["_id","id"]),b=t=>{const e=[];for(const r of t??[])for(const[o,s]of Object.entries(r))e.push({direction:s,field:o});return e.length===0?[{direction:"asc",field:"_creationTime"}]:e},S=t=>{const e=new TextEncoder().encode(t);let r="";for(const o of e)r+=String.fromCodePoint(o);return btoa(r)},g=t=>{const e=atob(t),r=Uint8Array.from(e,o=>o.codePointAt(0)??0);return new TextDecoder().decode(r)},A=(t,e)=>{const r=e.map(o=>t[o.field]);return r.push(t._id),S(JSON.stringify(r))},u=()=>new m("BAD_REQUEST","invalid cursor"),D=t=>{let e;try{e=JSON.parse(g(t))}catch{throw u()}if(!Array.isArray(e))throw u();return e},_=(t,e)=>{const r=t.some(s=>h.has(s.field))?t:[...t,{direction:"asc",field:a}],o=[];for(const[s,n]of r.entries()){const i=[];for(const[d,l]of r.slice(0,s).entries())i.push({[l.field]:{eq:e[d]}});const f=n.direction==="desc"?"lt":"gt";i.push({[n.field]:{[f]:e[s]}});const[c]=i;o.push(i.length===1&&c!==void 0?c:{AND:i})}return{OR:o}},y=(t,e)=>t==="desc"?e?"gte":"gt":e?"lte":"lt",E=(t,e)=>{const r=t.some(s=>h.has(s.field))?t:[...t,{direction:"asc",field:a}],o=[];for(const[s,n]of r.entries()){const i=[];for(const[l,p]of r.slice(0,s).entries())i.push({[p.field]:{eq:e[l]}});const f=s===r.length-1,c=y(n.direction,f);i.push({[n.field]:{[c]:e[s]}});const[d]=i;o.push(i.length===1&&d!==void 0?d:{AND:i})}return{OR:o}},w=["_id","_creationTime"],N=(t,e,r)=>{if(!e)return t;const o=new Set([...e,...w,...r?Object.keys(r):[]]);return t.map(s=>{const n={};for(const i of o)i in s&&(n[i]=s[i]);return n})},T=(t,e)=>t&&e!==!0?{[t.field]:{isNull:!0}}:void 0;export{N as applySelect,E as buildSeekBeforeWhere,_ as buildSeekWhere,D as decodeCursor,A as encodeCursor,b as normalizeOrderKeys,T as softDeleteScope};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as a}from"@lunora/errors";const t=()=>Object.assign(new Error("native PITR is unavailable here (local dev or a non-SQLite Durable Object); use `lunora backup restore` for off-platform recovery"),{code:"PITR_UNAVAILABLE",name:"LunoraError",status:409}),i=o=>{if(typeof o=="number")return o;const r=Date.parse(o);if(Number.isNaN(r))throw new a("BAD_REQUEST",`pitr: invalid time "${o}" — expected epoch-ms or an ISO timestamp`);return r},s=async(o,r)=>{if(!o.getCurrentBookmark)throw t();const e=await o.getCurrentBookmark();return r===void 0||!o.getBookmarkForTime?{current:e}:{current:e,forTime:await o.getBookmarkForTime(i(r))}},k=async(o,r)=>{if(!o.onNextSessionRestoreBookmark)throw t();let e=r.bookmark;if(e===void 0){if(r.time===void 0)throw new a("BAD_REQUEST","pitrRestore: provide a `bookmark` or a `time` to restore to");if(!o.getBookmarkForTime)throw t();e=await o.getBookmarkForTime(i(r.time))}const n=await o.onNextSessionRestoreBookmark(e);return{restoredTo:e,undoBookmark:n}};export{k as armRestore,s as readBookmark};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{sql as e}from"drizzle-orm";import{matchesStaticWhere as u}from"./AGGREGATE_SQL_FUNCTION-QYaiuty4.mjs";import{encodeAggregateKey as S,foldAggregateTally as E,aggregateTableName as b}from"./aggregateTableName-G-eXyjcz.mjs";import{r as f}from"./do-exec-BLe9lLrN.mjs";import{s as g,L as p,a as _,d as h,m as k}from"./do-sql-BYIQTG3z.mjs";import{param as y}from"./renderSql-B5lF5Jd9.mjs";import{sortColumnName as I,matchesRankStaticWhere as N,encodePartitionKey as O,rankTableName as A}from"./RANK_TIEBREAK-DtX8zQyc.mjs";import{t as R}from"./serialize-sql-DiRzL7A4.mjs";const M=(t,i,o)=>{const r=b(i,o.name);if(f(t,e`SELECT COUNT(*) AS count FROM ${e.identifier(r)}`).one().count>0)return;const s=o.by??[],c=new Map,m=f(t,e`SELECT id, _creationTime, ${e.identifier(g)} FROM ${e.identifier(i)}`).toArray();for(const a of m){const n=p(a);if(!n||o.where&&!u(n,o.where))continue;const d=S(s,n);E(c,d,o,n)}for(const[a,n]of c)f(t,e`INSERT INTO ${e.identifier(r)} (${_}, ${h}, ${k}) VALUES (${a}, ${n.value}, ${n.count})`)},K=(t,i)=>{for(const[o,r]of Object.entries(i.tables))if(!(r.shardMode?.kind==="global"||!r.aggregateIndexes))for(const s of r.aggregateIndexes)M(t,o,s)},x=(t,i,o)=>{const r=A(i,o.name);if(f(t,e`SELECT COUNT(*) AS count FROM ${e.identifier(r)}`).one().count>0)return;const s=o.sortBy.map((a,n)=>I(n)),c=e.join(["__id__","__partition__",...s].map(a=>e.identifier(a)),e`, `),m=f(t,e`SELECT id, _creationTime, ${e.identifier(g)} FROM ${e.identifier(i)}`).toArray();for(const a of m){const n=p(a);if(!n||o.where&&!N(n,o.where))continue;const d=O(o.partitionBy??[],n),T=o.sortBy.map(l=>R(n[l.field]??null)),$=e.join([n._id,d,...T].map(l=>y(l)),e`, `);f(t,e`INSERT INTO ${e.identifier(r)} (${c}) VALUES (${$})`)}},V=(t,i)=>{for(const[o,r]of Object.entries(i.tables))if(!(r.shardMode?.kind==="global"||!r.rankIndexes))for(const s of r.rankIndexes)x(t,o,s)};export{K as backfillAggregateIndexes,V as backfillRankIndexes};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const l=(e,t)=>`${e}__fts_${t}`,a=e=>e.toLowerCase().match(/[\p{L}\p{N}]+/gu)??[],g=e=>e.map((t,o)=>o===e.length-1?`"${t}"*`:`"${t}"`).join(" AND "),h=e=>typeof e=="string"?e:e==null?"":typeof e=="number"||typeof e=="bigint"||typeof e=="boolean"?String(e):JSON.stringify(e)??"",p=(e,t)=>{const o=a(e);if(o.length===0)return 0;let r=0;for(const[f,s]of t.entries()){const c=f===t.length-1;let n=0;for(const i of o)(c?i.startsWith(s):i===s)&&(n+=1);if(n===0)return 0;r+=n}return r};export{g as buildFtsMatch,l as ftsTableName,p as scoreDocument,h as stringifySearchText,a as tokenizeSearch};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as $}from"@lunora/errors";import{sql as i}from"drizzle-orm";const c="__relationExists",N=["eq","ne","lt","lte","gt","gte","in","notIn","isNull","contains"],h=new Set(N),p={eq:"=",gt:">",gte:">=",lt:"<",lte:"<=",ne:"<>"},I=r=>{if(r===null||typeof r!="object"||Array.isArray(r))return!1;const e=Object.keys(r);return e.length>0&&e.every(t=>h.has(t))},g=r=>typeof r=="string"?r.replaceAll(/[\\%_]/g,e=>`\\${e}`):r,L=(r,e,t)=>{const s=i`${t.serialize(g(e))}`;return t.likeContains?t.likeContains(r,s):i`${r} LIKE '%' || ${s} || '%' ESCAPE '\\'`},O=(r,e,t,s,o)=>s===null?e==="ne"?i`${r} IS NOT NULL`:i`${r} IS NULL`:i`${r} ${i.raw(t)} ${o.serialize(s)}`,y=(r,e,t,s)=>{const o=Array.isArray(t)?t:[];if(o.length===0)return e==="IN"?i`0 = 1`:i`1 = 1`;const n=i.join(o.map(l=>i`${s.serialize(l)}`),i`, `);return e==="IN"?i`${r} IN (${n})`:i`${r} NOT IN (${n})`},S=(r,e,t)=>{const s=e,o=[];for(const n of N){if(!(n in s))continue;const l=s[n],u=p[n];u?o.push(O(r,n,u,l,t)):n==="isNull"?o.push(l?i`${r} IS NULL`:i`${r} IS NOT NULL`):n==="contains"?o.push(L(r,l,t)):o.push(y(r,n==="in"?"IN":"NOT IN",l,t))}return o},A=(r,e,t)=>{const s=t.fieldRef(r);return I(e)?S(s,e,t):e===null?[i`${s} IS NULL`]:[i`${s} = ${t.serialize(e)}`]},f=(r,e)=>{if(r.length!==0)return r.length===1?r[0]:i.join(r.map(t=>i`(${t})`),i` ${i.raw(e)} `)},E=(r,e,t)=>{const s=Array.isArray(r)?r:[],o=[];for(const n of s){const l=a(n??{},t);l&&o.push(l)}return o.length===0?e==="OR"?i`0 = 1`:void 0:f(o,e)},m=new Set(["AND","NOT","OR",c]),T=(r,e,t)=>{if(r===c){if(!t.relationExists)throw new $("INTERNAL","encountered a relation EXISTS marker without a relationExists strategy hook");return t.relationExists(e)}if(r==="NOT"){const s=a(e??{},t);return s?i`NOT (${s})`:void 0}return E(e,r,t)},a=(r,e)=>{const t=[];for(const[s,o]of Object.entries(r))if(m.has(s)){const n=T(s,o,e);n&&t.push(n)}else t.push(...A(s,o,e));return f(t,"AND")},j=(r,e)=>{if(!(!r||Object.keys(r).length===0))return a(r,e)};export{j as compileWhereSql};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const c=(e,h)=>{const n=Math.max(e.length,h.length);let l=e.length^h.length;for(let t=0;t<n;t+=1){const o=t<e.length?e.charCodeAt(t):0,a=t<h.length?h.charCodeAt(t):0;l|=o^a}return l===0};export{c};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isLunoraError as E}from"@lunora/errors";const M=t=>{if(typeof t=="string")return t;try{return JSON.stringify(t)??String(t)}catch{return String(t)}},k=t=>typeof t=="boolean"||typeof t=="number"||typeof t=="string"?t:M(t),y=(t,r)=>{if(t===void 0&&r===void 0)return;const o={};if(r!==void 0)for(const[e,n]of Object.entries(r))o[e]=k(n);if(t!==void 0)for(const[e,n]of Object.entries(t))o[e]=k(n);return Object.keys(o).length===0?void 0:o},I=t=>{const r=new Uint8Array(t);crypto.getRandomValues(r);let o="";for(const e of r)o+=e.toString(16).padStart(2,"0");return o},p=/^[0-9a-f]+$/,C=t=>{if(t==null)return;const r=t.trim().toLowerCase().split("-"),[o,e,n,a]=r;if(!(r.length<4||o===void 0||o.length!==2||!p.test(o)||o==="ff"||o==="00"&&r.length!==4||e===void 0||n===void 0||a===void 0||a.length!==2||!p.test(a)||e.length!==32||n.length!==16||!p.test(e)||!p.test(n)||e==="00000000000000000000000000000000"||n==="0000000000000000"))return{parentSpanId:n,sampled:(Number.parseInt(a,16)&1)===1,traceId:e}},_=t=>{const r=C(t);return{rootSpanId:r?.parentSpanId??I(8),traceId:r?.traceId??I(16)}},K=t=>E(t)?t.code:t instanceof Error?t.constructor.name:"Error",F=(t,r)=>{if(t.isTraced){t.setAttribute("lunora.function_path",r.functionPath),t.setAttribute("lunora.ok",r.ok),t.setAttribute("lunora.duration_ms",r.durationMs),r.shardKey!==void 0&&t.setAttribute("lunora.shard_key",r.shardKey),r.userId!==void 0&&t.setAttribute("lunora.user_id",r.userId),r.error!==void 0&&(t.setAttribute("lunora.error.type",r.error.type),t.setAttribute("lunora.error.message",r.error.message));for(const[o,e]of Object.entries(r.attributes))(typeof e=="boolean"||typeof e=="number"||typeof e=="string")&&t.setAttribute(`lunora.attr.${o}`,e)}},D=t=>{const{anchor:r,fuseCloudflareSpans:o,functionPath:e,record:n,resolveCloudflareTracing:a,shardKey:s,userId:i}=t,f=l=>async(v,T,O)=>{const m=I(8),S=Date.now(),P=y(O),g={},j={setAttribute:(u,d)=>{Object.assign(g,y({[u]:d}))},setAttributes:u=>{Object.assign(g,y(u))}},w=async u=>{let d=!0,h;try{return await T(f(m),j)}catch(c){throw d=!1,h={message:c instanceof Error?c.message:String(c),type:K(c)},c}finally{const c=Date.now()-S,A=i(),b={...P,...g};try{n({...Object.keys(b).length===0?{}:{attributes:b},durationMs:c,...h===void 0?{}:{error:h},functionPath:e,name:v,ok:d,parentSpanId:l,shardKey:s,spanId:m,startTs:S,traceId:r.traceId,userId:A})}catch{}if(u!==void 0)try{F(u,{attributes:b,durationMs:c,error:h,functionPath:e,ok:d,shardKey:s,userId:A})}catch{}}};if(o===!0&&a!==void 0){const u=await a();if(u!==void 0&&typeof u.enterSpan=="function")return await u.enterSpan(v,d=>w(d))}return await w()};return f(r.rootSpanId)},N=t=>{const{functionPath:r,record:o,shardKey:e}=t,n=(a,s,i,f)=>{if(!Number.isFinite(i))return;const l=y(f);try{o({...l===void 0?{}:{attributes:l},functionPath:r,kind:a,name:s,shardKey:e,ts:Date.now(),value:i})}catch{}};return{count:(a,s=1,i)=>{n("counter",a,s,i)},gauge:(a,s,i)=>{n("gauge",a,s,i)},record:(a,s,i)=>{n("histogram",a,s,i)}}},V=t=>{const{anchor:r,durationMs:o,failure:e,functionPath:n,shardKey:a,startTs:s,userId:i}=t;return{dispatch:!0,durationMs:o,...e===void 0?{}:{error:{message:e.thrown instanceof Error?e.thrown.message:String(e.thrown),type:K(e.thrown)}},functionPath:n,name:n,ok:e===void 0,parentSpanId:"",shardKey:a,spanId:r.rootSpanId,startTs:s,traceId:r.traceId,userId:i}};export{D as a,F as b,N as c,V as d,C as m,y as n,_ as r};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as r,c as t,a as s,d as c}from"./context-telemetry-8eigmiNQ.mjs";export{r as applyCloudflareSpanAttributes,t as createMetrics,s as createTracer,c as dispatchRootSpan};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as c}from"@lunora/errors";const d=t=>{const e={args:t.args??{},enqueuedAt:typeof t.enqueuedAt=="number"?t.enqueuedAt:0,functionPath:typeof t.functionPath=="string"?t.functionPath:"",id:typeof t.id=="string"?t.id:"",scheduledFor:typeof t.scheduledFor=="number"?t.scheduledFor:0};return typeof t.attempts=="number"&&(e.attempts=t.attempts),typeof t.shardKey=="string"&&(e.shardKey=t.shardKey),e},i=t=>{const e={key:typeof t.key=="string"?t.key:"",size:typeof t.size=="number"?t.size:0},s=t.httpMetadata?.contentType??t.contentType;typeof s=="string"&&(e.contentType=s),t.customMetadata&&typeof t.customMetadata=="object"&&(e.customMetadata=t.customMetadata),typeof t.sha256=="string"&&(e.sha256=t.sha256);const{uploaded:r}=t;return typeof r=="number"?e.uploaded=r:r instanceof Date&&(e.uploaded=r.getTime()),e},f=(t={})=>{const e=()=>{if(!t.scheduler)throw new c("INTERNAL",'ctx.db.system.query("_scheduled_functions"): no scheduler configured. Pass `scheduler` to createShardDO().');return t.scheduler},s=()=>{if(!t.storage)throw new c("INTERNAL",'ctx.db.system.query("_storage"): no storage configured. Pass `storage` to createShardDO().');return t.storage},r=async()=>(await e().list()).map(a=>d(a)),y=async()=>{const{objects:a}=await s().list();return a.map(n=>i(n))};return{get:(async(a,n)=>{if(a==="_scheduled_functions"){const u=await e().get(n);return u?d(u):null}const o=await s().getMetadata(n);return o?i(o):null}),query:(a=>a==="_scheduled_functions"?{collect:r}:{collect:y})}};export{f as createSystemReader};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import{sql as i}from"drizzle-orm";import{r as T}from"./do-exec-BLe9lLrN.mjs";const s="__client_watermark",L=t=>{T(t,i`CREATE TABLE IF NOT EXISTS ${i.identifier(s)} (
|
|
2
|
+
identity TEXT NOT NULL,
|
|
3
|
+
client_id TEXT NOT NULL,
|
|
4
|
+
last_mutation_id INTEGER NOT NULL,
|
|
5
|
+
PRIMARY KEY (identity, client_id)
|
|
6
|
+
)`)},a=(t,e,n)=>T(t,i`SELECT last_mutation_id FROM ${i.identifier(s)} WHERE identity = ${e} AND client_id = ${n} LIMIT 1`).toArray()[0]?.last_mutation_id??0,c=(t,e,n,E)=>{T(t,i`INSERT INTO ${i.identifier(s)} (identity, client_id, last_mutation_id) VALUES (${e}, ${n}, ${E})
|
|
7
|
+
ON CONFLICT(identity, client_id) DO UPDATE SET last_mutation_id = MAX(last_mutation_id, excluded.last_mutation_id)`)},o="__global_shape_snapshot",O=t=>{T(t,i`CREATE TABLE IF NOT EXISTS ${i.identifier(o)} (
|
|
8
|
+
connection_id TEXT NOT NULL,
|
|
9
|
+
sub_id TEXT NOT NULL,
|
|
10
|
+
members TEXT NOT NULL,
|
|
11
|
+
PRIMARY KEY (connection_id, sub_id)
|
|
12
|
+
)`)},$=(t,e,n)=>{const E=T(t,i`SELECT members FROM ${i.identifier(o)} WHERE connection_id = ${e} AND sub_id = ${n} LIMIT 1`).toArray()[0]?.members;if(E===void 0)return new Map;try{const d=JSON.parse(E);return d===null||typeof d!="object"?new Map:new Map(Object.entries(d))}catch{return new Map}},m=(t,e,n,E)=>{const d=JSON.stringify(Object.fromEntries(E));T(t,i`INSERT INTO ${i.identifier(o)} (connection_id, sub_id, members) VALUES (${e}, ${n}, ${d})
|
|
13
|
+
ON CONFLICT(connection_id, sub_id) DO UPDATE SET members = excluded.members`)},u=(t,e,n)=>{T(t,i`DELETE FROM ${i.identifier(o)} WHERE connection_id = ${e} AND sub_id = ${n}`)},l=(t,e)=>{T(t,i`DELETE FROM ${i.identifier(o)} WHERE connection_id = ${e}`)},r="__idempotency",R=t=>{T(t,i`CREATE TABLE IF NOT EXISTS ${i.identifier(r)} (
|
|
14
|
+
identity TEXT NOT NULL,
|
|
15
|
+
mutation_id TEXT NOT NULL,
|
|
16
|
+
result_json TEXT NOT NULL,
|
|
17
|
+
ts REAL NOT NULL,
|
|
18
|
+
PRIMARY KEY (identity, mutation_id)
|
|
19
|
+
)`)},I=(t,e,n)=>{const E=T(t,i`SELECT result_json, ts FROM ${i.identifier(r)} WHERE identity = ${e} AND mutation_id = ${n} LIMIT 1`).toArray()[0];return E===void 0?void 0:{resultJson:E.result_json,ts:E.ts}},A=(t,e,n,E,d)=>{T(t,i`INSERT OR IGNORE INTO ${i.identifier(r)} (identity, mutation_id, result_json, ts) VALUES (${e}, ${n}, ${E}, ${d})`)},S=(t,e)=>{T(t,i`DELETE FROM ${i.identifier(r)} WHERE ts < ${e}`)};export{R as E,m as S,A as T,L as _,O as a,a as b,$ as d,s as e,u as l,I as m,c as o,l as p,r,o as t,S as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{sql as e}from"drizzle-orm";import{r as m}from"./do-exec-BLe9lLrN.mjs";import{s as a,L as l,T as h}from"./do-sql-BYIQTG3z.mjs";import{compileWhereSql as u}from"./compileWhereSql-BLcfs4QW.mjs";import{t as $}from"./serialize-sql-DiRzL7A4.mjs";const S={fieldRef:h,serialize:$},E=i=>{if(i.length!==0)return e`id IN (${e.join(i.map(r=>e`${r}`),e`, `)})`},c=(i,r)=>{const t=[];r&&t.push(r);const o=u(i,S);return o&&t.push(o),t.length===0?e``:e` WHERE ${e.join(t,e` AND `)}`},z=(i,r,t)=>{const o=c(t,void 0),d=m(i,e`SELECT id, _creationTime, ${e.identifier(a)} FROM ${e.identifier(r)}${o}`).toArray(),n=[];for(const s of d){const f=l(s),{id:p}=s;f!==void 0&&typeof p=="string"&&n.push({doc:f,id:p})}return n},A=(i,r,t,o)=>{if(o.length===0)return new Set;const d=c(t,E(o)),n=m(i,e`SELECT id FROM ${e.identifier(r)}${d}`).toArray();return new Set(n.map(s=>s.id))};export{A as a,z as s};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{stableStringify as u}from"./stableStringify-BjLh4gvA.mjs";const l=(t,s)=>{const o={_id:t._id};if(s){for(const e of s)Object.hasOwn(t,e)&&(o[e]=t[e]);return o}for(const[e,n]of Object.entries(t))e!=="_id"&&e!=="_creationTime"&&(o[e]=n);return o},h=(t,s,o)=>{const{columns:e,table:n}=o,i=[],d=new Map;for(const r of t){const c=l(r,e),a=String(c._id),f=u(c);d.set(a,f);const p=s.get(a);p===void 0?i.push({doc:c,id:a,op:"insert",seq:0,table:n,ts:0}):p!==f&&i.push({doc:c,id:a,op:"update",seq:0,table:n,ts:0})}for(const r of s.keys())d.has(r)||i.push({id:r,op:"delete",seq:0,table:n,ts:0});return{changes:i,nextBaseline:d}};export{h as diffExternalSource,l as projectExternalSourceRow};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{renderSql as o}from"./renderSql-B5lF5Jd9.mjs";const s=(r,e,...l)=>r.exec.call(r,e,...l),a=(r,e)=>{const{params:l,sql:n}=o("sqlite",e);return s(r,n,...l)};export{a as r};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{sql as i}from"drizzle-orm";import{r as c}from"./do-exec-BLe9lLrN.mjs";const _="__doc__",E=(t,e)=>`${t}__geo_${e}`,s=t=>`"${t.replaceAll('"','""')}"`,f=t=>t==="_id"||t==="id"?"id":t==="_creationTime"?"_creationTime":`json_extract(${_}, '$.${t.replaceAll("'","''")}')`,m=t=>i.raw(f(t)),T=(t,e)=>{const r=s(t);return e==="_id"||e==="id"?`${r}.id`:e==="_creationTime"?`${r}._creationTime`:`json_extract(${r}.${_}, '$.${e.replaceAll("'","''")}')`},I=(t,e)=>i.raw(T(t,e)),N=(t,e,r,n)=>i`CREATE ${n?i`UNIQUE `:i``}INDEX IF NOT EXISTS ${i.identifier(t)} ON ${i.identifier(e)} (${r})`,$=i.identifier("__key__"),l=i.identifier("__value__"),d=i.identifier("__count__"),S=(t,e,r,n,o)=>i`INSERT INTO ${i.identifier(t)} (${$}, ${l}, ${d}) VALUES (${e}, ${r}, ${n}) ON CONFLICT(${$}) DO UPDATE SET ${o}`,A=t=>{const e=[];for(const[r,n]of Object.entries(t.shape)){const o=n._meta?.column;o&&e.push([r,o])}return e},O=t=>{if(!t)return;const e=t[_];let r;typeof e=="string"?r=JSON.parse(e):e&&typeof e=="object"?r=e:r={};const{id:n}=t;typeof n=="string"&&(r._id=n);const o=t._creationTime;return typeof o=="number"&&(r._creationTime=o),r},a=new WeakMap,y=t=>{const e=a.get(t);if(e!==void 0)return e;let r;try{c(t,i`CREATE VIRTUAL TABLE IF NOT EXISTS ${i.identifier("__lunora_fts_probe")} USING fts5(x)`),r=!0}catch{r=!1}finally{try{c(t,i`DROP TABLE IF EXISTS ${i.identifier("__lunora_fts_probe")}`)}catch{}}return a.set(t,r),r};export{I as $,A as E,O as L,y as N,N as S,m as T,$ as a,l as d,E as g,d as m,S as p,_ as s,s as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{toErrorBody as f}from"@lunora/errors";const d=200,b=(r,s)=>{const n=t=>{const e=r.tables[t];return e?e.shardMode?.kind!=="global":!1};if(s&&s.length>0){const t=[];for(const e of s)n(e)&&t.push(e);return t}const o=[];for(const t of Object.keys(r.tables))n(t)&&o.push(t);return o},u=async function*(r,s,n=d){let o=null,t=!1;for(;!t;){const e=await r.findMany(s,{cursor:o,limit:n});for(const a of e.page)yield{doc:a,table:s};o=e.continueCursor,t=e.isDone||o===null}},k=async function*(r,s,n){const o=b(s,n.tables),t=n.batchSize??d;for(const e of o)yield*u(r,e,t)},p=new Set(["_creationTime","_id"]),y=(r,s)=>{for(const[n,o]of Object.entries(r.shape)){const t=s[n];if(t===void 0&&o.kind==="optional")continue;const e=o.parse;if(typeof e=="function")try{e(t)}catch(a){const c=a instanceof Error?a.message:String(a);return`field "${n}": ${c}`}}},h=(r,s,n)=>{const o=r.tables[s];if(!o)return`unknown table: ${s}`;if(o.shardMode?.kind==="global")return`table "${s}" is a global (.global()) table and is not importable through the shard import path`;const t=Object.fromEntries(Object.entries(n).filter(([e])=>!p.has(e)));for(const e of Object.keys(t))if(!(e in o.shape))return`unexpected field "${e}": not declared in table "${s}"`;return y(o,t)},g=async(r,s)=>{try{return await r.get(s)!==null}catch{return!1}},m=async(r,s,n,o)=>{const{doc:t,table:e}=n;if(typeof e!="string"||e.length===0)return{error:{code:"BAD_ROW",line:o,message:"row is missing `table`",table:e},kind:"error"};if(!t||typeof t!="object"||Array.isArray(t))return{error:{code:"BAD_ROW",line:o,message:"row is missing or malformed `doc`",table:e},kind:"error"};const a=h(s,e,t);if(a!==void 0)return{error:{code:"VALIDATION_ERROR",line:o,message:a,table:e},kind:"error"};const c=typeof t._id=="string"?t._id:void 0;if(c!==void 0&&await g(r,c))return{kind:"conflict"};try{return await r.insert(e,t,{allowExplicitId:!0}),{kind:"inserted",table:e}}catch(i){const{body:l}=f(i,{fallbackCode:"INSERT_FAILED"});return{error:{code:l.code,line:o,message:l.message,table:e},kind:"error"}}},A=async(r,s,n)=>{const o=[],t={};let e=0,a=(n.startLine??1)-1;for(const c of n.rows){a+=1;const i=await m(r,s,c,a);i.kind==="error"?o.push(i.error):i.kind==="conflict"?e+=1:t[i.table]=(t[i.table]??0)+1}return{conflicts:e,errors:o,inserted:t}},S=r=>{const s=Array.isArray(r.tables)?r.tables.filter(n=>typeof n=="string"):void 0;return{batchSize:typeof r.batchSize=="number"?r.batchSize:void 0,tables:s}},E=r=>{const s=Array.isArray(r.rows)?r.rows:[],n=[];for(const t of s){if(!t||typeof t!="object")continue;const e=t;if(typeof e.table!="string"||!e.doc||typeof e.doc!="object"||Array.isArray(e.doc)){n.push({doc:e.doc??{},table:typeof e.table=="string"?e.table:""});continue}n.push({doc:e.doc,table:e.table})}const o=typeof r.startLine=="number"?r.startLine:void 0;return{rows:n,startLine:o}};export{k as exportShardRows,u as exportShardTable,A as importShardRows,S as parseExportShardArgs,E as parseImportShardArgs,b as selectExportTables,h as validateImportRow};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i=async t=>{const e=t.schema.tables[t.tableName]?.triggerMap;if(e)for(const a of Object.values(e))a.timing===t.timing&&a.op===t.op&&await a.handler(t.ctx,t.event)},n=(t,e,a)=>{const r=t.tables[e]?.triggerMap;return r?Object.values(r).some(s=>s.op===a):!1};export{n as hasTrigger,i as runTriggers};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{LunoraError as f}from"@lunora/errors";import{sql as m}from"drizzle-orm";import{r as T}from"./do-exec-BLe9lLrN.mjs";import{runExternalSourceTick as v,materializeExternalRowsIncremental as A}from"./materializeExternalRows-BFmT9gsw.mjs";const h="__lunora_source_cursor",D=e=>e instanceof Date?`d:${e.toISOString()}`:typeof e=="bigint"?`b:${e.toString()}`:typeof e=="number"?`n:${e.toString()}`:`s:${e}`,O=e=>{const t=e.slice(2);switch(e[0]){case"b":return BigInt(t);case"d":return new Date(t);case"n":return Number(t);default:return t}},N=/^-?\d+$/,I=/^-?\d+(?:\.\d+)?$/,M=(e,t)=>e instanceof Date&&t instanceof Date?e.getTime()>t.getTime():typeof e=="bigint"&&typeof t=="bigint"||typeof e=="number"&&typeof t=="number"?e>t:typeof e=="string"&&typeof t=="string"&&I.test(e)&&I.test(t)?N.test(e)&&N.test(t)?BigInt(e)>BigInt(t):Number(e)>Number(t):String(e)>String(t),q=(e,t,o)=>{let r=o===null?void 0:O(o);for(const n of e){const s=n[t];if(s==null)continue;const c=s;(r===void 0||M(c,r))&&(r=c)}return r===void 0?null:D(r)},C=e=>{T(e,m`CREATE TABLE IF NOT EXISTS ${m.identifier(h)} (
|
|
2
|
+
table_name TEXT NOT NULL,
|
|
3
|
+
shard_key TEXT NOT NULL,
|
|
4
|
+
watermark TEXT,
|
|
5
|
+
last_reconcile_ms INTEGER,
|
|
6
|
+
PRIMARY KEY (table_name, shard_key)
|
|
7
|
+
)`)},j=(e,t,o)=>{const r=T(e,m`SELECT watermark, last_reconcile_ms FROM ${m.identifier(h)} WHERE table_name = ${t} AND shard_key = ${o} LIMIT 1`).toArray()[0];return{lastReconcileMs:r?.last_reconcile_ms??null,watermark:r?.watermark??null}},B=(e,t,o,r)=>{T(e,m`INSERT INTO ${m.identifier(h)} (table_name, shard_key, watermark, last_reconcile_ms)
|
|
8
|
+
VALUES (${t}, ${o}, ${r.watermark}, ${r.lastReconcileMs})
|
|
9
|
+
ON CONFLICT(table_name, shard_key) DO UPDATE SET watermark = excluded.watermark, last_reconcile_ms = excluded.last_reconcile_ms`)},x=e=>e instanceof Date?e.toISOString():typeof e=="bigint"?String(e):Array.isArray(e)?e.map(t=>x(t)):e!==null&&typeof e=="object"&&Object.getPrototypeOf(e)===Object.prototype?g(e):e,g=e=>{const t={};for(const[o,r]of Object.entries(e))t[o]=x(r);return t},z=(e,t={})=>{const{idColumn:o="id",map:r}=t,n=e[o];if(n==null)throw new f("INTERNAL",`external-source: row is missing id column "${o}"`);if(typeof n!="string"&&typeof n!="number"&&typeof n!="bigint")throw new TypeError(`external-source: id column "${o}" must be a string or number`);const s=String(n);if(r)return g({...r(e),_id:s});const c={};for(const[l,i]of Object.entries(e))l!==o&&(c[l]=i);return g({...c,_id:s})},V=(e,t,o)=>e==="manual"?!1:e===void 0||t===void 0?!0:o-t>=e.everyMs,E=async(e,t,o,r)=>{const n=await e.query(t,o);return{documents:n.map(s=>z(s,{idColumn:r.idColumn,map:r.map})),rows:n}},Y=async(e,t,o,r,n,s)=>{const c=n.tenantBy?n.tenantBy(s):[],{documents:l}=await E(o,n.query,c,n);return v(e,t,l,{columns:n.columns,table:r})},R=(e,t)=>{const o=e[t];return o!=null&&o!==!1&&o!==0},G=async(e,t,o,r,n,s,c)=>{const{cursor:l}=n;if(!l)throw new f("INTERNAL",`external-source: table "${r}" is mode "incremental" but has no \`cursor\` — this should have been rejected at defineSchema`);C(e);const i=j(e,r,s),S=n.tenantBy?n.tenantBy(s):[],_=n.reconcileEveryMs!==void 0&&(i.lastReconcileMs===null||c-i.lastReconcileMs>=n.reconcileEveryMs),w=i.watermark===null||_;let a,y;if(i.watermark===null||_){a=await E(o,n.query,S,n);const{softDeleteColumn:u}=n,p=u?a.documents.filter((k,b)=>{const d=a.rows[b];return!(d&&R(d,u))}):a.documents;({applied:y}=await v(e,t,p,{columns:n.columns,table:r}))}else{a=await E(o,l.query,[...S,O(i.watermark)],n);const{softDeleteColumn:u}=n,p=u?new Set(a.documents.flatMap((k,b)=>{const d=a.rows[b];return d&&R(d,u)?[String(k._id)]:[]})):void 0;({applied:y}=await A(t,a.documents,{columns:n.columns,deletedIds:p,table:r}))}const $=q(a.rows,l.column,i.watermark);if(w&&$===null&&a.rows.length>0)throw new f("INTERNAL",`external-source: table "${r}" (mode "incremental") pulled ${String(a.rows.length)} rows but none carry the cursor column "${l.column}" — the seed \`query\` must project it (matching \`cursor.query\`'s alias), or the watermark can never advance.`);const L=a.rows.length>0&&a.rows.every(u=>u[l.column]===null||u[l.column]===void 0);if(!w&&L)throw new f("INTERNAL",`external-source: table "${r}" (mode "incremental") pulled ${String(a.rows.length)} rows but none carry the cursor column "${l.column}" — \`cursor.query\` must project it (matching the seed \`query\`'s alias), or the watermark can never advance and every tick re-pulls the same stranded slice.`);return B(e,r,s,{lastReconcileMs:w?c:i.lastReconcileMs,watermark:$}),{applied:y}};export{R as isSoftDeleted,V as isSourceDue,z as liftSourceId,x as normalizeSourceValue,G as pullExternalSourceIncrementalTick,Y as pullExternalSourceTick};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o=(s,e=200,n)=>Response.json(s,{headers:{"content-type":"application/json",...n},status:e});export{o as j};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{applyCdcChanges as m}from"./CDC_LOG_TABLE-E_J5LPoK.mjs";import{s as f}from"./ctx-db-shapes-DzX_H5q8.mjs";import{diffExternalSource as g,projectExternalSourceRow as c}from"./diffExternalSource-DMpkJta1.mjs";import{stableStringify as p}from"./stableStringify-BjLh4gvA.mjs";const x=async(t,s,r,e)=>{const{changes:n,nextBaseline:a}=g(s,r,e);return await m(t,n),{applied:n.length,nextBaseline:a}},E=async(t,s,r)=>{const{columns:e,deletedIds:n,table:a}=r,i=[];for(const u of s){const l=c(u,e),o=String(l._id);if(n?.has(o)){await t.get(o,a)&&i.push({id:o,op:"delete",seq:0,table:a,ts:0});continue}const d=await t.get(o,a);d&&p(c({...d,_id:o},e))===p(l)||i.push({doc:l,id:o,op:"insert",seq:0,table:a,ts:0})}return await m(t,i),{applied:i.length}},w=(t,s,r)=>{const e=new Map;for(const{doc:n,id:a}of f(t,s,void 0))e.set(a,p(c({...n,_id:a},r)));return e},R=async(t,s,r,e)=>{const n=w(t,e.table,e.columns);return x(s,r,n,e)};export{x as materializeExternalRows,E as materializeExternalRowsIncremental,w as readExternalSourceBaseline,R as runExternalSourceTick};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{sql as m}from"drizzle-orm";import{MySqlDialect as s}from"drizzle-orm/mysql-core";import{PgDialect as l}from"drizzle-orm/pg-core";import{SQLiteSyncDialect as n}from"drizzle-orm/sqlite-core";const p=new l,a=new s,i=new n,q={mysql:a,postgres:p,sqlite:i},w=(r,t)=>{const{params:e,sql:o}=q[r].sqlToQuery(t);return{params:e,sql:o}},D=r=>m`${r}`;export{D as param,w as renderSql};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{sql as e}from"drizzle-orm";import{aggregateTableName as N}from"./aggregateTableName-G-eXyjcz.mjs";import{migrateCdcLog as I,migrateCdcMeta as g}from"./CDC_LOG_TABLE-E_J5LPoK.mjs";import{_ as R,E as S,a as l}from"./ctx-db-idempotency-wiVoGnpQ.mjs";import{r as _}from"./do-exec-BLe9lLrN.mjs";import{s as p,T as $,S as T,E as O,N as u,a as C,d as U,m,g as X}from"./do-sql-BYIQTG3z.mjs";import{sortColumnName as h,rankTableName as x}from"./RANK_TIEBREAK-DtX8zQyc.mjs";import{ftsTableName as B}from"./buildFtsMatch-CV0Z7PWv.mjs";const M=(i,o,r)=>{for(const n of r.indexes){const t=`${o}_${n.name}`,s=e.join(n.fields.map(a=>$(a)),e`, `);_(i,T(t,o,s,n.unique??!1))}for(const[n,t]of O(r)){if(!t.unique)continue;const s=`${o}_unique_${n}`;_(i,T(s,o,$(n),!0))}},b=(i,o,r)=>{if(!(!r.searchIndexes||r.searchIndexes.length===0||!u(i)))for(const n of r.searchIndexes){const t=B(o,n.name);_(i,e`CREATE VIRTUAL TABLE IF NOT EXISTS ${e.identifier(t)} USING fts5(${e.identifier("__text__")}, ${e.identifier("__id__")} UNINDEXED)`)}},D=(i,o,r)=>{if(r.geoIndexes)for(const n of r.geoIndexes){const t=X(o,n.name);_(i,e`CREATE TABLE IF NOT EXISTS ${e.identifier(t)} (${e.identifier("__id__")} TEXT PRIMARY KEY, ${e.identifier("__geohash__")} TEXT NOT NULL, ${e.identifier("__lat__")} REAL NOT NULL, ${e.identifier("__lng__")} REAL NOT NULL)`);const s=`${o}__geo_${n.name}__btree`;_(i,T(s,t,e`${e.identifier("__geohash__")} ASC, ${e.identifier("__id__")} ASC`,!1))}},Y=(i,o,r)=>{if(r.aggregateIndexes)for(const n of r.aggregateIndexes){const t=N(o,n.name);_(i,e`CREATE TABLE IF NOT EXISTS ${e.identifier(t)} (${C} TEXT PRIMARY KEY, ${U} REAL, ${m} INTEGER NOT NULL DEFAULT 0)`),_(i,e`PRAGMA table_info(${e.identifier(t)})`).toArray().some(s=>s.name==="__count__")||_(i,e`ALTER TABLE ${e.identifier(t)} ADD COLUMN ${m} INTEGER NOT NULL DEFAULT 0`)}},F=(i,o,r)=>{if(r.rankIndexes)for(const n of r.rankIndexes){const t=x(o,n.name),s=n.sortBy.map((f,E)=>h(E)),a=s.map(f=>e`${e.identifier(f)} BLOB`),c=a.length>0?e`, ${e.join(a,e`, `)}`:e``;_(i,e`CREATE TABLE IF NOT EXISTS ${e.identifier(t)} (${e.identifier("__id__")} TEXT PRIMARY KEY, ${e.identifier("__partition__")} TEXT NOT NULL${c})`);const d=[e`${e.identifier("__partition__")} ASC`];for(const[f,E]of s.entries()){const A=n.sortBy[f]?.direction;d.push(e`${e.identifier(E)} ${e.raw(A==="desc"?"DESC":"ASC")}`)}d.push(e`${e.identifier("__id__")} ASC`);const L=`${o}__rank_${n.name}__btree`;_(i,T(L,t,e.join(d,e`, `),!1))}},w=(i,o,r={})=>{for(const[n,t]of Object.entries(o.tables))t.shardMode?.kind!=="global"&&(_(i,e`CREATE TABLE IF NOT EXISTS ${e.identifier(n)} (
|
|
2
|
+
id TEXT PRIMARY KEY,
|
|
3
|
+
_creationTime REAL NOT NULL,
|
|
4
|
+
${e.identifier(p)} TEXT NOT NULL
|
|
5
|
+
)`),M(i,n,t),b(i,n,t),D(i,n,t),Y(i,n,t),F(i,n,t));r.cdc&&(I(i),g(i),R(i)),S(i),l(i)};export{w as runShardMigrations};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const g=/key|secret|token|password|passwd|credential|private|auth|bearer|session|cookie|salt|signature|dsn|webhook/iu,R=new Set(["LUNORA_ADMIN_TOKEN","LUNORA_WS_BEARER"]),E=["CF_PAGES_URL","WORKER_URL","LUNORA_WORKER_URL"],c=["CF_ENV","ENVIRONMENT","WORKER_ENV","NODE_ENV"],h=t=>t.length<=4?"••••":`${t.slice(0,4)}${"•".repeat(Math.min(8,t.length-4))}`,_=t=>g.test(t),v=t=>{const e=n=>typeof t[n]=="function";return e("idFromName")||e("idFromString")?"durable-object":e("createMultipartUpload")||e("put")&&e("get")&&e("list")&&e("head")?"r2":e("getWithMetadata")?"kv":e("prepare")&&e("dump")?"d1":e("send")&&e("sendBatch")?"queue":e("fetch")&&!e("get")?"service":"object"},k=t=>{const e={};for(const r of E)if(typeof t[r]=="string"&&t[r]!==""){e.workerUrl=t[r];break}for(const r of c)if(typeof t[r]=="string"&&t[r]!==""){e.environment=t[r];break}const n=t.CF_VERSION_METADATA;if(n!==null&&typeof n=="object"){const r=n;typeof r.id=="string"&&(e.deploymentId=r.id),typeof r.tag=="string"&&(e.versionTag=r.tag)}return e},A=/^(?:dev(?:elopment)?|local(?:host)?|test)$/iu,N=t=>{const e=t??{};for(const n of c){const r=e[n];if(typeof r=="string"&&A.test(r))return!0}return!1},w=t=>{const e=t??{},n=[];for(const[r,o]of Object.entries(e))if(!R.has(r)){if(typeof o=="string"){const s=_(r);n.push({kind:s?"secret":"var",name:r,value:h(o)});continue}if(typeof o=="number"||typeof o=="boolean"){n.push({kind:"var",name:r,value:String(o)});continue}if(o!==null&&typeof o=="object"){n.push({bindingType:v(o),kind:"binding",name:r,value:null});continue}n.push({kind:"var",name:r,value:null})}return n.sort((r,o)=>r.name.localeCompare(o.name)),{deploy:k(e),settings:n}},a=24,l=32,d={error:0,info:2,warning:1},u=new Set(["0","disabled","false","no","off"]),m=new Set(["1","enabled","on","true","yes"]),i=t=>typeof t=="string"?t.trim().toLowerCase():void 0,y=t=>{const e=t.AUTH_SECRET??t.BETTER_AUTH_SECRET,n=typeof e=="string"?e.trim().length:0;return n>0&&n<l?[{detail:{length:n,min:l},kind:"auth-secret-weak",level:"warning"}]:[]},O=t=>{const e=i(t.LUNORA_ALLOWED_ORIGINS),n=m.has(i(t.LUNORA_CORS_ALLOW_CREDENTIALS)??"");return(e?.split(",").some(r=>r.trim()==="*")??!1)&&n?[{kind:"cors-wildcard-credentials",level:"error"}]:[]},U=(t,e)=>{if(e)return[];const n=[];return u.has(i(t.LUNORA_SECURITY_HEADERS)??"")&&n.push({kind:"security-headers-disabled",level:"warning"}),u.has(i(t.LUNORA_SECURITY_CSRF)??"")&&n.push({kind:"csrf-disabled",level:"warning"}),i(t.BETTER_AUTH_URL)?.startsWith("http://")===!0&&n.push({kind:"cookies-insecure",level:"warning"}),n},L=t=>{const e=t??{},n=[],r=e.LUNORA_ADMIN_TOKEN;typeof r=="string"&&r.length>0&&r.length<a&&n.push({detail:{length:r.length,min:a},kind:"admin-token-weak",level:"warning"});const o=e.LUNORA_WS_BEARER,s=N(e);return(typeof o!="string"||o==="")&&n.push({kind:"ws-gate-open",level:s?"info":"error"}),s&&n.push({kind:"dev-args-unredacted",level:"warning"}),n.push(...y(e),...O(e),...U(e,s)),{findings:n.toSorted((p,f)=>d[p.level]-d[f.level])}};export{w as E,N as R,L as _,l as c,a as o};
|