@lunora/do 1.0.0-alpha.167 → 1.0.0-alpha.168
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-BbU25BWj.mjs";import{ROOT_DO_SIZE_WARN_BYTES as i,ROOT_SHARD_NAME as s,ShardDO as l}from"./packem_shared/ROOT_DO_SIZE_WARN_BYTES-
|
|
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-BbU25BWj.mjs";import{ROOT_DO_SIZE_WARN_BYTES as i,ROOT_SHARD_NAME as s,ShardDO as l}from"./packem_shared/ROOT_DO_SIZE_WARN_BYTES-D0fJRtB_.mjs";import{SHARD_REGISTRY_DO_NAME as d,ShardRegistryDO as R}from"./packem_shared/SHARD_REGISTRY_DO_NAME-DvxEa7qM.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 b,backfillSearchIndexes as A,backfillVectorIndexes as M,buildReprojectionMigration as g,clearMemoryTables as k,countLegacyRows as N,createReadFootprint as y,createShardCtxDb as C,exportShardRows as H,importShardRows as L,isSourceDue as P,markUnvouchableReads as F,pullExternalSourceIncrementalTick as U,pullExternalSourceTick as j,reprojectionMigrationId as v,reprojectionTables as w,runDataMigration as B,runShardMigrations as G,subscriptionListDeltas as V}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,d as SHARD_REGISTRY_DO_NAME,c as SessionDO,l as ShardDO,R as ShardRegistryDO,I as UNVOUCHABLE_DEP,f as applyCdcChanges,b as assertShapeShardable,A as backfillSearchIndexes,M as backfillVectorIndexes,g as buildReprojectionMigration,k as clearMemoryTables,N as countLegacyRows,y as createReadFootprint,h as createShardAlarms,C as createShardCtxDb,D as createShardDirectory,O as createShardHost,_ as createShardKvStore,E as createShardPlatform,m as createSocketHost,u as createWorkerPlatform,H as exportShardRows,L as importShardRows,P as isSourceDue,F as markUnvouchableReads,U as pullExternalSourceIncrementalTick,j as pullExternalSourceTick,v as reprojectionMigrationId,w as reprojectionTables,B as runDataMigration,G as runShardMigrations,a as serveRelationFanout,V as subscriptionListDeltas};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{LunoraError as p,toErrorBody as H,isLunoraError as We}from"@lunora/errors";import{ISSUE_SEVERITIES as Kt,ISSUE_STATUSES as jt,ensureRequestLogTable as _t,readRequestLog as Gt,readErrorIssues as zt,findDanglingReferences as Jt,readAuthMetrics as Xt,readQueryInsights as Vt,LogBuffer as Yt,SpanBuffer as Zt,MetricBuffer as er,emitLogEvent as tr,resolveTraceAnchor as X,createTracer as rr,instrumentDatabase as sr,createTracedFetch as nr,createMetrics as ir,redactArgs as or,REQUEST_LOG_TABLE as Qe,createDatabaseTally as ar,formatTally as cr,dispatchRootSpan as dr,readFunctionMetricsTotals as lr,readFunctionMetricIndexHits as ur,readQueryMetrics as hr,recordFunctionMetric as pr,mergeScanAttribution as fr,FUNCTION_METRICS_MAX_PATHS as mr,recordQueryMetric as yr,readFunctionMetrics as Sr,readFunctionMetricBuckets as br,upsertIssueState as gr,ISSUE_STATE_TABLE as Rr,recordAuthEvent as Er,explainIssue as Ar,appendRequestLogEntry as vr,emitRequestLogEvent as wr,foldTraces as Tr,readMetricHistory as _r,buildSecurityAudit as Cr,parseLogArgs as kr,createSpanCollector as Ir,recordMetricHistory as Mr}from"@lunora/observability";import{createShardHost as Or,createSocketHost as qr}from"@lunora/platform-cloudflare";import{tableFromDepKey as Nr,ADMIN_FUNCTION_PREFIX as N,ensureAuditTable as Dr,readAuditLog as Pr,ADMIN_FUNCTIONS as h,facetColumn as xr,runReadonlySql as Br,findStorageReferences as Lr,readCapturedMail as Ur,MAIL_TABLE as Hr,readQueueMessages as Fr,QUEUE_TABLE as $r,envOptionalPositiveInt as Me,cdcSeqLeavingRows as ce,readCdcArchivedThrough as Wr,readCdcChanges as Ct,cdcArchiveRewound as Qr,archiveCdcSegment as Kr,writeCdcArchivedThrough as jr,readArchivedCdcChanges as Gr,compactCdcDocs as zr,trimCdcChanges as Jr,renderSql as Ke,sqliteInList as Xr,DOC_COLUMN as je,readSchemaVersion as Vr,readSchemaHistory as Yr,lintReadonlySql as Zr,stableStringify as kt,createShapeProbeCounters as es,createGlobalPollCounters as ts,DurableStreamRunner as rs,createFanoutCounters as Ge,ShardRunner as ss,ReactiveCache as ns,createRelayLink as is,listTables as de,minCdcReplayableSeq as os,createReplicaLink as as,readReactorState as cs,reactorNeedsRun as ds,MAX_PAGE_SIZE as ls,selectMatchingIds as us,CDC_LOG_TABLE as ze,readCdcCursor as le,readCdcEpoch as V,cdcForkedError as hs,minCdcSeq as ue,cursorBelowRetainedFloor as Y,cdcTrimmedError as ps,bumpCdcEpoch as Je,cdcCanVouchFor as fs,cdcTouchesTables as ms,readIdempotent as ys,writeIdempotent as Ss,trimIdempotent as bs,readClientWatermark as he,migrateClientWatermark as gs,advanceClientWatermark as Rs,deleteGlobalShapeSnapshot as Es,deleteShapePokeCursor as As,trySendFrame as E,selectExpiredIds as vs,recordScheduleOutbox as ws,forgetScheduleOutbox as pe,probeScheduleOutbox as fe,readDueScheduleOutbox as Ts,trimScheduleOutbox as _s,createDependencyTracker as Cs,createReadFootprint as ks,reactiveCacheKey as Xe,SCAN_DEP as Z,TransactionHeadroomTracker as ee,recordChangedKeys as Is,DATA_MIGRATION_STATE_TABLE as Ms,isDevEnvironment as P,gateReplicaDispatch as Os,RELATION_FUNCTION_PREFIX as qs,ConflictError as Ns,deleteGlobalShapeSnapshotsForConnection as Ds,deleteShapePokeCursorsForConnection as Ps,parseExportShardArgs as xs,parseImportShardArgs as Bs,writeReactorState as Ve,UNVOUCHABLE_DEP as Ye,listReactorStates as Ls,recordCapturedMail as Ze,clearCapturedMail as Us,recordQueueMessages as Hs,clearQueueMessages as Fs,readQueueMessageById as $s,isLossyBody as Ws,appendAuditEntry as Qs,readDeployInfo as Ks,readBookmark as js,armRestore as Gs,readMigrationStatus as zs,buildSettings as Js,summarizeSubscriptions as Xs,summarizeFanoutTopics as Vs,DEFAULT_MAX_RELAYS as Ys,readTablePage as Zs,FLAGS_FUNCTION_PREFIX as en,awaitWsDrain as F,stableWireKey as tn,mergeChangedKeys as rn,runSocketPool as et,createShapeDiffCache as me,writeShapePokeCursors as sn,recordFanoutPass as ye,recordShapeProbePass as tt,minShapePokeCursor as nn,readCdcChangeKeys as on,buildShapeDiff as an,selectShapeRows as cn,projectColumns as dn,diffGlobalMembership as rt,readGlobalShapeSnapshot as ln,writeGlobalShapeSnapshot as un,deferScheduleOutbox as hn,parkScheduleOutbox as pn,GlobalPollTick as Se,globalShapeReadKey as fn,recordGlobalPollPass as mn,buildPokeFrames as yn,readShapePokeCursor as Sn,writeShapePokeCursor as bn,subscriptionFrames as gn,handleReplicaControl as Rn,VECTOR_BACKFILL_MAX_PAGES as En,writeTouchesMemo as An}from"@lunora/shard-engine";import{subscriptionListDeltas as va}from"@lunora/shard-engine";import{drizzle as vn}from"drizzle-orm/durable-sqlite";import{c as be}from"./constant-time-equal-BRh9yUCr.mjs";import{j as w}from"./json-response-0Bq2ky0N.mjs";import{sql as D}from"drizzle-orm";const st=500,wn=9e5,Tn="DISPATCH_IN_PROGRESS",_n="x-lunora-dispatch-declined",se=(i,e)=>{if(i.size<e)return;const t=i.keys().next().value;t!==void 0&&i.delete(t)},ne=i=>{let e="";for(let r=0;r<i.length;r+=32768)e+=String.fromCharCode(...i.subarray(r,r+32768));return btoa(e)},It=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},x="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",Cn=i=>{let e="",t=0;const r=i.length-2;for(;t<r;t+=3){const s=i[t]<<16|i[t+1]<<8|i[t+2];e+=x.charAt(s>>18&63)+x.charAt(s>>12&63)+x.charAt(s>>6&63)+x.charAt(s&63)}const n=i.length-t;if(n===1){const s=i[t]<<16;e+=x.charAt(s>>18&63)+x.charAt(s>>12&63)}else if(n===2){const s=i[t]<<16|i[t+1]<<8;e+=x.charAt(s>>18&63)+x.charAt(s>>12&63)+x.charAt(s>>6&63)}return e},Ne=i=>{const e=i.replaceAll("-","+").replaceAll("_","/"),t=e+"=".repeat((4-e.length%4)%4);return It(t)},Mt=new TextDecoder;new TextEncoder;const nt="=",kn=i=>{if(i)try{const e=i[0]==="{"?i:Mt.decode(Ne(i)),t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}},it=i=>{if(i){if(!i.startsWith(nt))return i;try{return Mt.decode(Ne(i.slice(nt.length)))}catch{return}}},In=i=>{const e=Number(i);return Number.isFinite(e)&&e>0?e:void 0},ge=i=>typeof i=="number"&&Date.now()>=i,Mn=i=>{try{i.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},message:"authentication token expired",type:"error"})),i.close?.(4001,"token_expired")}catch{}},On="x-lunora-paywall",qn="1";Array.from({length:256},(i,e)=>e.toString(16).padStart(2,"0"));const te=/^[0-9a-f]+$/,Nn=(i,e,t=!0)=>`00-${i}-${e}-${t?"01":"00"}`,Dn=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||!te.test(t)||t==="ff"||t==="00"&&e.length!==4||r===void 0||n===void 0||s===void 0||s.length!==2||!te.test(s)||r.length!==32||n.length!==16||!te.test(r)||!te.test(n)||r==="00000000000000000000000000000000"||n==="0000000000000000"))return{parentSpanId:n,sampled:(Number.parseInt(s,16)&1)===1,traceId:r}},Re=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$",ie=64,ot=1024,oe="__proto__",at={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},ct={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},Pn=i=>{if(i===null||typeof i!="object")return!1;const e=Object.getPrototypeOf(i);return e===null||e===Object.prototype},C=(i,e=0)=>{if(e>ie)throw new RangeError(`wire-codec: value nesting exceeds the ${ie}-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",C(i.getTime(),e+1)];if(i instanceof Error){const s=i,o={};for(const c of Object.keys(s)){if(s[c]===void 0)continue;const d=C(s[c],e+1);c===oe?Object.defineProperty(o,c,{configurable:!0,enumerable:!0,value:d,writable:!0}):o[c]=d}const a=[T,"error",String(s.name),String(s.message),o];return s.cause!==void 0&&a.push(C(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])=>[C(s,e+1),C(o,e+1)])];if(i instanceof Set)return[T,"set",[...i].map(s=>C(s,e+1))];if(i instanceof ArrayBuffer)return[T,"bytes",ne(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",ne(a)]:[T,"bytes",ne(a),o]}if(Array.isArray(i)){const s=i.map(o=>C(o,e+1));return s.length>0&&s[0]===T?[T,"arr",s]:s}if(!Pn(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=C(o,e+1);s===oe?Object.defineProperty(n,s,{configurable:!0,enumerable:!0,value:a,writable:!0}):n[s]=a}return n},_=(i,e=0)=>{if(e>ie)throw new RangeError(`wire-codec: value nesting exceeds the ${ie}-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=>_(s,e+1));case"bigint":{const s=i[2];if(typeof s!="string"||s.length>ot||!/^-?\d+$/.test(s))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${ot} digits)`);return BigInt(s)}case"date":{const s=_(i[2],e+1);if(typeof s!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(s)}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[_(o[0],e+1),_(o[1],e+1)]}))}case"set":return new Set(i[2].map(s=>_(s,e+1)));case"url":{const s=i[2];if(typeof s!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(s)}case"error":{const s=i[2],o=i[3];if(typeof s!="string"||typeof o!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const a=(Object.hasOwn(ct,s)?ct[s]:void 0)??Error,c=new a(o);c.name!==s&&Object.defineProperty(c,"name",{configurable:!0,value:s,writable:!0});const d=_(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 l of Object.keys(d))l===oe?Object.defineProperty(c,l,{configurable:!0,enumerable:!0,value:d[l],writable:!0}):c[l]=d[l];return i.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:_(i[5],e+1),writable:!0}),c}case"bytes":{const s=i[2];if(typeof s!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const o=It(s);if(ne(o)!==s)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const a=i[3]??"Uint8Array";if(a==="ArrayBuffer")return o.buffer.byteLength===o.byteLength?o.buffer:o.slice().buffer;const c=Object.hasOwn(at,a)?at[a]:void 0;return c?new c(o.slice().buffer):o}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return i.map(s=>_(s,e+1))}return i.map(n=>_(n,e+1))}const t=i,r={};for(const n of Object.keys(t)){const s=_(t[n],e+1);n===oe?Object.defineProperty(r,n,{configurable:!0,enumerable:!0,value:s,writable:!0}):r[n]=s}return r},xn="pageDelta",Bn="x-lunora-sample-errors",Ln=(i,e,t,r)=>{const n=i.get(e);if(n!==void 0)return n;se(i,r);const s=t().catch(o=>{throw i.get(e)===s&&i.delete(e),o});return i.set(e,s),s},De=new TextEncoder,Un=Array.from({length:32},(i,e)=>e);new RegExp(`[${Un.map(i=>String.fromCodePoint(i)).join("")}]`,"u");const Hn=64,Fn=new Map,Ot=async i=>Ln(Fn,i,async()=>crypto.subtle.importKey("raw",De.encode(i),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),Hn),$n=async(i,e)=>{const t=await Ot(i),r=await crypto.subtle.sign("HMAC",t,De.encode(e));return Cn(new Uint8Array(r))},Wn=async(i,e,t)=>{const r=await Ot(i);return crypto.subtle.verify("HMAC",r,t,De.encode(e))},Qn=new Set(["1","enabled","on","true","yes"]),Kn=new Set(["0","disabled","false","no","off"]),jn=(i,e)=>{const t=(i??"").trim().toLowerCase();return Qn.has(t)?!0:Kn.has(t)?!1:e},qt="v1",Gn=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!==qt||o.length===0)return!1;const a=Number(s);if(!Number.isFinite(a)||a<=t)return!1;let c;try{c=Ne(o)}catch{return!1}return Wn(i,`${n}.${s}`,c)},zn=`${qt}.admin-socket-binding`,Jn=async i=>$n(i,zn),Nt="__lunoraBranch",Xn=i=>typeof i=="object"&&i!==null&&Object.hasOwn(i,Nt),Vn=`may not contain the reserved workflow branch-marker key ("${Nt}")`,Yn=/\(exit (\d+)\)/,Zn=new Set(["contains","eq","gt","gte","lt","lte","ne"]),dt=100,ei="test@lunora.sh",ti=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),Dt=null,lt=(i,e)=>(i===void 0?"":`,"cursor":${String(i)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),ri=(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},si=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}},ni=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}},ii=i=>typeof i=="string"&&jt.includes(i),oi=i=>typeof i=="string"&&Kt.includes(i),ai=i=>{const e=typeof i.hash=="string"?i.hash.trim():"";if(e==="")throw new p("BAD_REQUEST","issue triage: `hash` is required");return e},ci=i=>{const e=i.assignee;if(e===null)return Dt;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)")},di=i=>{const e=i.severity;if(e===null)return Dt;if(oi(e))return e;throw new p("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},li=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(Xn(i.params))throw new p("BAD_REQUEST",`createWorkflowInstance: params ${Vn}`);return{exportName:e,id:t,params:i.params}},ui=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}},ut=i=>typeof i=="string"&&ti.has(i)?i:"unknown",hi=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"}},ae=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"||!Zn.has(s)||e.push({column:n,operator:s,value:r.value})}return e.length>0?e:void 0},pi=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"}},fi=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","deleteRows: `table` is required");const t=ae(i.filters),r=typeof i.search=="string"?i.search:void 0;if((t===void 0||t.length===0)&&(r===void 0||r.trim()===""))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}},mi=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:ae(i.filters),limit:typeof i.limit=="number"?i.limit:void 0,search:typeof i.search=="string"?i.search:void 0,table:e}},yi=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}},Si=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}},bi=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:Yn.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}},gi=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(N))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}}},Ri=i=>{const e=y=>{throw new p("BAD_REQUEST",`recordMail: ${y}`)},{bcc:t,cc:r,from:n,headers:s,html:o,replyTo:a,subject:c,text:d,to:l}=i;typeof c!="string"&&e("`subject` must be a string"),typeof l=="string"||Array.isArray(l)&&l.every(y=>typeof y=="string")||e("`to` must be a string or string[]");const f=(y,m)=>{if(y!==void 0)return(!Array.isArray(y)||!y.every(v=>typeof v=="string"))&&e(`\`${m}\` must be a string[]`),y},S=(y,m)=>(y!==void 0&&typeof y!="string"&&e(`\`${m}\` must be a string`),y);return{bcc:f(t,"bcc"),cc:f(r,"cc"),from:S(n,"from"),headers:s!==void 0&&typeof s=="object"&&s!==null?s:void 0,html:S(o,"html"),replyTo:S(a,"replyTo"),subject:c,text:S(d,"text"),to:l}},Ei=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??ei,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 H,isLunoraError as We}from"@lunora/errors";import{ISSUE_SEVERITIES as Kt,ISSUE_STATUSES as jt,ensureRequestLogTable as _t,readRequestLog as Gt,readErrorIssues as zt,findDanglingReferences as Jt,readAuthMetrics as Xt,readQueryInsights as Vt,LogBuffer as Yt,SpanBuffer as Zt,MetricBuffer as er,emitLogEvent as tr,resolveTraceAnchor as X,createTracer as rr,instrumentDatabase as sr,createTracedFetch as nr,createMetrics as ir,redactArgs as or,REQUEST_LOG_TABLE as Qe,createDatabaseTally as ar,formatTally as cr,dispatchRootSpan as dr,readFunctionMetricsTotals as lr,readFunctionMetricIndexHits as ur,readQueryMetrics as hr,recordFunctionMetric as pr,mergeScanAttribution as fr,FUNCTION_METRICS_MAX_PATHS as mr,recordQueryMetric as yr,readFunctionMetrics as Sr,readFunctionMetricBuckets as br,upsertIssueState as gr,ISSUE_STATE_TABLE as Rr,recordAuthEvent as Er,explainIssue as Ar,appendRequestLogEntry as vr,emitRequestLogEvent as wr,foldTraces as Tr,readMetricHistory as _r,buildSecurityAudit as Cr,parseLogArgs as kr,createSpanCollector as Ir,recordMetricHistory as Mr}from"@lunora/observability";import{createShardHost as Or,createSocketHost as qr}from"@lunora/platform-cloudflare";import{tableFromDepKey as Nr,ADMIN_FUNCTION_PREFIX as N,ensureAuditTable as Dr,readAuditLog as Pr,ADMIN_FUNCTIONS as h,facetColumn as xr,runReadonlySql as Br,findStorageReferences as Lr,readCapturedMail as Ur,MAIL_TABLE as Hr,readQueueMessages as Fr,QUEUE_TABLE as $r,envOptionalPositiveInt as Me,cdcSeqLeavingRows as ce,readCdcArchivedThrough as Wr,readCdcChanges as Ct,cdcArchiveRewound as Qr,archiveCdcSegment as Kr,writeCdcArchivedThrough as jr,readArchivedCdcChanges as Gr,compactCdcDocs as zr,trimCdcChanges as Jr,renderSql as Ke,sqliteInList as Xr,DOC_COLUMN as je,readSchemaVersion as Vr,readSchemaHistory as Yr,lintReadonlySql as Zr,stableStringify as kt,createShapeProbeCounters as es,createGlobalPollCounters as ts,DurableStreamRunner as rs,createFanoutCounters as Ge,ShardRunner as ss,ReactiveCache as ns,createRelayLink as is,listTables as de,minCdcReplayableSeq as os,createReplicaLink as as,readReactorState as cs,reactorNeedsRun as ds,MAX_PAGE_SIZE as ls,selectMatchingIds as us,CDC_LOG_TABLE as ze,readCdcCursor as le,readCdcEpoch as V,cdcForkedError as hs,minCdcSeq as ue,cursorBelowRetainedFloor as Y,cdcTrimmedError as ps,bumpCdcEpoch as Je,cdcCanVouchFor as fs,cdcTouchesTables as ms,readIdempotent as ys,writeIdempotent as Ss,trimIdempotent as bs,readClientWatermark as he,migrateClientWatermark as gs,advanceClientWatermark as Rs,deleteGlobalShapeSnapshot as Es,deleteShapePokeCursor as As,trySendFrame as E,selectExpiredIds as vs,recordScheduleOutbox as ws,forgetScheduleOutbox as pe,probeScheduleOutbox as fe,readDueScheduleOutbox as Ts,trimScheduleOutbox as _s,createDependencyTracker as Cs,createReadFootprint as ks,reactiveCacheKey as Xe,SCAN_DEP as Z,TransactionHeadroomTracker as ee,recordChangedKeys as Is,DATA_MIGRATION_STATE_TABLE as Ms,isDevEnvironment as P,gateReplicaDispatch as Os,RELATION_FUNCTION_PREFIX as qs,ConflictError as Ns,deleteGlobalShapeSnapshotsForConnection as Ds,deleteShapePokeCursorsForConnection as Ps,parseExportShardArgs as xs,parseImportShardArgs as Bs,writeReactorState as Ve,UNVOUCHABLE_DEP as Ye,listReactorStates as Ls,recordCapturedMail as Ze,clearCapturedMail as Us,recordQueueMessages as Hs,clearQueueMessages as Fs,readQueueMessageById as $s,isLossyBody as Ws,appendAuditEntry as Qs,readDeployInfo as Ks,readBookmark as js,armRestore as Gs,readMigrationStatus as zs,buildSettings as Js,summarizeSubscriptions as Xs,summarizeFanoutTopics as Vs,DEFAULT_MAX_RELAYS as Ys,readTablePage as Zs,FLAGS_FUNCTION_PREFIX as en,awaitWsDrain as F,stableWireKey as tn,mergeChangedKeys as rn,runSocketPool as et,createShapeDiffCache as me,writeShapePokeCursors as sn,recordFanoutPass as ye,recordShapeProbePass as tt,minShapePokeCursor as nn,readCdcChangeKeys as on,buildShapeDiff as an,selectShapeRows as cn,projectColumns as dn,diffGlobalMembership as rt,readGlobalShapeSnapshot as ln,writeGlobalShapeSnapshot as un,deferScheduleOutbox as hn,parkScheduleOutbox as pn,GlobalPollTick as Se,globalShapeReadKey as fn,recordGlobalPollPass as mn,buildPokeFrames as yn,readShapePokeCursor as Sn,writeShapePokeCursor as bn,subscriptionFrames as gn,handleReplicaControl as Rn,VECTOR_BACKFILL_MAX_PAGES as En,writeTouchesMemo as An}from"@lunora/shard-engine";import{subscriptionListDeltas as va}from"@lunora/shard-engine";import{drizzle as vn}from"drizzle-orm/durable-sqlite";import{c as be}from"./constant-time-equal-BRh9yUCr.mjs";import{j as w}from"./json-response-0Bq2ky0N.mjs";import{sql as D}from"drizzle-orm";const st=500,wn=9e5,Tn="DISPATCH_IN_PROGRESS",_n="x-lunora-dispatch-declined",se=(i,e)=>{if(i.size<e)return;const t=i.keys().next().value;t!==void 0&&i.delete(t)},ne=i=>{let e="";for(let r=0;r<i.length;r+=32768)e+=String.fromCharCode(...i.subarray(r,r+32768));return btoa(e)},It=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},x="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",Cn=i=>{let e="",t=0;const r=i.length-2;for(;t<r;t+=3){const s=i[t]<<16|i[t+1]<<8|i[t+2];e+=x.charAt(s>>18&63)+x.charAt(s>>12&63)+x.charAt(s>>6&63)+x.charAt(s&63)}const n=i.length-t;if(n===1){const s=i[t]<<16;e+=x.charAt(s>>18&63)+x.charAt(s>>12&63)}else if(n===2){const s=i[t]<<16|i[t+1]<<8;e+=x.charAt(s>>18&63)+x.charAt(s>>12&63)+x.charAt(s>>6&63)}return e},Ne=i=>{const e=i.replaceAll("-","+").replaceAll("_","/"),t=e+"=".repeat((4-e.length%4)%4);return It(t)},Mt=new TextDecoder;new TextEncoder;const nt="=",kn=i=>{if(i)try{const e=i[0]==="{"?i:Mt.decode(Ne(i)),t=JSON.parse(e);if(t&&typeof t=="object"&&!Array.isArray(t))return t}catch{}},it=i=>{if(i){if(!i.startsWith(nt))return i;try{return Mt.decode(Ne(i.slice(nt.length)))}catch{return}}},In=i=>{const e=Number(i);return Number.isFinite(e)&&e>0?e:void 0},ge=i=>typeof i=="number"&&Date.now()>=i,Mn=i=>{try{i.send(JSON.stringify({code:"TOKEN_EXPIRED",error:{code:"TOKEN_EXPIRED",message:"authentication token expired"},message:"authentication token expired",type:"error"})),i.close?.(4001,"token_expired")}catch{}},On="x-lunora-paywall",qn="1";Array.from({length:256},(i,e)=>e.toString(16).padStart(2,"0"));const te=/^[0-9a-f]+$/,Nn=(i,e,t=!0)=>`00-${i}-${e}-${t?"01":"00"}`,Dn=i=>{if(i==null)return;const e=i.split("-"),[t,r,n,s]=e;if(!(e.length<4||t===void 0||t.length!==2||!te.test(t)||t==="ff"||t==="00"&&e.length!==4||r===void 0||n===void 0||s===void 0||s.length!==2||!te.test(s)||r.length!==32||n.length!==16||!te.test(r)||!te.test(n)||r==="00000000000000000000000000000000"||n==="0000000000000000"))return{parentSpanId:n,sampled:(Number.parseInt(s,16)&1)===1,traceId:r}},Re=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$",ie=64,ot=1024,oe="__proto__",at={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},ct={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},Pn=i=>{if(i===null||typeof i!="object")return!1;const e=Object.getPrototypeOf(i);return e===null||e===Object.prototype},C=(i,e=0)=>{if(e>ie)throw new RangeError(`wire-codec: value nesting exceeds the ${ie}-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",C(i.getTime(),e+1)];if(i instanceof Error){const s=i,o={};for(const c of Object.keys(s)){if(s[c]===void 0)continue;const d=C(s[c],e+1);c===oe?Object.defineProperty(o,c,{configurable:!0,enumerable:!0,value:d,writable:!0}):o[c]=d}const a=[T,"error",String(s.name),String(s.message),o];return s.cause!==void 0&&a.push(C(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])=>[C(s,e+1),C(o,e+1)])];if(i instanceof Set)return[T,"set",[...i].map(s=>C(s,e+1))];if(i instanceof ArrayBuffer)return[T,"bytes",ne(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",ne(a)]:[T,"bytes",ne(a),o]}if(Array.isArray(i)){const s=i.map(o=>C(o,e+1));return s.length>0&&s[0]===T?[T,"arr",s]:s}if(!Pn(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=C(o,e+1);s===oe?Object.defineProperty(n,s,{configurable:!0,enumerable:!0,value:a,writable:!0}):n[s]=a}return n},_=(i,e=0)=>{if(e>ie)throw new RangeError(`wire-codec: value nesting exceeds the ${ie}-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=>_(s,e+1));case"bigint":{const s=i[2];if(typeof s!="string"||s.length>ot||!/^-?\d+$/.test(s))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${ot} digits)`);return BigInt(s)}case"date":{const s=_(i[2],e+1);if(typeof s!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(s)}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[_(o[0],e+1),_(o[1],e+1)]}))}case"set":return new Set(i[2].map(s=>_(s,e+1)));case"url":{const s=i[2];if(typeof s!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(s)}case"error":{const s=i[2],o=i[3];if(typeof s!="string"||typeof o!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const a=(Object.hasOwn(ct,s)?ct[s]:void 0)??Error,c=new a(o);c.name!==s&&Object.defineProperty(c,"name",{configurable:!0,value:s,writable:!0});const d=_(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 l of Object.keys(d))l===oe?Object.defineProperty(c,l,{configurable:!0,enumerable:!0,value:d[l],writable:!0}):c[l]=d[l];return i.length>5&&Object.defineProperty(c,"cause",{configurable:!0,value:_(i[5],e+1),writable:!0}),c}case"bytes":{const s=i[2];if(typeof s!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const o=It(s);if(ne(o)!==s)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const a=i[3]??"Uint8Array";if(a==="ArrayBuffer")return o.buffer.byteLength===o.byteLength?o.buffer:o.slice().buffer;const c=Object.hasOwn(at,a)?at[a]:void 0;return c?new c(o.slice().buffer):o}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return i.map(s=>_(s,e+1))}return i.map(n=>_(n,e+1))}const t=i,r={};for(const n of Object.keys(t)){const s=_(t[n],e+1);n===oe?Object.defineProperty(r,n,{configurable:!0,enumerable:!0,value:s,writable:!0}):r[n]=s}return r},xn="pageDelta",Bn="x-lunora-sample-errors",Ln=(i,e,t,r)=>{const n=i.get(e);if(n!==void 0)return n;se(i,r);const s=t().catch(o=>{throw i.get(e)===s&&i.delete(e),o});return i.set(e,s),s},De=new TextEncoder,Un=Array.from({length:32},(i,e)=>e);new RegExp(`[${Un.map(i=>String.fromCodePoint(i)).join("")}]`,"u");const Hn=64,Fn=new Map,Ot=async i=>Ln(Fn,i,async()=>crypto.subtle.importKey("raw",De.encode(i),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),Hn),$n=async(i,e)=>{const t=await Ot(i),r=await crypto.subtle.sign("HMAC",t,De.encode(e));return Cn(new Uint8Array(r))},Wn=async(i,e,t)=>{const r=await Ot(i);return crypto.subtle.verify("HMAC",r,t,De.encode(e))},Qn=new Set(["1","enabled","on","true","yes"]),Kn=new Set(["0","disabled","false","no","off"]),jn=(i,e)=>{const t=(i??"").trim().toLowerCase();return Qn.has(t)?!0:Kn.has(t)?!1:e},qt="v1",Gn=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!==qt||o.length===0)return!1;const a=Number(s);if(!Number.isFinite(a)||a<=t)return!1;let c;try{c=Ne(o)}catch{return!1}return Wn(i,`${n}.${s}`,c)},zn=`${qt}.admin-socket-binding`,Jn=async i=>$n(i,zn),Nt="__lunoraBranch",Xn=i=>typeof i=="object"&&i!==null&&Object.hasOwn(i,Nt),Vn=`may not contain the reserved workflow branch-marker key ("${Nt}")`,Yn=/\(exit (\d+)\)/,Zn=new Set(["contains","eq","gt","gte","lt","lte","ne"]),dt=100,ei="test@lunora.sh",ti=new Set(["complete","errored","paused","queued","running","terminated","unknown","waiting","waitingForPause"]),Dt=null,lt=(i,e)=>(i===void 0?"":`,"cursor":${String(i)}`)+(e===void 0?"":`,"epoch":${JSON.stringify(e)}`),ri=(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},si=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}},ni=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}},ii=i=>typeof i=="string"&&jt.includes(i),oi=i=>typeof i=="string"&&Kt.includes(i),ai=i=>{const e=typeof i.hash=="string"?i.hash.trim():"";if(e==="")throw new p("BAD_REQUEST","issue triage: `hash` is required");return e},ci=i=>{const e=i.assignee;if(e===null)return Dt;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)")},di=i=>{const e=i.severity;if(e===null)return Dt;if(oi(e))return e;throw new p("BAD_REQUEST","setIssueSeverity: `severity` must be one of critical|high|medium|low, or null to clear")},li=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(Xn(i.params))throw new p("BAD_REQUEST",`createWorkflowInstance: params ${Vn}`);return{exportName:e,id:t,params:i.params}},ui=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}},ut=i=>typeof i=="string"&&ti.has(i)?i:"unknown",hi=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"}},ae=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"||!Zn.has(s)||e.push({column:n,operator:s,value:r.value})}return e.length>0?e:void 0},pi=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"}},fi=i=>{const e=typeof i.table=="string"?i.table:"";if(e.trim()==="")throw new p("BAD_REQUEST","deleteRows: `table` is required");const t=ae(i.filters),r=typeof i.search=="string"?i.search:void 0;if((t===void 0||t.length===0)&&(r===void 0||r.trim()===""))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}},mi=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:ae(i.filters),limit:typeof i.limit=="number"?i.limit:void 0,search:typeof i.search=="string"?i.search:void 0,table:e}},yi=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}},Si=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}},bi=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:Yn.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}},gi=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(N))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}}},Ri=i=>{const e=y=>{throw new p("BAD_REQUEST",`recordMail: ${y}`)},{bcc:t,cc:r,from:n,headers:s,html:o,replyTo:a,subject:c,text:d,to:l}=i;typeof c!="string"&&e("`subject` must be a string"),typeof l=="string"||Array.isArray(l)&&l.every(y=>typeof y=="string")||e("`to` must be a string or string[]");const f=(y,m)=>{if(y!==void 0)return(!Array.isArray(y)||!y.every(v=>typeof v=="string"))&&e(`\`${m}\` must be a string[]`),y},S=(y,m)=>(y!==void 0&&typeof y!="string"&&e(`\`${m}\` must be a string`),y);return{bcc:f(t,"bcc"),cc:f(r,"cc"),from:S(n,"from"),headers:s!==void 0&&typeof s=="object"&&s!==null?s:void 0,html:S(o,"html"),replyTo:S(a,"replyTo"),subject:c,text:S(d,"text"),to:l}},Ei=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??ei,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}},Ai=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:l,timestamp:u}=o;return{attempts:typeof l=="number"&&Number.isFinite(l)?l: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 u=="number"&&Number.isFinite(u)?u:0}})},$=i=>`${i.traceId}:${i.rootSpanId}`,vi=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>dt))throw new p("BAD_REQUEST",`sendQueueMessage: \`batch\` must contain between 1 and ${String(dt)} messages`);return{batch:r,body:i.body,contentType:typeof i.contentType=="string"?i.contentType:void 0,delaySeconds:t,exportName:e}},wi=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}},Ti=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}},_i=i=>{if(i!==void 0){if(!Array.isArray(i)||!i.every(e=>typeof e=="string"))throw new p("BAD_REQUEST","findRelated: `edges` must be an array of edge-name strings");return i}},Ci=i=>{const e=typeof i.table=="string"?i.table:"",t=typeof i.id=="string"?i.id:"";if(e.trim()==="")throw new p("BAD_REQUEST","findRelated: `table` is required");if(t.trim()==="")throw new p("BAD_REQUEST","findRelated: `id` is required");const{cursor:r,depth:n,direction:s,edges:o,limit:a}=i;if(r!=null&&typeof r!="string")throw new p("BAD_REQUEST","findRelated: `cursor` must be a string");if(n!==void 0&&typeof n!="number")throw new p("BAD_REQUEST","findRelated: `depth` must be a number");if(s!==void 0&&s!=="both"&&s!=="in"&&s!=="out")throw new p("BAD_REQUEST",'findRelated: `direction` must be one of "in", "out" or "both"');if(a!==void 0&&typeof a!="number")throw new p("BAD_REQUEST","findRelated: `limit` must be a number");return{cursor:typeof r=="string"?r:void 0,depth:n,direction:s,edges:_i(o),id:t,limit:a,table:e}},G=i=>{throw new p("BAD_REQUEST",i)},ht=(i,e)=>((typeof i!="string"||i.trim()==="")&&G(`rankPage: \`${e}\` is required`),i),ki=i=>{if(i===void 0)return;(typeof i!="object"||i===null||Array.isArray(i))&&G("rankPage: `after` must be an object");const e=i;return(typeof e.partitionKey!="string"||typeof e.rowId!="string"||!Array.isArray(e.sortValues))&&G("rankPage: `after` must have a string partitionKey, string rowId, and array sortValues"),{partitionKey:e.partitionKey,rowId:e.rowId,sortValues:e.sortValues}},Ii=i=>{const e=ht(i.table,"table"),t=ht(i.index,"index");i.take!==void 0&&typeof i.take!="number"&&G("rankPage: `take` must be a number"),i.cursor!==void 0&&i.cursor!==null&&typeof i.cursor!="string"&&G("rankPage: `cursor` must be a string or null"),i.partitionKey!==void 0&&typeof i.partitionKey!="string"&&G("rankPage: `partitionKey` must be a string"),i.directions!==void 0&&!Array.isArray(i.directions)&&G("rankPage: `directions` must be an array");const r=i.directions===void 0?void 0:i.directions.map(n=>n==="desc"?"desc":"asc");return{after:ki(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}},Mi=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{}},Oi=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 l=d;if(l!==void 0&&typeof l._id=="string"&&l._id!==c)throw new p("BAD_REQUEST",`applyCdc: changes[${String(n)}].doc._id must match the entry id`);return{doc:l,id:c,op:o,seq:typeof s.seq=="number"?s.seq:0,table:a,ts:typeof s.ts=="number"?s.ts:0}})}},qi=i=>{const e=r=>{const n=typeof r=="number"?r:Number(r);return Number.isFinite(n)&&n>=0?Math.floor(n):void 0},{sinceEpoch:t}=i;return{limit:e(i.limit),...typeof t=="string"&&t.length>0?{sinceEpoch:t}:{},sinceSeq:e(i.sinceSeq)??0}},W=i=>i?{"x-d1-bookmark":i}:void 0,pt=i=>kn(i),Ni=i=>{if(!i)return;const e=Number(i);return Number.isInteger(e)&&e>=0?e:void 0},Di=i=>{if(i!==null)return i!=="0"},Pi=i=>{if(!i)return;const e=Number(i);return Number.isInteger(e)&&e>0?e:void 0},xi=i=>{const e=new Set;for(const t of i){const r=Nr(t);r!==""&&e.add(r)}return e},Bi=i=>{if(i===void 0)return;const e=Number.parseInt(i,10);return Number.isFinite(e)&&e>0?e:void 0},Li=(i,e)=>i==="1"||i==="true"?!0:i==="0"||i==="false"?!1:e,Ui=i=>{if(i===void 0)return 1;const e=Number.parseFloat(i);return Number.isFinite(e)?Math.min(1,Math.max(0,e)):1},Hi=i=>i>=1?!0:i<=0?!1:Math.random()<i,Ee=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},B="*",ft=(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?[B]:t)}},Fi=(i,e)=>{Dr(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([B])}},$i=(i,e)=>{_t(i);const t=e.outcome==="ok"||e.outcome==="error"?e.outcome:void 0;return{result:{entries:Gt(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([B])}},Wi=(i,e)=>(_t(i),{result:{issues:zt(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:ii(e.status)?e.status:void 0,userId:typeof e.userId=="string"?e.userId:void 0})},tables:new Set([B])}),Qi=i=>{let e;try{e=Xt(i)}catch{e={attempts:0,failureRate:0,failures:0,history:[],sinceMs:0}}return{result:e,tables:new Set([B])}},Ki=(i,e)=>{const t=typeof e.limit=="number"?e.limit:void 0;let r;try{r=Ur(i,{limit:t})}catch{r={entries:[]}}return{result:r,tables:new Set([Hr])}},ji=(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=Fr(i,{limit:t,queue:r})}catch{n={entries:[]}}return{result:n,tables:new Set([$r])}},Gi=(i,e)=>{const t=typeof e.table=="string"?e.table:"";return{result:xr(i,{column:typeof e.column=="string"?e.column:"",filters:ae(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===""?B:t])}},zi=(i,e)=>{const t=typeof e.sql=="string"?e.sql:"";return{result:Br(i,t),tables:new Set([B])}},Ji=(i,e,t)=>{const r=Array.isArray(e.keys)?e.keys.filter(n=>typeof n=="string"):[];return{result:Lr(i,t,r),tables:new Set([B])}},Xi=(i,e,t)=>{const r=Array.isArray(e.liveKeys)?e.liveKeys.filter(s=>typeof s=="string"):[],n=Jt(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([B])}},Vi=(i,e,t)=>{if(i===h.getAuthMetrics)return Qi(e);if(i===h.getCapturedMail)return Ki(e,t);if(i===h.getQueueMessages)return ji(e,t)},Yi=["x-lunora-userid","x-lunora-identity","x-d1-bookmark","x-lunora-client-ip","x-lunora-system","x-lunora-shard-binding"],Zi=(i,e)=>{const t=new Headers({"content-type":"application/json"});for(const r of Yi){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)),e.baselineSeq!==void 0&&t.set("x-lunora-base-seq",String(e.baselineSeq)),new Request("https://shard.internal/rpc",{body:JSON.stringify({args:e.args??{},functionPath:e.functionPath}),headers:t,method:"POST"})},eo="LUNORA_CDC_ARCHIVE",to=6e4,Ae=5e4,ro=1e4,mt=i=>{if(typeof i!="object"||i===null)return;const e=i[eo];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 so{host;lastSweepAt=0;constructor(e){this.host=e}sweep(){if(!this.host.enabled())return;const e=Date.now();if(e-this.lastSweepAt<=to)return;this.lastSweepAt=e;const t=this.host.env(),r=Me(t,"LUNORA_CDC_LOG_RETENTION"),n=Me(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=mt(t);if(a===void 0||r===void 0){this.applyRetention(o,s,r,Number.POSITIVE_INFINITY,Ae);return}const c=ce(o,s??r);if(c===void 0||c<=0)return;const d=Math.min(c,this.host.retentionFloor(o)),l=Wr(o),u=Ct(o,{limit:ro,sinceSeq:l}).changes.filter(y=>y.seq<=d),f=u.at(-1)?.seq;if(f===void 0){this.applyRetention(o,s,r,l,Ae);return}const S=(async()=>{try{const m={epoch:this.host.epoch(),shard:this.host.shardKey()};if(await Qr(a,m,l)){this.host.sealTimeline();return}await Kr(a,m,u),jr(o,f),this.applyRetention(o,s,r,f,Ae)}catch(y){this.host.recordError("cdc:archive",y)}})();this.host.waitUntil?.(S)}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=mt(this.host.env()),s=this.host.epoch();if(n===void 0||s===void 0)throw r;let o;try{o=await Gr(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,epoch:s}}}applyRetention(e,t,r,n,s){const o=this.host.retentionFloor(e);if(t!==void 0){const a=ce(e,t);a!==void 0&&a>0&&zr(e,Math.min(a,o,n),s)}if(r!==void 0){const a=ce(e,r);a!==void 0&&a>0&&Jr(e,Math.min(a,o,n),s)}}}const no=wn;class io{claims=new Map;claim(e,t){if(e===void 0)return;const r=`${e}\0${t}`,n=Date.now(),s=this.claims.get(r);if(s!==void 0&&n-s.claimedAt<no)return"declined";const o={claimedAt:n,key:r};return this.claims.set(r,o),o}release(e){this.claims.get(e.key)===e&&this.claims.delete(e.key)}}const oo=/^[A-Za-z_$][\w$]*$/u,ao=i=>oo.test(i)?i:`"${i.replaceAll("\\",String.raw`\\`).replaceAll('"',String.raw`\"`)}"`,co=500,lo=8,uo=(i,e)=>{if(e.includes(i))return D`${D.identifier(i)}`;if(e.includes(je))return D`json_extract(${D.identifier(je)}, ${`$.${ao(i)}`})`},ho=(i,e)=>{const t=[...new Set(e.ids.filter(s=>typeof s=="string"&&s!==""))].slice(0,co),r=e.relations.slice(0,lo);if(t.length===0||r.length===0)return{relations:[]};const n=[];for(const s of r){let o;try{o=i.exec(Ke("sqlite",D`PRAGMA table_info(${D.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=uo(s.column,o);if(a===void 0)continue;const c={};try{const d=Ke("sqlite",D`SELECT ${a} AS ${D.identifier("parent")}, COUNT(*) AS ${D.identifier("n")}
|
|
4
4
|
FROM ${D.identifier(s.table)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/do",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.168",
|
|
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.
|
|
50
|
-
"@lunora/observability": "1.0.0-alpha.
|
|
51
|
-
"@lunora/platform-cloudflare": "1.0.0-alpha.
|
|
52
|
-
"@lunora/shard-engine": "1.0.0-alpha.
|
|
49
|
+
"@lunora/errors": "1.0.0-alpha.42",
|
|
50
|
+
"@lunora/observability": "1.0.0-alpha.97",
|
|
51
|
+
"@lunora/platform-cloudflare": "1.0.0-alpha.54",
|
|
52
|
+
"@lunora/shard-engine": "1.0.0-alpha.88",
|
|
53
53
|
"drizzle-orm": "^0.45.2"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|