@lunora/do 1.0.0-alpha.113 → 1.0.0-alpha.114

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.mjs CHANGED
@@ -1 +1 @@
1
- import{serveRelationFanout as a}from"./packem_shared/serveRelationFanout-DcSjzAZv.mjs";import{SESSION_DO_TTL_DEFAULT as t,SessionDO as c}from"./packem_shared/SESSION_DO_TTL_DEFAULT-C4oEfgFy.mjs";import{ROOT_DO_SIZE_WARN_BYTES as i,ROOT_SHARD_NAME as s,ShardDO as n}from"./packem_shared/ROOT_DO_SIZE_WARN_BYTES-C5WTIynR.mjs";import{SHARD_REGISTRY_DO_NAME as R,ShardRegistryDO as d}from"./packem_shared/SHARD_REGISTRY_DO_NAME-CF4ion0i.mjs";import{createShardAlarms as h,createShardDirectory as D,createShardHost as O,createShardKvStore as _,createShardPlatform as E,createSocketHost as m,createWorkerPlatform as u}from"@lunora/platform-cloudflare";import{REPROJECTION_MIGRATION_PREFIX as x,UNVOUCHABLE_DEP as I,applyCdcChanges as f,assertShapeShardable as A,backfillSearchIndexes as b,buildReprojectionMigration as M,clearMemoryTables as g,countLegacyRows as N,createReadFootprint as k,createShardCtxDb as y,exportShardRows as C,importShardRows as H,isSourceDue as L,markUnvouchableReads as P,pullExternalSourceIncrementalTick as F,pullExternalSourceTick as U,reprojectionMigrationId as j,reprojectionTables as v,runDataMigration as w,runShardMigrations as B,subscriptionListDeltas as G}from"@lunora/shard-engine";export{x as REPROJECTION_MIGRATION_PREFIX,i as ROOT_DO_SIZE_WARN_BYTES,s as ROOT_SHARD_NAME,t as SESSION_DO_TTL_DEFAULT,R as SHARD_REGISTRY_DO_NAME,c as SessionDO,n as ShardDO,d as ShardRegistryDO,I as UNVOUCHABLE_DEP,f as applyCdcChanges,A as assertShapeShardable,b as backfillSearchIndexes,M as buildReprojectionMigration,g as clearMemoryTables,N as countLegacyRows,k as createReadFootprint,h as createShardAlarms,y as createShardCtxDb,D as createShardDirectory,O as createShardHost,_ as createShardKvStore,E as createShardPlatform,m as createSocketHost,u as createWorkerPlatform,C as exportShardRows,H as importShardRows,L as isSourceDue,P as markUnvouchableReads,F as pullExternalSourceIncrementalTick,U as pullExternalSourceTick,j as reprojectionMigrationId,v as reprojectionTables,w as runDataMigration,B as runShardMigrations,a as serveRelationFanout,G as subscriptionListDeltas};
1
+ import{serveRelationFanout as a}from"./packem_shared/serveRelationFanout-DcSjzAZv.mjs";import{SESSION_DO_TTL_DEFAULT as t,SessionDO as c}from"./packem_shared/SESSION_DO_TTL_DEFAULT-C4oEfgFy.mjs";import{ROOT_DO_SIZE_WARN_BYTES as i,ROOT_SHARD_NAME as s,ShardDO as n}from"./packem_shared/ROOT_DO_SIZE_WARN_BYTES-B4sEEdp9.mjs";import{SHARD_REGISTRY_DO_NAME as R,ShardRegistryDO as d}from"./packem_shared/SHARD_REGISTRY_DO_NAME-CF4ion0i.mjs";import{createShardAlarms as h,createShardDirectory as D,createShardHost as O,createShardKvStore as _,createShardPlatform as E,createSocketHost as m,createWorkerPlatform as u}from"@lunora/platform-cloudflare";import{REPROJECTION_MIGRATION_PREFIX as x,UNVOUCHABLE_DEP as I,applyCdcChanges as f,assertShapeShardable as A,backfillSearchIndexes as b,buildReprojectionMigration as M,clearMemoryTables as g,countLegacyRows as N,createReadFootprint as k,createShardCtxDb as y,exportShardRows as C,importShardRows as H,isSourceDue as L,markUnvouchableReads as P,pullExternalSourceIncrementalTick as F,pullExternalSourceTick as U,reprojectionMigrationId as j,reprojectionTables as v,runDataMigration as w,runShardMigrations as B,subscriptionListDeltas as G}from"@lunora/shard-engine";export{x as REPROJECTION_MIGRATION_PREFIX,i as ROOT_DO_SIZE_WARN_BYTES,s as ROOT_SHARD_NAME,t as SESSION_DO_TTL_DEFAULT,R as SHARD_REGISTRY_DO_NAME,c as SessionDO,n as ShardDO,d as ShardRegistryDO,I as UNVOUCHABLE_DEP,f as applyCdcChanges,A as assertShapeShardable,b as backfillSearchIndexes,M as buildReprojectionMigration,g as clearMemoryTables,N as countLegacyRows,k as createReadFootprint,h as createShardAlarms,y as createShardCtxDb,D as createShardDirectory,O as createShardHost,_ as createShardKvStore,E as createShardPlatform,m as createSocketHost,u as createWorkerPlatform,C as exportShardRows,H as importShardRows,L as isSourceDue,P as markUnvouchableReads,F as pullExternalSourceIncrementalTick,U as pullExternalSourceTick,j as reprojectionMigrationId,v as reprojectionTables,w as runDataMigration,B as runShardMigrations,a as serveRelationFanout,G as subscriptionListDeltas};
@@ -1,4 +1,4 @@
1
- import{LunoraError as p,toErrorBody as $,isLunoraError as Et}from"@lunora/errors";import{ISSUE_SEVERITIES as vt,ISSUE_STATUSES as wt,ensureRequestLogTable as ot,readRequestLog as Tt,readErrorIssues as Ct,findDanglingReferences as kt,readAuthMetrics as _t,readQueryInsights as It,LogBuffer as Mt,SpanBuffer as Ot,MetricBuffer as Nt,emitLogEvent as qt,resolveTraceAnchor as G,createTracer as xt,instrumentDatabase as Dt,createTracedFetch as Pt,createMetrics as Lt,redactArgs as Bt,REQUEST_LOG_TABLE as _e,createDatabaseTally as Ut,formatTally as Ht,dispatchRootSpan as Ft,readFunctionMetricsTotals as Wt,readFunctionMetricIndexHits as $t,readQueryMetrics as Kt,recordFunctionMetric as Qt,mergeScanAttribution as jt,FUNCTION_METRICS_MAX_PATHS as Gt,recordQueryMetric as zt,readFunctionMetrics as Jt,readFunctionMetricBuckets as Xt,upsertIssueState as Vt,ISSUE_STATE_TABLE as Yt,recordAuthEvent as Zt,explainIssue as er,appendRequestLogEntry as tr,emitRequestLogEvent as rr,foldTraces as sr,readMetricHistory as nr,buildSecurityAudit as ir,parseLogArgs as or,createSpanCollector as ar,recordMetricHistory as cr}from"@lunora/observability";import{createShardHost as dr,createSocketHost as lr}from"@lunora/platform-cloudflare";import{tableFromDepKey as ur,ADMIN_FUNCTION_PREFIX as I,ensureAuditTable as hr,readAuditLog as pr,ADMIN_FUNCTIONS as h,facetColumn as fr,runReadonlySql as mr,findStorageReferences as yr,readCapturedMail as Sr,MAIL_TABLE as br,readQueueMessages as gr,QUEUE_TABLE as Rr,envOptionalPositiveInt as ge,cdcSeqLeavingRows as te,readCdcArchivedThrough as Ar,readCdcChanges as at,archiveCdcSegment as Er,writeCdcArchivedThrough as vr,readArchivedCdcChanges as wr,compactCdcDocs as Tr,trimCdcChanges as Cr,renderSql as Ie,sqliteInList as kr,DOC_COLUMN as Me,readSchemaVersion as _r,readSchemaHistory as Ir,lintReadonlySql as Mr,createShapeProbeCounters as Or,createGlobalPollCounters as Nr,DurableStreamRunner as qr,createFanoutCounters as Oe,ShardRunner as xr,ReactiveCache as Dr,createRelayLink as Pr,listTables as re,minCdcReplayableSeq as Lr,createReplicaLink as Br,readReactorState as Ur,reactorNeedsRun as Hr,MAX_PAGE_SIZE as Fr,selectMatchingIds as Wr,CDC_LOG_TABLE as Ne,minCdcSeq as se,cursorBelowRetainedFloor as z,cdcTrimmedError as $r,readCdcCursor as qe,readCdcEpoch as ne,bumpCdcEpoch as xe,cdcCanVouchFor as Kr,cdcTouchesTables as Qr,readIdempotent as jr,writeIdempotent as Gr,trimIdempotent as zr,readClientWatermark as ie,migrateClientWatermark as Jr,advanceClientWatermark as Xr,deleteGlobalShapeSnapshot as Vr,deleteShapePokeCursor as Yr,trySendFrame as A,selectExpiredIds as Zr,createDependencyTracker as es,createReadFootprint as ts,stableStringify as rs,reactiveCacheKey as De,SCAN_DEP as J,TransactionHeadroomTracker as oe,recordChangedKeys as ss,DATA_MIGRATION_STATE_TABLE as ns,isDevEnvironment as N,gateReplicaDispatch as is,RELATION_FUNCTION_PREFIX as os,ConflictError as as,deleteGlobalShapeSnapshotsForConnection as cs,deleteShapePokeCursorsForConnection as ds,parseExportShardArgs as ls,parseImportShardArgs as us,writeReactorState as Pe,UNVOUCHABLE_DEP as Le,listReactorStates as hs,recordCapturedMail as Be,clearCapturedMail as ps,recordQueueMessages as fs,clearQueueMessages as ms,readQueueMessageById as ys,isLossyBody as Ss,appendAuditEntry as bs,readBookmark as gs,armRestore as Rs,readMigrationStatus as As,buildSettings as Es,summarizeSubscriptions as vs,summarizeFanoutTopics as ws,DEFAULT_MAX_RELAYS as Ts,readTablePage as Cs,FLAGS_FUNCTION_PREFIX as ks,awaitWsDrain as B,stableWireKey as _s,mergeChangedKeys as Is,runSocketPool as Ue,createShapeDiffCache as ae,writeShapePokeCursors as Ms,recordFanoutPass as ce,recordShapeProbePass as He,minShapePokeCursor as Os,readCdcChangeKeys as Ns,buildShapeDiff as qs,selectShapeRows as xs,projectColumns as Ds,diffGlobalMembership as Fe,readGlobalShapeSnapshot as Ps,writeGlobalShapeSnapshot as Ls,GlobalPollTick as de,globalShapeReadKey as Bs,recordGlobalPollPass as Us,buildPokeFrames as Hs,readShapePokeCursor as Fs,writeShapePokeCursor as Ws,subscriptionFrames as $s,handleReplicaControl as Ks,writeTouchesMemo as Qs}from"@lunora/shard-engine";import{subscriptionListDeltas as Co}from"@lunora/shard-engine";import{drizzle as js}from"drizzle-orm/durable-sqlite";import{c as le}from"./constant-time-equal-BRh9yUCr.mjs";import{j as v}from"./json-response-wrh9TBPw.mjs";import{sql as M}from"drizzle-orm";const We=500,Y=(i,e)=>{if(i.size<e)return;const t=i.keys().next().value;t!==void 0&&i.delete(t)},ue=i=>{let e="";for(let r=0;r<i.length;r+=32768)e+=String.fromCharCode(...i.subarray(r,r+32768));return btoa(e)},ct=i=>{const e=atob(i),t=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)t[r]=e.codePointAt(r)??0;return t},Ee=i=>{const e=i.replaceAll("-","+").replaceAll("_","/"),t=e+"=".repeat((4-e.length%4)%4);return ct(t)},dt=new TextDecoder;new TextEncoder;const $e="=",Gs=i=>{if(i)try{const e=i[0]==="{"?i:dt.decode(Ee(i)),t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}},Ke=i=>{if(i){if(!i.startsWith($e))return i;try{return dt.decode(Ee(i.slice($e.length)))}catch{return}}},zs=i=>{const e=Number(i);return Number.isFinite(e)&&e>0?e:void 0},Js=i=>typeof i=="number"&&Date.now()>=i,Xs=i=>{try{i.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},type:"error"})),i.close?.(4001,"token_expired")}catch{}};Array.from({length:256},(i,e)=>e.toString(16).padStart(2,"0"));const X=/^[0-9a-f]+$/,Vs=i=>{if(i==null)return;const e=i.trim().toLowerCase().split("-"),[t,r,n,s]=e;if(!(e.length<4||t===void 0||t.length!==2||!X.test(t)||t==="ff"||t==="00"&&e.length!==4||r===void 0||n===void 0||s===void 0||s.length!==2||!X.test(s)||r.length!==32||n.length!==16||!X.test(r)||!X.test(n)||r==="00000000000000000000000000000000"||n==="0000000000000000"))return{parentSpanId:n,sampled:(Number.parseInt(s,16)&1)===1,traceId:r}},he=Object.freeze({durationMs:"lunora.duration_ms",errorMessage:"error.message",errorType:"error.type",functionPath:"lunora.function_path",ok:"lunora.ok",shardKey:"lunora.shard_key",userId:"lunora.user_id"}),T="$lunora.wire$",Z=64,Qe=1024,Re="__proto__",je={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},Ge={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},Ys=i=>{if(i===null||typeof i!="object")return!1;const e=Object.getPrototypeOf(i);return e===null||e===Object.prototype},w=(i,e=0)=>{if(e>Z)throw new RangeError(`wire-codec: value nesting exceeds the ${Z}-level limit`);if(i===void 0)return[T,"undefined"];if(i===null)return null;const t=typeof i;if(t==="bigint")return[T,"bigint",i.toString()];if(t==="number"){const s=i;return Number.isNaN(s)?[T,"nan"]:s===1/0?[T,"inf"]:s===-1/0?[T,"-inf"]:s}if(t!=="object")return i;if(i instanceof Date)return[T,"date",w(i.getTime(),e+1)];if(i instanceof Error){const s=i,o={};for(const c of Object.keys(s))s[c]!==void 0&&(o[c]=w(s[c],e+1));const a=[T,"error",s.name,s.message,o];return s.cause!==void 0&&a.push(w(s.cause,e+1)),a}if(i instanceof URL)return[T,"url",i.href];if(i instanceof Map)return[T,"map",[...i.entries()].map(([s,o])=>[w(s,e+1),w(o,e+1)])];if(i instanceof Set)return[T,"set",[...i].map(s=>w(s,e+1))];if(i instanceof ArrayBuffer)return[T,"bytes",ue(new Uint8Array(i)),"ArrayBuffer"];if(ArrayBuffer.isView(i)){const s=i,o=s.constructor.name,a=new Uint8Array(s.buffer,s.byteOffset,s.byteLength);return o==="Uint8Array"?[T,"bytes",ue(a)]:[T,"bytes",ue(a),o]}if(Array.isArray(i)){const s=i.map(o=>w(o,e+1));return s.length>0&&s[0]===T?[T,"arr",s]:s}if(!Ys(i)){const s=i.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${s} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const r=i,n={};for(const s of Object.keys(r)){const o=r[s];if(o===void 0)continue;const a=w(o,e+1);s===Re?Object.defineProperty(n,s,{configurable:!0,enumerable:!0,value:a,writable:!0}):n[s]=a}return n},C=(i,e=0)=>{if(e>Z)throw new RangeError(`wire-codec: value nesting exceeds the ${Z}-level limit`);if(i===null||typeof i!="object")return i;if(Array.isArray(i)){if(i[0]===T)switch(i[1]){case"-inf":return-1/0;case"arr":return i[2].map(s=>C(s,e+1));case"bigint":{const s=i[2];if(typeof s!="string"||s.length>Qe||!/^-?\d+$/.test(s))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${Qe} digits)`);return BigInt(s)}case"date":return new Date(C(i[2],e+1));case"map":{const s=i[2];return new Map(s.map(o=>{if(!Array.isArray(o)||o.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[C(o[0],e+1),C(o[1],e+1)]}))}case"set":return new Set(i[2].map(s=>C(s,e+1)));case"url":return new URL(i[2]);case"error":{const s=i[2],o=i[3],a=(Object.hasOwn(Ge,s)?Ge[s]:void 0)??Error,c=new a(o);c.name!==s&&Object.defineProperty(c,"name",{configurable:!0,value:s,writable:!0});const d=C(i[4],e+1);for(const u of Object.keys(d))u===Re?Object.defineProperty(c,u,{configurable:!0,enumerable:!0,value:d[u],writable:!0}):c[u]=d[u];return i.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:C(i[5],e+1),writable:!0}),c}case"bytes":{const s=ct(i[2]),o=i[3]??"Uint8Array";if(o==="ArrayBuffer")return s.buffer.byteLength===s.byteLength?s.buffer:s.slice().buffer;const a=Object.hasOwn(je,o)?je[o]:void 0;return a?new a(s.slice().buffer):s}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return i.map(s=>C(s,e+1))}return i.map(n=>C(n,e+1))}const t=i,r={};for(const n of Object.keys(t)){const s=C(t[n],e+1);n===Re?Object.defineProperty(r,n,{configurable:!0,enumerable:!0,value:s,writable:!0}):r[n]=s}return r},Zs="pageDelta",en=(i,e,t,r)=>{const n=i.get(e);if(n!==void 0)return n;Y(i,r);const s=t().catch(o=>{throw i.get(e)===s&&i.delete(e),o});return i.set(e,s),s},lt=new TextEncoder,tn=Array.from({length:32},(i,e)=>e);new RegExp(`[${tn.map(i=>String.fromCodePoint(i)).join("")}]`,"u");const rn=64,sn=new Map,nn=async i=>en(sn,i,async()=>crypto.subtle.importKey("raw",lt.encode(i),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),rn),on=async(i,e,t)=>{const r=await nn(i);return crypto.subtle.verify("HMAC",r,t,lt.encode(e))},an=new Set(["1","enabled","on","true","yes"]),cn=new Set(["0","disabled","false","no","off"]),dn=(i,e)=>{const t=(i??"").trim().toLowerCase();return an.has(t)?!0:cn.has(t)?!1:e},ln="v1",un=async(i,e,t=Date.now())=>{if(i.length===0||e.length===0)return!1;const r=e.split(".");if(r.length!==3)return!1;const[n,s,o]=r;if(n!==ln||o.length===0)return!1;const a=Number(s);if(!Number.isFinite(a)||a<=t)return!1;let c;try{c=Ee(o)}catch{return!1}return on(i,`${n}.${s}`,c)},ut="__lunoraBranch",hn=i=>typeof i=="object"&&i!==null&&Object.hasOwn(i,ut),pn=`may not contain the reserved workflow branch-marker key ("${ut}")`,fn=/\(exit (\d+)\)/,mn=new Set(["contains","eq","gt","gte","lt","lte","ne"]),ze=100,yn="test@lunora.sh",Sn=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),ht=null,Je=(i,e)=>(i===void 0?"":`,"cursor":${String(i)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),bn=(i,e)=>{const[t,r]=i.size<=e.size?[i,e]:[e,i];for(const n of t)if(r.has(n))return!0;return!1},gn=i=>{const e=typeof i.id=="string"?i.id:"";if(e.trim()==="")throw new p("MIGRATION_ID_REQUIRED","runMigration: `id` is required",{status:400});return{batchSize:typeof i.batchSize=="number"?i.batchSize:void 0,direction:i.direction==="down"?"down":"up",dryRun:i.dryRun===!0,id:e,maxBatches:typeof i.maxBatches=="number"?i.maxBatches:void 0}},Rn=i=>{const{op:e}=i,t=typeof i.table=="string"?i.table:"";if(e!=="insert"&&e!=="patch"&&e!=="replace"&&e!=="delete")throw new p("BAD_REQUEST","writeRow: `op` must be insert|patch|replace|delete");if(t.trim()==="")throw new p("BAD_REQUEST","writeRow: `table` is required");const r=typeof i.id=="string"?i.id:void 0,n=typeof i.doc=="object"&&i.doc!==null&&!Array.isArray(i.doc)?i.doc:void 0;if(e!=="insert"&&(r===void 0||r===""))throw new p("BAD_REQUEST",`writeRow: \`id\` is required for op "${e}"`);if(e!=="delete"&&n===void 0)throw new p("BAD_REQUEST",`writeRow: \`doc\` is required for op "${e}"`);return{doc:n,id:r,op:e,table:t}},An=i=>typeof i=="string"&&wt.includes(i),En=i=>typeof i=="string"&&vt.includes(i),vn=i=>{const e=typeof i.hash=="string"?i.hash.trim():"";if(e==="")throw new p("BAD_REQUEST","issue triage: `hash` is required");return e},wn=i=>{const e=i.assignee;if(e===null)return ht;if(typeof e=="string"&&e.trim()!=="")return e;throw new p("BAD_REQUEST","assignIssue: `assignee` must be a non-empty string (assign) or null (unassign)")},Tn=i=>{const e=i.severity;if(e===null)return ht;if(En(e))return e;throw new p("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},Cn=i=>{const e=typeof i.exportName=="string"?i.exportName.trim():"";if(e==="")throw new p("BAD_REQUEST","createWorkflowInstance: `exportName` is required");const t=typeof i.id=="string"&&i.id!==""?i.id:void 0;if(hn(i.params))throw new p("BAD_REQUEST",`createWorkflowInstance: params ${pn}`);return{exportName:e,id:t,params:i.params}},kn=i=>{const e=typeof i.exportName=="string"?i.exportName.trim():"",t=typeof i.id=="string"?i.id.trim():"";if(e==="")throw new p("BAD_REQUEST","getWorkflowInstanceStatus: `exportName` is required");if(t==="")throw new p("BAD_REQUEST","getWorkflowInstanceStatus: `id` is required");return{exportName:e,id:t}},Xe=i=>typeof i=="string"&&Sn.has(i)?i:"unknown",_n=i=>{if(typeof i!="object"||i===null)return;const{message:e,name:t}=i;return{message:typeof e=="string"?e:"",name:typeof t=="string"?t:"Error"}},ee=i=>{if(!Array.isArray(i))return;const e=[];for(const t of i){if(typeof t!="object"||t===null)continue;const r=t,{column:n,operator:s}=r;typeof n!="string"||n===""||typeof s!="string"||!mn.has(s)||e.push({column:n,operator:s,value:r.value})}return e.length>0?e:void 0},In=i=>{if(typeof i!="object"||i===null)return;const{column:e,direction:t}=i;if(!(typeof e!="string"||e===""))return{column:e,direction:t==="desc"?"desc":"asc"}},Mn=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","deleteRows: `table` is required");return{filters:ee(i.filters),limit:typeof i.limit=="number"?i.limit:void 0,search:typeof i.search=="string"?i.search:void 0,table:e}},On=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","patchRows: `table` is required");const t=i.doc,r=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0;if(r===void 0||Object.keys(r).length===0)throw new p("BAD_REQUEST","patchRows: `doc` must be a non-empty object of fields to set");return{after:typeof i.after=="string"?i.after:void 0,doc:r,filters:ee(i.filters),limit:typeof i.limit=="number"?i.limit:void 0,search:typeof i.search=="string"?i.search:void 0,table:e}},Nn=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","clearTable: `table` is required");return{limit:typeof i.limit=="number"?i.limit:void 0,table:e}},qn=i=>{const{outcome:e}=i;if(e!=="ok"&&e!=="fail")throw new p("BAD_REQUEST",'recordAuthEvent: `outcome` must be "ok" or "fail"');return{outcome:e}},xn=i=>{const e=i.event;if(typeof e!="object"||e===null||Array.isArray(e))throw new p("BAD_REQUEST","recordContainerEvent: `event` must be an object");const t=e,r=typeof t.container=="string"?t.container:"",n=typeof t.event=="string"?t.event:"";if(r.trim()===""||n.trim()==="")throw new p("BAD_REQUEST","recordContainerEvent: `event.container` and `event.event` are required");const s=t.level==="error"?"error":"info",o=typeof t.message=="string"?t.message:void 0,a=typeof t.ts=="number"?t.ts:Date.now(),c=typeof t.instance=="string"&&t.instance!==""?t.instance:void 0,d=o===void 0?void 0:fn.exec(o)?.[1];return{exitCode:d===void 0?void 0:Number.parseInt(d,10),functionPath:`container:${r}`,instance:c,level:s,message:o===void 0||o===""?n:`${n}: ${o}`,timestamp:a}},Dn=i=>{const e=typeof i.functionPath=="string"?i.functionPath:"",t=typeof i.userId=="string"?i.userId:"";if(e.trim()==="")throw new p("BAD_REQUEST","runAs: `functionPath` is required");if(e.startsWith(I))throw new p("BAD_REQUEST","runAs: cannot target a reserved admin function");if(t.trim()==="")throw new p("BAD_REQUEST","runAs: `userId` is required");const r=i.args;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new p("BAD_REQUEST","runAs: `args` must be an object");const n=i.identity;if(n!==void 0&&(typeof n!="object"||n===null||Array.isArray(n)))throw new p("BAD_REQUEST","runAs: `identity` must be an object");return{args:r===void 0?{}:r,functionPath:e,userId:t,...n===void 0?{}:{identity:n}}},Pn=i=>{const e=m=>{throw new p("BAD_REQUEST",`recordMail: ${m}`)},{bcc:t,cc:r,from:n,headers:s,html:o,replyTo:a,subject:c,text:d,to:u}=i;typeof c!="string"&&e("`subject` must be a string"),typeof u=="string"||Array.isArray(u)&&u.every(m=>typeof m=="string")||e("`to` must be a string or string[]");const f=(m,g)=>{if(m!==void 0)return(!Array.isArray(m)||!m.every(b=>typeof b=="string"))&&e(`\`${g}\` must be a string[]`),m},y=(m,g)=>(m!==void 0&&typeof m!="string"&&e(`\`${g}\` must be a string`),m);return{bcc:f(t,"bcc"),cc:f(r,"cc"),from:y(n,"from"),headers:s!==void 0&&typeof s=="object"&&s!==null?s:void 0,html:y(o,"html"),replyTo:y(a,"replyTo"),subject:c,text:y(d,"text"),to:u}},Ln=i=>{const{to:e}=i;if(e!==void 0&&typeof e!="string")throw new p("BAD_REQUEST","sendTestMail: `to` must be a string");const t=e??yn,r="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="${r}">Verify your email</a></p>`,subject:"Lunora test email",text:`This is a test email from the Lunora dev mail catcher.
1
+ import{LunoraError as p,toErrorBody as $,isLunoraError as Et}from"@lunora/errors";import{ISSUE_SEVERITIES as vt,ISSUE_STATUSES as wt,ensureRequestLogTable as ot,readRequestLog as Tt,readErrorIssues as Ct,findDanglingReferences as kt,readAuthMetrics as _t,readQueryInsights as It,LogBuffer as Mt,SpanBuffer as Ot,MetricBuffer as Nt,emitLogEvent as qt,resolveTraceAnchor as G,createTracer as xt,instrumentDatabase as Dt,createTracedFetch as Pt,createMetrics as Lt,redactArgs as Bt,REQUEST_LOG_TABLE as _e,createDatabaseTally as Ut,formatTally as Ht,dispatchRootSpan as Ft,readFunctionMetricsTotals as Wt,readFunctionMetricIndexHits as $t,readQueryMetrics as Kt,recordFunctionMetric as Qt,mergeScanAttribution as jt,FUNCTION_METRICS_MAX_PATHS as Gt,recordQueryMetric as zt,readFunctionMetrics as Jt,readFunctionMetricBuckets as Xt,upsertIssueState as Vt,ISSUE_STATE_TABLE as Yt,recordAuthEvent as Zt,explainIssue as er,appendRequestLogEntry as tr,emitRequestLogEvent as rr,foldTraces as sr,readMetricHistory as nr,buildSecurityAudit as ir,parseLogArgs as or,createSpanCollector as ar,recordMetricHistory as cr}from"@lunora/observability";import{createShardHost as dr,createSocketHost as lr}from"@lunora/platform-cloudflare";import{tableFromDepKey as ur,ADMIN_FUNCTION_PREFIX as I,ensureAuditTable as hr,readAuditLog as pr,ADMIN_FUNCTIONS as h,facetColumn as fr,runReadonlySql as mr,findStorageReferences as yr,readCapturedMail as Sr,MAIL_TABLE as br,readQueueMessages as gr,QUEUE_TABLE as Rr,envOptionalPositiveInt as ge,cdcSeqLeavingRows as te,readCdcArchivedThrough as Ar,readCdcChanges as at,archiveCdcSegment as Er,writeCdcArchivedThrough as vr,readArchivedCdcChanges as wr,compactCdcDocs as Tr,trimCdcChanges as Cr,renderSql as Ie,sqliteInList as kr,DOC_COLUMN as Me,readSchemaVersion as _r,readSchemaHistory as Ir,lintReadonlySql as Mr,createShapeProbeCounters as Or,createGlobalPollCounters as Nr,DurableStreamRunner as qr,createFanoutCounters as Oe,ShardRunner as xr,ReactiveCache as Dr,createRelayLink as Pr,listTables as re,minCdcReplayableSeq as Lr,createReplicaLink as Br,readReactorState as Ur,reactorNeedsRun as Hr,MAX_PAGE_SIZE as Fr,selectMatchingIds as Wr,CDC_LOG_TABLE as Ne,minCdcSeq as se,cursorBelowRetainedFloor as z,cdcTrimmedError as $r,readCdcCursor as qe,readCdcEpoch as ne,bumpCdcEpoch as xe,cdcCanVouchFor as Kr,cdcTouchesTables as Qr,readIdempotent as jr,writeIdempotent as Gr,trimIdempotent as zr,readClientWatermark as ie,migrateClientWatermark as Jr,advanceClientWatermark as Xr,deleteGlobalShapeSnapshot as Vr,deleteShapePokeCursor as Yr,trySendFrame as A,selectExpiredIds as Zr,createDependencyTracker as es,createReadFootprint as ts,stableStringify as rs,reactiveCacheKey as De,SCAN_DEP as J,TransactionHeadroomTracker as oe,recordChangedKeys as ss,DATA_MIGRATION_STATE_TABLE as ns,isDevEnvironment as N,gateReplicaDispatch as is,RELATION_FUNCTION_PREFIX as os,ConflictError as as,deleteGlobalShapeSnapshotsForConnection as cs,deleteShapePokeCursorsForConnection as ds,parseExportShardArgs as ls,parseImportShardArgs as us,writeReactorState as Pe,UNVOUCHABLE_DEP as Le,listReactorStates as hs,recordCapturedMail as Be,clearCapturedMail as ps,recordQueueMessages as fs,clearQueueMessages as ms,readQueueMessageById as ys,isLossyBody as Ss,appendAuditEntry as bs,readBookmark as gs,armRestore as Rs,readMigrationStatus as As,buildSettings as Es,summarizeSubscriptions as vs,summarizeFanoutTopics as ws,DEFAULT_MAX_RELAYS as Ts,readTablePage as Cs,FLAGS_FUNCTION_PREFIX as ks,awaitWsDrain as B,stableWireKey as _s,mergeChangedKeys as Is,runSocketPool as Ue,createShapeDiffCache as ae,writeShapePokeCursors as Ms,recordFanoutPass as ce,recordShapeProbePass as He,minShapePokeCursor as Os,readCdcChangeKeys as Ns,buildShapeDiff as qs,selectShapeRows as xs,projectColumns as Ds,diffGlobalMembership as Fe,readGlobalShapeSnapshot as Ps,writeGlobalShapeSnapshot as Ls,GlobalPollTick as de,globalShapeReadKey as Bs,recordGlobalPollPass as Us,buildPokeFrames as Hs,readShapePokeCursor as Fs,writeShapePokeCursor as Ws,subscriptionFrames as $s,handleReplicaControl as Ks,writeTouchesMemo as Qs}from"@lunora/shard-engine";import{subscriptionListDeltas as Co}from"@lunora/shard-engine";import{drizzle as js}from"drizzle-orm/durable-sqlite";import{c as le}from"./constant-time-equal-BRh9yUCr.mjs";import{j as v}from"./json-response-wrh9TBPw.mjs";import{sql as M}from"drizzle-orm";const We=500,Y=(i,e)=>{if(i.size<e)return;const t=i.keys().next().value;t!==void 0&&i.delete(t)},ue=i=>{let e="";for(let r=0;r<i.length;r+=32768)e+=String.fromCharCode(...i.subarray(r,r+32768));return btoa(e)},ct=i=>{const e=atob(i),t=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)t[r]=e.codePointAt(r)??0;return t},Ee=i=>{const e=i.replaceAll("-","+").replaceAll("_","/"),t=e+"=".repeat((4-e.length%4)%4);return ct(t)},dt=new TextDecoder;new TextEncoder;const $e="=",Gs=i=>{if(i)try{const e=i[0]==="{"?i:dt.decode(Ee(i)),t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}},Ke=i=>{if(i){if(!i.startsWith($e))return i;try{return dt.decode(Ee(i.slice($e.length)))}catch{return}}},zs=i=>{const e=Number(i);return Number.isFinite(e)&&e>0?e:void 0},Js=i=>typeof i=="number"&&Date.now()>=i,Xs=i=>{try{i.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},type:"error"})),i.close?.(4001,"token_expired")}catch{}};Array.from({length:256},(i,e)=>e.toString(16).padStart(2,"0"));const X=/^[0-9a-f]+$/,Vs=i=>{if(i==null)return;const e=i.trim().toLowerCase().split("-"),[t,r,n,s]=e;if(!(e.length<4||t===void 0||t.length!==2||!X.test(t)||t==="ff"||t==="00"&&e.length!==4||r===void 0||n===void 0||s===void 0||s.length!==2||!X.test(s)||r.length!==32||n.length!==16||!X.test(r)||!X.test(n)||r==="00000000000000000000000000000000"||n==="0000000000000000"))return{parentSpanId:n,sampled:(Number.parseInt(s,16)&1)===1,traceId:r}},he=Object.freeze({durationMs:"lunora.duration_ms",errorMessage:"error.message",errorType:"error.type",functionPath:"lunora.function_path",ok:"lunora.ok",shardKey:"lunora.shard_key",userId:"lunora.user_id"}),T="$lunora.wire$",Z=64,Qe=1024,Re="__proto__",je={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},Ge={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},Ys=i=>{if(i===null||typeof i!="object")return!1;const e=Object.getPrototypeOf(i);return e===null||e===Object.prototype},w=(i,e=0)=>{if(e>Z)throw new RangeError(`wire-codec: value nesting exceeds the ${Z}-level limit`);if(i===void 0)return[T,"undefined"];if(i===null)return null;const t=typeof i;if(t==="bigint")return[T,"bigint",i.toString()];if(t==="number"){const s=i;return Number.isNaN(s)?[T,"nan"]:s===1/0?[T,"inf"]:s===-1/0?[T,"-inf"]:s}if(t!=="object")return i;if(i instanceof Date)return[T,"date",w(i.getTime(),e+1)];if(i instanceof Error){const s=i,o={};for(const c of Object.keys(s))s[c]!==void 0&&(o[c]=w(s[c],e+1));const a=[T,"error",s.name,s.message,o];return s.cause!==void 0&&a.push(w(s.cause,e+1)),a}if(i instanceof URL)return[T,"url",i.href];if(i instanceof Map)return[T,"map",[...i.entries()].map(([s,o])=>[w(s,e+1),w(o,e+1)])];if(i instanceof Set)return[T,"set",[...i].map(s=>w(s,e+1))];if(i instanceof ArrayBuffer)return[T,"bytes",ue(new Uint8Array(i)),"ArrayBuffer"];if(ArrayBuffer.isView(i)){const s=i,o=s.constructor.name,a=new Uint8Array(s.buffer,s.byteOffset,s.byteLength);return o==="Uint8Array"?[T,"bytes",ue(a)]:[T,"bytes",ue(a),o]}if(Array.isArray(i)){const s=i.map(o=>w(o,e+1));return s.length>0&&s[0]===T?[T,"arr",s]:s}if(!Ys(i)){const s=i.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${s} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const r=i,n={};for(const s of Object.keys(r)){const o=r[s];if(o===void 0)continue;const a=w(o,e+1);s===Re?Object.defineProperty(n,s,{configurable:!0,enumerable:!0,value:a,writable:!0}):n[s]=a}return n},C=(i,e=0)=>{if(e>Z)throw new RangeError(`wire-codec: value nesting exceeds the ${Z}-level limit`);if(i===null||typeof i!="object")return i;if(Array.isArray(i)){if(i[0]===T)switch(i[1]){case"-inf":return-1/0;case"arr":return i[2].map(s=>C(s,e+1));case"bigint":{const s=i[2];if(typeof s!="string"||s.length>Qe||!/^-?\d+$/.test(s))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${Qe} digits)`);return BigInt(s)}case"date":{if(i.length<3)throw new TypeError("wire-codec: malformed date — missing payload");return new Date(C(i[2],e+1))}case"map":{const s=i[2];return new Map(s.map(o=>{if(!Array.isArray(o)||o.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[C(o[0],e+1),C(o[1],e+1)]}))}case"set":return new Set(i[2].map(s=>C(s,e+1)));case"url":return new URL(i[2]);case"error":{const s=i[2],o=i[3],a=(Object.hasOwn(Ge,s)?Ge[s]:void 0)??Error,c=new a(o);c.name!==s&&Object.defineProperty(c,"name",{configurable:!0,value:s,writable:!0});const d=C(i[4],e+1);if(d===null||typeof d!="object"||Array.isArray(d))throw new TypeError("wire-codec: malformed error — props must be an object");for(const u of Object.keys(d))u===Re?Object.defineProperty(c,u,{configurable:!0,enumerable:!0,value:d[u],writable:!0}):c[u]=d[u];return i.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:C(i[5],e+1),writable:!0}),c}case"bytes":{const s=ct(i[2]),o=i[3]??"Uint8Array";if(o==="ArrayBuffer")return s.buffer.byteLength===s.byteLength?s.buffer:s.slice().buffer;const a=Object.hasOwn(je,o)?je[o]:void 0;return a?new a(s.slice().buffer):s}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return i.map(s=>C(s,e+1))}return i.map(n=>C(n,e+1))}const t=i,r={};for(const n of Object.keys(t)){const s=C(t[n],e+1);n===Re?Object.defineProperty(r,n,{configurable:!0,enumerable:!0,value:s,writable:!0}):r[n]=s}return r},Zs="pageDelta",en=(i,e,t,r)=>{const n=i.get(e);if(n!==void 0)return n;Y(i,r);const s=t().catch(o=>{throw i.get(e)===s&&i.delete(e),o});return i.set(e,s),s},lt=new TextEncoder,tn=Array.from({length:32},(i,e)=>e);new RegExp(`[${tn.map(i=>String.fromCodePoint(i)).join("")}]`,"u");const rn=64,sn=new Map,nn=async i=>en(sn,i,async()=>crypto.subtle.importKey("raw",lt.encode(i),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),rn),on=async(i,e,t)=>{const r=await nn(i);return crypto.subtle.verify("HMAC",r,t,lt.encode(e))},an=new Set(["1","enabled","on","true","yes"]),cn=new Set(["0","disabled","false","no","off"]),dn=(i,e)=>{const t=(i??"").trim().toLowerCase();return an.has(t)?!0:cn.has(t)?!1:e},ln="v1",un=async(i,e,t=Date.now())=>{if(i.length===0||e.length===0)return!1;const r=e.split(".");if(r.length!==3)return!1;const[n,s,o]=r;if(n!==ln||o.length===0)return!1;const a=Number(s);if(!Number.isFinite(a)||a<=t)return!1;let c;try{c=Ee(o)}catch{return!1}return on(i,`${n}.${s}`,c)},ut="__lunoraBranch",hn=i=>typeof i=="object"&&i!==null&&Object.hasOwn(i,ut),pn=`may not contain the reserved workflow branch-marker key ("${ut}")`,fn=/\(exit (\d+)\)/,mn=new Set(["contains","eq","gt","gte","lt","lte","ne"]),ze=100,yn="test@lunora.sh",Sn=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),ht=null,Je=(i,e)=>(i===void 0?"":`,"cursor":${String(i)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),bn=(i,e)=>{const[t,r]=i.size<=e.size?[i,e]:[e,i];for(const n of t)if(r.has(n))return!0;return!1},gn=i=>{const e=typeof i.id=="string"?i.id:"";if(e.trim()==="")throw new p("MIGRATION_ID_REQUIRED","runMigration: `id` is required",{status:400});return{batchSize:typeof i.batchSize=="number"?i.batchSize:void 0,direction:i.direction==="down"?"down":"up",dryRun:i.dryRun===!0,id:e,maxBatches:typeof i.maxBatches=="number"?i.maxBatches:void 0}},Rn=i=>{const{op:e}=i,t=typeof i.table=="string"?i.table:"";if(e!=="insert"&&e!=="patch"&&e!=="replace"&&e!=="delete")throw new p("BAD_REQUEST","writeRow: `op` must be insert|patch|replace|delete");if(t.trim()==="")throw new p("BAD_REQUEST","writeRow: `table` is required");const r=typeof i.id=="string"?i.id:void 0,n=typeof i.doc=="object"&&i.doc!==null&&!Array.isArray(i.doc)?i.doc:void 0;if(e!=="insert"&&(r===void 0||r===""))throw new p("BAD_REQUEST",`writeRow: \`id\` is required for op "${e}"`);if(e!=="delete"&&n===void 0)throw new p("BAD_REQUEST",`writeRow: \`doc\` is required for op "${e}"`);return{doc:n,id:r,op:e,table:t}},An=i=>typeof i=="string"&&wt.includes(i),En=i=>typeof i=="string"&&vt.includes(i),vn=i=>{const e=typeof i.hash=="string"?i.hash.trim():"";if(e==="")throw new p("BAD_REQUEST","issue triage: `hash` is required");return e},wn=i=>{const e=i.assignee;if(e===null)return ht;if(typeof e=="string"&&e.trim()!=="")return e;throw new p("BAD_REQUEST","assignIssue: `assignee` must be a non-empty string (assign) or null (unassign)")},Tn=i=>{const e=i.severity;if(e===null)return ht;if(En(e))return e;throw new p("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},Cn=i=>{const e=typeof i.exportName=="string"?i.exportName.trim():"";if(e==="")throw new p("BAD_REQUEST","createWorkflowInstance: `exportName` is required");const t=typeof i.id=="string"&&i.id!==""?i.id:void 0;if(hn(i.params))throw new p("BAD_REQUEST",`createWorkflowInstance: params ${pn}`);return{exportName:e,id:t,params:i.params}},kn=i=>{const e=typeof i.exportName=="string"?i.exportName.trim():"",t=typeof i.id=="string"?i.id.trim():"";if(e==="")throw new p("BAD_REQUEST","getWorkflowInstanceStatus: `exportName` is required");if(t==="")throw new p("BAD_REQUEST","getWorkflowInstanceStatus: `id` is required");return{exportName:e,id:t}},Xe=i=>typeof i=="string"&&Sn.has(i)?i:"unknown",_n=i=>{if(typeof i!="object"||i===null)return;const{message:e,name:t}=i;return{message:typeof e=="string"?e:"",name:typeof t=="string"?t:"Error"}},ee=i=>{if(!Array.isArray(i))return;const e=[];for(const t of i){if(typeof t!="object"||t===null)continue;const r=t,{column:n,operator:s}=r;typeof n!="string"||n===""||typeof s!="string"||!mn.has(s)||e.push({column:n,operator:s,value:r.value})}return e.length>0?e:void 0},In=i=>{if(typeof i!="object"||i===null)return;const{column:e,direction:t}=i;if(!(typeof e!="string"||e===""))return{column:e,direction:t==="desc"?"desc":"asc"}},Mn=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","deleteRows: `table` is required");const t=ee(i.filters),r=typeof i.search=="string"?i.search:void 0;if((t===void 0||t.length===0)&&(r===void 0||r===""))throw new p("BAD_REQUEST","deleteRows: a predicate (`filters` or `search`) is required — use `clearTable` to empty the table");return{filters:t,limit:typeof i.limit=="number"?i.limit:void 0,search:r,table:e}},On=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","patchRows: `table` is required");const t=i.doc,r=typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0;if(r===void 0||Object.keys(r).length===0)throw new p("BAD_REQUEST","patchRows: `doc` must be a non-empty object of fields to set");return{after:typeof i.after=="string"?i.after:void 0,doc:r,filters:ee(i.filters),limit:typeof i.limit=="number"?i.limit:void 0,search:typeof i.search=="string"?i.search:void 0,table:e}},Nn=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","clearTable: `table` is required");return{limit:typeof i.limit=="number"?i.limit:void 0,table:e}},qn=i=>{const{outcome:e}=i;if(e!=="ok"&&e!=="fail")throw new p("BAD_REQUEST",'recordAuthEvent: `outcome` must be "ok" or "fail"');return{outcome:e}},xn=i=>{const e=i.event;if(typeof e!="object"||e===null||Array.isArray(e))throw new p("BAD_REQUEST","recordContainerEvent: `event` must be an object");const t=e,r=typeof t.container=="string"?t.container:"",n=typeof t.event=="string"?t.event:"";if(r.trim()===""||n.trim()==="")throw new p("BAD_REQUEST","recordContainerEvent: `event.container` and `event.event` are required");const s=t.level==="error"?"error":"info",o=typeof t.message=="string"?t.message:void 0,a=typeof t.ts=="number"?t.ts:Date.now(),c=typeof t.instance=="string"&&t.instance!==""?t.instance:void 0,d=o===void 0?void 0:fn.exec(o)?.[1];return{exitCode:d===void 0?void 0:Number.parseInt(d,10),functionPath:`container:${r}`,instance:c,level:s,message:o===void 0||o===""?n:`${n}: ${o}`,timestamp:a}},Dn=i=>{const e=typeof i.functionPath=="string"?i.functionPath:"",t=typeof i.userId=="string"?i.userId:"";if(e.trim()==="")throw new p("BAD_REQUEST","runAs: `functionPath` is required");if(e.startsWith(I))throw new p("BAD_REQUEST","runAs: cannot target a reserved admin function");if(t.trim()==="")throw new p("BAD_REQUEST","runAs: `userId` is required");const r=i.args;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))throw new p("BAD_REQUEST","runAs: `args` must be an object");const n=i.identity;if(n!==void 0&&(typeof n!="object"||n===null||Array.isArray(n)))throw new p("BAD_REQUEST","runAs: `identity` must be an object");return{args:r===void 0?{}:r,functionPath:e,userId:t,...n===void 0?{}:{identity:n}}},Pn=i=>{const e=m=>{throw new p("BAD_REQUEST",`recordMail: ${m}`)},{bcc:t,cc:r,from:n,headers:s,html:o,replyTo:a,subject:c,text:d,to:u}=i;typeof c!="string"&&e("`subject` must be a string"),typeof u=="string"||Array.isArray(u)&&u.every(m=>typeof m=="string")||e("`to` must be a string or string[]");const f=(m,g)=>{if(m!==void 0)return(!Array.isArray(m)||!m.every(b=>typeof b=="string"))&&e(`\`${g}\` must be a string[]`),m},y=(m,g)=>(m!==void 0&&typeof m!="string"&&e(`\`${g}\` must be a string`),m);return{bcc:f(t,"bcc"),cc:f(r,"cc"),from:y(n,"from"),headers:s!==void 0&&typeof s=="object"&&s!==null?s:void 0,html:y(o,"html"),replyTo:y(a,"replyTo"),subject:c,text:y(d,"text"),to:u}},Ln=i=>{const{to:e}=i;if(e!==void 0&&typeof e!="string")throw new p("BAD_REQUEST","sendTestMail: `to` must be a string");const t=e??yn,r="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="${r}">Verify your email</a></p>`,subject:"Lunora test email",text:`This is a test email from the Lunora dev mail catcher.
2
2
 
3
3
  Verify your email: ${r}`,to:t}},Bn=i=>{const e=n=>{throw new p("BAD_REQUEST",`recordQueueMessage: ${n}`)},t=i.messages;Array.isArray(t)||e("`messages` must be an array");const r=new Set(["ack","error","retry"]);return t.map((n,s)=>{(typeof n!="object"||n===null)&&e(`\`messages[${String(s)}]\` must be an object`);const o=n,a=typeof o.messageId=="string"?o.messageId:"",c=typeof o.queue=="string"?o.queue:"",d=typeof o.outcome=="string"?o.outcome:"";a===""&&e(`\`messages[${String(s)}].messageId\` is required`),c===""&&e(`\`messages[${String(s)}].queue\` is required`),r.has(d)||e(`\`messages[${String(s)}].outcome\` must be one of ack | error | retry`);const{attempts:u,timestamp:l}=o;return{attempts:typeof u=="number"&&Number.isFinite(u)?u:1,body:o.body,deadLettered:o.deadLettered===!0,error:typeof o.error=="string"?o.error:void 0,exportName:typeof o.exportName=="string"?o.exportName:void 0,messageId:a,outcome:d,queue:c,timestamp:typeof l=="number"&&Number.isFinite(l)?l:0}})},U=i=>`${i.traceId}:${i.rootSpanId}`,Un=i=>{const e=typeof i.exportName=="string"?i.exportName.trim():"";if(e==="")throw new p("BAD_REQUEST","sendQueueMessage: `exportName` is required");const t=i.delaySeconds;if(t!==void 0&&(typeof t!="number"||!Number.isFinite(t)||t<0))throw new p("BAD_REQUEST","sendQueueMessage: `delaySeconds` must be a non-negative number");const r=Array.isArray(i.batch)?i.batch:void 0;if(r!==void 0&&(r.length===0||r.length>ze))throw new p("BAD_REQUEST",`sendQueueMessage: \`batch\` must contain between 1 and ${String(ze)} messages`);return{batch:r,body:i.body,contentType:typeof i.contentType=="string"?i.contentType:void 0,delaySeconds:t,exportName:e}},Hn=i=>{const e=typeof i.id=="string"?i.id.trim():"";if(e==="")throw new p("BAD_REQUEST","replayQueueMessage: `id` is required");const t=typeof i.target=="string"&&i.target.trim()!==""?i.target.trim():void 0;return{id:e,target:t}},Fn=i=>{const e=typeof i.table=="string"?i.table:"",t=typeof i.index=="string"?i.index:"",r=typeof i.rowId=="string"?i.rowId:"";if(e.trim()==="")throw new p("BAD_REQUEST","rankBefore: `table` is required");if(t.trim()==="")throw new p("BAD_REQUEST","rankBefore: `index` is required");if(typeof i.partitionKey!="string")throw new p("BAD_REQUEST","rankBefore: `partitionKey` must be a string");if(r.trim()==="")throw new p("BAD_REQUEST","rankBefore: `rowId` is required");if(!Array.isArray(i.sortValues))throw new p("BAD_REQUEST","rankBefore: `sortValues` must be an array");return{index:t,partitionKey:i.partitionKey,rowId:r,sortValues:i.sortValues,table:e}},W=i=>{throw new p("BAD_REQUEST",i)},Ve=(i,e)=>((typeof i!="string"||i.trim()==="")&&W(`rankPage: \`${e}\` is required`),i),Wn=i=>{if(i===void 0)return;(typeof i!="object"||i===null||Array.isArray(i))&&W("rankPage: `after` must be an object");const e=i;return(typeof e.partitionKey!="string"||typeof e.rowId!="string"||!Array.isArray(e.sortValues))&&W("rankPage: `after` must have a string partitionKey, string rowId, and array sortValues"),{partitionKey:e.partitionKey,rowId:e.rowId,sortValues:e.sortValues}},$n=i=>{const e=Ve(i.table,"table"),t=Ve(i.index,"index");i.take!==void 0&&typeof i.take!="number"&&W("rankPage: `take` must be a number"),i.cursor!==void 0&&i.cursor!==null&&typeof i.cursor!="string"&&W("rankPage: `cursor` must be a string or null"),i.partitionKey!==void 0&&typeof i.partitionKey!="string"&&W("rankPage: `partitionKey` must be a string"),i.directions!==void 0&&!Array.isArray(i.directions)&&W("rankPage: `directions` must be an array");const r=i.directions===void 0?void 0:i.directions.map(n=>n==="desc"?"desc":"asc");return{after:Wn(i.after),cursor:typeof i.cursor=="string"?i.cursor:void 0,directions:r,index:t,partitionKey:typeof i.partitionKey=="string"?i.partitionKey:void 0,take:typeof i.take=="number"?i.take:void 0,table:e}},Kn=i=>{try{const e=JSON.parse(i);if(Array.isArray(e)&&typeof e[0]=="string"&&typeof e[1]=="string")return{index:e[1],table:e[0]}}catch{}},Qn=i=>{const e=i.changes;if(!Array.isArray(e))throw new p("BAD_REQUEST","applyCdc: `changes` must be an array");return{changes:e.map((r,n)=>{const s=r,{op:o}=s,a=typeof s.table=="string"?s.table:"",c=typeof s.id=="string"?s.id:"";if(a===""||c===""||o!=="insert"&&o!=="update"&&o!=="delete")throw new p("BAD_REQUEST",`applyCdc: changes[${String(n)}] must have a table, id, and op of insert|update|delete`);const d=s.doc;if(d!==void 0&&(typeof d!="object"||d===null||Array.isArray(d)))throw new p("BAD_REQUEST",`applyCdc: changes[${String(n)}].doc must be an object`);const u=d;if(u!==void 0&&typeof u._id=="string"&&u._id!==c)throw new p("BAD_REQUEST",`applyCdc: changes[${String(n)}].doc._id must match the entry id`);return{doc:u,id:c,op:o,seq:typeof s.seq=="number"?s.seq:0,table:a,ts:typeof s.ts=="number"?s.ts:0}})}},jn=i=>{const e=t=>{const r=typeof t=="number"?t:Number(t);return Number.isFinite(r)&&r>=0?Math.floor(r):void 0};return{limit:e(i.limit),sinceSeq:e(i.sinceSeq)??0}},H=i=>i?{"x-d1-bookmark":i}:void 0,Ye=i=>Gs(i),Gn=i=>{if(!i)return;const e=Number(i);return Number.isInteger(e)&&e>0?e:void 0},zn=i=>{const e=new Set;for(const t of i){const r=ur(t);r!==""&&e.add(r)}return e},Jn=i=>{if(i===void 0)return;const e=Number.parseInt(i,10);return Number.isFinite(e)&&e>0?e:void 0},Xn=(i,e)=>i==="1"||i==="true"?!0:i==="0"||i==="false"?!1:e,Vn=i=>{if(i===void 0)return 1;const e=Number.parseFloat(i);return Number.isFinite(e)?Math.min(1,Math.max(0,e)):1},Yn=i=>i>=1?!0:i<=0?!1:Math.random()<i,pe=i=>{if(!i)return;const[e,...t]=i.split(" ");if(e?.toLowerCase()!=="bearer")return;const r=t.join(" ").trim();return r.length>0?r:void 0},q="*",Ze=(i,e)=>{const t=Array.isArray(i.tables)?i.tables.filter(n=>typeof n=="string"):[];return{byTable:Object.fromEntries(t.map(n=>[n,e(n)])),tables:new Set(t.length===0?[q]:t)}},Zn=(i,e)=>{hr(i);const t=typeof e.limit=="number"?e.limit:void 0,r=typeof e.sinceSeq=="number"?e.sinceSeq:void 0;return{result:{entries:pr(i,{limit:t,sinceSeq:r})},tables:new Set([q])}},ei=(i,e)=>{ot(i);const t=e.outcome==="ok"||e.outcome==="error"?e.outcome:void 0;return{result:{entries:Tt(i,{functionPathPrefix:typeof e.functionPathPrefix=="string"?e.functionPathPrefix:void 0,limit:typeof e.limit=="number"?e.limit:void 0,outcome:t,shardKey:typeof e.shardKey=="string"?e.shardKey:void 0,sinceSeq:typeof e.sinceSeq=="number"?e.sinceSeq:void 0,tableTouched:typeof e.tableTouched=="string"?e.tableTouched:void 0,userId:typeof e.userId=="string"?e.userId:void 0})},tables:new Set([q])}},ti=(i,e)=>(ot(i),{result:{issues:Ct(i,{functionPathPrefix:typeof e.functionPathPrefix=="string"?e.functionPathPrefix:void 0,limit:typeof e.limit=="number"?e.limit:void 0,shardKey:typeof e.shardKey=="string"?e.shardKey:void 0,status:An(e.status)?e.status:void 0,userId:typeof e.userId=="string"?e.userId:void 0})},tables:new Set([q])}),ri=i=>{let e;try{e=_t(i)}catch{e={attempts:0,failureRate:0,failures:0,history:[],sinceMs:0}}return{result:e,tables:new Set([q])}},si=(i,e)=>{const t=typeof e.limit=="number"?e.limit:void 0;let r;try{r=Sr(i,{limit:t})}catch{r={entries:[]}}return{result:r,tables:new Set([br])}},ni=(i,e)=>{const t=typeof e.limit=="number"?e.limit:void 0,r=typeof e.queue=="string"?e.queue:void 0;let n;try{n=gr(i,{limit:t,queue:r})}catch{n={entries:[]}}return{result:n,tables:new Set([Rr])}},ii=(i,e)=>{const t=typeof e.table=="string"?e.table:"";return{result:fr(i,{column:typeof e.column=="string"?e.column:"",filters:ee(e.filters),limit:typeof e.limit=="number"?e.limit:void 0,search:typeof e.search=="string"?e.search:void 0,table:t}),tables:new Set([t===""?q:t])}},oi=(i,e)=>{const t=typeof e.sql=="string"?e.sql:"";return{result:mr(i,t),tables:new Set([q])}},ai=(i,e,t)=>{const r=Array.isArray(e.keys)?e.keys.filter(n=>typeof n=="string"):[];return{result:yr(i,t,r),tables:new Set([q])}},ci=(i,e,t)=>{const r=Array.isArray(e.liveKeys)?e.liveKeys.filter(s=>typeof s=="string"):[],n=kt(i,t,r);return n.truncated&&console.warn(`[@lunora/do] storageOrphans scan truncated after checking ${String(n.scanned)} storage references; reporting the first ${String(n.references.length)} dangling reference(s).`),{result:n,tables:new Set([q])}},di=(i,e,t)=>{if(i===h.getAuthMetrics)return ri(e);if(i===h.getCapturedMail)return si(e,t);if(i===h.getQueueMessages)return ni(e,t)},li=["x-lunora-userid","x-lunora-identity","x-d1-bookmark","x-lunora-client-ip","x-lunora-system","x-lunora-shard-binding"],ui=(i,e)=>{const t=new Headers({"content-type":"application/json"});for(const r of li){const n=i.headers.get(r);n!==null&&t.set(r,n)}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"})},hi="LUNORA_CDC_ARCHIVE",pi=6e4,fe=5e4,fi=1e4,et=i=>{if(typeof i!="object"||i===null)return;const e=i[hi];if(typeof e!="object"||e===null)return;const t=e;return typeof t.get=="function"&&typeof t.list=="function"&&typeof t.put=="function"?e:void 0};class mi{host;lastSweepAt=0;constructor(e){this.host=e}sweep(){if(!this.host.enabled())return;const e=Date.now();if(e-this.lastSweepAt<=pi)return;this.lastSweepAt=e;const t=this.host.env(),r=ge(t,"LUNORA_CDC_LOG_RETENTION"),n=ge(t,"LUNORA_CDC_PAYLOAD_RETENTION");if(r===void 0&&n===void 0)return;const s=n===void 0?void 0:Math.min(n,r??Number.POSITIVE_INFINITY),o=this.host.sql();try{const a=et(t);if(a===void 0||r===void 0){this.applyRetention(o,s,r,Number.POSITIVE_INFINITY,fe);return}const c=te(o,s??r);if(c===void 0||c<=0)return;const d=Math.min(c,this.host.retentionFloor(o)),u=Ar(o),l=at(o,{limit:fi,sinceSeq:u}).changes.filter(m=>m.seq<=d),f=l.at(-1)?.seq;if(f===void 0){this.applyRetention(o,s,r,u,fe);return}const y=(async()=>{try{const m=this.host.epoch();await Er(a,{epoch:m,shard:this.host.shardKey()},l),vr(o,f),this.applyRetention(o,s,r,f,fe)}catch(m){this.host.recordError("cdc:archive",m)}})();this.host.waitUntil?.(y)}catch(a){this.host.recordError("cdc:sweep",a)}}async syncPage(e,t){try{return e()}catch(r){if(!(r instanceof p)||r.code!=="CDC_LOG_TRIMMED")throw r;const n=et(this.host.env()),s=this.host.epoch();if(n===void 0||s===void 0)throw r;let o;try{o=await wr(n,{epoch:s,shard:this.host.shardKey()},t.sinceSeq,t.limit)}catch(a){throw this.host.recordError("cdc:archive-read",a),r}if(o===void 0)throw r;return o}}applyRetention(e,t,r,n,s){const o=this.host.retentionFloor(e);if(t!==void 0){const a=te(e,t);a!==void 0&&a>0&&Tr(e,Math.min(a,o,n),s)}if(r!==void 0){const a=te(e,r);a!==void 0&&a>0&&Cr(e,Math.min(a,o,n),s)}}}const yi=500,Si=8,bi=(i,e)=>{if(e.includes(i))return M`${M.identifier(i)}`;if(e.includes(Me))return M`json_extract(${M.identifier(Me)}, ${`$."${i.replaceAll('"','""')}"`})`},gi=(i,e)=>{const t=[...new Set(e.ids.filter(s=>typeof s=="string"&&s!==""))].slice(0,yi),r=e.relations.slice(0,Si);if(t.length===0||r.length===0)return{relations:[]};const n=[];for(const s of r){let o;try{o=i.exec(Ie("sqlite",M`PRAGMA table_info(${M.identifier(s.table)})`).sql).toArray().map(d=>d.name)}catch(d){console.warn(`[@lunora/do] backRelationCounts: skipping "${s.table}.${s.column}" — cannot read its columns:`,d);continue}if(o.length===0)continue;const a=bi(s.column,o);if(a===void 0)continue;const c={};try{const d=Ie("sqlite",M`SELECT ${a} AS ${M.identifier("parent")}, COUNT(*) AS ${M.identifier("n")}
4
4
  FROM ${M.identifier(s.table)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/do",
3
- "version": "1.0.0-alpha.113",
3
+ "version": "1.0.0-alpha.114",
4
4
  "description": "Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,10 +46,10 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/errors": "1.0.0-alpha.28",
50
- "@lunora/observability": "1.0.0-alpha.52",
51
- "@lunora/platform-cloudflare": "1.0.0-alpha.29",
52
- "@lunora/shard-engine": "1.0.0-alpha.51",
49
+ "@lunora/errors": "1.0.0-alpha.29",
50
+ "@lunora/observability": "1.0.0-alpha.53",
51
+ "@lunora/platform-cloudflare": "1.0.0-alpha.30",
52
+ "@lunora/shard-engine": "1.0.0-alpha.52",
53
53
  "drizzle-orm": "^0.45.2"
54
54
  },
55
55
  "engines": {