@lunora/sql-store 1.0.0-alpha.209 → 1.0.0-alpha.210

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{createSqlCtxDb as a,readSqlCdcChangedTables as o,readSqlCdcChanges as t,readSqlCdcFloor as l,runSqlCdcMigration as s,sweepSqlCdcRetention as n}from"./packem_shared/createSqlCtxDb-B_kk-E2v.mjs";import{runSqlGlobalTableMigrations as i}from"./packem_shared/runSqlGlobalTableMigrations-qVa5Q8BM.mjs";import{runSqlAggregateMigrations as c,runSqlRankMigrations as q}from"./packem_shared/runSqlAggregateMigrations-BqfzHcG8.mjs";import{d as f,r as m}from"./packem_shared/ctx-db-search-DB_ejfgj.mjs";import{S as x,m as p}from"./packem_shared/ctx-db-search-state-DRiojLLm.mjs";import{d as u,a as h,c as M,s as T,t as A}from"./packem_shared/value-codec-CiS1h_97.mjs";import{z as R}from"./packem_shared/sql-exec-UH-aJj2C.mjs";export{x as SEARCH_STATE_TABLE,f as backfillSqlSearchIndexes,a as createSqlCtxDb,u as decodeBigint,R as decodeGlobalRow,h as effectiveColumnKind,p as migrateSearchState,o as readSqlCdcChangedTables,t as readSqlCdcChanges,l as readSqlCdcFloor,c as runSqlAggregateMigrations,s as runSqlCdcMigration,i as runSqlGlobalTableMigrations,q as runSqlRankMigrations,m as runSqlSearchMigrations,M as sqliteDecode,T as sqliteEncode,n as sweepSqlCdcRetention,A as tryJsonParse};
1
+ import{createSqlCtxDb as a,readSqlCdcChangedTables as o,readSqlCdcChanges as t,readSqlCdcFloor as l,runSqlCdcMigration as s,sweepSqlCdcRetention as n}from"./packem_shared/createSqlCtxDb-BMta9wri.mjs";import{runSqlGlobalTableMigrations as i}from"./packem_shared/runSqlGlobalTableMigrations-qVa5Q8BM.mjs";import{runSqlAggregateMigrations as c,runSqlRankMigrations as q}from"./packem_shared/runSqlAggregateMigrations-BqfzHcG8.mjs";import{d as f,r as m}from"./packem_shared/ctx-db-search-DB_ejfgj.mjs";import{S as x,m as p}from"./packem_shared/ctx-db-search-state-DRiojLLm.mjs";import{d as u,a as h,c as M,s as T,t as A}from"./packem_shared/value-codec-CiS1h_97.mjs";import{z as R}from"./packem_shared/sql-exec-UH-aJj2C.mjs";export{x as SEARCH_STATE_TABLE,f as backfillSqlSearchIndexes,a as createSqlCtxDb,u as decodeBigint,R as decodeGlobalRow,h as effectiveColumnKind,p as migrateSearchState,o as readSqlCdcChangedTables,t as readSqlCdcChanges,l as readSqlCdcFloor,c as runSqlAggregateMigrations,s as runSqlCdcMigration,i as runSqlGlobalTableMigrations,q as runSqlRankMigrations,m as runSqlSearchMigrations,M as sqliteDecode,T as sqliteEncode,n as sweepSqlCdcRetention,A as tryJsonParse};
@@ -0,0 +1,7 @@
1
+ import{LunoraError as g}from"@lunora/errors";import{m as rn,D as sn}from"./ctx-db-search-state-DRiojLLm.mjs";import{c as an,r as cn,A as dn,C as ln,R as un,u as fn,a as wn,T as hn,x as $n,b as _n}from"./ctx-db-search-DB_ejfgj.mjs";import{throwingScheduler as En,describeRelationWrites as pn,CDC_LOG_TABLE as H,cdcForkedError as yn,cursorBelowRetainedFloor as Rn,cdcTrimmedError as Sn,serverInList as gn,assertNoExplicitUndefined as We,hasTrigger as vn,runRowValidators as Fe,assertFlatPredicate as dt,mergeWhere as B,rankTableName as $e,sortColumnName as pe,resolveRankPartition as lt,encodePartitionKey as Le,resolveRankSeekTuple as Tn,RANK_TIEBREAK as ye,CountRlsUnsupportedError as ut,compileWhereSql as z,ConflictError as se,patchDependsOnRow as mn,normalizeIdStructurally as In,applyInsertDefaults as An,assertValidClientId as bn,assertStorableRowId as Cn,aggregateSqlFunction as _e,softDeleteScope as Me,resolveWith as ft,relationHooks as wt,applySelect as ht,encodeCursor as Ln,NotFoundError as Mn,applyOnDelete as Nn,normalizeCountArgument as qn,selectIndexForCount as kn,encodeAggregateKey as J,aggregateTableName as ie,selectIndexForAggregate as Dn,readAggregateValue as Ue,runTriggers as On,matchesRankStaticWhere as $t,nullsOrderSuffix as _t,nullsFirstOf as Et,rankPivotConditionSql as kt,CURSOR_PREFIX as Bn,resolvePatch as Wn,stripReservedPatchFields as Fn,assertPatchAllowed as Un,resolveRelationPredicates as xn,selectIndexForGroupBy as Pn,composeReadPredicate as Hn,fanOutScalarCounts as Kn,matchesStaticWhere as xe,foldAggregateTally as pt,coerceAggregateNumber as Pe,whereOfFilter as jn,isPushableWhere as Gn,tiebreakDirectionFor as Vn,CDC_LOG_TABLE_SEQ_INDEX as Yn,NotUniqueError as Xn,WORKERD_SQLITE_LIMITS as Qn}from"@lunora/shard-engine";import{decodeWire as Dt,needsWireEncoding as Ot,encodeWire as Bt}from"@lunora/wire";import{sql as e,SQL as zn}from"drizzle-orm";import{p as yt,m as Rt,q as b,a as V,c as Jn,o as Zn,f as Y,s as oe,O as Ee,b as U,h as St,t as ei,r as ti,j as He,u as gt,l as vt,B as Ke,v as Ne,n as Je,e as Tt,w as mt,x as It,y as ni}from"./sql-exec-UH-aJj2C.mjs";import{z as to}from"./sql-exec-UH-aJj2C.mjs";import{runSqlGlobalTableMigrations as ii}from"./runSqlGlobalTableMigrations-qVa5Q8BM.mjs";import{runSqlAggregateMigrations as oi,runSqlRankMigrations as ri}from"./runSqlAggregateMigrations-BqfzHcG8.mjs";import{c as Wt,a as Ft}from"./value-codec-CiS1h_97.mjs";const si=(o,c)=>{if(o.size<c)return;const h=o.keys().next().value;h!==void 0&&o.delete(h)},At=50,ai=(o,c={})=>{const h=c.maxBatch??At,a=Number.isInteger(h)&&h>0?h:At,R=new Map;let f=!1;const l=async(I,m)=>{const T=[...m.keys()];for(let C=0;C<T.length;C+=a){const M=T.slice(C,C+a);try{const D=await o(I,M);for(const K of M){const X=D.get(K);for(const Z of m.get(K)??[])Z.resolve(X)}}catch(D){for(const K of M)for(const X of m.get(K)??[])X.reject(D)}}},q=()=>{f=!1;const I=[...R.entries()];R.clear();for(const[m,T]of I)l(m,T).catch(()=>{})};return{async load(I,m){return new Promise((T,C)=>{let M=R.get(I);M||(M=new Map,R.set(I,M));const D=M.get(m);D?D.push({reject:C,resolve:T}):M.set(m,[{reject:C,resolve:T}]),f||(f=!0,queueMicrotask(q))})}}},ci=new Set(["_id","id"]),di=o=>{throw new g("INTERNAL",`no ORDER BY NULL placement for dialect "${String(o)}"`)},Ut=(o,c)=>{const h=c.direction==="desc"?"DESC":"ASC",a=c.nullable===!0,R=f=>e`${Ne(o,c.field)} ${e.raw(`${h}${f}`)}`;switch(o.name){case"mysql":{const f=R("");return!a||c.nulls===void 0?[f]:[e`(${Ne(o,c.field)} IS NULL) ${e.raw(c.nulls==="first"?"DESC":"ASC")}`,f]}case"postgres":return[R(a?_t(Et(c)):"")];case"sqlite":return[R(a&&c.nulls!==void 0?_t(Et(c)):"")];default:return di(o.name)}},li=(o,c)=>{const h=o.flatMap(a=>Ut(c,a));if(!o.some(a=>ci.has(a.field))){const a=Vn(o);h.push(e`${U("id")} ${e.raw(a==="desc"?"DESC":"ASC")}`)}return e.join(h,e`, `)},bt=50,ui=o=>{const c=o.detail??o["QUERY PLAN"];return typeof c=="string"?c:Object.values(o).map(String).join(" | ")},je=(o,c,h,a)=>{for(const[R,f]of ei(o)){if(f.serverDefault){R in c&&(h[R]=f.serverDefault({auth:a}));continue}f.onUpdateFn&&!(R in c)&&(h[R]=f.onUpdateFn())}},fi=128,wi=()=>{const o=new Map;return{delete:c=>{o.delete(c)},get:c=>{const h=o.get(c);if(h!==void 0)return o.delete(c),o.set(c,h),h},set:(c,h)=>{o.has(c)?o.delete(c):si(o,fi),o.set(c,h)}}},Xe=o=>`u${o}`,xt=(o,c)=>`p${o}\0${c}`,hi=async(o,c,h,a,R,f)=>{const l=f===void 0?Xe(a):xt(f,a),q=R.get(l);if(q!==void 0)return q;const I=Object.entries(h.tables).filter(([,T])=>T.shardMode===void 0||T.shardMode.kind==="global").map(([T])=>T).filter(T=>f===void 0||T===f),m=await Promise.all(I.map(async T=>({found:(await b(o,c,e`SELECT 1 FROM ${e.identifier(T)} WHERE ${e.identifier("id")} = ${a} LIMIT 1`)).length>0,tableName:T})));for(const T of m)if(T.found)return R.set(l,T.tableName),T.tableName},ae=o=>o==null?null:Number(o),$i=(o,c,h)=>h.map(a=>{const R={};for(const f of c){const l=o.shape[f];R[f]=Wt(a[f]??null,l&&Ft(l))}return{key:R,value:ae(a.value)}}),_i=(o,c,h)=>[...o.partitionBy??[],...o.sortBy.map(R=>R.field),...o.where?Object.keys(o.where):[]].every(R=>mt(c,R)===mt(h,R)),Pt=o=>o.length===1?o[0]:e`(${e.join(o,e` AND `)})`,re=o=>e.join(o.map(c=>e`${e.identifier(c)}`),e`, `),ce=o=>e.join(o.map(c=>e`${c}`),e`, `),Ge=(o,c)=>{if(o==="postgres"){for(const[h,a]of Object.entries(c))if(typeof a=="string"&&a.includes("\0"))throw new g("BAD_REQUEST",`"${h}" holds a NUL character (U+0000), which a Postgres text column cannot store`)}},qe=o=>o instanceof ArrayBuffer?new Uint8Array(o):Array.isArray(o)?Uint8Array.from(o):o,Ei=(o,c,h,a,R)=>{const f=[];for(let l=0;l<h.length+1;l+=1){const q=h[l],I=c.sortBy[l],m=l<h.length&&q!==void 0&&I!==void 0,T=I?.direction==="desc"?"desc":"asc",C=m?kt(q,qe(a[q]),T,!1):e`${e.identifier(ye)} < ${R}`;if(C===void 0)continue;const M=h.slice(0,l).map(D=>Je(o,e`${e.identifier(D)}`,qe(a[D])));M.push(C),f.push(Pt(M))}return f.length>0?e.join(f,e` OR `):e`1 = 0`},pi=(o,c,h)=>{if(h.length!==c.length)return;const a=[];for(const[R,f]of c.entries()){const l=kt(f.column,qe(h[R]),f.direction,!0);if(l===void 0)continue;const q=[];for(let I=0;I<R;I+=1){const m=c[I];m!==void 0&&q.push(Je(o,e`${e.identifier(m.column)}`,qe(h[I])))}q.push(l),a.push(Pt(q))}return a.length===0?e`(1 = 0)`:e`(${e.join(a,e` OR `)})`},yi=(o,c)=>{if(o.sortBy.length===0)throw new g("INTERNAL",`rankIndex "${o.name}" requires at least one "sortBy" column for stable pagination`);const h=[{column:"__partition__",direction:"asc",nullable:!1}];for(const[a,R]of o.sortBy.entries())h.push({column:c[a]??pe(a),direction:R.direction,nullable:!0});return h.push({column:ye,direction:"asc",nullable:!1}),h},Ri=async(o,c,h,a,R)=>{const l=[];for(let T=0;T<R.length;T+=50)l.push(R.slice(T,T+50));const q=await Promise.all(l.map(async T=>b(o,c,e`SELECT * FROM ${e.identifier(a)} WHERE ${e.identifier("id")} IN (${ce(T)})`))),I=new Map;for(const T of q)for(const C of T)I.set(C.id,C);const m=[];for(const T of R){const C=Y(h,I.get(T));C&&m.push(C)}return m},Si=o=>{const c=o.map(f=>Wt(f,"bytes")),h=JSON.stringify(Ot(c)?Bt(c):c),a=new TextEncoder().encode(h);let R="";for(const f of a)R+=String.fromCodePoint(f);return Bn+btoa(R)},Ht=o=>{if(o===void 0)return!1;const c=Ft(o);return c==="any"||c==="bigint"||c==="from"||c==="union"},Qe=(o,c,h)=>{if(Ht(o.shape[c]))throw new g("BAD_REQUEST",`${h}: "${c}" may hold an order-preserving key rather than a value SQL can reduce or group — declare an aggregateIndex covering this (by, field, op) so the maintained companion answers it instead (its running total is a REAL, so it stays exact only while the total is inside 2^53)`)},gi=(o,c,h,a)=>{for(const R of h)Qe(o,R,`groupBy(${c}, { by: [..."${R}"] })`);a.field!==void 0&&Qe(o,a.field,`groupBy(${c}, { agg: { op: "${a.op}", field: "${a.field}" } })`)},ze="__cdc_sweep",Kt="global",vi=6e4,Ti=1e4,mi=3e4;let Ct=0;const Ii=async(o,c)=>{const{autoincrementPrimaryKey:h,key:a,real:R,text:f}=c.companionTypes;await V(o,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(H)} (${e.identifier("seq")} ${e.raw(h)}, ${e.identifier("ts")} ${e.raw(R)} NOT NULL, ${e.identifier("table")} ${e.raw(a)} NOT NULL, ${e.identifier("id")} ${e.raw(a)} NOT NULL, ${e.identifier("op")} ${e.raw(a)} NOT NULL, ${e.identifier("doc")} ${e.raw(f)})`);const l=c.indexKeyPrefix?.("string");await Jn(o,c,{columns:e`${l===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(l))})`}, ${e.identifier("seq")}`,name:Yn,table:H,unique:!1}),await V(o,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(ze)} (${e.identifier("id")} ${e.raw(a)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(R)} NOT NULL)`),await V(o,c,e`INSERT INTO ${e.identifier(ze)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${Kt}, ${0}) ${c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},Ai=async(o,c,h)=>{const a=e`UPDATE ${e.identifier(ze)} SET ${e.identifier("lease_until")} = ${h+vi} WHERE ${e.identifier("id")} = ${Kt} AND ${e.identifier("lease_until")} <= ${h}`;if(c.supportsReturning)return(await b(o,c,e`${a} RETURNING ${e.identifier("id")}`)).length>0;const R=await V(o,c,a);return(c.affectedRows?c.affectedRows(R??{rowsAffected:0}):0)>0},bi=async(o,c,h,a)=>{if(!await Ai(o,c,a))return;const R=a-h;await V(o,c,e`
2
+ DELETE FROM ${e.identifier(H)} WHERE ${e.identifier("seq")} IN (
3
+ SELECT ${e.identifier("seq")} FROM (
4
+ SELECT ${e.identifier("seq")} FROM ${e.identifier(H)} WHERE ${e.identifier("ts")} <= ${R} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Ti))}
5
+ ) AS ${e.identifier("expired")}
6
+ )
7
+ `)},jt=async(o,c)=>{const h=await b(o,c,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(H)}`),a=Number(h[0]?.seq??Number.NaN);return Number.isFinite(a)?a:void 0},Ci=async(o,c)=>{if(c.name!=="sqlite")return;const h=await b(o,c,e`SELECT ${e.identifier("seq")} AS ${e.identifier("seq")} FROM ${e.identifier("sqlite_sequence")} WHERE ${e.identifier("name")} = ${H}`),a=Number(h[0]?.seq??Number.NaN);return Number.isFinite(a)?a:0},Li=o=>JSON.stringify(Ot(o)?Bt(o):o),Mi=(o,c,h,a,R)=>e`INSERT INTO ${e.identifier(H)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${o}, ${c}, ${h}, ${a}, ${R===void 0?null:Li(R)})`,zi=async(o,c,h)=>{const a=c.sinceSeq??0,R=Math.max(1,Math.min(c.limit??1e3,1e4)),f=await jt(o,h),l=await Ci(o,h);if(l!==void 0&&a>l)throw yn(l,a,"global");if(f!==void 0&&Rn(f,a))throw Sn(f,a,"global");const I=(await b(o,h,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(H)} WHERE seq > ${a} ORDER BY seq ASC LIMIT ${e.raw(String(R))}`)).map(m=>{const{doc:T}=m,C={id:String(m.id),op:String(m.op),seq:Number(m.seq),table:String(m.table),ts:Number(m.ts)};return typeof T=="string"?{...C,doc:Dt(JSON.parse(T))}:C});return{changes:I,cursor:I.at(-1)?.seq??a}},Ni=1e4,qi=1e3,Lt=(o,c)=>{const h=e.identifier(H),a=e`(SELECT MIN(v.seq) FROM ${h} v WHERE v.seq > ${o} AND v.seq - 1 > ${o} AND v.ts > ${c} AND NOT EXISTS (SELECT 1 FROM ${h} p WHERE p.seq = v.seq - 1))`;return e`${a} AS ${e.identifier("gap")}, (SELECT MAX(q.seq) FROM ${h} q WHERE q.seq > ${o} AND q.seq < ${a}) AS ${e.identifier("below")}`},Mt=(o,c,h)=>{const a=Number(c?.gap??Number.NaN);if(!Number.isFinite(a))return o;const R=Number(c?.below??Number.NaN);return Math.min(o,Number.isFinite(R)?R:h)},ki=async(o,c,h,a={})=>{const R=e.identifier(H),f=h.name!=="sqlite",l=(a.now??Date.now())-Ni;if(a.cursorOnly){const C=e`GREATEST((SELECT MAX(seq) FROM ${R}) - ${e.raw(String(qi))}, ${c})`,M=await b(o,h,e`SELECT MAX(seq) AS seq${f?e`, ${Lt(C,l)}`:e``} FROM ${R}`),D=Number(M[0]?.seq??c);return{cursor:Mt(Number.isFinite(D)?D:c,M[0],c),tables:[]}}const q=await b(o,h,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq${f?e`, ${Lt(e`${c}`,l)}`:e``} FROM ${R} WHERE seq > ${c} GROUP BY ${e.identifier("table")}`);let I=c;const m=[];for(const C of q){const M=Number(C.seq);Number.isFinite(M)&&M>I&&(I=M),m.push(String(C.table))}I=Mt(I,q[0],c);const T=a.retained===!0?await jt(o,h):void 0;return{cursor:I,tables:m,...T===void 0?{}:{floor:T}}},Di=/string or blob too big/iu,Oi=/row is too big/iu,Bi=(o,c)=>{const{code:h,errno:a}=c,R=c instanceof Error?c.message:"";switch(o.name){case"mysql":return a===1118||h==="ER_TOO_BIG_ROWSIZE"?"InnoDB's per-row ceiling — roughly 8 KB, half a 16 KB page, for the part of the row stored inline":void 0;case"postgres":return Oi.test(R)?"the 8 KB heap page a tuple must fit once its wide columns have been TOASTed out":void 0;default:return Di.test(R)?"the storage engine's per-row ceiling (2 MB on D1)":void 0}},Wi=(o,c,h)=>{const a=Bi(o,c);if(a!==void 0)throw new g("PAYLOAD_TOO_LARGE",`document is too large to store in "${h}": a single row cannot exceed ${a}. The limit is on the STORED bytes, which are UTF-8. Keep the payload in R2 (ctx.storage) and store a reference on the row.`)},Ve=16,Nt="__lunora_patch_if_match__",qt=(o,c,h)=>{throw o.isUniqueViolation(c)?new se(`unique constraint violation on "${h}"`,"unique"):(Wi(o,c,h),c)},Ye=new WeakMap,Fi=o=>{const c=gn(o);return(h,a,R,f)=>a.some(l=>l instanceof zn)?Zn(o,h,a,R):c(h,a,R,f)},Ji=o=>{const{crossShardCounter:c,crossShardReader:h,exec:a,maxRelationKeys:R,schema:f}=o,{dialect:l}=o,q={fieldRef:t=>Ne(l,t),rangeTypeGuard:(t,n)=>ni(l,t,n),...l.name==="mysql"?{containsExpr:(t,n)=>{const i=yt(t);return i===void 0?e`LOCATE(${n}, ${t}) > 0`:e`LOCATE(${Rt("mysql",n)}, ${i}) > 0`}}:{},...l.name==="postgres"?{containsExpr:(t,n)=>{const i=yt(t);return i===void 0?e`strpos(${t}, ${n}) > 0`:e`strpos(${i}, ${Rt("postgres",n)}) > 0`}}:{},...l.name==="sqlite"?{}:{inList:Fi(l.name)}},I=new WeakMap,m=t=>{const n=I.get(t);if(n!==void 0)return n;const i={...q,serialize:(s,r)=>It(l,r,s,d=>oe(t,r,d))};return I.set(t,i),i},T=(t,n)=>Je(l.name,t,n),C=t=>{const n=re(t.columns),i=ce(t.values),s=_=>l.name==="mysql"?e`VALUES(${e.identifier(_)})`:e`excluded.${e.identifier(_)}`,r=_=>l.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(_)}`:e`${e.identifier(_)}`,d=e.join(Object.entries(t.set(s,r)).map(([_,p])=>e`${e.identifier(_)} = ${p}`),e`, `),$=l.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${d}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${d}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${i}) ${$}`},M=o.clock??(()=>Date.now()),D=o.idGenerator??(()=>crypto.randomUUID()),K=o.cdc??!1,X=typeof o.cdcRetentionMs=="number"&&Number.isFinite(o.cdcRetentionMs)&&o.cdcRetentionMs>0?o.cdcRetentionMs:void 0,Z=o.auth??{identity:null,userId:null},de=(t,n,i,s)=>K?[Mi(M(),t,n,i,s)]:[],Gt=async()=>{if(!K||X===void 0)return;const t=M();if(!(t-Ct<mi)){Ct=t;try{await bi(a,l,X,t)}catch{}}},Vt=o.scheduler??En,Re=wi(),Yt=Object.entries(f.tables).filter(([,t])=>t.shardMode===void 0||t.shardMode.kind==="global").map(([t])=>t);let Se=0;const ke=o.provisionScope??{},W=async()=>{const t=Ye.get(ke);if(t)return t;const n=(async()=>{await ii(a,f,l),await oi(a,f,l),await ri(a,f,l),await rn(a,l),await cn(a,f,l),K&&await Ii(a,l)})().catch(i=>{throw Ye.delete(ke),i});return Ye.set(ke,n),n},ge=async(t,n)=>{await W();const i=await hi(a,l,f,t,Re,n);if(!(n!==void 0&&i!==n))return i},le=new Map,Ze=async(t,n)=>{const i=ie(t,n);return(await b(a,l,l.tableExists(i))).length>0},ve=async(t,n)=>{const i=`${t}::${n.name}`,s=le.get(i);if(s!==void 0)return s;if(!await Ze(t,n.name))return le.set(i,!1),!1;const d=f.tables[t];if(!d)return le.set(i,!1),!1;const $=n.by??[],_=new Map;await vt(a,l,d,t,w=>{if(n.where&&!xe(w,n.where))return;const u=J($,w);pt(_,u,n,w)});const p=ie(t,n.name);await V(a,l,e`DELETE FROM ${e.identifier(p)}`);const E=[];for(const[w,u]of _)E.push(e`INSERT INTO ${e.identifier(p)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${w}, ${u.value}, ${u.count})`);return await Tt(a,l,E),le.set(i,!0),!0},Xt=async(t,n,i,s)=>{const r=new Map;let d,$=!0;for(;$;){const _=d===void 0?s:[...s,e`${e.identifier("id")} > ${d}`],p=_.length>0?e` WHERE ${e.join(_,e` AND `)}`:e``,E=await b(a,l,e`SELECT ${e.identifier("id")}, ${U(i.field??"")} FROM ${e.identifier(n)}${p} ORDER BY ${e.identifier("id")} ASC LIMIT ${e.raw(String(Ke))}`);for(const w of St(t,E))pt(r,"",i,w);d=E.at(-1)?.id,$=E.length===Ke}return r.get("")?.value??null},Qt=async(t,n,i)=>{const s=n.field??"",r=[],d=f.tables[t],$=(w,u)=>It(l,w,u,S=>d?oe(d,w,S):He(S));for(const w of n.by??[]){const u=$(w,i[w]??null);r.push(u===null?e`${U(w)} IS NULL`:e`${U(w)} = ${u}`)}for(const[w,u]of Object.entries(n.where??{})){const S=u!==null&&typeof u=="object"&&!Array.isArray(u)?u.eq:u,y=$(w,S),v=Ne(l,w);r.push(y===null?e`${v} IS NULL`:e`${v} = ${y}`)}const _=r.length>0?e` WHERE ${e.join(r,e` AND `)}`:e``;if(d&&Ht(d.shape[s]))return Xt(d,t,n,r);const p=_e(n.op),E=await b(a,l,e`SELECT ${e.raw(p)}(${U(s)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}${_}`);return ae(E[0]?.value)},zt=(t,n)=>e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`,Jt=async(t,n,i,s)=>{const r=ie(t,n.name),{op:d}=n,$=n.field??"",_=i&&(!n.where||xe(i,n.where))?i:void 0,p=s&&(!n.where||xe(s,n.where))?s:void 0;if(!_&&!p)return[];if(d==="count"||d==="sum"||d==="avg"){const w=[],u=new Set;for(const[S,y]of[[_,-1],[p,1]]){if(!S)continue;const v=d==="count"?1:Pe(S[$]);if(v===void 0)continue;const L=J(n.by??[],S);u.add(L),w.push(C({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(A,N)=>({__count__:e`${N("__count__")} + ${A("__count__")}`,__value__:d==="count"?e`${N("__value__")} + ${A("__value__")}`:e`COALESCE(${N("__value__")}, 0) + ${A("__value__")}`}),table:r,values:[L,y*v,y]}))}for(const S of u)w.push(zt(r,S));return w}const E=[];if(_){const w=J(n.by??[],_),u=Pe(_[$]),y=(await b(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${w}`))[0],v=ae(y?.value),L=(y?.count??0)-1;if(L<=0)E.push(e`DELETE FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${w}`);else if(y&&u!==void 0&&v!==null&&u===v){const A=await Qt(t,n,_);E.push(e`UPDATE ${e.identifier(r)} SET ${e.identifier("__value__")} = ${A}, ${e.identifier("__count__")} = ${L} WHERE ${e.identifier("__key__")} = ${w}`)}else E.push(e`UPDATE ${e.identifier(r)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${w}`)}if(p){const w=J(n.by??[],p),u=Pe(p[$]);if(u===void 0)E.push(C({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,y)=>({__count__:e`${y("__count__")} + 1`}),table:r,values:[w,null,1]}));else{const S=d==="min"?"MIN":"MAX";E.push(C({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(y,v)=>({__count__:e`${v("__count__")} + 1`,__value__:e`${e.raw(S)}(COALESCE(${v("__value__")}, ${y("__value__")}), ${y("__value__")})`}),table:r,values:[w,u,1]}))}}return E},Te=async t=>{const n=f.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const i of n)await ve(t,i)},ue=async(t,n,i)=>{const s=f.tables[t]?.aggregateIndexes,r=[];if(!s||s.length===0)return r;for(const d of s){const $=`${t}::${d.name}`;(le.get($)??await Ze(t,d.name))&&r.push(...await Jt(t,d,n,i))}return r},fe=new Map,et=async(t,n)=>{const i=$e(t,n);return(await b(a,l,l.tableExists(i))).length>0},De=async(t,n)=>{const i=`${t}::rank::${n.name}`,s=fe.get(i);if(s!==void 0)return s;if(!await et(t,n.name))return fe.set(i,!1),!1;const d=f.tables[t];if(!d)return fe.set(i,!1),!1;const $=$e(t,n.name);await V(a,l,e`DELETE FROM ${e.identifier($)}`);const _=n.sortBy.map((u,S)=>pe(S)),p=re(["__id__","__partition__",..._]);let E=[];const w=async()=>{if(E.length===0)return;const u=E;E=[],await Tt(a,l,u)};return await vt(a,l,d,t,async u=>{if(n.where&&!$t(u,n.where))return;const S=Le(n.partitionBy??[],u),y=n.sortBy.map(v=>He(u[v.field]??null));E.push(e`INSERT INTO ${e.identifier($)} (${p}) VALUES (${ce([u._id,S,...y])})`),E.length>=Ke&&await w()}),await w(),fe.set(i,!0),!0},me=async t=>{const n=f.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const i of n)await De(t,i)},ee=async(t,n,i,s)=>{const r=f.tables[t],d=r?.rankIndexes,$=[];if(!d||d.length===0)return $;const _=r?.softDeleteMode?.field,p=_===void 0||s===void 0?void 0:s[_],E=p!=null;for(const w of d){if(i!==void 0&&s!==void 0&&_i(w,i,s))continue;const u=`${t}::rank::${w.name}`;if(!(fe.get(u)??await et(t,w.name)))continue;const v=$e(t,w.name);if(i&&$.push(e`DELETE FROM ${e.identifier(v)} WHERE ${e.identifier("__id__")} = ${n}`),s&&!E){if(w.where&&!$t(s,w.where))continue;const L=w.sortBy.map((F,Q)=>pe(Q)),A=re(["__id__","__partition__",...L]),N=Le(w.partitionBy??[],s),O=w.sortBy.map(F=>He(s[F.field]??null));$.push(e`INSERT INTO ${e.identifier(v)} (${A}) VALUES (${ce([n,N,...O])})`)}}return $},te=async t=>{t.length>0&&await ti(a,l,t),await Gt()},we=an({dialect:l,exec:a,schema:f}),tt=new Set;for(const[t,n]of Object.entries(f.tables))for(const i of Object.values(n.triggerMap??{}))tt.add(`${t} ${i.timing} ${i.op}`);const j=(t,n,i)=>tt.has(`${t} ${n} ${i}`);let nt;const G=async(t,n,i)=>{if(Se+=1,Se>bt)throw Se-=1,new se(`trigger recursion exceeded ${String(bt)} levels on "${i.table}" — check for a self-triggering write`,"trigger");try{await On({ctx:nt,event:i,op:n,schema:f,tableName:i.table,timing:t})}finally{Se-=1}},Zt=async(t,n)=>{try{await V(a,l,n)}catch(i){qt(l,i,t)}},Ie=async(t,n)=>(await b(a,l,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],it=async(t,n,i,s,r)=>{const d=e`${e.identifier(Ee)}`,$=e.join([T(e`${e.identifier("id")}`,s.id),T(d,s[Ee]??null),...r===void 0?[]:[e`(${r})`]],e` AND `),_=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${i}, ${d} = ${gt.sql(d)} WHERE ${$}`:e`DELETE FROM ${e.identifier(t)} WHERE ${$}`;try{if(l.supportsReturning)return(await b(a,l,e`${_} RETURNING ${e.identifier("id")}`)).length>0;const p=await V(a,l,_);return(l.affectedRows?l.affectedRows(p??{rowsAffected:0}):0)>0}catch(p){return qt(l,p,t)}},Oe=async(t,n,i,s)=>{if(s!==void 0&&!await it(t,n,i,s))throw new se(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")},Be=(t,n=t?._creationTime)=>({_creationTime:n,[Ee]:gt.value(t?.[Ee])}),ot=async(t,n,i,s,r,d,$)=>{const _=Y(n,r);if(!_||r===void 0)throw new g("INTERNAL",`document not found: ${i}`);const p=Wn(n,s,_),E={..._,...Fn(p),_id:i};je(n,p,E,Z);const w=Fe(n,E,{only:new Set(Object.keys(p)),previous:()=>_,tolerateStoredNull:!0});Ge(l.name,Object.fromEntries(Object.keys(p).map(y=>[y,w[y]]))),Un($,_,w),j(t,"before","update")&&await G("before","update",{doc:{...w},id:i,op:"update",previous:_,table:t}),await Te(t),await me(t);const u=Object.keys(n.shape),S=e.join(u.map(y=>e`${e.identifier(y)} = ${oe(n,y,w[y]??null)}`),e`, `);if(await it(t,"UPDATE",S,r,d))return await te([...await ue(t,_,w),...await ee(t,i,_,w),...de(t,i,"update",w)]),await we(t,i,{document:w,previous:_,written:Be(r)}),j(t,"after","update")&&await G("after","update",{doc:w,id:i,op:"update",previous:_,table:t}),w},en=(t,n,i,s)=>{const r=Object.keys(t.shape);return{columns:["id","_creationTime",...r],values:[n,i,...r.map(d=>oe(t,d,s[d]??null))]}},tn=async(t,n,i,s)=>{const r=Pn(n,i.op,i.field,s.by,s.where);if(!r||!await ve(t,r.index))return;const $=ie(t,r.index.name),_=Object.keys(r.partial);if(_.length===(r.index.by??[]).length&&_.length>0){const E=J(r.index.by??[],r.partial),w=await b(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier($)} WHERE ${e.identifier("__key__")} = ${E}`);if(w.length===0)return[];const u=w[0];return[{key:{...r.partial},value:Ue(i.op,{count:u.count,value:ae(u.value)})}]}return _.length>0?void 0:(await b(a,l,e`SELECT ${e.identifier("__key__")} AS ${e.identifier("key")}, ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier($)}`)).map(E=>{const w=E;return{key:Dt(JSON.parse(w.key)),value:Ue(i.op,{count:w.count,value:ae(w.value)})}})},rt=t=>{const n=f.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},st=t=>{throw new g("INTERNAL",`cross-backend relation: a global table cannot load the shard-local relation '${t}' (it spans every shard) — wire a cross-shard reader to support it`)},nn=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new g("MASK_UNSUPPORTED",`masking cannot follow a nested \`with\` across the cross-shard relation hop to "${t}" — the nested rows are hydrated on the serving shard, where the mask policy does not exist. Read the nested relation at its own (masked) call site instead.`);const i={};if(n?.relationBaseWhere)for(const s of Object.keys(f.tables)){const r=n.relationBaseWhere(s);r!==void 0&&(i[s]=r)}return{orderBy:n?.orderBy,relationPolicies:i,where:B(n?.baseWhere,n?.where),with:n?.with}},Ae=(t,n)=>rt(t)?h?h(t,nn(t,n)):st(t):x.findMany(t,n),be=(t,n,i)=>xn(t,{fetcher:Ae,maxRelationKeys:R,relationBaseWhere:i,schema:f,tableName:n}),on=ai(async(t,n)=>{const i=await b(a,l,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${ce(n)})`),s=new Map;for(const r of i){const{id:d}=r;typeof d=="string"&&s.set(d,r)}return s}),at=async(t,n,i)=>{const{fetchLimit:s,limit:r,orderKeys:d,predicate:$}=await Hn(n,i,{fetcher:Ae,maxRelationKeys:R,schema:f,tableName:t}),_=z($,m(n)),p=li(d,l);let E=e`SELECT * FROM ${e.identifier(t)}`;return _&&(E=e`${E} WHERE ${_}`),E=e`${E} ORDER BY ${p}`,s!==void 0&&(E=e`${E} LIMIT ${e.raw(String(s))}`),{limit:r,orderKeys:d,query:E}},x={relationWrites:pn(f),async cdcChangedTables(t,n){if(K)try{return await W(),await ki(a,t,l,{...n,now:M(),retained:X!==void 0})}catch{return}},async aggregate(t,n){const i=f.tables[t];if(!i)throw new g("INTERNAL",`unknown table: ${t}`);if(await W(),_e(n.op),n.op==="count")return x.count(t,{baseWhere:n.baseWhere,relationBaseWhere:n.relationBaseWhere,restrictsCounts:n.restrictsCounts,where:n.where});if(!n.field)throw new g("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const s=Me(i.softDeleteMode,void 0),r=B(B(n.baseWhere,n.where),s),d=await be(r,t,n.relationBaseWhere),$=d!==r;if(i.aggregateIndexes&&!n.baseWhere&&!$&&!s){const S=Dn(i.aggregateIndexes,n.op,n.field,n.where);if(S&&await ve(t,S.index)){const v=J(S.index.by??[],S.key),L=ie(t,S.index.name),N=(await b(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(L)} WHERE ${e.identifier("__key__")} = ${v}`))[0];return Ue(n.op,N===void 0?void 0:{count:N.count,value:ae(N.value)})}}Qe(i,n.field,`aggregate(${t}, { op: "${n.op}", field: "${n.field}" })`);const _=z(d,m(i)),p=e.raw(_e(n.op)),E=e`SELECT ${p}(${U(n.field)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}`,u=(await b(a,l,_?e`${E} WHERE ${_}`:E))[0]?.value;return u==null?null:Number(u)},async count(t,n){const i=f.tables[t];if(!i)throw new g("INTERNAL",`unknown table: ${t}`);await W();const s=qn(n);if(s.restrictsCounts)throw new ut(t);const r=Me(i.softDeleteMode,void 0),d=B(B(s.baseWhere,s.where),r),$=await be(d,t,s.relationBaseWhere),_=$!==d;if(i.aggregateIndexes&&!s.baseWhere&&!_&&!r){const u=kn(i.aggregateIndexes,s.where);if(u&&await ve(t,u.index)){const y=J(u.index.by??[],u.key),v=ie(t,u.index.name),L=await b(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")} FROM ${e.identifier(v)} WHERE ${e.identifier("__key__")} = ${y}`);return Number(L[0]?.value??0)}}const p=z($,m(i)),E=e`SELECT COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(t)}`,w=await b(a,l,p?e`${E} WHERE ${p}`:E);return Number(w[0]?.count??0)},async delete(t,n,i){const s=await ge(t,n);if(!s)return;const r=f.tables[s];if(!r)return;const d=await Ie(s,t),$=Y(r,d),_=i?.hard===!0,p=!_&&r.softDeleteMode?r.softDeleteMode.field:void 0;if(!(p&&(!$||$[p]!==null&&$[p]!==void 0))){if(j(s,"before","delete")&&await G("before","delete",{id:t,op:"delete",previous:$??void 0,table:s}),await Nn({deletedId:t,deletedReference:E=>$?.[E],findHolders:async(E,w,u,S)=>{if(f.tables[E]?.shardMode?.kind==="shardBy")throw new g("INTERNAL",`cross-backend cascade from global '${s}' into shardBy '${E}' is not supported — would require Query Coordinator fan-out across shards`);return(await x.findMany(E,{...S,includeDeleted:_,where:{[w]:u}})).page},onCascade:(E,w)=>x.delete(w,void 0,i),onRestrict:E=>{throw new se(E,"restrict")},onSetNull:(E,w,u)=>x.patch(w,{[u]:null}),schema:f,tableName:s}),await Te(s),await me(s),p&&$){const E={[p]:M()},w={...$,...E};je(r,E,w,Z);const u=e.join(Object.keys(r.shape).map(S=>e`${e.identifier(S)} = ${oe(r,S,w[S]??null)}`),e`, `);await Oe(s,"UPDATE",u,d),await te([...await ue(s,$,w),...await ee(s,t,$,void 0),...de(s,t,"update",w)]),await we(s,t,{document:w,previous:$,written:Be(d)}),j(s,"after","delete")&&await G("after","delete",{id:t,op:"delete",previous:$,table:s});return}await Oe(s,"DELETE",void 0,d),Re.delete(Xe(t));for(const E of Yt)Re.delete(xt(E,t));await te([...await ue(s,$??void 0,void 0),...await ee(s,t,$??void 0,void 0),...de(s,t,"delete")]),await we(s,t,void 0),j(s,"after","delete")&&await G("after","delete",{id:t,op:"delete",previous:$??void 0,table:s})}},async findFirst(t,n={}){return(await x.findMany(t,{...n,limit:1})).page[0]??null},async findFirstOrThrow(t,n={}){const i=await x.findFirst(t,n);if(i===null)throw new Mn(`findFirstOrThrow: no "${t}" document matched`);return i},async findMany(t,n={}){const i=f.tables[t];if(!i)throw new g("INTERNAL",`unknown table: ${t}`);await W();const s=async(S,y,v,L)=>{if(rt(S))return c?Kn(c,S,y,v,L):st(S);const A=f.tables[S];if(!A)throw new g("INTERNAL",`unknown table: ${S}`);const N=Me(A.softDeleteMode,void 0),O={[y]:{in:v}},F=B(B(O,L),N),Q=await be(F,S,void 0),Ce=z(Q,m(A)),he=U(y);let P=e`SELECT ${he} AS __fk__, COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(S)}`;Ce&&(P=e`${P} WHERE ${Ce}`),P=e`${P} GROUP BY ${he}`;const k=await b(a,l,P),ne=new Map;for(const ct of k)ne.set(ct.__fk__,Number(ct.count??0));return ne},{limit:r,orderKeys:d,query:$}=await at(t,i,n),_=await b(a,l,$),p=St(i,_);if(r===void 0)return n.with&&await ft({fetcher:Ae,groupedCounter:s,parents:p,...wt(n),schema:f,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:ht(p,n.select,n.with)};const E=p.length>r,w=E?p.slice(0,r):p,u=w.at(-1);return n.with&&await ft({fetcher:Ae,groupedCounter:s,parents:w,...wt(n),schema:f,tableName:t,with:n.with}),{continueCursor:E&&u?Ln(u,d):null,isDone:!E,page:ht(w,n.select,n.with)}},async explain(t,n={}){const i=f.tables[t];if(!i)throw new g("INTERNAL",`unknown table: ${t}`);await W();const{query:s}=await at(t,i,n),r=l.name==="sqlite"?"EXPLAIN QUERY PLAN":"EXPLAIN",d=await b(a,l,e`${e.raw(r)} ${s}`),{params:$,sql:_}=l.render(s);return{params:$,plan:d.map(p=>ui(p)),sql:_}},async get(t,n){const i=Object.hasOwn(f.tables,t)?f.tables[t]:void 0;if(!i)throw new g("BAD_REQUEST",`ctx.db.get(table, id): "${t}" is not a table in this schema`);return i.shardMode!==void 0&&i.shardMode.kind!=="global"?null:(await W(),Y(i,await on.load(t,n)))},async groupBy(t,n){const i=f.tables[t];if(!i)throw new g("INTERNAL",`unknown table: ${t}`);await W();const s=n.agg??{op:"count"};if(_e(s.op),s.op!=="count"&&!s.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${s.op}" } }): "field" is required for non-count reducers`);const r=Me(i.softDeleteMode,void 0),d=B(B(n.baseWhere,n.where),r),$=await be(d,t,n.relationBaseWhere),_=$!==d;if(i.aggregateIndexes&&!n.baseWhere&&!_&&!r){const y=await tn(t,i.aggregateIndexes,s,n);if(y!==void 0)return y}gi(i,t,n.by,s);const p=z($,m(i)),E=n.by.map(y=>e`${U(y)} AS ${e.identifier(y)}`);if(s.op==="count")E.push(e`COUNT(*) AS ${e.identifier("value")}`);else{if(!s.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${s.op}" } }): "field" is required for non-count reducers`);E.push(e`${e.raw(_e(s.op))}(${U(s.field)}) AS ${e.identifier("value")}`)}const w=e.join(n.by.map(y=>U(y)),e`, `);let u=e`SELECT ${e.join(E,e`, `)} FROM ${e.identifier(t)}`;p&&(u=e`${u} WHERE ${p}`),u=e`${u} GROUP BY ${w}`;const S=await b(a,l,u);return $i(i,n.by,S)},async insert(t,n,i){const s=f.tables[t];if(!s)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Fe(s,An(s,n,Z),{supplied:n,trusted:i?.allowExplicitId===!0});Ge(l.name,r);let d,$=!0;i?.clientId!==void 0?(bn(i.clientId),d=i.clientId):i?.allowExplicitId&&typeof r._id=="string"?(Cn(r._id),d=r._id):(d=D(),$=!1);const _=i?.allowExplicitId&&typeof r._creationTime=="number"?r._creationTime:M(),p={...r,_creationTime:_,_id:d};j(t,"before","insert")&&await G("before","insert",{doc:{...p},id:d,op:"insert",table:t}),await Te(t),await me(t);const{columns:E,values:w}=en(s,d,_,r);return await Zt(t,e`INSERT INTO ${e.identifier(t)} (${re(E)}) VALUES (${ce(w)})`),$&&Re.set(Xe(d),t),await te([...await ue(t,void 0,p),...await ee(t,d,void 0,p),...de(t,d,"insert",p)]),await we(t,d,{document:p,written:{_creationTime:_,[Ee]:null}}),j(t,"after","insert")&&await G("after","insert",{doc:p,id:d,op:"insert",table:t}),d},normalizeId(t,n){return In(f,t,n)},async patch(t,n,i,s){We("patch",n);const r=await ge(t,i);if(!r)throw new g("INTERNAL",`document not found: ${t}`);const d=f.tables[r];if(!d)throw new g("INTERNAL",`document not found: ${t}`);const $=mn(d,n)?Ve:1;for(let _=0;_<$;_+=1){const p=await Ie(r,t);if(await ot(r,d,t,n,p,void 0,s))return}throw new se(`optimistic concurrency conflict on "${r}" — the row changed during this mutation; refetch and retry`,"occ")},async patchIf(t,n,i){We("patchIf",i.patch);const s=f.tables[t];if(!s)throw new g("INTERNAL",`unknown table: ${t}`);const r=z(i.where,m(s))??e`1 = 1`;for(let d=0;d<Ve;d+=1){const[$]=await b(a,l,e`SELECT *, CASE WHEN (${r}) THEN 1 ELSE 0 END AS ${e.identifier(Nt)} FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`);if($===void 0)return{applied:!1,doc:null};const{[Nt]:_,...p}=$;if(Number(_)!==1)return{applied:!1,doc:Y(s,p)??null};const E=await ot(t,s,n,i.patch,p,r,{verify:i.verify});if(E)return{applied:!0,doc:E}}throw new se(`patchIf on "${t}" lost the row to concurrent writes ${String(Ve)} times in a row; retry the operation`,"occ")},async restore(t,n){const i=await ge(t,n);if(!i)throw new g("INTERNAL",`document not found: ${t}`);const s=f.tables[i],r=s?.softDeleteMode?.field;if(!s||!r)throw new g("INTERNAL",`ctx.db.restore: table "${i}" is not a .softDelete() table`);const d=await Ie(i,t),$=d?.[r]!==null&&d?.[r]!==void 0;if(await x.patch(t,{[r]:null},n),$){const _=Y(s,d);_!==null&&await te(await ee(i,t,void 0,{..._,[r]:null}))}},query(t){const n=f.tables[t];if(!n)throw new g("INTERNAL",`unknown table: ${t}`);const i="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",s=[];let r=0,d;const $=l.name!=="mysql",_={...m(n),fieldRef:u=>e`m.${U(u)}`,rangeTypeGuard:()=>{throw new g("INTERNAL","a path range is never pushed into a search")}},p=u=>s.every(S=>S(u)),E=async(u,S)=>{await W();const y=2*fn+u.filters.length,v=d===void 0?void 0:z(d,_,void 0,y),L=v!==void 0&&l.name==="sqlite"&&l.render(v).params.length+y>Qn.boundParams,A=L?void 0:v,N=r>0||L,O=await wn(a,l,n,t,A===void 0?u:{...u,scope:A},hn(N?void 0:S));!N&&S===void 0&&$n(O);const F=O.filter(Q=>p(Q));return S===void 0?F:F.slice(0,S)},w=u=>{const S={async*[Symbol.asyncIterator](){if(!u)throw new g("INTERNAL",i);yield*await E(u,void 0)},async collect(){if(!u)throw new g("INTERNAL",i);return E(u,void 0)},async collectWithScores(){throw new g("GLOBAL_SEARCH_SCORES_UNSUPPORTED",`collectWithScores() is not supported on \`.global()\` tables (table "${t}") — relevance scores are not yet surfaced on this backend; use .collect() instead`)},filter(y){s.push(y);const v=jn(y);return v!==void 0&&Gn(v,n.shape,$)?d=B(d,v):r+=1,S},async first(){if(!u)throw new g("INTERNAL",i);return(await E(u,1))[0]??null},order(){return S},async paginate(y){if(!u)throw new g("INTERNAL",i);const v=ln(y);return un(await E(u,_n(v)),v)},async take(y){if(!u)throw new g("INTERNAL",i);return E(u,y)},async unique(){if(!u)throw new g("INTERNAL",i);const y=await E(u,2);if(y.length>1)throw new Xn(`unique() on table "${t}" matched ${String(y.length)} documents; expected at most one`);return y[0]??null},withGeoIndex(){throw new g("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new g("INTERNAL",i)},withSearchIndex(y,v){const L=(n.searchIndexes??[]).find(N=>N.name===y);if(!L)throw new g("INTERNAL",`unknown search index "${y}" on table "${t}"`);const A={definition:L,field:L.field,filters:[],hasQuery:!1,indexName:y,query:""};if(v(dn(A,t,sn(L.language))),!A.hasQuery)throw new g("INTERNAL",`search index "${y}" on table "${t}" requires a .search(field, query) call`);return w(A)}};return S};return w(void 0)},async rank(t,n,i){const s=f.tables[t];if(!s)throw new g("INTERNAL",`unknown table: ${t}`);const r=s.rankIndexes?.find(O=>O.name===n);if(!r)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(i.restrictsCounts)throw new ut(t);if(await W(),!await De(t,r))return null;const $=typeof i.row=="string"?i.row:i.row._id;if(!$)return null;const _=$e(t,r.name),p=r.sortBy.map((O,F)=>pe(F)),E=re(["__partition__",...p]),u=(await b(a,l,e`SELECT ${E} FROM ${e.identifier(_)} WHERE ${e.identifier("__id__")} = ${$}`))[0];if(!u)return null;const S=u.__partition__,y=B(i.baseWhere,i.where);dt(y,f,t,"rank");const v=lt(r,y);if(v&&Le(r.partitionBy??[],v)!==S)return null;const L=Ei(l.name,r,p,u,$),A=await b(a,l,e`SELECT COUNT(*) AS c FROM ${e.identifier(_)} WHERE ${e.identifier("__partition__")} = ${S} AND (${L})`),N=await b(a,l,e`SELECT COUNT(*) AS c FROM ${e.identifier(_)} WHERE ${e.identifier("__partition__")} = ${S}`);return{position:Number(A[0]?.c??0)+1,total:Number(N[0]?.c??0)}},async rankPage(t,n,i={}){dt(B(i.baseWhere,i.where),f,t,"rankPage");const s=f.tables[t];if(!s)throw new g("INTERNAL",`unknown table: ${t}`);const r=s.rankIndexes?.find(k=>k.name===n);if(!r)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await W(),!await De(t,r))return{continueCursor:null,isDone:!0,page:[]};const $=$e(t,r.name),_=r.sortBy.map((k,ne)=>pe(ne)),p=Math.max(1,Math.min(1e3,Math.floor(i.take??100))),E=B(i.baseWhere,i.where),w=lt(r,E),u=yi(r,_),S=e.join(u.flatMap(k=>Ut(l,{direction:k.direction,field:k.column,nullable:k.nullable})),e`, `),y=[];typeof i.partitionKey=="string"?y.push(e`${e.identifier("__partition__")} = ${i.partitionKey}`):w&&y.push(e`${e.identifier("__partition__")} = ${Le(r.partitionBy??[],w)}`);const v=Tn(i);if(v!==void 0){const k=pi(l.name,u,v);k!==void 0&&y.push(k)}const L=re([ye,"__partition__",..._]);let A=e`SELECT ${L} FROM ${e.identifier($)}`;y.length>0&&(A=e`${A} WHERE ${e.join(y,e` AND `)}`),A=e`${A} ORDER BY ${S} LIMIT ${e.raw(String(p+1))}`;const N=await b(a,l,A),O=N.length>p,F=O?N.slice(0,p):N,Q=F.map(k=>k[ye]),Ce=await Ri(a,l,s,t,Q);let he=null;const P=F.at(-1);if(O&&P!==void 0){const k=[P.__partition__,..._.map(ne=>P[ne]),P[ye]];he=Si(k)}return{continueCursor:he,isDone:!O,page:Ce}},async replace(t,n,i,s){We("replace",n);const r=await ge(t,i);if(!r)throw new g("INTERNAL",`document not found: ${t}`);const d=f.tables[r];if(!d)throw new g("INTERNAL",`document not found: ${t}`);const $=await Ie(r,t);if($===void 0)throw new g("INTERNAL",`document not found: ${t}`);const p=vn(f,r,"update")||(d.aggregateIndexes??[]).length>0||(d.rankIndexes??[]).length>0?Y(d,$)??void 0:void 0,E=s?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:void 0,w=typeof $._creationTime=="number"?$._creationTime:void 0,u=E??w??M(),S={...n,_creationTime:u,_id:t};je(d,n,S,Z);const y=Fe(d,S,{previous:()=>p??Y(d,$)??void 0,supplied:n,trusted:s?.allowExplicitId===!0});Ge(l.name,y),j(r,"before","update")&&await G("before","update",{doc:{...y},id:t,op:"update",previous:p,table:r}),await Te(r),await me(r);const v=Object.keys(d.shape),L=e.join([e`${e.identifier("_creationTime")} = ${u}`,...v.map(A=>e`${e.identifier(A)} = ${oe(d,A,y[A]??null)}`)],e`, `);await Oe(r,"UPDATE",L,$),await te([...await ue(r,p,y),...await ee(r,t,p,y),...de(r,t,"update",y)]),await we(r,t,{document:y,previous:p,written:Be($,u)}),j(r,"after","update")&&await G("after","update",{doc:y,id:t,op:"update",previous:p,table:r})}};return nt={db:x,scheduler:Vt},x};export{Ji as createSqlCtxDb,to as decodeGlobalRow,ki as readSqlCdcChangedTables,zi as readSqlCdcChanges,jt as readSqlCdcFloor,Ii as runSqlCdcMigration,bi as sweepSqlCdcRetention};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/sql-store",
3
- "version": "1.0.0-alpha.209",
3
+ "version": "1.0.0-alpha.210",
4
4
  "description": "Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale)",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
54
- "@lunora/shard-engine": "1.0.0-alpha.160",
54
+ "@lunora/shard-engine": "1.0.0-alpha.161",
55
55
  "@lunora/wire": "1.0.0-alpha.2",
56
56
  "drizzle-orm": "1.0.0-rc.5"
57
57
  },
@@ -1,7 +0,0 @@
1
- import{LunoraError as v}from"@lunora/errors";import{m as rn,D as sn}from"./ctx-db-search-state-DRiojLLm.mjs";import{c as an,r as cn,A as dn,C as ln,R as un,u as fn,a as wn,T as $n,x as hn,b as _n}from"./ctx-db-search-DB_ejfgj.mjs";import{throwingScheduler as En,describeRelationWrites as pn,CDC_LOG_TABLE as H,cdcForkedError as yn,cursorBelowRetainedFloor as Rn,cdcTrimmedError as Sn,serverInList as gn,assertNoExplicitUndefined as We,hasTrigger as vn,runRowValidators as Fe,assertFlatPredicate as dt,mergeWhere as B,rankTableName as _e,sortColumnName as ye,resolveRankPartition as lt,encodePartitionKey as Le,resolveRankSeekTuple as Tn,RANK_TIEBREAK as Re,CountRlsUnsupportedError as ut,compileWhereSql as z,ConflictError as se,patchDependsOnRow as mn,normalizeIdStructurally as In,applyInsertDefaults as An,assertValidClientId as Cn,assertStorableRowId as bn,aggregateSqlFunction as Ee,softDeleteScope as Me,resolveWith as ft,relationHooks as wt,applySelect as $t,encodeCursor as Ln,NotFoundError as Mn,applyOnDelete as Nn,normalizeCountArgument as qn,selectIndexForCount as kn,encodeAggregateKey as J,aggregateTableName as ie,selectIndexForAggregate as Dn,readAggregateValue as Ue,runTriggers as On,matchesRankStaticWhere as ht,nullsOrderSuffix as _t,nullsFirstOf as Et,rankPivotConditionSql as kt,CURSOR_PREFIX as Bn,resolvePatch as Wn,stripReservedPatchFields as Fn,assertPatchAllowed as Un,resolveRelationPredicates as xn,selectIndexForGroupBy as Pn,composeReadPredicate as Hn,fanOutScalarCounts as Kn,matchesStaticWhere as xe,foldAggregateTally as pt,coerceAggregateNumber as Pe,whereOfFilter as jn,isPushableWhere as Gn,tiebreakDirectionFor as Vn,CDC_LOG_TABLE_SEQ_INDEX as Yn,NotUniqueError as Xn,WORKERD_SQLITE_LIMITS as Qn}from"@lunora/shard-engine";import{decodeWire as Dt,needsWireEncoding as Ot,encodeWire as Bt}from"@lunora/wire";import{sql as e,SQL as zn}from"drizzle-orm";import{p as yt,m as Rt,q as C,a as V,c as Jn,o as Zn,f as Y,s as oe,O as pe,b as U,h as St,t as ei,r as ti,j as He,u as gt,l as vt,B as Ke,v as Ne,n as Je,e as Tt,w as mt,x as It,y as ni}from"./sql-exec-UH-aJj2C.mjs";import{z as to}from"./sql-exec-UH-aJj2C.mjs";import{runSqlGlobalTableMigrations as ii}from"./runSqlGlobalTableMigrations-qVa5Q8BM.mjs";import{runSqlAggregateMigrations as oi,runSqlRankMigrations as ri}from"./runSqlAggregateMigrations-BqfzHcG8.mjs";import{c as Wt,a as Ft}from"./value-codec-CiS1h_97.mjs";const si=(o,c)=>{if(o.size<c)return;const $=o.keys().next().value;$!==void 0&&o.delete($)},At=50,ai=(o,c={})=>{const $=c.maxBatch??At,a=Number.isInteger($)&&$>0?$:At,R=new Map;let w=!1;const l=async(I,m)=>{const T=[...m.keys()];for(let b=0;b<T.length;b+=a){const M=T.slice(b,b+a);try{const D=await o(I,M);for(const K of M){const X=D.get(K);for(const Z of m.get(K)??[])Z.resolve(X)}}catch(D){for(const K of M)for(const X of m.get(K)??[])X.reject(D)}}},q=()=>{w=!1;const I=[...R.entries()];R.clear();for(const[m,T]of I)l(m,T).catch(()=>{})};return{async load(I,m){return new Promise((T,b)=>{let M=R.get(I);M||(M=new Map,R.set(I,M));const D=M.get(m);D?D.push({reject:b,resolve:T}):M.set(m,[{reject:b,resolve:T}]),w||(w=!0,queueMicrotask(q))})}}},ci=new Set(["_id","id"]),di=o=>{throw new v("INTERNAL",`no ORDER BY NULL placement for dialect "${String(o)}"`)},Ut=(o,c)=>{const $=c.direction==="desc"?"DESC":"ASC",a=c.nullable===!0,R=w=>e`${Ne(o,c.field)} ${e.raw(`${$}${w}`)}`;switch(o.name){case"mysql":{const w=R("");return!a||c.nulls===void 0?[w]:[e`(${Ne(o,c.field)} IS NULL) ${e.raw(c.nulls==="first"?"DESC":"ASC")}`,w]}case"postgres":return[R(a?_t(Et(c)):"")];case"sqlite":return[R(a&&c.nulls!==void 0?_t(Et(c)):"")];default:return di(o.name)}},li=(o,c)=>{const $=o.flatMap(a=>Ut(c,a));if(!o.some(a=>ci.has(a.field))){const a=Vn(o);$.push(e`${U("id")} ${e.raw(a==="desc"?"DESC":"ASC")}`)}return e.join($,e`, `)},Ct=50,ui=o=>{const c=o.detail??o["QUERY PLAN"];return typeof c=="string"?c:Object.values(o).map(String).join(" | ")},je=(o,c,$,a)=>{for(const[R,w]of ei(o)){if(w.serverDefault){R in c&&($[R]=w.serverDefault({auth:a}));continue}w.onUpdateFn&&!(R in c)&&($[R]=w.onUpdateFn())}},fi=128,wi=()=>{const o=new Map;return{delete:c=>{o.delete(c)},get:c=>{const $=o.get(c);if($!==void 0)return o.delete(c),o.set(c,$),$},set:(c,$)=>{o.has(c)?o.delete(c):si(o,fi),o.set(c,$)}}},Xe=o=>`u${o}`,xt=(o,c)=>`p${o}\0${c}`,$i=async(o,c,$,a,R,w)=>{const l=w===void 0?Xe(a):xt(w,a),q=R.get(l);if(q!==void 0)return q;const I=Object.entries($.tables).filter(([,T])=>T.shardMode===void 0||T.shardMode.kind==="global").map(([T])=>T).filter(T=>w===void 0||T===w),m=await Promise.all(I.map(async T=>({found:(await C(o,c,e`SELECT 1 FROM ${e.identifier(T)} WHERE ${e.identifier("id")} = ${a} LIMIT 1`)).length>0,tableName:T})));for(const T of m)if(T.found)return R.set(l,T.tableName),T.tableName},ae=o=>o==null?null:Number(o),hi=(o,c,$)=>$.map(a=>{const R={};for(const w of c){const l=o.shape[w];R[w]=Wt(a[w]??null,l&&Ft(l))}return{key:R,value:ae(a.value)}}),_i=(o,c,$)=>[...o.partitionBy??[],...o.sortBy.map(R=>R.field),...o.where?Object.keys(o.where):[]].every(R=>mt(c,R)===mt($,R)),Pt=o=>o.length===1?o[0]:e`(${e.join(o,e` AND `)})`,re=o=>e.join(o.map(c=>e`${e.identifier(c)}`),e`, `),ce=o=>e.join(o.map(c=>e`${c}`),e`, `),Ge=(o,c)=>{if(o==="postgres"){for(const[$,a]of Object.entries(c))if(typeof a=="string"&&a.includes("\0"))throw new v("BAD_REQUEST",`"${$}" holds a NUL character (U+0000), which a Postgres text column cannot store`)}},qe=o=>o instanceof ArrayBuffer?new Uint8Array(o):Array.isArray(o)?Uint8Array.from(o):o,Ei=(o,c,$,a,R)=>{const w=[];for(let l=0;l<$.length+1;l+=1){const q=$[l],I=c.sortBy[l],m=l<$.length&&q!==void 0&&I!==void 0,T=I?.direction==="desc"?"desc":"asc",b=m?kt(q,qe(a[q]),T,!1):e`${e.identifier(Re)} < ${R}`;if(b===void 0)continue;const M=$.slice(0,l).map(D=>Je(o,e`${e.identifier(D)}`,qe(a[D])));M.push(b),w.push(Pt(M))}return w.length>0?e.join(w,e` OR `):e`1 = 0`},pi=(o,c,$)=>{if($.length!==c.length)return;const a=[];for(const[R,w]of c.entries()){const l=kt(w.column,qe($[R]),w.direction,!0);if(l===void 0)continue;const q=[];for(let I=0;I<R;I+=1){const m=c[I];m!==void 0&&q.push(Je(o,e`${e.identifier(m.column)}`,qe($[I])))}q.push(l),a.push(Pt(q))}return a.length===0?e`(1 = 0)`:e`(${e.join(a,e` OR `)})`},yi=(o,c)=>{if(o.sortBy.length===0)throw new v("INTERNAL",`rankIndex "${o.name}" requires at least one "sortBy" column for stable pagination`);const $=[{column:"__partition__",direction:"asc",nullable:!1}];for(const[a,R]of o.sortBy.entries())$.push({column:c[a]??ye(a),direction:R.direction,nullable:!0});return $.push({column:Re,direction:"asc",nullable:!1}),$},Ri=async(o,c,$,a,R)=>{const l=[];for(let T=0;T<R.length;T+=50)l.push(R.slice(T,T+50));const q=await Promise.all(l.map(async T=>C(o,c,e`SELECT * FROM ${e.identifier(a)} WHERE ${e.identifier("id")} IN (${ce(T)})`))),I=new Map;for(const T of q)for(const b of T)I.set(b.id,b);const m=[];for(const T of R){const b=Y($,I.get(T));b&&m.push(b)}return m},Si=o=>{const c=o.map(w=>Wt(w,"bytes")),$=JSON.stringify(Ot(c)?Bt(c):c),a=new TextEncoder().encode($);let R="";for(const w of a)R+=String.fromCodePoint(w);return Bn+btoa(R)},Ht=o=>{if(o===void 0)return!1;const c=Ft(o);return c==="any"||c==="bigint"||c==="from"||c==="union"},Qe=(o,c,$)=>{if(Ht(o.shape[c]))throw new v("BAD_REQUEST",`${$}: "${c}" may hold an order-preserving key rather than a value SQL can reduce or group — declare an aggregateIndex covering this (by, field, op) so the maintained companion answers it instead (its running total is a REAL, so it stays exact only while the total is inside 2^53)`)},gi=(o,c,$,a)=>{for(const R of $)Qe(o,R,`groupBy(${c}, { by: [..."${R}"] })`);a.field!==void 0&&Qe(o,a.field,`groupBy(${c}, { agg: { op: "${a.op}", field: "${a.field}" } })`)},ze="__cdc_sweep",Kt="global",vi=6e4,Ti=1e4,mi=3e4;let bt=0;const Ii=async(o,c)=>{const{autoincrementPrimaryKey:$,key:a,real:R,text:w}=c.companionTypes;await V(o,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(H)} (${e.identifier("seq")} ${e.raw($)}, ${e.identifier("ts")} ${e.raw(R)} NOT NULL, ${e.identifier("table")} ${e.raw(a)} NOT NULL, ${e.identifier("id")} ${e.raw(a)} NOT NULL, ${e.identifier("op")} ${e.raw(a)} NOT NULL, ${e.identifier("doc")} ${e.raw(w)})`);const l=c.indexKeyPrefix?.("string");await Jn(o,c,{columns:e`${l===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(l))})`}, ${e.identifier("seq")}`,name:Yn,table:H,unique:!1}),await V(o,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(ze)} (${e.identifier("id")} ${e.raw(a)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(R)} NOT NULL)`),await V(o,c,e`INSERT INTO ${e.identifier(ze)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${Kt}, ${0}) ${c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},Ai=async(o,c,$)=>{const a=e`UPDATE ${e.identifier(ze)} SET ${e.identifier("lease_until")} = ${$+vi} WHERE ${e.identifier("id")} = ${Kt} AND ${e.identifier("lease_until")} <= ${$}`;if(c.supportsReturning)return(await C(o,c,e`${a} RETURNING ${e.identifier("id")}`)).length>0;const R=await V(o,c,a);return(c.affectedRows?c.affectedRows(R??{rowsAffected:0}):0)>0},Ci=async(o,c,$,a)=>{if(!await Ai(o,c,a))return;const R=a-$;await V(o,c,e`
2
- DELETE FROM ${e.identifier(H)} WHERE ${e.identifier("seq")} IN (
3
- SELECT ${e.identifier("seq")} FROM (
4
- SELECT ${e.identifier("seq")} FROM ${e.identifier(H)} WHERE ${e.identifier("ts")} <= ${R} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Ti))}
5
- ) AS ${e.identifier("expired")}
6
- )
7
- `)},jt=async(o,c)=>{const $=await C(o,c,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(H)}`),a=Number($[0]?.seq??Number.NaN);return Number.isFinite(a)?a:void 0},bi=async(o,c)=>{if(c.name!=="sqlite")return;const $=await C(o,c,e`SELECT ${e.identifier("seq")} AS ${e.identifier("seq")} FROM ${e.identifier("sqlite_sequence")} WHERE ${e.identifier("name")} = ${H}`),a=Number($[0]?.seq??Number.NaN);return Number.isFinite(a)?a:0},Li=o=>JSON.stringify(Ot(o)?Bt(o):o),Mi=(o,c,$,a,R)=>e`INSERT INTO ${e.identifier(H)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${o}, ${c}, ${$}, ${a}, ${R===void 0?null:Li(R)})`,zi=async(o,c,$)=>{const a=c.sinceSeq??0,R=Math.max(1,Math.min(c.limit??1e3,1e4)),w=await jt(o,$),l=await bi(o,$);if(l!==void 0&&a>l)throw yn(l,a,"global");if(w!==void 0&&Rn(w,a))throw Sn(w,a,"global");const I=(await C(o,$,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(H)} WHERE seq > ${a} ORDER BY seq ASC LIMIT ${e.raw(String(R))}`)).map(m=>{const{doc:T}=m,b={id:String(m.id),op:String(m.op),seq:Number(m.seq),table:String(m.table),ts:Number(m.ts)};return typeof T=="string"?{...b,doc:Dt(JSON.parse(T))}:b});return{changes:I,cursor:I.at(-1)?.seq??a}},Ni=1e4,qi=1e3,Lt=(o,c)=>{const $=e.identifier(H),a=e`(SELECT MIN(v.seq) FROM ${$} v WHERE v.seq > ${o} AND v.seq - 1 > ${o} AND v.ts > ${c} AND NOT EXISTS (SELECT 1 FROM ${$} p WHERE p.seq = v.seq - 1))`;return e`${a} AS ${e.identifier("gap")}, (SELECT MAX(q.seq) FROM ${$} q WHERE q.seq > ${o} AND q.seq < ${a}) AS ${e.identifier("below")}`},Mt=(o,c,$)=>{const a=Number(c?.gap??Number.NaN);if(!Number.isFinite(a))return o;const R=Number(c?.below??Number.NaN);return Math.min(o,Number.isFinite(R)?R:$)},ki=async(o,c,$,a={})=>{const R=e.identifier(H),w=$.name!=="sqlite",l=(a.now??Date.now())-Ni;if(a.cursorOnly){const b=e`GREATEST((SELECT MAX(seq) FROM ${R}) - ${e.raw(String(qi))}, ${c})`,M=await C(o,$,e`SELECT MAX(seq) AS seq${w?e`, ${Lt(b,l)}`:e``} FROM ${R}`),D=Number(M[0]?.seq??c);return{cursor:Mt(Number.isFinite(D)?D:c,M[0],c),tables:[]}}const q=await C(o,$,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq${w?e`, ${Lt(e`${c}`,l)}`:e``} FROM ${R} WHERE seq > ${c} GROUP BY ${e.identifier("table")}`);let I=c;const m=[];for(const b of q){const M=Number(b.seq);Number.isFinite(M)&&M>I&&(I=M),m.push(String(b.table))}I=Mt(I,q[0],c);const T=a.retained===!0?await jt(o,$):void 0;return{cursor:I,tables:m,...T===void 0?{}:{floor:T}}},Di=/string or blob too big/iu,Oi=/row is too big/iu,Bi=(o,c)=>{const{code:$,errno:a}=c,R=c instanceof Error?c.message:"";switch(o.name){case"mysql":return a===1118||$==="ER_TOO_BIG_ROWSIZE"?"InnoDB's per-row ceiling — roughly 8 KB, half a 16 KB page, for the part of the row stored inline":void 0;case"postgres":return Oi.test(R)?"the 8 KB heap page a tuple must fit once its wide columns have been TOASTed out":void 0;default:return Di.test(R)?"the storage engine's per-row ceiling (2 MB on D1)":void 0}},Wi=(o,c,$)=>{const a=Bi(o,c);if(a!==void 0)throw new v("PAYLOAD_TOO_LARGE",`document is too large to store in "${$}": a single row cannot exceed ${a}. The limit is on the STORED bytes, which are UTF-8. Keep the payload in R2 (ctx.storage) and store a reference on the row.`)},Ve=16,Nt="__lunora_patch_if_match__",qt=(o,c,$)=>{throw o.isUniqueViolation(c)?new se(`unique constraint violation on "${$}"`,"unique"):(Wi(o,c,$),c)},Ye=new WeakMap,Fi=o=>{const c=gn(o);return($,a,R,w)=>a.some(l=>l instanceof zn)?Zn(o,$,a,R):c($,a,R,w)},Ji=o=>{const{crossShardCounter:c,crossShardReader:$,exec:a,maxRelationKeys:R,schema:w}=o,{dialect:l}=o,q={fieldRef:t=>Ne(l,t),rangeTypeGuard:(t,n)=>ni(l,t,n),...l.name==="mysql"?{containsExpr:(t,n)=>{const i=yt(t);return i===void 0?e`LOCATE(${n}, ${t}) > 0`:e`LOCATE(${Rt("mysql",n)}, ${i}) > 0`}}:{},...l.name==="postgres"?{containsExpr:(t,n)=>{const i=yt(t);return i===void 0?e`strpos(${t}, ${n}) > 0`:e`strpos(${i}, ${Rt("postgres",n)}) > 0`}}:{},...l.name==="sqlite"?{}:{inList:Fi(l.name)}},I=new WeakMap,m=t=>{const n=I.get(t);if(n!==void 0)return n;const i={...q,serialize:(r,s)=>It(l,s,r,d=>oe(t,s,d))};return I.set(t,i),i},T=(t,n)=>Je(l.name,t,n),b=t=>{const n=re(t.columns),i=ce(t.values),r=_=>l.name==="mysql"?e`VALUES(${e.identifier(_)})`:e`excluded.${e.identifier(_)}`,s=_=>l.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(_)}`:e`${e.identifier(_)}`,d=e.join(Object.entries(t.set(r,s)).map(([_,p])=>e`${e.identifier(_)} = ${p}`),e`, `),h=l.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${d}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${d}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${i}) ${h}`},M=o.clock??(()=>Date.now()),D=o.idGenerator??(()=>crypto.randomUUID()),K=o.cdc??!1,X=typeof o.cdcRetentionMs=="number"&&Number.isFinite(o.cdcRetentionMs)&&o.cdcRetentionMs>0?o.cdcRetentionMs:void 0,Z=o.auth??{identity:null,userId:null},de=(t,n,i,r)=>K?[Mi(M(),t,n,i,r)]:[],Gt=async()=>{if(!K||X===void 0)return;const t=M();if(!(t-bt<mi)){bt=t;try{await Ci(a,l,X,t)}catch{}}},Vt=o.scheduler??En,Se=wi(),Yt=Object.entries(w.tables).filter(([,t])=>t.shardMode===void 0||t.shardMode.kind==="global").map(([t])=>t);let ge=0;const ke=o.provisionScope??{},F=async()=>{const t=Ye.get(ke);if(t)return t;const n=(async()=>{await ii(a,w,l),await oi(a,w,l),await ri(a,w,l),await rn(a,l),await cn(a,w,l),K&&await Ii(a,l)})().catch(i=>{throw Ye.delete(ke),i});return Ye.set(ke,n),n},le=async(t,n)=>{await F();const i=await $i(a,l,w,t,Se,n);if(!(n!==void 0&&i!==n))return i},ue=new Map,Ze=async(t,n)=>{const i=ie(t,n);return(await C(a,l,l.tableExists(i))).length>0},ve=async(t,n)=>{const i=`${t}::${n.name}`,r=ue.get(i);if(r!==void 0)return r;if(!await Ze(t,n.name))return ue.set(i,!1),!1;const d=w.tables[t];if(!d)return ue.set(i,!1),!1;const h=n.by??[],_=new Map;await vt(a,l,d,t,f=>{if(n.where&&!xe(f,n.where))return;const u=J(h,f);pt(_,u,n,f)});const p=ie(t,n.name);await V(a,l,e`DELETE FROM ${e.identifier(p)}`);const E=[];for(const[f,u]of _)E.push(e`INSERT INTO ${e.identifier(p)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${f}, ${u.value}, ${u.count})`);return await Tt(a,l,E),ue.set(i,!0),!0},Xt=async(t,n,i,r)=>{const s=new Map;let d,h=!0;for(;h;){const _=d===void 0?r:[...r,e`${e.identifier("id")} > ${d}`],p=_.length>0?e` WHERE ${e.join(_,e` AND `)}`:e``,E=await C(a,l,e`SELECT ${e.identifier("id")}, ${U(i.field??"")} FROM ${e.identifier(n)}${p} ORDER BY ${e.identifier("id")} ASC LIMIT ${e.raw(String(Ke))}`);for(const f of St(t,E))pt(s,"",i,f);d=E.at(-1)?.id,h=E.length===Ke}return s.get("")?.value??null},Qt=async(t,n,i)=>{const r=n.field??"",s=[],d=w.tables[t],h=(f,u)=>It(l,f,u,S=>d?oe(d,f,S):He(S));for(const f of n.by??[]){const u=h(f,i[f]??null);s.push(u===null?e`${U(f)} IS NULL`:e`${U(f)} = ${u}`)}for(const[f,u]of Object.entries(n.where??{})){const S=u!==null&&typeof u=="object"&&!Array.isArray(u)?u.eq:u,y=h(f,S),g=Ne(l,f);s.push(y===null?e`${g} IS NULL`:e`${g} = ${y}`)}const _=s.length>0?e` WHERE ${e.join(s,e` AND `)}`:e``;if(d&&Ht(d.shape[r]))return Xt(d,t,n,s);const p=Ee(n.op),E=await C(a,l,e`SELECT ${e.raw(p)}(${U(r)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}${_}`);return ae(E[0]?.value)},zt=(t,n)=>e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`,Jt=async(t,n,i,r)=>{const s=ie(t,n.name),{op:d}=n,h=n.field??"",_=i&&(!n.where||xe(i,n.where))?i:void 0,p=r&&(!n.where||xe(r,n.where))?r:void 0;if(!_&&!p)return[];if(d==="count"||d==="sum"||d==="avg"){const f=[],u=new Set;for(const[S,y]of[[_,-1],[p,1]]){if(!S)continue;const g=d==="count"?1:Pe(S[h]);if(g===void 0)continue;const L=J(n.by??[],S);u.add(L),f.push(b({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(A,N)=>({__count__:e`${N("__count__")} + ${A("__count__")}`,__value__:d==="count"?e`${N("__value__")} + ${A("__value__")}`:e`COALESCE(${N("__value__")}, 0) + ${A("__value__")}`}),table:s,values:[L,y*g,y]}))}for(const S of u)f.push(zt(s,S));return f}const E=[];if(_){const f=J(n.by??[],_),u=Pe(_[h]),y=(await C(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(s)} WHERE ${e.identifier("__key__")} = ${f}`))[0],g=ae(y?.value),L=(y?.count??0)-1;if(L<=0)E.push(e`DELETE FROM ${e.identifier(s)} WHERE ${e.identifier("__key__")} = ${f}`);else if(y&&u!==void 0&&g!==null&&u===g){const A=await Qt(t,n,_);E.push(e`UPDATE ${e.identifier(s)} SET ${e.identifier("__value__")} = ${A}, ${e.identifier("__count__")} = ${L} WHERE ${e.identifier("__key__")} = ${f}`)}else E.push(e`UPDATE ${e.identifier(s)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${f}`)}if(p){const f=J(n.by??[],p),u=Pe(p[h]);if(u===void 0)E.push(b({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,y)=>({__count__:e`${y("__count__")} + 1`}),table:s,values:[f,null,1]}));else{const S=d==="min"?"MIN":"MAX";E.push(b({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(y,g)=>({__count__:e`${g("__count__")} + 1`,__value__:e`${e.raw(S)}(COALESCE(${g("__value__")}, ${y("__value__")}), ${y("__value__")})`}),table:s,values:[f,u,1]}))}}return E},Te=async t=>{const n=w.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const i of n)await ve(t,i)},fe=async(t,n,i)=>{const r=w.tables[t]?.aggregateIndexes,s=[];if(!r||r.length===0)return s;for(const d of r){const h=`${t}::${d.name}`;(ue.get(h)??await Ze(t,d.name))&&s.push(...await Jt(t,d,n,i))}return s},we=new Map,et=async(t,n)=>{const i=_e(t,n);return(await C(a,l,l.tableExists(i))).length>0},De=async(t,n)=>{const i=`${t}::rank::${n.name}`,r=we.get(i);if(r!==void 0)return r;if(!await et(t,n.name))return we.set(i,!1),!1;const d=w.tables[t];if(!d)return we.set(i,!1),!1;const h=_e(t,n.name);await V(a,l,e`DELETE FROM ${e.identifier(h)}`);const _=n.sortBy.map((u,S)=>ye(S)),p=re(["__id__","__partition__",..._]);let E=[];const f=async()=>{if(E.length===0)return;const u=E;E=[],await Tt(a,l,u)};return await vt(a,l,d,t,async u=>{if(n.where&&!ht(u,n.where))return;const S=Le(n.partitionBy??[],u),y=n.sortBy.map(g=>He(u[g.field]??null));E.push(e`INSERT INTO ${e.identifier(h)} (${p}) VALUES (${ce([u._id,S,...y])})`),E.length>=Ke&&await f()}),await f(),we.set(i,!0),!0},me=async t=>{const n=w.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const i of n)await De(t,i)},ee=async(t,n,i,r)=>{const s=w.tables[t],d=s?.rankIndexes,h=[];if(!d||d.length===0)return h;const _=s?.softDeleteMode?.field,p=_===void 0||r===void 0?void 0:r[_],E=p!=null;for(const f of d){if(i!==void 0&&r!==void 0&&_i(f,i,r))continue;const u=`${t}::rank::${f.name}`;if(!(we.get(u)??await et(t,f.name)))continue;const g=_e(t,f.name);if(i&&h.push(e`DELETE FROM ${e.identifier(g)} WHERE ${e.identifier("__id__")} = ${n}`),r&&!E){if(f.where&&!ht(r,f.where))continue;const L=f.sortBy.map((W,Q)=>ye(Q)),A=re(["__id__","__partition__",...L]),N=Le(f.partitionBy??[],r),O=f.sortBy.map(W=>He(r[W.field]??null));h.push(e`INSERT INTO ${e.identifier(g)} (${A}) VALUES (${ce([n,N,...O])})`)}}return h},te=async t=>{t.length>0&&await ti(a,l,t),await Gt()},$e=an({dialect:l,exec:a,schema:w}),tt=new Set;for(const[t,n]of Object.entries(w.tables))for(const i of Object.values(n.triggerMap??{}))tt.add(`${t} ${i.timing} ${i.op}`);const j=(t,n,i)=>tt.has(`${t} ${n} ${i}`);let nt;const G=async(t,n,i)=>{if(ge+=1,ge>Ct)throw ge-=1,new se(`trigger recursion exceeded ${String(Ct)} levels on "${i.table}" — check for a self-triggering write`,"trigger");try{await On({ctx:nt,event:i,op:n,schema:w,tableName:i.table,timing:t})}finally{ge-=1}},Zt=async(t,n)=>{try{await V(a,l,n)}catch(i){qt(l,i,t)}},Ie=async(t,n)=>(await C(a,l,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],it=async(t,n,i,r,s)=>{const d=e`${e.identifier(pe)}`,h=e.join([T(e`${e.identifier("id")}`,r.id),T(d,r[pe]??null),...s===void 0?[]:[e`(${s})`]],e` AND `),_=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${i}, ${d} = ${gt.sql(d)} WHERE ${h}`:e`DELETE FROM ${e.identifier(t)} WHERE ${h}`;try{if(l.supportsReturning)return(await C(a,l,e`${_} RETURNING ${e.identifier("id")}`)).length>0;const p=await V(a,l,_);return(l.affectedRows?l.affectedRows(p??{rowsAffected:0}):0)>0}catch(p){return qt(l,p,t)}},Oe=async(t,n,i,r)=>{if(r!==void 0&&!await it(t,n,i,r))throw new se(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")},Be=(t,n=t?._creationTime)=>({_creationTime:n,[pe]:gt.value(t?.[pe])}),ot=async(t,n,i,r,s,d,h)=>{const _=Y(n,s);if(!_||s===void 0)throw new v("INTERNAL",`document not found: ${i}`);const p=Wn(n,r,_),E={..._,...Fn(p),_id:i};je(n,p,E,Z);const f=Fe(n,E,{only:new Set(Object.keys(p)),previous:()=>_,tolerateStoredNull:!0});Ge(l.name,Object.fromEntries(Object.keys(p).map(y=>[y,f[y]]))),Un(h,_,f),j(t,"before","update")&&await G("before","update",{doc:{...f},id:i,op:"update",previous:_,table:t}),await Te(t),await me(t);const u=Object.keys(n.shape),S=e.join(u.map(y=>e`${e.identifier(y)} = ${oe(n,y,f[y]??null)}`),e`, `);if(await it(t,"UPDATE",S,s,d))return await te([...await fe(t,_,f),...await ee(t,i,_,f),...de(t,i,"update",f)]),await $e(t,i,{document:f,previous:_,written:Be(s)}),j(t,"after","update")&&await G("after","update",{doc:f,id:i,op:"update",previous:_,table:t}),f},en=(t,n,i,r)=>{const s=Object.keys(t.shape);return{columns:["id","_creationTime",...s],values:[n,i,...s.map(d=>oe(t,d,r[d]??null))]}},tn=async(t,n,i,r)=>{const s=Pn(n,i.op,i.field,r.by,r.where);if(!s||!await ve(t,s.index))return;const h=ie(t,s.index.name),_=Object.keys(s.partial);if(_.length===(s.index.by??[]).length&&_.length>0){const E=J(s.index.by??[],s.partial),f=await C(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(h)} WHERE ${e.identifier("__key__")} = ${E}`);if(f.length===0)return[];const u=f[0];return[{key:{...s.partial},value:Ue(i.op,{count:u.count,value:ae(u.value)})}]}return _.length>0?void 0:(await C(a,l,e`SELECT ${e.identifier("__key__")} AS ${e.identifier("key")}, ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(h)}`)).map(E=>{const f=E;return{key:Dt(JSON.parse(f.key)),value:Ue(i.op,{count:f.count,value:ae(f.value)})}})},rt=t=>{const n=w.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},st=t=>{throw new v("INTERNAL",`cross-backend relation: a global table cannot load the shard-local relation '${t}' (it spans every shard) — wire a cross-shard reader to support it`)},nn=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new v("MASK_UNSUPPORTED",`masking cannot follow a nested \`with\` across the cross-shard relation hop to "${t}" — the nested rows are hydrated on the serving shard, where the mask policy does not exist. Read the nested relation at its own (masked) call site instead.`);const i={};if(n?.relationBaseWhere)for(const r of Object.keys(w.tables)){const s=n.relationBaseWhere(r);s!==void 0&&(i[r]=s)}return{orderBy:n?.orderBy,relationPolicies:i,where:B(n?.baseWhere,n?.where),with:n?.with}},Ae=(t,n)=>rt(t)?$?$(t,nn(t,n)):st(t):x.findMany(t,n),Ce=(t,n,i)=>xn(t,{fetcher:Ae,maxRelationKeys:R,relationBaseWhere:i,schema:w,tableName:n}),on=ai(async(t,n)=>{const i=await C(a,l,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${ce(n)})`),r=new Map;for(const s of i){const{id:d}=s;typeof d=="string"&&r.set(d,s)}return r}),at=async(t,n,i)=>{const{fetchLimit:r,limit:s,orderKeys:d,predicate:h}=await Hn(n,i,{fetcher:Ae,maxRelationKeys:R,schema:w,tableName:t}),_=z(h,m(n)),p=li(d,l);let E=e`SELECT * FROM ${e.identifier(t)}`;return _&&(E=e`${E} WHERE ${_}`),E=e`${E} ORDER BY ${p}`,r!==void 0&&(E=e`${E} LIMIT ${e.raw(String(r))}`),{limit:s,orderKeys:d,query:E}},x={relationWrites:pn(w),async cdcChangedTables(t,n){if(K)try{return await F(),await ki(a,t,l,{...n,now:M(),retained:X!==void 0})}catch{return}},async aggregate(t,n){const i=w.tables[t];if(!i)throw new v("INTERNAL",`unknown table: ${t}`);if(await F(),Ee(n.op),n.op==="count")return x.count(t,{baseWhere:n.baseWhere,relationBaseWhere:n.relationBaseWhere,restrictsCounts:n.restrictsCounts,where:n.where});if(!n.field)throw new v("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const r=Me(i.softDeleteMode,void 0),s=B(B(n.baseWhere,n.where),r),d=await Ce(s,t,n.relationBaseWhere),h=d!==s;if(i.aggregateIndexes&&!n.baseWhere&&!h&&!r){const S=Dn(i.aggregateIndexes,n.op,n.field,n.where);if(S&&await ve(t,S.index)){const g=J(S.index.by??[],S.key),L=ie(t,S.index.name),N=(await C(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(L)} WHERE ${e.identifier("__key__")} = ${g}`))[0];return Ue(n.op,N===void 0?void 0:{count:N.count,value:ae(N.value)})}}Qe(i,n.field,`aggregate(${t}, { op: "${n.op}", field: "${n.field}" })`);const _=z(d,m(i)),p=e.raw(Ee(n.op)),E=e`SELECT ${p}(${U(n.field)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}`,u=(await C(a,l,_?e`${E} WHERE ${_}`:E))[0]?.value;return u==null?null:Number(u)},async count(t,n){const i=w.tables[t];if(!i)throw new v("INTERNAL",`unknown table: ${t}`);await F();const r=qn(n);if(r.restrictsCounts)throw new ut(t);const s=Me(i.softDeleteMode,void 0),d=B(B(r.baseWhere,r.where),s),h=await Ce(d,t,r.relationBaseWhere),_=h!==d;if(i.aggregateIndexes&&!r.baseWhere&&!_&&!s){const u=kn(i.aggregateIndexes,r.where);if(u&&await ve(t,u.index)){const y=J(u.index.by??[],u.key),g=ie(t,u.index.name),L=await C(a,l,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")} FROM ${e.identifier(g)} WHERE ${e.identifier("__key__")} = ${y}`);return Number(L[0]?.value??0)}}const p=z(h,m(i)),E=e`SELECT COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(t)}`,f=await C(a,l,p?e`${E} WHERE ${p}`:E);return Number(f[0]?.count??0)},async delete(t,n,i){const r=await le(t,n);if(!r)return;const s=w.tables[r];if(!s)return;const d=await Ie(r,t),h=Y(s,d),_=i?.hard===!0,p=!_&&s.softDeleteMode?s.softDeleteMode.field:void 0;if(!(p&&(!h||h[p]!==null&&h[p]!==void 0))){if(j(r,"before","delete")&&await G("before","delete",{id:t,op:"delete",previous:h??void 0,table:r}),await Nn({deletedId:t,deletedReference:E=>h?.[E],findHolders:async(E,f,u,S)=>{if(w.tables[E]?.shardMode?.kind==="shardBy")throw new v("INTERNAL",`cross-backend cascade from global '${r}' into shardBy '${E}' is not supported — would require Query Coordinator fan-out across shards`);return(await x.findMany(E,{...S,includeDeleted:_,where:{[f]:u}})).page},onCascade:(E,f)=>x.delete(f,void 0,i),onRestrict:E=>{throw new se(E,"restrict")},onSetNull:(E,f,u)=>x.patch(f,{[u]:null}),schema:w,tableName:r}),await Te(r),await me(r),p&&h){const E={[p]:M()},f={...h,...E};je(s,E,f,Z);const u=e.join(Object.keys(s.shape).map(S=>e`${e.identifier(S)} = ${oe(s,S,f[S]??null)}`),e`, `);await Oe(r,"UPDATE",u,d),await te([...await fe(r,h,f),...await ee(r,t,h,void 0),...de(r,t,"update",f)]),await $e(r,t,{document:f,previous:h,written:Be(d)}),j(r,"after","delete")&&await G("after","delete",{id:t,op:"delete",previous:h,table:r});return}await Oe(r,"DELETE",void 0,d),Se.delete(Xe(t));for(const E of Yt)Se.delete(xt(E,t));await te([...await fe(r,h??void 0,void 0),...await ee(r,t,h??void 0,void 0),...de(r,t,"delete")]),await $e(r,t,void 0),j(r,"after","delete")&&await G("after","delete",{id:t,op:"delete",previous:h??void 0,table:r})}},async findFirst(t,n={}){return(await x.findMany(t,{...n,limit:1})).page[0]??null},async findFirstOrThrow(t,n={}){const i=await x.findFirst(t,n);if(i===null)throw new Mn(`findFirstOrThrow: no "${t}" document matched`);return i},async findMany(t,n={}){const i=w.tables[t];if(!i)throw new v("INTERNAL",`unknown table: ${t}`);await F();const r=async(S,y,g,L)=>{if(rt(S))return c?Kn(c,S,y,g,L):st(S);const A=w.tables[S];if(!A)throw new v("INTERNAL",`unknown table: ${S}`);const N=Me(A.softDeleteMode,void 0),O={[y]:{in:g}},W=B(B(O,L),N),Q=await Ce(W,S,void 0),be=z(Q,m(A)),he=U(y);let P=e`SELECT ${he} AS __fk__, COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(S)}`;be&&(P=e`${P} WHERE ${be}`),P=e`${P} GROUP BY ${he}`;const k=await C(a,l,P),ne=new Map;for(const ct of k)ne.set(ct.__fk__,Number(ct.count??0));return ne},{limit:s,orderKeys:d,query:h}=await at(t,i,n),_=await C(a,l,h),p=St(i,_);if(s===void 0)return n.with&&await ft({fetcher:Ae,groupedCounter:r,parents:p,...wt(n),schema:w,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:$t(p,n.select,n.with)};const E=p.length>s,f=E?p.slice(0,s):p,u=f.at(-1);return n.with&&await ft({fetcher:Ae,groupedCounter:r,parents:f,...wt(n),schema:w,tableName:t,with:n.with}),{continueCursor:E&&u?Ln(u,d):null,isDone:!E,page:$t(f,n.select,n.with)}},async explain(t,n={}){const i=w.tables[t];if(!i)throw new v("INTERNAL",`unknown table: ${t}`);await F();const{query:r}=await at(t,i,n),s=l.name==="sqlite"?"EXPLAIN QUERY PLAN":"EXPLAIN",d=await C(a,l,e`${e.raw(s)} ${r}`),{params:h,sql:_}=l.render(r);return{params:h,plan:d.map(p=>ui(p)),sql:_}},async get(t,n){const i=await le(t,n);if(!i)return null;const r=w.tables[i];return r?Y(r,await on.load(i,t)):null},async groupBy(t,n){const i=w.tables[t];if(!i)throw new v("INTERNAL",`unknown table: ${t}`);await F();const r=n.agg??{op:"count"};if(Ee(r.op),r.op!=="count"&&!r.field)throw new v("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);const s=Me(i.softDeleteMode,void 0),d=B(B(n.baseWhere,n.where),s),h=await Ce(d,t,n.relationBaseWhere),_=h!==d;if(i.aggregateIndexes&&!n.baseWhere&&!_&&!s){const y=await tn(t,i.aggregateIndexes,r,n);if(y!==void 0)return y}gi(i,t,n.by,r);const p=z(h,m(i)),E=n.by.map(y=>e`${U(y)} AS ${e.identifier(y)}`);if(r.op==="count")E.push(e`COUNT(*) AS ${e.identifier("value")}`);else{if(!r.field)throw new v("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);E.push(e`${e.raw(Ee(r.op))}(${U(r.field)}) AS ${e.identifier("value")}`)}const f=e.join(n.by.map(y=>U(y)),e`, `);let u=e`SELECT ${e.join(E,e`, `)} FROM ${e.identifier(t)}`;p&&(u=e`${u} WHERE ${p}`),u=e`${u} GROUP BY ${f}`;const S=await C(a,l,u);return hi(i,n.by,S)},async insert(t,n,i){const r=w.tables[t];if(!r)throw new v("INTERNAL",`unknown table: ${t}`);await F();const s=Fe(r,An(r,n,Z),{supplied:n,trusted:i?.allowExplicitId===!0});Ge(l.name,s);let d,h=!0;i?.clientId!==void 0?(Cn(i.clientId),d=i.clientId):i?.allowExplicitId&&typeof s._id=="string"?(bn(s._id),d=s._id):(d=D(),h=!1);const _=i?.allowExplicitId&&typeof s._creationTime=="number"?s._creationTime:M(),p={...s,_creationTime:_,_id:d};j(t,"before","insert")&&await G("before","insert",{doc:{...p},id:d,op:"insert",table:t}),await Te(t),await me(t);const{columns:E,values:f}=en(r,d,_,s);return await Zt(t,e`INSERT INTO ${e.identifier(t)} (${re(E)}) VALUES (${ce(f)})`),h&&Se.set(Xe(d),t),await te([...await fe(t,void 0,p),...await ee(t,d,void 0,p),...de(t,d,"insert",p)]),await $e(t,d,{document:p,written:{_creationTime:_,[pe]:null}}),j(t,"after","insert")&&await G("after","insert",{doc:p,id:d,op:"insert",table:t}),d},normalizeId(t,n){return In(w,t,n)},async patch(t,n,i,r){We("patch",n);const s=await le(t,i);if(!s)throw new v("INTERNAL",`document not found: ${t}`);const d=w.tables[s];if(!d)throw new v("INTERNAL",`document not found: ${t}`);const h=mn(d,n)?Ve:1;for(let _=0;_<h;_+=1){const p=await Ie(s,t);if(await ot(s,d,t,n,p,void 0,r))return}throw new se(`optimistic concurrency conflict on "${s}" — the row changed during this mutation; refetch and retry`,"occ")},async patchIf(t,n,i){We("patchIf",i.patch);const r=w.tables[t];if(!r)throw new v("INTERNAL",`unknown table: ${t}`);const s=z(i.where,m(r))??e`1 = 1`;for(let d=0;d<Ve;d+=1){const[h]=await C(a,l,e`SELECT *, CASE WHEN (${s}) THEN 1 ELSE 0 END AS ${e.identifier(Nt)} FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`);if(h===void 0)return{applied:!1,doc:null};const{[Nt]:_,...p}=h;if(Number(_)!==1)return{applied:!1,doc:Y(r,p)??null};const E=await ot(t,r,n,i.patch,p,s,{verify:i.verify});if(E)return{applied:!0,doc:E}}throw new se(`patchIf on "${t}" lost the row to concurrent writes ${String(Ve)} times in a row; retry the operation`,"occ")},async restore(t,n){const i=await le(t,n);if(!i)throw new v("INTERNAL",`document not found: ${t}`);const r=w.tables[i],s=r?.softDeleteMode?.field;if(!r||!s)throw new v("INTERNAL",`ctx.db.restore: table "${i}" is not a .softDelete() table`);const d=await Ie(i,t),h=d?.[s]!==null&&d?.[s]!==void 0;if(await x.patch(t,{[s]:null},n),h){const _=Y(r,d);_!==null&&await te(await ee(i,t,void 0,{..._,[s]:null}))}},query(t){const n=w.tables[t];if(!n)throw new v("INTERNAL",`unknown table: ${t}`);const i="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",r=[];let s=0,d;const h=l.name!=="mysql",_={...m(n),fieldRef:u=>e`m.${U(u)}`,rangeTypeGuard:()=>{throw new v("INTERNAL","a path range is never pushed into a search")}},p=u=>r.every(S=>S(u)),E=async(u,S)=>{await F();const y=2*fn+u.filters.length,g=d===void 0?void 0:z(d,_,void 0,y),L=g!==void 0&&l.name==="sqlite"&&l.render(g).params.length+y>Qn.boundParams,A=L?void 0:g,N=s>0||L,O=await wn(a,l,n,t,A===void 0?u:{...u,scope:A},$n(N?void 0:S));!N&&S===void 0&&hn(O);const W=O.filter(Q=>p(Q));return S===void 0?W:W.slice(0,S)},f=u=>{const S={async*[Symbol.asyncIterator](){if(!u)throw new v("INTERNAL",i);yield*await E(u,void 0)},async collect(){if(!u)throw new v("INTERNAL",i);return E(u,void 0)},async collectWithScores(){throw new v("GLOBAL_SEARCH_SCORES_UNSUPPORTED",`collectWithScores() is not supported on \`.global()\` tables (table "${t}") — relevance scores are not yet surfaced on this backend; use .collect() instead`)},filter(y){r.push(y);const g=jn(y);return g!==void 0&&Gn(g,n.shape,h)?d=B(d,g):s+=1,S},async first(){if(!u)throw new v("INTERNAL",i);return(await E(u,1))[0]??null},order(){return S},async paginate(y){if(!u)throw new v("INTERNAL",i);const g=ln(y);return un(await E(u,_n(g)),g)},async take(y){if(!u)throw new v("INTERNAL",i);return E(u,y)},async unique(){if(!u)throw new v("INTERNAL",i);const y=await E(u,2);if(y.length>1)throw new Xn(`unique() on table "${t}" matched ${String(y.length)} documents; expected at most one`);return y[0]??null},withGeoIndex(){throw new v("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new v("INTERNAL",i)},withSearchIndex(y,g){const L=(n.searchIndexes??[]).find(N=>N.name===y);if(!L)throw new v("INTERNAL",`unknown search index "${y}" on table "${t}"`);const A={definition:L,field:L.field,filters:[],hasQuery:!1,indexName:y,query:""};if(g(dn(A,t,sn(L.language))),!A.hasQuery)throw new v("INTERNAL",`search index "${y}" on table "${t}" requires a .search(field, query) call`);return f(A)}};return S};return f(void 0)},async rank(t,n,i){const r=w.tables[t];if(!r)throw new v("INTERNAL",`unknown table: ${t}`);const s=r.rankIndexes?.find(O=>O.name===n);if(!s)throw new v("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(i.restrictsCounts)throw new ut(t);if(await F(),!await De(t,s))return null;const h=typeof i.row=="string"?i.row:i.row._id;if(!h)return null;const _=_e(t,s.name),p=s.sortBy.map((O,W)=>ye(W)),E=re(["__partition__",...p]),u=(await C(a,l,e`SELECT ${E} FROM ${e.identifier(_)} WHERE ${e.identifier("__id__")} = ${h}`))[0];if(!u)return null;const S=u.__partition__,y=B(i.baseWhere,i.where);dt(y,w,t,"rank");const g=lt(s,y);if(g&&Le(s.partitionBy??[],g)!==S)return null;const L=Ei(l.name,s,p,u,h),A=await C(a,l,e`SELECT COUNT(*) AS c FROM ${e.identifier(_)} WHERE ${e.identifier("__partition__")} = ${S} AND (${L})`),N=await C(a,l,e`SELECT COUNT(*) AS c FROM ${e.identifier(_)} WHERE ${e.identifier("__partition__")} = ${S}`);return{position:Number(A[0]?.c??0)+1,total:Number(N[0]?.c??0)}},async rankPage(t,n,i={}){dt(B(i.baseWhere,i.where),w,t,"rankPage");const r=w.tables[t];if(!r)throw new v("INTERNAL",`unknown table: ${t}`);const s=r.rankIndexes?.find(k=>k.name===n);if(!s)throw new v("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await F(),!await De(t,s))return{continueCursor:null,isDone:!0,page:[]};const h=_e(t,s.name),_=s.sortBy.map((k,ne)=>ye(ne)),p=Math.max(1,Math.min(1e3,Math.floor(i.take??100))),E=B(i.baseWhere,i.where),f=lt(s,E),u=yi(s,_),S=e.join(u.flatMap(k=>Ut(l,{direction:k.direction,field:k.column,nullable:k.nullable})),e`, `),y=[];typeof i.partitionKey=="string"?y.push(e`${e.identifier("__partition__")} = ${i.partitionKey}`):f&&y.push(e`${e.identifier("__partition__")} = ${Le(s.partitionBy??[],f)}`);const g=Tn(i);if(g!==void 0){const k=pi(l.name,u,g);k!==void 0&&y.push(k)}const L=re([Re,"__partition__",..._]);let A=e`SELECT ${L} FROM ${e.identifier(h)}`;y.length>0&&(A=e`${A} WHERE ${e.join(y,e` AND `)}`),A=e`${A} ORDER BY ${S} LIMIT ${e.raw(String(p+1))}`;const N=await C(a,l,A),O=N.length>p,W=O?N.slice(0,p):N,Q=W.map(k=>k[Re]),be=await Ri(a,l,r,t,Q);let he=null;const P=W.at(-1);if(O&&P!==void 0){const k=[P.__partition__,..._.map(ne=>P[ne]),P[Re]];he=Si(k)}return{continueCursor:he,isDone:!O,page:be}},async replace(t,n,i,r){We("replace",n);const s=await le(t,i);if(!s)throw new v("INTERNAL",`document not found: ${t}`);const d=w.tables[s];if(!d)throw new v("INTERNAL",`document not found: ${t}`);const h=await Ie(s,t);if(h===void 0)throw new v("INTERNAL",`document not found: ${t}`);const p=vn(w,s,"update")||(d.aggregateIndexes??[]).length>0||(d.rankIndexes??[]).length>0?Y(d,h)??void 0:void 0,E=r?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:void 0,f=typeof h._creationTime=="number"?h._creationTime:void 0,u=E??f??M(),S={...n,_creationTime:u,_id:t};je(d,n,S,Z);const y=Fe(d,S,{previous:()=>p??Y(d,h)??void 0,supplied:n,trusted:r?.allowExplicitId===!0});Ge(l.name,y),j(s,"before","update")&&await G("before","update",{doc:{...y},id:t,op:"update",previous:p,table:s}),await Te(s),await me(s);const g=Object.keys(d.shape),L=e.join([e`${e.identifier("_creationTime")} = ${u}`,...g.map(A=>e`${e.identifier(A)} = ${oe(d,A,y[A]??null)}`)],e`, `);await Oe(s,"UPDATE",L,h),await te([...await fe(s,p,y),...await ee(s,t,p,y),...de(s,t,"update",y)]),await $e(s,t,{document:y,previous:p,written:Be(h,u)}),j(s,"after","update")&&await G("after","update",{doc:y,id:t,op:"update",previous:p,table:s})}};return nt={db:x,scheduler:Vt},x};export{Ji as createSqlCtxDb,to as decodeGlobalRow,ki as readSqlCdcChangedTables,zi as readSqlCdcChanges,jt as readSqlCdcFloor,Ii as runSqlCdcMigration,Ci as sweepSqlCdcRetention};