@lunora/sql-store 1.0.0-alpha.111 → 1.0.0-alpha.112

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-BK0nDY1l.mjs";import{runSqlAggregateMigrations as d,runSqlGlobalTableMigrations as S,runSqlRankMigrations as c}from"./packem_shared/runSqlAggregateMigrations-DYQCOK8J.mjs";import{d as g,r as C}from"./packem_shared/ctx-db-search-CdewhEdG.mjs";import{S as m,m as x}from"./packem_shared/ctx-db-search-state-D_X8wIwk.mjs";import{c as b,e as u,a as h,s as M,t as T}from"./packem_shared/value-codec-Dzavzwao.mjs";import{decodeGlobalRow as E}from"./packem_shared/decodeGlobalRow-BdC0SILc.mjs";export{m as SEARCH_STATE_TABLE,g as backfillSqlSearchIndexes,a as createSqlCtxDb,b as decodeBigint,E as decodeGlobalRow,u as effectiveColumnKind,x as migrateSearchState,o as readSqlCdcChangedTables,t as readSqlCdcChanges,l as readSqlCdcFloor,d as runSqlAggregateMigrations,s as runSqlCdcMigration,S as runSqlGlobalTableMigrations,c as runSqlRankMigrations,C as runSqlSearchMigrations,h as sqliteDecode,M as sqliteEncode,n as sweepSqlCdcRetention,T 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-Cn2VRFCH.mjs";import{runSqlAggregateMigrations as d,runSqlGlobalTableMigrations as S,runSqlRankMigrations as c}from"./packem_shared/runSqlAggregateMigrations-DYQCOK8J.mjs";import{d as g,r as C}from"./packem_shared/ctx-db-search-CdewhEdG.mjs";import{S as m,m as x}from"./packem_shared/ctx-db-search-state-D_X8wIwk.mjs";import{c as b,e as u,a as h,s as M,t as T}from"./packem_shared/value-codec-Dzavzwao.mjs";import{decodeGlobalRow as E}from"./packem_shared/decodeGlobalRow-BdC0SILc.mjs";export{m as SEARCH_STATE_TABLE,g as backfillSqlSearchIndexes,a as createSqlCtxDb,b as decodeBigint,E as decodeGlobalRow,u as effectiveColumnKind,x as migrateSearchState,o as readSqlCdcChangedTables,t as readSqlCdcChanges,l as readSqlCdcFloor,d as runSqlAggregateMigrations,s as runSqlCdcMigration,S as runSqlGlobalTableMigrations,c as runSqlRankMigrations,C as runSqlSearchMigrations,h as sqliteDecode,M as sqliteEncode,n as sweepSqlCdcRetention,T as tryJsonParse};
@@ -0,0 +1,7 @@
1
+ import{LunoraError as T}from"@lunora/errors";import{m as Wt,D as Ut}from"./ctx-db-search-state-D_X8wIwk.mjs";import{c as xt,r as Pt,A as Ht,C as Kt,R as jt,a as Gt,T as Vt,x as Yt,b as Xt}from"./ctx-db-search-CdewhEdG.mjs";import{d as Ei}from"./ctx-db-search-CdewhEdG.mjs";import{literalInList as zt,throwingScheduler as Qt,CDC_LOG_TABLE as j,cursorBelowRetainedFloor as Jt,cdcTrimmedError as Zt,assertNoExplicitUndefined as et,hasTrigger as en,runRowValidators as Ne,assertFlatPredicate as tt,mergeWhere as q,rankTableName as we,sortColumnName as Ee,resolveRankPartition as nt,encodePartitionKey as Ce,resolveRankSeekTuple as tn,RANK_TIEBREAK as ye,CountRlsUnsupportedError as it,normalizeIdStructurally as nn,assertValidClientId as on,aggregateSqlFunction as $e,softDeleteScope as _e,compileWhereSql as he,normalizeOrderKeys as rn,uniqueIndexFields as sn,equalityPinnedFields as an,buildSeekWhere as cn,decodeCursor as dn,resolveRelationPredicates as ot,resolveWith as rt,relationHooks as st,applySelect as at,encodeCursor as ln,NotFoundError as un,applyOnDelete as fn,ConflictError as Ae,normalizeCountArgument as wn,selectIndexForCount as $n,encodeAggregateKey as Y,aggregateTableName as Q,selectIndexForAggregate as _n,readAggregateValue as De,runTriggers as hn,matchesRankStaticWhere as ct,rankPivotConditionSql as pt,CURSOR_PREFIX as En,selectIndexForGroupBy as yn,tiebreakDirectionFor as pn,fanOutScalarCounts as Rn,matchesStaticWhere as Be,foldAggregateTally as dt,coerceAggregateNumber as qe,CDC_LOG_TABLE_SEQ_INDEX as Sn,NotUniqueError as gn}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{d as Rt,a as Tn,e as St,n as vn,b as mn}from"./value-codec-Dzavzwao.mjs";import{runSqlGlobalTableMigrations as In,runSqlAggregateMigrations as bn,runSqlRankMigrations as Cn}from"./runSqlAggregateMigrations-DYQCOK8J.mjs";import{queryAll as m,queryRun as M,createIndexIfNotExists as An,decodeRow as ee,serializeDocumentColumn as J,columnRefSql as O,decodeRows as lt,tableColumns as gt,OCC_VERSION_COLUMN as ut,serializeColumnValue as Oe,forEachRowPaged as ft,BACKFILL_BATCH_SIZE as Fe,queryBatch as wt}from"./decodeGlobalRow-BdC0SILc.mjs";import{decodeGlobalRow as pi}from"./decodeGlobalRow-BdC0SILc.mjs";const Ln=(a,c)=>{if(a.size<c)return;const h=a.keys().next().value;h!==void 0&&a.delete(h)},$t=50,kn=(a,c={})=>{const h=c.maxBatch??$t,s=Number.isInteger(h)&&h>0?h:$t,p=new Map;let $=!1;const d=async(S,v)=>{const I=[...v.keys()];for(let A=0;A<I.length;A+=s){const N=I.slice(A,A+s);try{const W=await a(S,N);for(const G of N){const V=W.get(G);for(const ie of v.get(G)??[])ie.resolve(V)}}catch(W){for(const G of N)for(const V of v.get(G)??[])V.reject(W)}}},C=()=>{$=!1;const S=[...p.entries()];p.clear();for(const[v,I]of S)d(v,I).catch(()=>{})};return{async load(S,v){return new Promise((I,A)=>{let N=p.get(S);N||(N=new Map,p.set(S,N));const W=N.get(v);W?W.push({reject:A,resolve:I}):N.set(v,[{reject:A,resolve:I}]),$||($=!0,queueMicrotask(C))})}}},Mn=new Set(["_id","id"]),Pe=(a,c,h)=>a==="postgres"?e`${c} IS NOT DISTINCT FROM ${h}`:a==="mysql"?e`${c} <=> ${h}`:e`${c} IS ${h}`,Tt=(a,c)=>a.name!=="postgres"||c.nullable!==!0?"":c.direction==="desc"?" NULLS LAST":" NULLS FIRST",Nn=(a,c)=>{const h=a.map(s=>e`${O(s.field)} ${e.raw(`${s.direction==="desc"?"DESC":"ASC"}${Tt(c,s)}`)}`);if(!a.some(s=>Mn.has(s.field))){const s=pn(a);h.push(e`${O("id")} ${e.raw(s==="desc"?"DESC":"ASC")}`)}return e.join(h,e`, `)},_t=50,Dn=(a,c,h)=>{const s={...c};for(const[p,$]of gt(a)){if($.serverDefault){s[p]=$.serverDefault({auth:h});continue}s[p]===void 0&&($.defaultFn?s[p]=$.defaultFn():"defaultValue"in $&&(s[p]=$.defaultValue))}return s},ht=(a,c,h,s)=>{for(const[p,$]of gt(a)){if($.serverDefault){p in c&&(h[p]=$.serverDefault({auth:s}));continue}$.onUpdateFn&&!(p in c)&&(h[p]=$.onUpdateFn())}},Bn=128,qn=()=>{const a=new Map;return{delete:c=>{a.delete(c)},get:c=>{const h=a.get(c);if(h!==void 0)return a.delete(c),a.set(c,h),h},set:(c,h)=>{a.has(c)?a.delete(c):Ln(a,Bn),a.set(c,h)}}},On=async(a,c,h,s,p)=>{const $=p.get(s);if($!==void 0)return $;const d=Object.entries(h.tables).filter(([,S])=>S.shardMode===void 0||S.shardMode.kind==="global").map(([S])=>S),C=await Promise.all(d.map(async S=>({found:(await m(a,c,e`SELECT 1 FROM ${e.identifier(S)} WHERE ${e.identifier("id")} = ${s} LIMIT 1`)).length>0,tableName:S})));for(const S of C)if(S.found)return p.set(s,S.tableName),S.tableName},te=a=>a==null?null:Number(a),Fn=(a,c,h)=>h.map(s=>{const p={};for(const $ of c){const d=a.shape[$];p[$]=Tn(s[$]??null,d&&St(d))}return{key:p,value:te(s.value)}}),Wn=(a,c,h)=>[...a.partitionBy??[],...a.sortBy.map(p=>p.field),...a.where?Object.keys(a.where):[]].every(p=>c[p]===h[p]),vt=a=>a.length===1?a[0]:e`(${e.join(a,e` AND `)})`,Z=a=>e.join(a.map(c=>e`${e.identifier(c)}`),e`, `),ne=a=>e.join(a.map(c=>e`${c}`),e`, `),Un=(a,c,h,s,p)=>{const $=[];for(let d=0;d<h.length+1;d+=1){const C=h[d],S=c.sortBy[d],v=d<h.length&&C!==void 0&&S!==void 0,I=S?.direction==="desc"?"desc":"asc",A=v?pt(C,s[C],I,!1):e`${e.identifier(ye)} < ${p}`;if(A===void 0)continue;const N=h.slice(0,d).map(W=>Pe(a,e`${e.identifier(W)}`,s[W]));N.push(A),$.push(vt(N))}return $.length>0?e.join($,e` OR `):e`1 = 0`},xn=(a,c,h)=>{if(h.length!==c.length)return;const s=[];for(const[p,$]of c.entries()){const d=pt($.column,h[p],$.direction,!0);if(d===void 0)continue;const C=[];for(let S=0;S<p;S+=1){const v=c[S];v!==void 0&&C.push(Pe(a,e`${e.identifier(v.column)}`,h[S]))}C.push(d),s.push(vt(C))}return s.length===0?e`(1 = 0)`:e`(${e.join(s,e` OR `)})`},Pn=(a,c)=>{if(a.sortBy.length===0)throw new T("INTERNAL",`rankIndex "${a.name}" requires at least one "sortBy" column for stable pagination`);const h=[{column:"__partition__",direction:"asc",nullable:!1}];for(const[s,p]of a.sortBy.entries())h.push({column:c[s]??Ee(s),direction:p.direction,nullable:!0});return h.push({column:ye,direction:"asc",nullable:!1}),h},Hn=async(a,c,h,s,p)=>{const d=[];for(let I=0;I<p.length;I+=50)d.push(p.slice(I,I+50));const C=await Promise.all(d.map(async I=>m(a,c,e`SELECT * FROM ${e.identifier(s)} WHERE ${e.identifier("id")} IN (${ne(I)})`))),S=new Map;for(const I of C)for(const A of I)S.set(A.id,A);const v=[];for(const I of p){const A=ee(h,S.get(I));A&&v.push(A)}return v},Kn=a=>{const c=JSON.stringify(a),h=new TextEncoder().encode(c);let s="";for(const p of h)s+=String.fromCodePoint(p);return En+btoa(s)},mt=a=>{if(a===void 0)return!1;const c=St(a);return c==="any"||c==="bigint"||c==="from"||c==="union"},Ue=(a,c,h)=>{if(mt(a.shape[c]))throw new T("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)`)},jn=(a,c,h,s)=>{for(const p of h)Ue(a,p,`groupBy(${c}, { by: [..."${p}"] })`);s.field!==void 0&&Ue(a,s.field,`groupBy(${c}, { agg: { op: "${s.op}", field: "${s.field}" } })`)},xe="__cdc_sweep",It="global",Gn=6e4,Vn=1e4,Yn=3e4;let Et=0;const Xn=async(a,c)=>{const{autoincrementPrimaryKey:h,key:s,real:p,text:$}=c.companionTypes;await M(a,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(j)} (${e.identifier("seq")} ${e.raw(h)}, ${e.identifier("ts")} ${e.raw(p)} NOT NULL, ${e.identifier("table")} ${e.raw(s)} NOT NULL, ${e.identifier("id")} ${e.raw(s)} NOT NULL, ${e.identifier("op")} ${e.raw(s)} NOT NULL, ${e.identifier("doc")} ${e.raw($)})`);const d=c.indexKeyPrefix?.("string");await An(a,c,{columns:e`${d===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(d))})`}, ${e.identifier("seq")}`,name:Sn,table:j,unique:!1}),await M(a,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(xe)} (${e.identifier("id")} ${e.raw(s)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(p)} NOT NULL)`),await M(a,c,e`INSERT INTO ${e.identifier(xe)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${It}, ${0}) ${c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},zn=async(a,c,h)=>{const s=e`UPDATE ${e.identifier(xe)} SET ${e.identifier("lease_until")} = ${h+Gn} WHERE ${e.identifier("id")} = ${It} AND ${e.identifier("lease_until")} <= ${h}`;if(c.supportsReturning)return(await m(a,c,e`${s} RETURNING ${e.identifier("id")}`)).length>0;const p=await M(a,c,s);return(c.affectedRows?c.affectedRows(p??{rowsAffected:0}):0)>0},Qn=async(a,c,h,s)=>{if(!await zn(a,c,s))return;const p=s-h;await M(a,c,e`
2
+ DELETE FROM ${e.identifier(j)} WHERE ${e.identifier("seq")} IN (
3
+ SELECT ${e.identifier("seq")} FROM (
4
+ SELECT ${e.identifier("seq")} FROM ${e.identifier(j)} WHERE ${e.identifier("ts")} <= ${p} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Vn))}
5
+ ) AS ${e.identifier("expired")}
6
+ )
7
+ `)},bt=async(a,c)=>{const h=await m(a,c,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(j)}`),s=Number(h[0]?.seq??Number.NaN);return Number.isFinite(s)?s:void 0},Jn=a=>JSON.stringify(vn(a)?mn(a):a),Zn=async(a,c,h,s,p,$,d)=>{await M(a,d,e`INSERT INTO ${e.identifier(j)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${c}, ${h}, ${s}, ${p}, ${$===void 0?null:Jn($)})`)},wi=async(a,c,h)=>{const s=c.sinceSeq??0,p=Math.max(1,Math.min(c.limit??1e3,1e4)),$=await bt(a,h);if($!==void 0&&Jt($,s))throw Zt($,s,"global");const C=(await m(a,h,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(j)} WHERE seq > ${s} ORDER BY seq ASC LIMIT ${e.raw(String(p))}`)).map(S=>{const{doc:v}=S,I={id:String(S.id),op:String(S.op),seq:Number(S.seq),table:String(S.table),ts:Number(S.ts)};return typeof v=="string"?{...I,doc:Rt(JSON.parse(v))}:I});return{changes:C,cursor:C.at(-1)?.seq??s}},ei=async(a,c,h,s={})=>{if(s.cursorOnly){const S=await m(a,h,e`SELECT MAX(seq) AS seq FROM ${e.identifier(j)}`),v=Number(S[0]?.seq??c);return{cursor:Number.isFinite(v)?v:c,tables:[]}}const p=await m(a,h,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq FROM ${e.identifier(j)} WHERE seq > ${c} GROUP BY ${e.identifier("table")}`);let $=c;const d=[];for(const S of p){const v=Number(S.seq);Number.isFinite(v)&&v>$&&($=v),d.push(String(S.table))}const C=s.retained===!0?await bt(a,h):void 0;return{cursor:$,tables:d,...C===void 0?{}:{floor:C}}},ti=/string or blob too big/iu,ni=/row is too big/iu,ii=(a,c)=>{const{code:h,errno:s}=c,p=c instanceof Error?c.message:"";switch(a.name){case"mysql":return s===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 ni.test(p)?"the 8 KB heap page a tuple must fit once its wide columns have been TOASTed out":void 0;default:return ti.test(p)?"the storage engine's per-row ceiling (2 MB on D1)":void 0}},oi=(a,c,h)=>{const s=ii(a,c);if(s!==void 0)throw new T("PAYLOAD_TOO_LARGE",`document is too large to store in "${h}": a single row cannot exceed ${s}. 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.`)},yt=(a,c,h)=>{throw a.isUniqueViolation(c)?new Ae(`unique constraint violation on "${h}"`,"unique"):(oi(a,c,h),c)},We=new WeakMap,$i=a=>{const{crossShardCounter:c,crossShardReader:h,exec:s,maxRelationKeys:p,schema:$}=a,{dialect:d}=a,C={fieldRef:O,...d.name==="mysql"?{containsExpr:(t,n)=>e`LOCATE(${n}, ${t}) > 0`}:{},...d.name==="postgres"?{containsExpr:(t,n)=>e`strpos(${t}, ${n}) > 0`}:{},...d.name==="sqlite"?{}:{inList:zt}},S=new WeakMap,v=t=>{const n=S.get(t);if(n!==void 0)return n;const i={...C,serialize:(o,r)=>J(t,r,o)};return S.set(t,i),i},I=(t,n)=>Pe(d.name,t,n),A=t=>{const n=Z(t.columns),i=ne(t.values),o=f=>d.name==="mysql"?e`VALUES(${e.identifier(f)})`:e`excluded.${e.identifier(f)}`,r=f=>d.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(f)}`:e`${e.identifier(f)}`,u=e.join(Object.entries(t.set(o,r)).map(([f,y])=>e`${e.identifier(f)} = ${y}`),e`, `),E=d.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${u}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${u}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${i}) ${E}`},N=a.clock??(()=>Date.now()),W=a.idGenerator??(()=>crypto.randomUUID()),G=a.cdc??!1,V=typeof a.cdcRetentionMs=="number"&&Number.isFinite(a.cdcRetentionMs)&&a.cdcRetentionMs>0?a.cdcRetentionMs:void 0,ie=a.auth??{identity:null,userId:null},oe=async(t,n,i,o)=>{if(!G||(await Zn(s,N(),t,n,i,o,d),V===void 0))return;const r=N();if(!(r-Et<Yn)){Et=r;try{await Qn(s,d,V,r)}catch{}}},Ct=a.scheduler??Qt,Le=qn();let pe=0;const ke=a.provisionScope??{},U=async()=>{const t=We.get(ke);if(t)return t;const n=(async()=>{await In(s,$,d),await bn(s,$,d),await Cn(s,$,d),await Wt(s,d),await Pt(s,$,d),G&&await Xn(s,d)})().catch(i=>{throw We.delete(ke),i});return We.set(ke,n),n},re=async(t,n)=>{await U();const i=await On(s,d,$,t,Le);if(!(n!==void 0&&i!==n))return i},se=new Map,He=async(t,n)=>{const i=Q(t,n);return(await m(s,d,d.tableExists(i))).length>0},Re=async(t,n)=>{const i=`${t}::${n.name}`,o=se.get(i);if(o!==void 0)return o;if(!await He(t,n.name))return se.set(i,!1),!1;const u=$.tables[t];if(!u)return se.set(i,!1),!1;const E=n.by??[],f=new Map;await ft(s,d,u,t,w=>{if(n.where&&!Be(w,n.where))return;const _=Y(E,w);dt(f,_,n,w)});const y=Q(t,n.name);await M(s,d,e`DELETE FROM ${e.identifier(y)}`);const l=[];for(const[w,_]of f)l.push(e`INSERT INTO ${e.identifier(y)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${w}, ${_.value}, ${_.count})`);return await wt(s,d,l),se.set(i,!0),!0},At=async(t,n,i,o)=>{const r=new Map;let u,E=!0;for(;E;){const f=u===void 0?o:[...o,e`${e.identifier("id")} > ${u}`],y=f.length>0?e` WHERE ${e.join(f,e` AND `)}`:e``,l=await m(s,d,e`SELECT ${e.identifier("id")}, ${O(i.field??"")} FROM ${e.identifier(n)}${y} ORDER BY ${e.identifier("id")} ASC LIMIT ${e.raw(String(Fe))}`);for(const w of lt(t,l))dt(r,"",i,w);u=l.at(-1)?.id,E=l.length===Fe}return r.get("")?.value??null},Lt=async(t,n,i)=>{const o=n.field??"",r=[],u=$.tables[t],E=(w,_)=>u?J(u,w,_):Oe(_);for(const w of n.by??[]){const _=E(w,i[w]??null);r.push(_===null?e`${O(w)} IS NULL`:e`${O(w)} = ${_}`)}for(const[w,_]of Object.entries(n.where??{})){const g=_!==null&&typeof _=="object"&&!Array.isArray(_)?_.eq:_,R=E(w,g);r.push(R===null?e`${O(w)} IS NULL`:e`${O(w)} = ${R}`)}const f=r.length>0?e` WHERE ${e.join(r,e` AND `)}`:e``;if(u&&mt(u.shape[o]))return At(u,t,n,r);const y=$e(n.op),l=await m(s,d,e`SELECT ${e.raw(y)}(${O(o)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}${f}`);return te(l[0]?.value)},kt=async(t,n)=>{await M(s,d,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`)},Mt=async(t,n,i,o)=>{const r=Q(t,n.name),{op:u}=n,E=n.field??"",f=i&&(!n.where||Be(i,n.where))?i:void 0,y=o&&(!n.where||Be(o,n.where))?o:void 0;if(!(!f&&!y)){if(u==="count"||u==="sum"||u==="avg"){const l=new Set;for(const[w,_]of[[f,-1],[y,1]]){if(!w)continue;const g=u==="count"?1:qe(w[E]);if(g===void 0)continue;const R=Y(n.by??[],w);l.add(R),await M(s,d,A({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(b,L)=>({__count__:e`${L("__count__")} + ${b("__count__")}`,__value__:u==="count"?e`${L("__value__")} + ${b("__value__")}`:e`COALESCE(${L("__value__")}, 0) + ${b("__value__")}`}),table:r,values:[R,_*g,_]}))}for(const w of l)await kt(r,w);return}if(f){const l=Y(n.by??[],f),w=qe(f[E]),g=(await m(s,d,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${l}`))[0],R=te(g?.value),b=(g?.count??0)-1;if(b<=0)await M(s,d,e`DELETE FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${l}`);else if(g&&w!==void 0&&R!==null&&w===R){const L=await Lt(t,n,f);await M(s,d,e`UPDATE ${e.identifier(r)} SET ${e.identifier("__value__")} = ${L}, ${e.identifier("__count__")} = ${b} WHERE ${e.identifier("__key__")} = ${l}`)}else await M(s,d,e`UPDATE ${e.identifier(r)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${l}`)}if(y){const l=Y(n.by??[],y),w=qe(y[E]);if(w===void 0)await M(s,d,A({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(_,g)=>({__count__:e`${g("__count__")} + 1`}),table:r,values:[l,null,1]}));else{const _=u==="min"?"MIN":"MAX";await M(s,d,A({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(g,R)=>({__count__:e`${R("__count__")} + 1`,__value__:e`${e.raw(_)}(COALESCE(${R("__value__")}, ${g("__value__")}), ${g("__value__")})`}),table:r,values:[l,w,1]}))}}}},Se=async t=>{const n=$.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const i of n)await Re(t,i)},ae=async(t,n,i)=>{const o=$.tables[t]?.aggregateIndexes;if(!(!o||o.length===0))for(const r of o){const u=`${t}::${r.name}`;(se.get(u)??await He(t,r.name))&&await Mt(t,r,n,i)}},ce=new Map,Ke=async(t,n)=>{const i=we(t,n);return(await m(s,d,d.tableExists(i))).length>0},Me=async(t,n)=>{const i=`${t}::rank::${n.name}`,o=ce.get(i);if(o!==void 0)return o;if(!await Ke(t,n.name))return ce.set(i,!1),!1;const u=$.tables[t];if(!u)return ce.set(i,!1),!1;const E=we(t,n.name);await M(s,d,e`DELETE FROM ${e.identifier(E)}`);const f=n.sortBy.map((_,g)=>Ee(g)),y=Z(["__id__","__partition__",...f]);let l=[];const w=async()=>{if(l.length===0)return;const _=l;l=[],await wt(s,d,_)};return await ft(s,d,u,t,async _=>{if(n.where&&!ct(_,n.where))return;const g=Ce(n.partitionBy??[],_),R=n.sortBy.map(b=>Oe(_[b.field]??null));l.push(e`INSERT INTO ${e.identifier(E)} (${y}) VALUES (${ne([_._id,g,...R])})`),l.length>=Fe&&await w()}),await w(),ce.set(i,!0),!0},ge=async t=>{const n=$.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const i of n)await Me(t,i)},X=async(t,n,i,o)=>{const r=$.tables[t],u=r?.rankIndexes;if(!u||u.length===0)return;const E=r?.softDeleteMode?.field,f=E===void 0||o===void 0?void 0:o[E],y=f!=null;for(const l of u){if(i!==void 0&&o!==void 0&&Wn(l,i,o))continue;const w=`${t}::rank::${l.name}`;if(!(ce.get(w)??await Ke(t,l.name)))continue;const R=we(t,l.name);if(i&&await M(s,d,e`DELETE FROM ${e.identifier(R)} WHERE ${e.identifier("__id__")} = ${n}`),o&&!y){if(l.where&&!ct(o,l.where))continue;const b=l.sortBy.map((B,K)=>Ee(K)),L=Z(["__id__","__partition__",...b]),F=Ce(l.partitionBy??[],o),k=l.sortBy.map(B=>Oe(o[B.field]??null));await M(s,d,e`INSERT INTO ${e.identifier(R)} (${L}) VALUES (${ne([n,F,...k])})`)}}},de=xt({dialect:d,exec:s,schema:$}),je=new Set;for(const[t,n]of Object.entries($.tables))for(const i of Object.values(n.triggerMap??{}))je.add(`${t} ${i.timing} ${i.op}`);const P=(t,n,i)=>je.has(`${t} ${n} ${i}`);let Ge;const H=async(t,n,i)=>{if(pe+=1,pe>_t)throw pe-=1,new Ae(`trigger recursion exceeded ${String(_t)} levels on "${i.table}" — check for a self-triggering write`,"trigger");try{await hn({ctx:Ge,event:i,op:n,schema:$,tableName:i.table,timing:t})}finally{pe-=1}},Nt=async(t,n)=>{try{await M(s,d,n)}catch(i){yt(d,i,t)}},Te=async(t,n)=>(await m(s,d,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],ve=async(t,n,i,o)=>{if(o===void 0)return;const r=e`${e.identifier(ut)}`,u=e.join([I(e`${e.identifier("id")}`,o.id),I(r,o[ut]??null)],e` AND `),E=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${i}, ${r} = COALESCE(${r}, 0) + 1 WHERE ${u}`:e`DELETE FROM ${e.identifier(t)} WHERE ${u}`,f=()=>{throw new Ae(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(d.supportsReturning)(await m(s,d,e`${E} RETURNING ${e.identifier("id")}`)).length===0&&f();else{const y=await M(s,d,E);(d.affectedRows?d.affectedRows(y??{rowsAffected:0}):0)===0&&f()}}catch(y){yt(d,y,t)}},Dt=(t,n,i,o)=>{const r=Object.keys(t.shape);return{columns:["id","_creationTime",...r],values:[n,i,...r.map(u=>J(t,u,o[u]??null))]}},Bt=async(t,n,i,o)=>{const r=yn(n,i.op,i.field,o.by,o.where);if(!r||!await Re(t,r.index))return;const E=Q(t,r.index.name),f=Object.keys(r.partial);if(f.length===(r.index.by??[]).length&&f.length>0){const l=Y(r.index.by??[],r.partial),w=await m(s,d,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(E)} WHERE ${e.identifier("__key__")} = ${l}`);if(w.length===0)return[];const _=w[0];return[{key:{...r.partial},value:De(i.op,{count:_.count,value:te(_.value)})}]}return f.length>0?void 0:(await m(s,d,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(E)}`)).map(l=>{const w=l;return{key:Rt(JSON.parse(w.key)),value:De(i.op,{count:w.count,value:te(w.value)})}})},Ve=t=>{const n=$.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},Ye=t=>{throw new T("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`)},qt=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new T("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 o of Object.keys($.tables)){const r=n.relationBaseWhere(o);r!==void 0&&(i[o]=r)}return{orderBy:n?.orderBy,relationPolicies:i,where:q(n?.baseWhere,n?.where),with:n?.with}},Xe=(t,n)=>Ve(t)?h?h(t,qt(t,n)):Ye(t):x.findMany(t,n),me=(t,n,i)=>ot(t,{fetcher:Xe,maxRelationKeys:p,relationBaseWhere:i,schema:$,tableName:n}),Ot=kn(async(t,n)=>{const i=await m(s,d,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${ne(n)})`),o=new Map;for(const r of i){const{id:u}=r;typeof u=="string"&&o.set(u,r)}return o}),x={async cdcChangedTables(t,n){if(G)try{return await U(),await ei(s,t,d,{...n,retained:V!==void 0})}catch{return}},async aggregate(t,n){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);if(await U(),$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 T("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const o=_e(i.softDeleteMode,void 0),r=q(q(n.baseWhere,n.where),o),u=await me(r,t,n.relationBaseWhere),E=u!==r;if(i.aggregateIndexes&&!n.baseWhere&&!E&&!o){const g=_n(i.aggregateIndexes,n.op,n.field,n.where);if(g&&await Re(t,g.index)){const b=Y(g.index.by??[],g.key),L=Q(t,g.index.name),k=(await m(s,d,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(L)} WHERE ${e.identifier("__key__")} = ${b}`))[0];return De(n.op,k===void 0?void 0:{count:k.count,value:te(k.value)})}}Ue(i,n.field,`aggregate(${t}, { op: "${n.op}", field: "${n.field}" })`);const f=he(u,v(i)),y=e.raw($e(n.op)),l=e`SELECT ${y}(${O(n.field)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}`,_=(await m(s,d,f?e`${l} WHERE ${f}`:l))[0]?.value;return _==null?null:Number(_)},async count(t,n){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);await U();const o=wn(n);if(o.restrictsCounts)throw new it(t);const r=_e(i.softDeleteMode,void 0),u=q(q(o.baseWhere,o.where),r),E=await me(u,t,o.relationBaseWhere),f=E!==u;if(i.aggregateIndexes&&!o.baseWhere&&!f&&!r){const _=$n(i.aggregateIndexes,o.where);if(_&&await Re(t,_.index)){const R=Y(_.index.by??[],_.key),b=Q(t,_.index.name),L=await m(s,d,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")} FROM ${e.identifier(b)} WHERE ${e.identifier("__key__")} = ${R}`);return Number(L[0]?.value??0)}}const y=he(E,v(i)),l=e`SELECT COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(t)}`,w=await m(s,d,y?e`${l} WHERE ${y}`:l);return Number(w[0]?.count??0)},async delete(t,n,i){const o=await re(t,n);if(!o)return;const r=$.tables[o];if(!r)return;const u=await Te(o,t),E=ee(r,u),f=i?.hard===!0,y=!f&&r.softDeleteMode?r.softDeleteMode.field:void 0;if(!(y&&(!E||E[y]!==null&&E[y]!==void 0))){if(P(o,"before","delete")&&await H("before","delete",{id:t,op:"delete",previous:E??void 0,table:o}),await fn({deletedId:t,deletedReference:l=>E?.[l],findHolders:async(l,w,_)=>{if($.tables[l]?.shardMode?.kind==="shardBy")throw new T("INTERNAL",`cross-backend cascade from global '${o}' into shardBy '${l}' is not supported — would require Query Coordinator fan-out across shards`);return(await x.findMany(l,{includeDeleted:f,where:{[w]:_}})).page},onCascade:(l,w)=>x.delete(w,void 0,i),onRestrict:l=>{throw new Ae(l,"restrict")},onSetNull:(l,w,_)=>x.patch(w,{[_]:null}),schema:$,tableName:o}),await Se(o),await ge(o),y&&E){const l={...E,[y]:N()},w=e.join(Object.keys(r.shape).map(_=>e`${e.identifier(_)} = ${J(r,_,l[_]??null)}`),e`, `);await ve(o,"UPDATE",w,u),await ae(o,E,l),await X(o,t,E,void 0),await de(o,t,l,E),await oe(o,t,"update",l),P(o,"after","delete")&&await H("after","delete",{id:t,op:"delete",previous:E,table:o});return}await ve(o,"DELETE",void 0,u),Le.delete(t),await ae(o,E??void 0,void 0),await X(o,t,E??void 0,void 0),await de(o,t,void 0),await oe(o,t,"delete"),P(o,"after","delete")&&await H("after","delete",{id:t,op:"delete",previous:E??void 0,table:o})}},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 un(`findFirstOrThrow: no "${t}" document matched`);return i},async findMany(t,n={}){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);await U();const o=rn(n.orderBy,i.shape,{pinned:an(n.where),uniqueBy:sn(i.indexes,i.shape)}),r=n.cursor?cn(o,dn(n.cursor)):void 0,u=Xe,E=async(k,B,K,Ie)=>{if(Ve(k))return c?Rn(c,k,B,K,Ie):Ye(k);const le=$.tables[k];if(!le)throw new T("INTERNAL",`unknown table: ${k}`);const be=_e(le.softDeleteMode,void 0),z={[B]:{in:K}},D=q(q(z,Ie),be),ue=await me(D,k,void 0),ze=he(ue,v(le)),Qe=O(B);let fe=e`SELECT ${Qe} AS __fk__, COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(k)}`;ze&&(fe=e`${fe} WHERE ${ze}`),fe=e`${fe} GROUP BY ${Qe}`;const Ft=await m(s,d,fe),Je=new Map;for(const Ze of Ft)Je.set(Ze.__fk__,Number(Ze.count??0));return Je};let f=q(n.baseWhere,n.where);f=q(f,_e(i.softDeleteMode,n.includeDeleted)),f=await ot(f,{fetcher:u,maxRelationKeys:p,relationBaseWhere:n.relationBaseWhere,schema:$,tableName:t}),r&&(f=f?{AND:[f,r]}:r);const y=he(f,v(i)),l=Nn(o,d);let w=e`SELECT * FROM ${e.identifier(t)}`;y&&(w=e`${w} WHERE ${y}`),w=e`${w} ORDER BY ${l}`;const _=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;_!==void 0&&(w=e`${w} LIMIT ${e.raw(String(_+1))}`);const g=await m(s,d,w),R=lt(i,g);if(_===void 0)return n.with&&await rt({fetcher:u,groupedCounter:E,parents:R,...st(n),schema:$,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:at(R,n.select,n.with)};const b=R.length>_,L=b?R.slice(0,_):R,F=L.at(-1);return n.with&&await rt({fetcher:u,groupedCounter:E,parents:L,...st(n),schema:$,tableName:t,with:n.with}),{continueCursor:b&&F?ln(F,o):null,isDone:!b,page:at(L,n.select,n.with)}},async get(t,n){const i=await re(t,n);if(!i)return null;const o=$.tables[i];return o?ee(o,await Ot.load(i,t)):null},async groupBy(t,n){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);await U();const o=n.agg??{op:"count"};if($e(o.op),o.op!=="count"&&!o.field)throw new T("INTERNAL",`groupBy(${t}, { agg: { op: "${o.op}" } }): "field" is required for non-count reducers`);const r=_e(i.softDeleteMode,void 0),u=q(q(n.baseWhere,n.where),r),E=await me(u,t,n.relationBaseWhere),f=E!==u;if(i.aggregateIndexes&&!n.baseWhere&&!f&&!r){const R=await Bt(t,i.aggregateIndexes,o,n);if(R!==void 0)return R}jn(i,t,n.by,o);const y=he(E,v(i)),l=n.by.map(R=>e`${O(R)} AS ${e.identifier(R)}`);if(o.op==="count")l.push(e`COUNT(*) AS ${e.identifier("value")}`);else{if(!o.field)throw new T("INTERNAL",`groupBy(${t}, { agg: { op: "${o.op}" } }): "field" is required for non-count reducers`);l.push(e`${e.raw($e(o.op))}(${O(o.field)}) AS ${e.identifier("value")}`)}const w=e.join(n.by.map(R=>O(R)),e`, `);let _=e`SELECT ${e.join(l,e`, `)} FROM ${e.identifier(t)}`;y&&(_=e`${_} WHERE ${y}`),_=e`${_} GROUP BY ${w}`;const g=await m(s,d,_);return Fn(i,n.by,g)},async insert(t,n,i){const o=$.tables[t];if(!o)throw new T("INTERNAL",`unknown table: ${t}`);await U();const r=Dn(o,n,ie);Ne(o,r);let u,E=!0;i?.clientId!==void 0?(on(i.clientId),u=i.clientId):i?.allowExplicitId&&typeof r._id=="string"?u=r._id:(u=W(),E=!1);const f=i?.allowExplicitId&&typeof r._creationTime=="number"?r._creationTime:N(),y={...r,_creationTime:f,_id:u};P(t,"before","insert")&&await H("before","insert",{doc:{...y},id:u,op:"insert",table:t}),await Se(t),await ge(t);const{columns:l,values:w}=Dt(o,u,f,r);return await Nt(t,e`INSERT INTO ${e.identifier(t)} (${Z(l)}) VALUES (${ne(w)})`),E&&Le.set(u,t),await ae(t,void 0,y),await X(t,u,void 0,y),await de(t,u,y),await oe(t,u,"insert",y),P(t,"after","insert")&&await H("after","insert",{doc:y,id:u,op:"insert",table:t}),u},normalizeId(t,n){return nn($,t,n)},async patch(t,n,i){et("patch",n);const o=await re(t,i);if(!o)throw new T("INTERNAL",`document not found: ${t}`);const r=$.tables[o];if(!r)throw new T("INTERNAL",`document not found: ${t}`);const u=await Te(o,t),E=ee(r,u);if(!E)throw new T("INTERNAL",`document not found: ${t}`);const f={...E,...n,_id:t};ht(r,n,f,ie),Ne(r,f,!0),P(o,"before","update")&&await H("before","update",{doc:{...f},id:t,op:"update",previous:E,table:o}),await Se(o),await ge(o);const y=Object.keys(r.shape),l=e.join(y.map(w=>e`${e.identifier(w)} = ${J(r,w,f[w]??null)}`),e`, `);await ve(o,"UPDATE",l,u),await ae(o,E,f),await X(o,t,E,f),await de(o,t,f,E),await oe(o,t,"update",f),P(o,"after","update")&&await H("after","update",{doc:f,id:t,op:"update",previous:E,table:o})},async restore(t,n){const i=await re(t,n);if(!i)throw new T("INTERNAL",`document not found: ${t}`);const o=$.tables[i],r=o?.softDeleteMode?.field;if(!o||!r)throw new T("INTERNAL",`ctx.db.restore: table "${i}" is not a .softDelete() table`);const u=await Te(i,t),E=u?.[r]!==null&&u?.[r]!==void 0;if(await x.patch(t,{[r]:null},n),E){const f=ee(o,u);f!==null&&await X(i,t,void 0,{...f,[r]:null})}},query(t){const n=$.tables[t];if(!n)throw new T("INTERNAL",`unknown table: ${t}`);const i="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",o=[],r=f=>o.every(y=>y(f)),u=async(f,y)=>{await U();const l=o.length>0,w=await Gt(s,d,n,t,f,Vt(l?void 0:y));if(!l)return y===void 0&&Yt(w),w;const _=w.filter(g=>r(g));return y===void 0?_:_.slice(0,y)},E=f=>{const y={async*[Symbol.asyncIterator](){if(!f)throw new T("INTERNAL",i);yield*await u(f,void 0)},async collect(){if(!f)throw new T("INTERNAL",i);return u(f,void 0)},async collectWithScores(){throw new T("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(l){return o.push(l),y},async first(){if(!f)throw new T("INTERNAL",i);return(await u(f,1))[0]??null},order(){return y},async paginate(l){if(!f)throw new T("INTERNAL",i);const w=Kt(l);return jt(await u(f,Xt(w)),w)},async take(l){if(!f)throw new T("INTERNAL",i);return u(f,l)},async unique(){if(!f)throw new T("INTERNAL",i);const l=await u(f,2);if(l.length>1)throw new gn(`unique() on table "${t}" matched ${String(l.length)} documents; expected at most one`);return l[0]??null},withGeoIndex(){throw new T("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new T("INTERNAL",i)},withSearchIndex(l,w){const _=(n.searchIndexes??[]).find(R=>R.name===l);if(!_)throw new T("INTERNAL",`unknown search index "${l}" on table "${t}"`);const g={definition:_,field:_.field,filters:[],hasQuery:!1,indexName:l,query:""};if(w(Ht(g,t,Ut(_.language))),!g.hasQuery)throw new T("INTERNAL",`search index "${l}" on table "${t}" requires a .search(field, query) call`);return E(g)}};return y};return E(void 0)},async rank(t,n,i){const o=$.tables[t];if(!o)throw new T("INTERNAL",`unknown table: ${t}`);const r=o.rankIndexes?.find(B=>B.name===n);if(!r)throw new T("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(i.restrictsCounts)throw new it(t);if(await U(),!await Me(t,r))return null;const E=typeof i.row=="string"?i.row:i.row._id;if(!E)return null;const f=we(t,r.name),y=r.sortBy.map((B,K)=>Ee(K)),l=Z(["__partition__",...y]),_=(await m(s,d,e`SELECT ${l} FROM ${e.identifier(f)} WHERE ${e.identifier("__id__")} = ${E}`))[0];if(!_)return null;const g=_.__partition__,R=q(i.baseWhere,i.where);tt(R,$,t,"rank");const b=nt(r,R);if(b&&Ce(r.partitionBy??[],b)!==g)return null;const L=Un(d.name,r,y,_,E),F=await m(s,d,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${g} AND (${L})`),k=await m(s,d,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${g}`);return{position:Number(F[0]?.c??0)+1,total:Number(k[0]?.c??0)}},async rankPage(t,n,i={}){tt(q(i.baseWhere,i.where),$,t,"rankPage");const o=$.tables[t];if(!o)throw new T("INTERNAL",`unknown table: ${t}`);const r=o.rankIndexes?.find(D=>D.name===n);if(!r)throw new T("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await U(),!await Me(t,r))return{continueCursor:null,isDone:!0,page:[]};const E=we(t,r.name),f=r.sortBy.map((D,ue)=>Ee(ue)),y=Math.max(1,Math.min(1e3,Math.floor(i.take??100))),l=q(i.baseWhere,i.where),w=nt(r,l),_=Pn(r,f),g=e.join(_.map(D=>e`${e.identifier(D.column)} ${e.raw(`${D.direction==="desc"?"DESC":"ASC"}${Tt(d,{direction:D.direction,nullable:D.nullable})}`)}`),e`, `),R=[];typeof i.partitionKey=="string"?R.push(e`${e.identifier("__partition__")} = ${i.partitionKey}`):w&&R.push(e`${e.identifier("__partition__")} = ${Ce(r.partitionBy??[],w)}`);const b=tn(i);if(b!==void 0){const D=xn(d.name,_,b);D!==void 0&&R.push(D)}const L=Z([ye,"__partition__",...f]);let F=e`SELECT ${L} FROM ${e.identifier(E)}`;R.length>0&&(F=e`${F} WHERE ${e.join(R,e` AND `)}`),F=e`${F} ORDER BY ${g} LIMIT ${e.raw(String(y+1))}`;const k=await m(s,d,F),B=k.length>y,K=B?k.slice(0,y):k,Ie=K.map(D=>D[ye]),le=await Hn(s,d,o,t,Ie);let be=null;const z=K.at(-1);if(B&&z!==void 0){const D=[z.__partition__,...f.map(ue=>z[ue]),z[ye]];be=Kn(D)}return{continueCursor:be,isDone:!B,page:le}},async replace(t,n,i,o){et("replace",n);const r=await re(t,i);if(!r)throw new T("INTERNAL",`document not found: ${t}`);const u=$.tables[r];if(!u)throw new T("INTERNAL",`document not found: ${t}`);const E=await Te(r,t);if(E===void 0)throw new T("INTERNAL",`document not found: ${t}`);const y=en($,r,"update")||(u.aggregateIndexes??[]).length>0||(u.rankIndexes??[]).length>0?ee(u,E)??void 0:void 0,l=o?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:N(),w={...n,_creationTime:l,_id:t};ht(u,n,w,ie),Ne(u,w),P(r,"before","update")&&await H("before","update",{doc:{...w},id:t,op:"update",previous:y,table:r}),await Se(r),await ge(r);const _=Object.keys(u.shape),g=e.join([e`${e.identifier("_creationTime")} = ${l}`,..._.map(R=>e`${e.identifier(R)} = ${J(u,R,w[R]??null)}`)],e`, `);await ve(r,"UPDATE",g,E),await ae(r,y,w),await X(r,t,y,w),await de(r,t,w,y),await oe(r,t,"update",w),P(r,"after","update")&&await H("after","update",{doc:w,id:t,op:"update",previous:y,table:r})}};return Ge={db:x,scheduler:Ct},x};export{Ei as backfillSqlSearchIndexes,$i as createSqlCtxDb,pi as decodeGlobalRow,ei as readSqlCdcChangedTables,wi as readSqlCdcChanges,bt as readSqlCdcFloor,Xn as runSqlCdcMigration,Pt as runSqlSearchMigrations,Qn as sweepSqlCdcRetention};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/sql-store",
3
- "version": "1.0.0-alpha.111",
3
+ "version": "1.0.0-alpha.112",
4
4
  "description": "Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale)",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,8 +50,8 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/errors": "1.0.0-alpha.33",
54
- "@lunora/shard-engine": "1.0.0-alpha.58",
53
+ "@lunora/errors": "1.0.0-alpha.35",
54
+ "@lunora/shard-engine": "1.0.0-alpha.60",
55
55
  "drizzle-orm": "^0.45.2"
56
56
  },
57
57
  "engines": {
@@ -1,7 +0,0 @@
1
- import{LunoraError as T}from"@lunora/errors";import{m as qt,D as Ot}from"./ctx-db-search-state-D_X8wIwk.mjs";import{c as Wt,r as Ft,A as Ut,C as xt,R as Pt,a as Ht,T as Kt,x as jt,b as Gt}from"./ctx-db-search-CdewhEdG.mjs";import{d as fi}from"./ctx-db-search-CdewhEdG.mjs";import{literalInList as Vt,throwingScheduler as Yt,CDC_LOG_TABLE as G,cursorBelowRetainedFloor as Xt,cdcTrimmedError as zt,assertNoExplicitUndefined as Ze,hasTrigger as Qt,runRowValidators as Ne,assertFlatPredicate as et,mergeWhere as q,rankTableName as de,sortColumnName as $e,resolveRankPartition as tt,encodePartitionKey as Ie,resolveRankSeekTuple as Jt,RANK_TIEBREAK as _e,CountRlsUnsupportedError as nt,normalizeIdStructurally as Zt,assertValidClientId as en,aggregateSqlFunction as le,softDeleteScope as ue,compileWhereSql as fe,normalizeOrderKeys as tn,buildSeekWhere as nn,decodeCursor as on,resolveRelationPredicates as it,resolveWith as ot,relationHooks as rt,applySelect as st,encodeCursor as rn,NotFoundError as sn,applyOnDelete as an,ConflictError as Ce,normalizeCountArgument as cn,selectIndexForCount as dn,encodeAggregateKey as Y,aggregateTableName as Q,selectIndexForAggregate as ln,readAggregateValue as De,runTriggers as un,matchesRankStaticWhere as at,rankPivotConditionSql as yt,CURSOR_PREFIX as fn,selectIndexForGroupBy as wn,tiebreakDirectionFor as $n,fanOutScalarCounts as _n,matchesStaticWhere as Be,foldAggregateTally as ct,coerceAggregateNumber as qe,CDC_LOG_TABLE_SEQ_INDEX as hn,NotUniqueError as En}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{d as pt,e as yn,n as pn,b as Rn}from"./value-codec-Dzavzwao.mjs";import{runSqlGlobalTableMigrations as Sn,runSqlAggregateMigrations as gn,runSqlRankMigrations as Tn}from"./runSqlAggregateMigrations-DYQCOK8J.mjs";import{queryAll as I,queryRun as k,createIndexIfNotExists as vn,decodeRow as Z,serializeDocumentColumn as be,serializeColumnValue as we,columnRefSql as O,decodeRows as dt,tableColumns as Rt,OCC_VERSION_COLUMN as lt,forEachRowPaged as ut,BACKFILL_BATCH_SIZE as Oe,queryBatch as ft}from"./decodeGlobalRow-BdC0SILc.mjs";import{decodeGlobalRow as $i}from"./decodeGlobalRow-BdC0SILc.mjs";const mn=(a,c)=>{if(a.size<c)return;const _=a.keys().next().value;_!==void 0&&a.delete(_)},wt=50,In=(a,c={})=>{const _=c.maxBatch??wt,s=Number.isInteger(_)&&_>0?_:wt,p=new Map;let $=!1;const u=async(g,v)=>{const m=[...v.keys()];for(let M=0;M<m.length;M+=s){const N=m.slice(M,M+s);try{const W=await a(g,N);for(const V of N){const P=W.get(V);for(const Ae of v.get(V)??[])Ae.resolve(P)}}catch(W){for(const V of N)for(const P of v.get(V)??[])P.reject(W)}}},b=()=>{$=!1;const g=[...p.entries()];p.clear();for(const[v,m]of g)u(v,m).catch(()=>{})};return{async load(g,v){return new Promise((m,M)=>{let N=p.get(g);N||(N=new Map,p.set(g,N));const W=N.get(v);W?W.push({reject:M,resolve:m}):N.set(v,[{reject:M,resolve:m}]),$||($=!0,queueMicrotask(b))})}}},bn=new Set(["_id","id"]),xe=(a,c,_)=>a==="postgres"?e`${c} IS NOT DISTINCT FROM ${_}`:a==="mysql"?e`${c} <=> ${_}`:e`${c} IS ${_}`,St=(a,c)=>a.name!=="postgres"||c.nullable!==!0?"":c.direction==="desc"?" NULLS LAST":" NULLS FIRST",Cn=(a,c)=>{const _=a.map(s=>e`${O(s.field)} ${e.raw(`${s.direction==="desc"?"DESC":"ASC"}${St(c,s)}`)}`);if(!a.some(s=>bn.has(s.field))){const s=$n(a);_.push(e`${O("id")} ${e.raw(s==="desc"?"DESC":"ASC")}`)}return e.join(_,e`, `)},$t=50,An=(a,c,_)=>{const s={...c};for(const[p,$]of Rt(a)){if($.serverDefault){s[p]=$.serverDefault({auth:_});continue}s[p]===void 0&&($.defaultFn?s[p]=$.defaultFn():"defaultValue"in $&&(s[p]=$.defaultValue))}return s},_t=(a,c,_,s)=>{for(const[p,$]of Rt(a)){if($.serverDefault){p in c&&(_[p]=$.serverDefault({auth:s}));continue}$.onUpdateFn&&!(p in c)&&(_[p]=$.onUpdateFn())}},Ln=128,kn=()=>{const a=new Map;return{delete:c=>{a.delete(c)},get:c=>{const _=a.get(c);if(_!==void 0)return a.delete(c),a.set(c,_),_},set:(c,_)=>{a.has(c)?a.delete(c):mn(a,Ln),a.set(c,_)}}},Mn=async(a,c,_,s,p)=>{const $=p.get(s);if($!==void 0)return $;const u=Object.entries(_.tables).filter(([,g])=>g.shardMode===void 0||g.shardMode.kind==="global").map(([g])=>g),b=await Promise.all(u.map(async g=>({found:(await I(a,c,e`SELECT 1 FROM ${e.identifier(g)} WHERE ${e.identifier("id")} = ${s} LIMIT 1`)).length>0,tableName:g})));for(const g of b)if(g.found)return p.set(s,g.tableName),g.tableName},ee=a=>a==null?null:Number(a),Nn=(a,c)=>c.map(_=>{const s={};for(const p of a)s[p]=_[p]??null;return{key:s,value:ee(_.value)}}),Dn=(a,c,_)=>[...a.partitionBy??[],...a.sortBy.map(p=>p.field),...a.where?Object.keys(a.where):[]].every(p=>c[p]===_[p]),gt=a=>a.length===1?a[0]:e`(${e.join(a,e` AND `)})`,J=a=>e.join(a.map(c=>e`${e.identifier(c)}`),e`, `),te=a=>e.join(a.map(c=>e`${c}`),e`, `),Bn=(a,c,_,s,p)=>{const $=[];for(let u=0;u<_.length+1;u+=1){const b=_[u],g=c.sortBy[u],v=u<_.length&&b!==void 0&&g!==void 0,m=g?.direction==="desc"?"desc":"asc",M=v?yt(b,s[b],m,!1):e`${e.identifier(_e)} < ${p}`;if(M===void 0)continue;const N=_.slice(0,u).map(W=>xe(a,e`${e.identifier(W)}`,s[W]));N.push(M),$.push(gt(N))}return $.length>0?e.join($,e` OR `):e`1 = 0`},qn=(a,c,_)=>{if(_.length!==c.length)return;const s=[];for(const[p,$]of c.entries()){const u=yt($.column,_[p],$.direction,!0);if(u===void 0)continue;const b=[];for(let g=0;g<p;g+=1){const v=c[g];v!==void 0&&b.push(xe(a,e`${e.identifier(v.column)}`,_[g]))}b.push(u),s.push(gt(b))}return s.length===0?e`(1 = 0)`:e`(${e.join(s,e` OR `)})`},On=(a,c)=>{if(a.sortBy.length===0)throw new T("INTERNAL",`rankIndex "${a.name}" requires at least one "sortBy" column for stable pagination`);const _=[{column:"__partition__",direction:"asc",nullable:!1}];for(const[s,p]of a.sortBy.entries())_.push({column:c[s]??$e(s),direction:p.direction,nullable:!0});return _.push({column:_e,direction:"asc",nullable:!1}),_},Wn=async(a,c,_,s,p)=>{const u=[];for(let m=0;m<p.length;m+=50)u.push(p.slice(m,m+50));const b=await Promise.all(u.map(async m=>I(a,c,e`SELECT * FROM ${e.identifier(s)} WHERE ${e.identifier("id")} IN (${te(m)})`))),g=new Map;for(const m of b)for(const M of m)g.set(M.id,M);const v=[];for(const m of p){const M=Z(_,g.get(m));M&&v.push(M)}return v},Fn=a=>{const c=JSON.stringify(a),_=new TextEncoder().encode(c);let s="";for(const p of _)s+=String.fromCodePoint(p);return fn+btoa(s)},Tt=a=>{if(a===void 0)return!1;const c=yn(a);return c==="any"||c==="bigint"||c==="from"||c==="union"},Fe=(a,c,_)=>{if(Tt(a.shape[c]))throw new T("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)`)},Un=(a,c,_,s)=>{for(const p of _)Fe(a,p,`groupBy(${c}, { by: [..."${p}"] })`);s.field!==void 0&&Fe(a,s.field,`groupBy(${c}, { agg: { op: "${s.op}", field: "${s.field}" } })`)},Ue="__cdc_sweep",vt="global",xn=6e4,Pn=1e4,Hn=3e4;let ht=0;const Kn=async(a,c)=>{const{autoincrementPrimaryKey:_,key:s,real:p,text:$}=c.companionTypes;await k(a,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(G)} (${e.identifier("seq")} ${e.raw(_)}, ${e.identifier("ts")} ${e.raw(p)} NOT NULL, ${e.identifier("table")} ${e.raw(s)} NOT NULL, ${e.identifier("id")} ${e.raw(s)} NOT NULL, ${e.identifier("op")} ${e.raw(s)} NOT NULL, ${e.identifier("doc")} ${e.raw($)})`);const u=c.indexKeyPrefix?.("string");await vn(a,c,{columns:e`${u===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(u))})`}, ${e.identifier("seq")}`,name:hn,table:G,unique:!1}),await k(a,c,e`CREATE TABLE IF NOT EXISTS ${e.identifier(Ue)} (${e.identifier("id")} ${e.raw(s)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(p)} NOT NULL)`),await k(a,c,e`INSERT INTO ${e.identifier(Ue)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${vt}, ${0}) ${c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},jn=async(a,c,_)=>{const s=e`UPDATE ${e.identifier(Ue)} SET ${e.identifier("lease_until")} = ${_+xn} WHERE ${e.identifier("id")} = ${vt} AND ${e.identifier("lease_until")} <= ${_}`;if(c.supportsReturning)return(await I(a,c,e`${s} RETURNING ${e.identifier("id")}`)).length>0;const p=await k(a,c,s);return(c.affectedRows?c.affectedRows(p??{rowsAffected:0}):0)>0},Gn=async(a,c,_,s)=>{if(!await jn(a,c,s))return;const p=s-_;await k(a,c,e`
2
- DELETE FROM ${e.identifier(G)} WHERE ${e.identifier("seq")} IN (
3
- SELECT ${e.identifier("seq")} FROM (
4
- SELECT ${e.identifier("seq")} FROM ${e.identifier(G)} WHERE ${e.identifier("ts")} <= ${p} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Pn))}
5
- ) AS ${e.identifier("expired")}
6
- )
7
- `)},mt=async(a,c)=>{const _=await I(a,c,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(G)}`),s=Number(_[0]?.seq??Number.NaN);return Number.isFinite(s)?s:void 0},Vn=a=>JSON.stringify(pn(a)?Rn(a):a),Yn=async(a,c,_,s,p,$,u)=>{await k(a,u,e`INSERT INTO ${e.identifier(G)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${c}, ${_}, ${s}, ${p}, ${$===void 0?null:Vn($)})`)},ci=async(a,c,_)=>{const s=c.sinceSeq??0,p=Math.max(1,Math.min(c.limit??1e3,1e4)),$=await mt(a,_);if($!==void 0&&Xt($,s))throw zt($,s,"global");const b=(await I(a,_,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(G)} WHERE seq > ${s} ORDER BY seq ASC LIMIT ${e.raw(String(p))}`)).map(g=>{const{doc:v}=g,m={id:String(g.id),op:String(g.op),seq:Number(g.seq),table:String(g.table),ts:Number(g.ts)};return typeof v=="string"?{...m,doc:pt(JSON.parse(v))}:m});return{changes:b,cursor:b.at(-1)?.seq??s}},Xn=async(a,c,_,s={})=>{if(s.cursorOnly){const g=await I(a,_,e`SELECT MAX(seq) AS seq FROM ${e.identifier(G)}`),v=Number(g[0]?.seq??c);return{cursor:Number.isFinite(v)?v:c,tables:[]}}const p=await I(a,_,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq FROM ${e.identifier(G)} WHERE seq > ${c} GROUP BY ${e.identifier("table")}`);let $=c;const u=[];for(const g of p){const v=Number(g.seq);Number.isFinite(v)&&v>$&&($=v),u.push(String(g.table))}const b=s.retained===!0?await mt(a,_):void 0;return{cursor:$,tables:u,...b===void 0?{}:{floor:b}}},zn=/string or blob too big/iu,Qn=/row is too big/iu,Jn=(a,c)=>{const{code:_,errno:s}=c,p=c instanceof Error?c.message:"";switch(a.name){case"mysql":return s===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 Qn.test(p)?"the 8 KB heap page a tuple must fit once its wide columns have been TOASTed out":void 0;default:return zn.test(p)?"the storage engine's per-row ceiling (2 MB on D1)":void 0}},Zn=(a,c,_)=>{const s=Jn(a,c);if(s!==void 0)throw new T("PAYLOAD_TOO_LARGE",`document is too large to store in "${_}": a single row cannot exceed ${s}. 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.`)},Et=(a,c,_)=>{throw a.isUniqueViolation(c)?new Ce(`unique constraint violation on "${_}"`,"unique"):(Zn(a,c,_),c)},We=new WeakMap,di=a=>{const{crossShardCounter:c,crossShardReader:_,exec:s,maxRelationKeys:p,schema:$}=a,{dialect:u}=a,b={fieldRef:O,serialize:we,...u.name==="mysql"?{containsExpr:(t,n)=>e`LOCATE(${n}, ${t}) > 0`}:{},...u.name==="postgres"?{containsExpr:(t,n)=>e`strpos(${t}, ${n}) > 0`}:{},...u.name==="sqlite"?{}:{inList:Vt}},g=(t,n)=>xe(u.name,t,n),v=t=>{const n=J(t.columns),i=te(t.values),o=l=>u.name==="mysql"?e`VALUES(${e.identifier(l)})`:e`excluded.${e.identifier(l)}`,r=l=>u.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(l)}`:e`${e.identifier(l)}`,f=e.join(Object.entries(t.set(o,r)).map(([l,E])=>e`${e.identifier(l)} = ${E}`),e`, `),h=u.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${f}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${f}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${i}) ${h}`},m=a.clock??(()=>Date.now()),M=a.idGenerator??(()=>crypto.randomUUID()),N=a.cdc??!1,W=typeof a.cdcRetentionMs=="number"&&Number.isFinite(a.cdcRetentionMs)&&a.cdcRetentionMs>0?a.cdcRetentionMs:void 0,V=a.auth??{identity:null,userId:null},P=async(t,n,i,o)=>{if(!N||(await Yn(s,m(),t,n,i,o,u),W===void 0))return;const r=m();if(!(r-ht<Hn)){ht=r;try{await Gn(s,u,W,r)}catch{}}},Ae=a.scheduler??Yt,Le=kn();let he=0;const ke=a.provisionScope??{},U=async()=>{const t=We.get(ke);if(t)return t;const n=(async()=>{await Sn(s,$,u),await gn(s,$,u),await Tn(s,$,u),await qt(s,u),await Ft(s,$,u),N&&await Kn(s,u)})().catch(i=>{throw We.delete(ke),i});return We.set(ke,n),n},ne=async(t,n)=>{await U();const i=await Mn(s,u,$,t,Le);if(!(n!==void 0&&i!==n))return i},ie=new Map,Pe=async(t,n)=>{const i=Q(t,n);return(await I(s,u,u.tableExists(i))).length>0},Ee=async(t,n)=>{const i=`${t}::${n.name}`,o=ie.get(i);if(o!==void 0)return o;if(!await Pe(t,n.name))return ie.set(i,!1),!1;const f=$.tables[t];if(!f)return ie.set(i,!1),!1;const h=n.by??[],l=new Map;await ut(s,u,f,t,w=>{if(n.where&&!Be(w,n.where))return;const y=Y(h,w);ct(l,y,n,w)});const E=Q(t,n.name);await k(s,u,e`DELETE FROM ${e.identifier(E)}`);const d=[];for(const[w,y]of l)d.push(e`INSERT INTO ${e.identifier(E)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${w}, ${y.value}, ${y.count})`);return await ft(s,u,d),ie.set(i,!0),!0},It=async(t,n,i,o)=>{const r=new Map;let f,h=!0;for(;h;){const l=f===void 0?o:[...o,e`${e.identifier("id")} > ${f}`],E=l.length>0?e` WHERE ${e.join(l,e` AND `)}`:e``,d=await I(s,u,e`SELECT ${e.identifier("id")}, ${O(i.field??"")} FROM ${e.identifier(n)}${E} ORDER BY ${e.identifier("id")} ASC LIMIT ${e.raw(String(Oe))}`);for(const w of dt(t,d))ct(r,"",i,w);f=d.at(-1)?.id,h=d.length===Oe}return r.get("")?.value??null},bt=async(t,n,i)=>{const o=n.field??"",r=[];for(const d of n.by??[]){const w=we(i[d]??null);r.push(w===null?e`${O(d)} IS NULL`:e`${O(d)} = ${w}`)}for(const[d,w]of Object.entries(n.where??{})){const y=w!==null&&typeof w=="object"&&!Array.isArray(w)?w.eq:w,R=we(y);r.push(R===null?e`${O(d)} IS NULL`:e`${O(d)} = ${R}`)}const f=r.length>0?e` WHERE ${e.join(r,e` AND `)}`:e``,h=$.tables[t];if(h&&Tt(h.shape[o]))return It(h,t,n,r);const l=le(n.op),E=await I(s,u,e`SELECT ${e.raw(l)}(${O(o)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}${f}`);return ee(E[0]?.value)},Ct=async(t,n)=>{await k(s,u,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`)},At=async(t,n,i,o)=>{const r=Q(t,n.name),{op:f}=n,h=n.field??"",l=i&&(!n.where||Be(i,n.where))?i:void 0,E=o&&(!n.where||Be(o,n.where))?o:void 0;if(!(!l&&!E)){if(f==="count"||f==="sum"||f==="avg"){const d=new Set;for(const[w,y]of[[l,-1],[E,1]]){if(!w)continue;const R=f==="count"?1:qe(w[h]);if(R===void 0)continue;const S=Y(n.by??[],w);d.add(S),await k(s,u,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(C,A)=>({__count__:e`${A("__count__")} + ${C("__count__")}`,__value__:f==="count"?e`${A("__value__")} + ${C("__value__")}`:e`COALESCE(${A("__value__")}, 0) + ${C("__value__")}`}),table:r,values:[S,y*R,y]}))}for(const w of d)await Ct(r,w);return}if(l){const d=Y(n.by??[],l),w=qe(l[h]),R=(await I(s,u,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${d}`))[0],S=ee(R?.value),C=(R?.count??0)-1;if(C<=0)await k(s,u,e`DELETE FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${d}`);else if(R&&w!==void 0&&S!==null&&w===S){const A=await bt(t,n,l);await k(s,u,e`UPDATE ${e.identifier(r)} SET ${e.identifier("__value__")} = ${A}, ${e.identifier("__count__")} = ${C} WHERE ${e.identifier("__key__")} = ${d}`)}else await k(s,u,e`UPDATE ${e.identifier(r)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${d}`)}if(E){const d=Y(n.by??[],E),w=qe(E[h]);if(w===void 0)await k(s,u,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(y,R)=>({__count__:e`${R("__count__")} + 1`}),table:r,values:[d,null,1]}));else{const y=f==="min"?"MIN":"MAX";await k(s,u,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(R,S)=>({__count__:e`${S("__count__")} + 1`,__value__:e`${e.raw(y)}(COALESCE(${S("__value__")}, ${R("__value__")}), ${R("__value__")})`}),table:r,values:[d,w,1]}))}}}},ye=async t=>{const n=$.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const i of n)await Ee(t,i)},oe=async(t,n,i)=>{const o=$.tables[t]?.aggregateIndexes;if(!(!o||o.length===0))for(const r of o){const f=`${t}::${r.name}`;(ie.get(f)??await Pe(t,r.name))&&await At(t,r,n,i)}},re=new Map,He=async(t,n)=>{const i=de(t,n);return(await I(s,u,u.tableExists(i))).length>0},Me=async(t,n)=>{const i=`${t}::rank::${n.name}`,o=re.get(i);if(o!==void 0)return o;if(!await He(t,n.name))return re.set(i,!1),!1;const f=$.tables[t];if(!f)return re.set(i,!1),!1;const h=de(t,n.name);await k(s,u,e`DELETE FROM ${e.identifier(h)}`);const l=n.sortBy.map((y,R)=>$e(R)),E=J(["__id__","__partition__",...l]);let d=[];const w=async()=>{if(d.length===0)return;const y=d;d=[],await ft(s,u,y)};return await ut(s,u,f,t,async y=>{if(n.where&&!at(y,n.where))return;const R=Ie(n.partitionBy??[],y),S=n.sortBy.map(C=>we(y[C.field]??null));d.push(e`INSERT INTO ${e.identifier(h)} (${E}) VALUES (${te([y._id,R,...S])})`),d.length>=Oe&&await w()}),await w(),re.set(i,!0),!0},pe=async t=>{const n=$.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const i of n)await Me(t,i)},X=async(t,n,i,o)=>{const r=$.tables[t],f=r?.rankIndexes;if(!f||f.length===0)return;const h=r?.softDeleteMode?.field,l=h===void 0||o===void 0?void 0:o[h],E=l!=null;for(const d of f){if(i!==void 0&&o!==void 0&&Dn(d,i,o))continue;const w=`${t}::rank::${d.name}`;if(!(re.get(w)??await He(t,d.name)))continue;const S=de(t,d.name);if(i&&await k(s,u,e`DELETE FROM ${e.identifier(S)} WHERE ${e.identifier("__id__")} = ${n}`),o&&!E){if(d.where&&!at(o,d.where))continue;const C=d.sortBy.map((B,j)=>$e(j)),A=J(["__id__","__partition__",...C]),F=Ie(d.partitionBy??[],o),L=d.sortBy.map(B=>we(o[B.field]??null));await k(s,u,e`INSERT INTO ${e.identifier(S)} (${A}) VALUES (${te([n,F,...L])})`)}}},se=Wt({dialect:u,exec:s,schema:$}),Ke=new Set;for(const[t,n]of Object.entries($.tables))for(const i of Object.values(n.triggerMap??{}))Ke.add(`${t} ${i.timing} ${i.op}`);const H=(t,n,i)=>Ke.has(`${t} ${n} ${i}`);let je;const K=async(t,n,i)=>{if(he+=1,he>$t)throw he-=1,new Ce(`trigger recursion exceeded ${String($t)} levels on "${i.table}" — check for a self-triggering write`,"trigger");try{await un({ctx:je,event:i,op:n,schema:$,tableName:i.table,timing:t})}finally{he-=1}},Lt=async(t,n)=>{try{await k(s,u,n)}catch(i){Et(u,i,t)}},Re=async(t,n)=>(await I(s,u,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],Se=async(t,n,i,o)=>{if(o===void 0)return;const r=e`${e.identifier(lt)}`,f=e.join([g(e`${e.identifier("id")}`,o.id),g(r,o[lt]??null)],e` AND `),h=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${i}, ${r} = COALESCE(${r}, 0) + 1 WHERE ${f}`:e`DELETE FROM ${e.identifier(t)} WHERE ${f}`,l=()=>{throw new Ce(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(u.supportsReturning)(await I(s,u,e`${h} RETURNING ${e.identifier("id")}`)).length===0&&l();else{const E=await k(s,u,h);(u.affectedRows?u.affectedRows(E??{rowsAffected:0}):0)===0&&l()}}catch(E){Et(u,E,t)}},kt=(t,n,i,o)=>{const r=Object.keys(t.shape);return{columns:["id","_creationTime",...r],values:[n,i,...r.map(f=>be(t,f,o[f]??null))]}},Mt=async(t,n,i,o)=>{const r=wn(n,i.op,i.field,o.by,o.where);if(!r||!await Ee(t,r.index))return;const h=Q(t,r.index.name),l=Object.keys(r.partial);if(l.length===(r.index.by??[]).length&&l.length>0){const d=Y(r.index.by??[],r.partial),w=await I(s,u,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(h)} WHERE ${e.identifier("__key__")} = ${d}`);if(w.length===0)return[];const y=w[0];return[{key:{...r.partial},value:De(i.op,{count:y.count,value:ee(y.value)})}]}return l.length>0?void 0:(await I(s,u,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(d=>{const w=d;return{key:pt(JSON.parse(w.key)),value:De(i.op,{count:w.count,value:ee(w.value)})}})},Ge=t=>{const n=$.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},Ve=t=>{throw new T("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`)},Nt=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new T("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 o of Object.keys($.tables)){const r=n.relationBaseWhere(o);r!==void 0&&(i[o]=r)}return{orderBy:n?.orderBy,relationPolicies:i,where:q(n?.baseWhere,n?.where),with:n?.with}},Ye=(t,n)=>Ge(t)?_?_(t,Nt(t,n)):Ve(t):x.findMany(t,n),ge=(t,n,i)=>it(t,{fetcher:Ye,maxRelationKeys:p,relationBaseWhere:i,schema:$,tableName:n}),Dt=In(async(t,n)=>{const i=await I(s,u,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${te(n)})`),o=new Map;for(const r of i){const{id:f}=r;typeof f=="string"&&o.set(f,r)}return o}),x={async cdcChangedTables(t,n){if(N)try{return await U(),await Xn(s,t,u,{...n,retained:W!==void 0})}catch{return}},async aggregate(t,n){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);if(await U(),le(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 T("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const o=ue(i.softDeleteMode,void 0),r=q(q(n.baseWhere,n.where),o),f=await ge(r,t,n.relationBaseWhere),h=f!==r;if(i.aggregateIndexes&&!n.baseWhere&&!h&&!o){const R=ln(i.aggregateIndexes,n.op,n.field,n.where);if(R&&await Ee(t,R.index)){const C=Y(R.index.by??[],R.key),A=Q(t,R.index.name),L=(await I(s,u,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")}, ${e.identifier("__count__")} AS ${e.identifier("count")} FROM ${e.identifier(A)} WHERE ${e.identifier("__key__")} = ${C}`))[0];return De(n.op,L===void 0?void 0:{count:L.count,value:ee(L.value)})}}Fe(i,n.field,`aggregate(${t}, { op: "${n.op}", field: "${n.field}" })`);const l=fe(f,b),E=e.raw(le(n.op)),d=e`SELECT ${E}(${O(n.field)}) AS ${e.identifier("value")} FROM ${e.identifier(t)}`,y=(await I(s,u,l?e`${d} WHERE ${l}`:d))[0]?.value;return y==null?null:Number(y)},async count(t,n){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);await U();const o=cn(n);if(o.restrictsCounts)throw new nt(t);const r=ue(i.softDeleteMode,void 0),f=q(q(o.baseWhere,o.where),r),h=await ge(f,t,o.relationBaseWhere),l=h!==f;if(i.aggregateIndexes&&!o.baseWhere&&!l&&!r){const y=dn(i.aggregateIndexes,o.where);if(y&&await Ee(t,y.index)){const S=Y(y.index.by??[],y.key),C=Q(t,y.index.name),A=await I(s,u,e`SELECT ${e.identifier("__value__")} AS ${e.identifier("value")} FROM ${e.identifier(C)} WHERE ${e.identifier("__key__")} = ${S}`);return Number(A[0]?.value??0)}}const E=fe(h,b),d=e`SELECT COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(t)}`,w=await I(s,u,E?e`${d} WHERE ${E}`:d);return Number(w[0]?.count??0)},async delete(t,n,i){const o=await ne(t,n);if(!o)return;const r=$.tables[o];if(!r)return;const f=await Re(o,t),h=Z(r,f),l=i?.hard===!0,E=!l&&r.softDeleteMode?r.softDeleteMode.field:void 0;if(!(E&&(!h||h[E]!==null&&h[E]!==void 0))){if(H(o,"before","delete")&&await K("before","delete",{id:t,op:"delete",previous:h??void 0,table:o}),await an({deletedId:t,deletedReference:d=>h?.[d],findHolders:async(d,w,y)=>{if($.tables[d]?.shardMode?.kind==="shardBy")throw new T("INTERNAL",`cross-backend cascade from global '${o}' into shardBy '${d}' is not supported — would require Query Coordinator fan-out across shards`);return(await x.findMany(d,{includeDeleted:l,where:{[w]:y}})).page},onCascade:(d,w)=>x.delete(w,void 0,i),onRestrict:d=>{throw new Ce(d,"restrict")},onSetNull:(d,w,y)=>x.patch(w,{[y]:null}),schema:$,tableName:o}),await ye(o),await pe(o),E&&h){const d={...h,[E]:m()},w=e.join(Object.keys(r.shape).map(y=>e`${e.identifier(y)} = ${be(r,y,d[y]??null)}`),e`, `);await Se(o,"UPDATE",w,f),await oe(o,h,d),await X(o,t,h,void 0),await se(o,t,d,h),await P(o,t,"update",d),H(o,"after","delete")&&await K("after","delete",{id:t,op:"delete",previous:h,table:o});return}await Se(o,"DELETE",void 0,f),Le.delete(t),await oe(o,h??void 0,void 0),await X(o,t,h??void 0,void 0),await se(o,t,void 0),await P(o,t,"delete"),H(o,"after","delete")&&await K("after","delete",{id:t,op:"delete",previous:h??void 0,table:o})}},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 sn(`findFirstOrThrow: no "${t}" document matched`);return i},async findMany(t,n={}){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);await U();const o=tn(n.orderBy,i.shape),r=n.cursor?nn(o,on(n.cursor)):void 0,f=Ye,h=async(L,B,j,Te)=>{if(Ge(L))return c?_n(c,L,B,j,Te):Ve(L);const ve=$.tables[L];if(!ve)throw new T("INTERNAL",`unknown table: ${L}`);const me=ue(ve.softDeleteMode,void 0),z={[B]:{in:j}},D=q(q(z,Te),me),ae=await ge(D,L,void 0),Xe=fe(ae,b),ze=O(B);let ce=e`SELECT ${ze} AS __fk__, COUNT(*) AS ${e.identifier("count")} FROM ${e.identifier(L)}`;Xe&&(ce=e`${ce} WHERE ${Xe}`),ce=e`${ce} GROUP BY ${ze}`;const Bt=await I(s,u,ce),Qe=new Map;for(const Je of Bt)Qe.set(Je.__fk__,Number(Je.count??0));return Qe};let l=q(n.baseWhere,n.where);l=q(l,ue(i.softDeleteMode,n.includeDeleted)),l=await it(l,{fetcher:f,maxRelationKeys:p,relationBaseWhere:n.relationBaseWhere,schema:$,tableName:t}),r&&(l=l?{AND:[l,r]}:r);const E=fe(l,b),d=Cn(o,u);let w=e`SELECT * FROM ${e.identifier(t)}`;E&&(w=e`${w} WHERE ${E}`),w=e`${w} ORDER BY ${d}`;const y=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;y!==void 0&&(w=e`${w} LIMIT ${e.raw(String(y+1))}`);const R=await I(s,u,w),S=dt(i,R);if(y===void 0)return n.with&&await ot({fetcher:f,groupedCounter:h,parents:S,...rt(n),schema:$,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:st(S,n.select,n.with)};const C=S.length>y,A=C?S.slice(0,y):S,F=A.at(-1);return n.with&&await ot({fetcher:f,groupedCounter:h,parents:A,...rt(n),schema:$,tableName:t,with:n.with}),{continueCursor:C&&F?rn(F,o):null,isDone:!C,page:st(A,n.select,n.with)}},async get(t,n){const i=await ne(t,n);if(!i)return null;const o=$.tables[i];return o?Z(o,await Dt.load(i,t)):null},async groupBy(t,n){const i=$.tables[t];if(!i)throw new T("INTERNAL",`unknown table: ${t}`);await U();const o=n.agg??{op:"count"};if(le(o.op),o.op!=="count"&&!o.field)throw new T("INTERNAL",`groupBy(${t}, { agg: { op: "${o.op}" } }): "field" is required for non-count reducers`);const r=ue(i.softDeleteMode,void 0),f=q(q(n.baseWhere,n.where),r),h=await ge(f,t,n.relationBaseWhere),l=h!==f;if(i.aggregateIndexes&&!n.baseWhere&&!l&&!r){const S=await Mt(t,i.aggregateIndexes,o,n);if(S!==void 0)return S}Un(i,t,n.by,o);const E=fe(h,b),d=n.by.map(S=>e`${O(S)} AS ${e.identifier(S)}`);if(o.op==="count")d.push(e`COUNT(*) AS ${e.identifier("value")}`);else{if(!o.field)throw new T("INTERNAL",`groupBy(${t}, { agg: { op: "${o.op}" } }): "field" is required for non-count reducers`);d.push(e`${e.raw(le(o.op))}(${O(o.field)}) AS ${e.identifier("value")}`)}const w=e.join(n.by.map(S=>O(S)),e`, `);let y=e`SELECT ${e.join(d,e`, `)} FROM ${e.identifier(t)}`;E&&(y=e`${y} WHERE ${E}`),y=e`${y} GROUP BY ${w}`;const R=await I(s,u,y);return Nn(n.by,R)},async insert(t,n,i){const o=$.tables[t];if(!o)throw new T("INTERNAL",`unknown table: ${t}`);await U();const r=An(o,n,V);Ne(o,r);let f,h=!0;i?.clientId!==void 0?(en(i.clientId),f=i.clientId):i?.allowExplicitId&&typeof r._id=="string"?f=r._id:(f=M(),h=!1);const l=i?.allowExplicitId&&typeof r._creationTime=="number"?r._creationTime:m(),E={...r,_creationTime:l,_id:f};H(t,"before","insert")&&await K("before","insert",{doc:{...E},id:f,op:"insert",table:t}),await ye(t),await pe(t);const{columns:d,values:w}=kt(o,f,l,r);return await Lt(t,e`INSERT INTO ${e.identifier(t)} (${J(d)}) VALUES (${te(w)})`),h&&Le.set(f,t),await oe(t,void 0,E),await X(t,f,void 0,E),await se(t,f,E),await P(t,f,"insert",E),H(t,"after","insert")&&await K("after","insert",{doc:E,id:f,op:"insert",table:t}),f},normalizeId(t,n){return Zt($,t,n)},async patch(t,n,i){Ze("patch",n);const o=await ne(t,i);if(!o)throw new T("INTERNAL",`document not found: ${t}`);const r=$.tables[o];if(!r)throw new T("INTERNAL",`document not found: ${t}`);const f=await Re(o,t),h=Z(r,f);if(!h)throw new T("INTERNAL",`document not found: ${t}`);const l={...h,...n,_id:t};_t(r,n,l,V),Ne(r,l,!0),H(o,"before","update")&&await K("before","update",{doc:{...l},id:t,op:"update",previous:h,table:o}),await ye(o),await pe(o);const E=Object.keys(r.shape),d=e.join(E.map(w=>e`${e.identifier(w)} = ${be(r,w,l[w]??null)}`),e`, `);await Se(o,"UPDATE",d,f),await oe(o,h,l),await X(o,t,h,l),await se(o,t,l,h),await P(o,t,"update",l),H(o,"after","update")&&await K("after","update",{doc:l,id:t,op:"update",previous:h,table:o})},async restore(t,n){const i=await ne(t,n);if(!i)throw new T("INTERNAL",`document not found: ${t}`);const o=$.tables[i],r=o?.softDeleteMode?.field;if(!o||!r)throw new T("INTERNAL",`ctx.db.restore: table "${i}" is not a .softDelete() table`);const f=await Re(i,t),h=f?.[r]!==null&&f?.[r]!==void 0;if(await x.patch(t,{[r]:null},n),h){const l=Z(o,f);l!==null&&await X(i,t,void 0,{...l,[r]:null})}},query(t){const n=$.tables[t];if(!n)throw new T("INTERNAL",`unknown table: ${t}`);const i="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",o=[],r=l=>o.every(E=>E(l)),f=async(l,E)=>{await U();const d=o.length>0,w=await Ht(s,u,n,t,l,Kt(d?void 0:E));if(!d)return E===void 0&&jt(w),w;const y=w.filter(R=>r(R));return E===void 0?y:y.slice(0,E)},h=l=>{const E={async*[Symbol.asyncIterator](){if(!l)throw new T("INTERNAL",i);yield*await f(l,void 0)},async collect(){if(!l)throw new T("INTERNAL",i);return f(l,void 0)},async collectWithScores(){throw new T("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(d){return o.push(d),E},async first(){if(!l)throw new T("INTERNAL",i);return(await f(l,1))[0]??null},order(){return E},async paginate(d){if(!l)throw new T("INTERNAL",i);const w=xt(d);return Pt(await f(l,Gt(w)),w)},async take(d){if(!l)throw new T("INTERNAL",i);return f(l,d)},async unique(){if(!l)throw new T("INTERNAL",i);const d=await f(l,2);if(d.length>1)throw new En(`unique() on table "${t}" matched ${String(d.length)} documents; expected at most one`);return d[0]??null},withGeoIndex(){throw new T("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new T("INTERNAL",i)},withSearchIndex(d,w){const y=(n.searchIndexes??[]).find(S=>S.name===d);if(!y)throw new T("INTERNAL",`unknown search index "${d}" on table "${t}"`);const R={definition:y,field:y.field,filters:[],hasQuery:!1,indexName:d,query:""};if(w(Ut(R,t,Ot(y.language))),!R.hasQuery)throw new T("INTERNAL",`search index "${d}" on table "${t}" requires a .search(field, query) call`);return h(R)}};return E};return h(void 0)},async rank(t,n,i){const o=$.tables[t];if(!o)throw new T("INTERNAL",`unknown table: ${t}`);const r=o.rankIndexes?.find(B=>B.name===n);if(!r)throw new T("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(i.restrictsCounts)throw new nt(t);if(await U(),!await Me(t,r))return null;const h=typeof i.row=="string"?i.row:i.row._id;if(!h)return null;const l=de(t,r.name),E=r.sortBy.map((B,j)=>$e(j)),d=J(["__partition__",...E]),y=(await I(s,u,e`SELECT ${d} FROM ${e.identifier(l)} WHERE ${e.identifier("__id__")} = ${h}`))[0];if(!y)return null;const R=y.__partition__,S=q(i.baseWhere,i.where);et(S,$,t,"rank");const C=tt(r,S);if(C&&Ie(r.partitionBy??[],C)!==R)return null;const A=Bn(u.name,r,E,y,h),F=await I(s,u,e`SELECT COUNT(*) AS c FROM ${e.identifier(l)} WHERE ${e.identifier("__partition__")} = ${R} AND (${A})`),L=await I(s,u,e`SELECT COUNT(*) AS c FROM ${e.identifier(l)} WHERE ${e.identifier("__partition__")} = ${R}`);return{position:Number(F[0]?.c??0)+1,total:Number(L[0]?.c??0)}},async rankPage(t,n,i={}){et(q(i.baseWhere,i.where),$,t,"rankPage");const o=$.tables[t];if(!o)throw new T("INTERNAL",`unknown table: ${t}`);const r=o.rankIndexes?.find(D=>D.name===n);if(!r)throw new T("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await U(),!await Me(t,r))return{continueCursor:null,isDone:!0,page:[]};const h=de(t,r.name),l=r.sortBy.map((D,ae)=>$e(ae)),E=Math.max(1,Math.min(1e3,Math.floor(i.take??100))),d=q(i.baseWhere,i.where),w=tt(r,d),y=On(r,l),R=e.join(y.map(D=>e`${e.identifier(D.column)} ${e.raw(`${D.direction==="desc"?"DESC":"ASC"}${St(u,{direction:D.direction,nullable:D.nullable})}`)}`),e`, `),S=[];typeof i.partitionKey=="string"?S.push(e`${e.identifier("__partition__")} = ${i.partitionKey}`):w&&S.push(e`${e.identifier("__partition__")} = ${Ie(r.partitionBy??[],w)}`);const C=Jt(i);if(C!==void 0){const D=qn(u.name,y,C);D!==void 0&&S.push(D)}const A=J([_e,"__partition__",...l]);let F=e`SELECT ${A} FROM ${e.identifier(h)}`;S.length>0&&(F=e`${F} WHERE ${e.join(S,e` AND `)}`),F=e`${F} ORDER BY ${R} LIMIT ${e.raw(String(E+1))}`;const L=await I(s,u,F),B=L.length>E,j=B?L.slice(0,E):L,Te=j.map(D=>D[_e]),ve=await Wn(s,u,o,t,Te);let me=null;const z=j.at(-1);if(B&&z!==void 0){const D=[z.__partition__,...l.map(ae=>z[ae]),z[_e]];me=Fn(D)}return{continueCursor:me,isDone:!B,page:ve}},async replace(t,n,i,o){Ze("replace",n);const r=await ne(t,i);if(!r)throw new T("INTERNAL",`document not found: ${t}`);const f=$.tables[r];if(!f)throw new T("INTERNAL",`document not found: ${t}`);const h=await Re(r,t);if(h===void 0)throw new T("INTERNAL",`document not found: ${t}`);const E=Qt($,r,"update")||(f.aggregateIndexes??[]).length>0||(f.rankIndexes??[]).length>0?Z(f,h)??void 0:void 0,d=o?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:m(),w={...n,_creationTime:d,_id:t};_t(f,n,w,V),Ne(f,w),H(r,"before","update")&&await K("before","update",{doc:{...w},id:t,op:"update",previous:E,table:r}),await ye(r),await pe(r);const y=Object.keys(f.shape),R=e.join([e`${e.identifier("_creationTime")} = ${d}`,...y.map(S=>e`${e.identifier(S)} = ${be(f,S,w[S]??null)}`)],e`, `);await Se(r,"UPDATE",R,h),await oe(r,E,w),await X(r,t,E,w),await se(r,t,w,E),await P(r,t,"update",w),H(r,"after","update")&&await K("after","update",{doc:w,id:t,op:"update",previous:E,table:r})}};return je={db:x,scheduler:Ae},x};export{fi as backfillSqlSearchIndexes,di as createSqlCtxDb,$i as decodeGlobalRow,Xn as readSqlCdcChangedTables,ci as readSqlCdcChanges,mt as readSqlCdcFloor,Kn as runSqlCdcMigration,Ft as runSqlSearchMigrations,Gn as sweepSqlCdcRetention};