@lunora/sql-store 1.0.0-alpha.56 → 1.0.0-alpha.57

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 o,readSqlCdcChanges as a,runSqlAggregateMigrations as t,runSqlCdcMigration as i,runSqlGlobalTableMigrations as l,runSqlRankMigrations as n,trimSqlCdcChanges as S}from"./packem_shared/createSqlCtxDb-uMXeBDio.mjs";import{A as s,B as d}from"./packem_shared/ctx-db-search-CSETWaAQ.mjs";import{SEARCH_STATE_TABLE as q,migrateSearchState as f}from"./packem_shared/SEARCH_STATE_TABLE-CtJTyVzp.mjs";import{decodeBigint as C,effectiveColumnKind as x,sqliteDecode as u,sqliteEncode as b,tryJsonParse as h}from"./packem_shared/decodeBigint-DfiI8pkL.mjs";import{decodeGlobalRow as A}from"./packem_shared/decodeGlobalRow-DhFrSrmu.mjs";export{q as SEARCH_STATE_TABLE,s as backfillSqlSearchIndexes,o as createSqlCtxDb,C as decodeBigint,A as decodeGlobalRow,x as effectiveColumnKind,f as migrateSearchState,a as readSqlCdcChanges,t as runSqlAggregateMigrations,i as runSqlCdcMigration,l as runSqlGlobalTableMigrations,n as runSqlRankMigrations,d as runSqlSearchMigrations,u as sqliteDecode,b as sqliteEncode,S as trimSqlCdcChanges,h as tryJsonParse};
1
+ import{createSqlCtxDb as o,readSqlCdcChanges as a,runSqlAggregateMigrations as t,runSqlCdcMigration as i,runSqlGlobalTableMigrations as l,runSqlRankMigrations as n,trimSqlCdcChanges as S}from"./packem_shared/createSqlCtxDb-DQTpO_JA.mjs";import{A as s,B as d}from"./packem_shared/ctx-db-search-CSETWaAQ.mjs";import{SEARCH_STATE_TABLE as q,migrateSearchState as f}from"./packem_shared/SEARCH_STATE_TABLE-CtJTyVzp.mjs";import{decodeBigint as C,effectiveColumnKind as x,sqliteDecode as u,sqliteEncode as b,tryJsonParse as h}from"./packem_shared/decodeBigint-DfiI8pkL.mjs";import{decodeGlobalRow as A}from"./packem_shared/decodeGlobalRow-DhFrSrmu.mjs";export{q as SEARCH_STATE_TABLE,s as backfillSqlSearchIndexes,o as createSqlCtxDb,C as decodeBigint,A as decodeGlobalRow,x as effectiveColumnKind,f as migrateSearchState,a as readSqlCdcChanges,t as runSqlAggregateMigrations,i as runSqlCdcMigration,l as runSqlGlobalTableMigrations,n as runSqlRankMigrations,d as runSqlSearchMigrations,u as sqliteDecode,b as sqliteEncode,S as trimSqlCdcChanges,h as tryJsonParse};
@@ -0,0 +1 @@
1
+ import{LunoraError as N}from"@lunora/errors";import{F as ht,B as pt,T as mt,a as Et,N as yt,_ as gt,v as bt,D as Nt,b as vt,C as Tt}from"./ctx-db-search-CSETWaAQ.mjs";import{A as Ai}from"./ctx-db-search-CSETWaAQ.mjs";import{aggregateTableName as z,rankTableName as X,hasTrigger as Rt,runRowValidators as Ie,assertFlatPredicate as ze,mergeWhere as q,sortColumnName as Q,resolveRankPartition as Qe,encodePartitionKey as be,decodeCursor as Je,RANK_TIEBREAK as $e,CountRlsUnsupportedError as Xe,normalizeIdStructurally as St,assertValidClientId as At,aggregateSqlFunction as de,softDeleteScope as le,compileWhereSql as ue,normalizeOrderKeys as It,buildSeekWhere as Lt,resolveRelationPredicates as Ze,resolveWith as et,applySelect as tt,encodeCursor as Ot,NotFoundError as Ct,applyOnDelete as kt,ConflictError as fe,normalizeCountArgument as xt,selectIndexForCount as Mt,encodeAggregateKey as V,selectIndexForAggregate as Dt,readAggregateValue as Le,runTriggers as qt,matchesRankStaticWhere as it,selectIndexForGroupBy as Wt,fanOutScalarCounts as jt,matchesStaticWhere as Oe,foldAggregateTally as Bt,coerceAggregateNumber as Ce,NotUniqueError as Ft,throwingScheduler as Ut}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{migrateSearchState as Pt}from"./SEARCH_STATE_TABLE-CtJTyVzp.mjs";import{queryAll as A,queryRun as I,createIndexIfNotExists as xe,decodeRow as Z,serializeColumnValue as H,columnRefSql as x,decodeRows as Ht,forEachRowPaged as nt}from"./decodeGlobalRow-DhFrSrmu.mjs";import{decodeGlobalRow as Li}from"./decodeGlobalRow-DhFrSrmu.mjs";import{effectiveColumnKind as Ne}from"./decodeBigint-DfiI8pkL.mjs";const Kt=(u,w)=>{if(u.size<w)return;const $=u.keys().next().value;$!==void 0&&u.delete($)},Vt=(u,w={})=>{const $=w.maxBatch??50,o=Number.isInteger($)&&$>0?$:50,E=new Map;let l=!1;const c=async(y,T)=>{const R=[...T.keys()];for(let O=0;O<R.length;O+=o){const M=R.slice(O,O+o);try{const j=await u(y,M);for(const K of M){const B=j.get(K);for(const Te of T.get(K)??[])Te.resolve(B)}}catch(j){for(const K of M)for(const B of T.get(K)??[])B.reject(j)}}},v=()=>{l=!1;const y=[...E.entries()];E.clear();for(const[T,R]of y)c(T,R).catch(()=>{})};return{async load(y,T){return new Promise((R,O)=>{let M=E.get(y);M||(M=new Map,E.set(y,M));const j=M.get(T);j?j.push({reject:O,resolve:R}):M.set(T,[{reject:O,resolve:R}]),l||(l=!0,queueMicrotask(v))})}}},Gt=new Set(["_id","id"]),Me=(u,w,$)=>u==="postgres"?e`${w} IS NOT DISTINCT FROM ${$}`:u==="mysql"?e`${w} <=> ${$}`:e`${w} IS ${$}`,Yt=u=>{const w=u.map($=>e`${x($.field)} ${e.raw($.direction==="desc"?"DESC":"ASC")}`);return u.some($=>Gt.has($.field))||w.push(e`${x("id")} ASC`),e.join(w,e`, `)},at=50,De=u=>{const w=[];for(const[$,o]of Object.entries(u.shape)){const E=o._meta?.column;E&&w.push([$,E])}return w},zt=(u,w,$)=>{const o={...w};for(const[E,l]of De(u)){if(l.serverDefault){o[E]=l.serverDefault({auth:$});continue}o[E]===void 0&&(l.defaultFn?o[E]=l.defaultFn():"defaultValue"in l&&(o[E]=l.defaultValue))}return o},ot=(u,w,$,o)=>{for(const[E,l]of De(u)){if(l.serverDefault){E in w&&($[E]=l.serverDefault({auth:o}));continue}l.onUpdateFn&&!(E in w)&&($[E]=l.onUpdateFn())}},Qt=128,Jt=()=>{const u=new Map;return{delete:w=>{u.delete(w)},get:w=>{const $=u.get(w);if($!==void 0)return u.delete(w),u.set(w,$),$},set:(w,$)=>{u.has(w)?u.delete(w):Kt(u,Qt),u.set(w,$)}}},Xt=async(u,w,$,o,E)=>{const l=E.get(o);if(l!==void 0)return l;const c=[];for(const[y,T]of Object.entries($.tables))T.shardMode!==void 0&&T.shardMode.kind!=="global"||c.push(y);const v=await Promise.all(c.map(async y=>({found:(await A(u,w,e`SELECT 1 FROM ${e.identifier(y)} WHERE ${e.identifier("id")} = ${o} LIMIT 1`)).length>0,tableName:y})));for(const y of v)if(y.found)return E.set(o,y.tableName),y.tableName},ee=u=>u==null?null:Number(u),Zt=(u,w)=>w.map($=>{const o={};for(const E of u)o[E]=$[E]??null;return{key:o,value:ee($.value)}}),ei=(u,w,$)=>[...u.partitionBy??[],...u.sortBy.map(o=>o.field),...u.where?Object.keys(u.where):[]].every(o=>w[o]===$[o]),rt=u=>u.length===1?u[0]:e`(${e.join(u,e` AND `)})`,ti=(u,w,$,o,E)=>{const l=[];for(let c=0;c<$.length+1;c+=1){const v=$.slice(0,c).map(R=>Me(u,e`${e.identifier(R)}`,o[R])),y=$[c],T=w.sortBy[c];c<$.length&&y!==void 0&&T!==void 0?v.push(e`${e.identifier(y)} ${e.raw(T.direction==="desc"?">":"<")} ${o[y]}`):v.push(e`${e.identifier($e)} < ${E}`),l.push(rt(v))}return l.length>0?e.join(l,e` OR `):void 0},ii=(u,w,$)=>{if($.length!==w.length)return;const o=[];for(const[E,l]of w.entries()){const c=[];for(let v=0;v<E;v+=1){const y=w[v];y!==void 0&&c.push(Me(u,e`${e.identifier(y.column)}`,$[v]))}c.push(e`${e.identifier(l.column)} ${e.raw(l.direction==="desc"?"<":">")} ${$[E]}`),o.push(rt(c))}return e`(${e.join(o,e` OR `)})`},ni=(u,w)=>{if(u.sortBy.length===0)throw new N("INTERNAL",`rankIndex "${u.name}" requires at least one "sortBy" column for stable pagination`);const $=[{column:"__partition__",direction:"asc"}];for(const[o,E]of u.sortBy.entries())$.push({column:w[o]??Q(o),direction:E.direction});return $.push({column:$e,direction:"asc"}),$},ai=async(u,w,$,o,E)=>{const l=[];for(let T=0;T<E.length;T+=50)l.push(E.slice(T,T+50));const c=await Promise.all(l.map(async T=>{const R=e.join(T.map(O=>e`${O}`),e`, `);return A(u,w,e`SELECT * FROM ${e.identifier(o)} WHERE ${e.identifier("id")} IN (${R})`)})),v=new Map;for(const T of c)for(const R of T)v.set(R.id,R);const y=[];for(const T of E){const R=Z($,v.get(T));R&&y.push(R)}return y},oi=u=>{const w=JSON.stringify(u),$=new TextEncoder().encode(w);let o="";for(const E of $)o+=String.fromCodePoint(E);return btoa(o)},ri=(u,w)=>w.columnType(Ne(u)),si=(u,w)=>{const $=[];for(const[E,l]of Object.entries(u.shape)){if(!l._meta?.column)continue;const c=l._meta.column.notNull&&l.kind!=="optional"?" NOT NULL":"";$.push(e`${e.identifier(E)} ${e.raw(`${ri(l,w)}${c}`)}`)}const o=w.frameworkColumns().map(E=>e`${e.identifier(E.name)} ${e.raw(E.type)}`);return e.join([...o,...$],e`, `)},ci=async(u,w,$,o)=>{const E=l=>{const c=x(l),v=$.shape[l],y=v&&o.indexKeyPrefix?o.indexKeyPrefix(Ne(v)):void 0;return y===void 0?c:e`${c}(${e.raw(String(y))})`};for(const l of $.indexes){const c=e.join(l.fields.map(v=>E(v)),e`, `);await xe(u,o,{columns:c,name:`${w}_${l.name}`,table:w,unique:l.unique??!1})}for(const[l,c]of De($))c.unique&&await xe(u,o,{columns:E(l),name:`${w}_unique_${l}`,table:w,unique:!0})},di=async(u,w,$)=>{for(const[o,E]of Object.entries(w.tables)){if(E.shardMode?.kind!=="global")continue;const l=si(E,$);await I(u,$,e`CREATE TABLE IF NOT EXISTS ${e.identifier(o)} (${l})`),await ci(u,o,E,$)}},li=async(u,w,$)=>{const{integer:o,key:E,real:l}=$.companionTypes;for(const[c,v]of Object.entries(w.tables)){const y=v.aggregateIndexes;if(!(!y||y.length===0))for(const T of y){const R=z(c,T.name);await I(u,$,e`CREATE TABLE IF NOT EXISTS ${e.identifier(R)} (${e.identifier("__key__")} ${e.raw(E)} PRIMARY KEY, ${e.identifier("__value__")} ${e.raw(l)}, ${e.identifier("__count__")} ${e.raw(o)} NOT NULL DEFAULT 0)`),$.name==="sqlite"&&((await A(u,$,e`PRAGMA table_info(${e.identifier(R)})`)).some(O=>O.name==="__count__")||await I(u,$,e`ALTER TABLE ${e.identifier(R)} ADD COLUMN ${e.identifier("__count__")} ${e.raw(o)} NOT NULL DEFAULT 0`))}}},ke=(u,w,$,o)=>{const E=u.name==="mysql"&&o?e`${e.identifier(w)}(191)`:e`${e.identifier(w)}`;return e`${E} ${e.raw($)}`},ui=(u,w,$)=>{const o=[ke(u,"__partition__","ASC",!0)];for(const[E,l]of w.sortBy.entries()){const c=$.shape[l.field],v=c!==void 0&&u.indexKeyPrefix?.(Ne(c))!==void 0;o.push(ke(u,Q(E),l.direction==="desc"?"DESC":"ASC",v))}return o.push(ke(u,"__id__","ASC",!0)),o},fi=(u,w,$)=>w.sortBy.map((o,E)=>{const l=$.shape[o.field],c=u.columnType(l?Ne(l):void 0);return e`${e.identifier(Q(E))} ${e.raw(c)}`}),$i=async(u,w,$)=>{const{key:o}=$.companionTypes;for(const[E,l]of Object.entries(w.tables)){const c=l.rankIndexes;if(!(!c||c.length===0))for(const v of c){const y=X(E,v.name),T=fi($,v,l),R=T.length>0?e`, ${e.join(T,e`, `)}`:e``;await I(u,$,e`CREATE TABLE IF NOT EXISTS ${e.identifier(y)} (${e.identifier("__id__")} ${e.raw(o)} PRIMARY KEY, ${e.identifier("__partition__")} ${e.raw(o)} NOT NULL${R})`);const O=ui($,v,l),M=`${E}__rank_${v.name}__btree`;await xe(u,$,{columns:e.join(O,e`, `),name:M,table:y,unique:!1})}}},ve="__cdc_log",wi=async(u,w)=>{const{autoincrementPrimaryKey:$,key:o,real:E,text:l}=w.companionTypes;await I(u,w,e`CREATE TABLE IF NOT EXISTS ${e.identifier(ve)} (${e.identifier("seq")} ${e.raw($)}, ${e.identifier("ts")} ${e.raw(E)} NOT NULL, ${e.identifier("table")} ${e.raw(o)} NOT NULL, ${e.identifier("id")} ${e.raw(o)} NOT NULL, ${e.identifier("op")} ${e.raw(o)} NOT NULL, ${e.identifier("doc")} ${e.raw(l)})`)},_i=async(u,w,$,o,E,l,c)=>{await I(u,c,e`INSERT INTO ${e.identifier(ve)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${w}, ${$}, ${o}, ${E}, ${l===void 0?null:JSON.stringify(l)})`)},Ni=async(u,w,$)=>{const o=w.sinceSeq??0,E=Math.max(1,Math.min(w.limit??1e3,1e4)),l=(await A(u,$,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(ve)} WHERE seq > ${o} ORDER BY seq ASC LIMIT ${e.raw(String(E))}`)).map(c=>{const{doc:v}=c,y={id:String(c.id),op:String(c.op),seq:Number(c.seq),table:String(c.table),ts:Number(c.ts)};return typeof v=="string"?{...y,doc:JSON.parse(v)}:y});return{changes:l,cursor:l.at(-1)?.seq??o}},vi=async(u,w,$)=>{await I(u,$,e`DELETE FROM ${e.identifier(ve)} WHERE ${e.identifier("seq")} <= ${w}`)},Ti=u=>{const{crossShardCounter:w,crossShardReader:$,exec:o,maxRelationKeys:E,schema:l}=u,{dialect:c}=u,{isUniqueViolation:v}=c,y={fieldRef:x,serialize:H,...c.name==="mysql"?{likeContains:(t,i)=>e`${t} LIKE CONCAT('%', ${i}, '%') ESCAPE '\\\\'`}:{}},T=(t,i)=>Me(c.name,t,i),R=t=>{const i=e.join(t.columns.map(d=>e`${e.identifier(d)}`),e`, `),n=e.join(t.values.map(d=>e`${d}`),e`, `),a=d=>c.name==="mysql"?e`VALUES(${e.identifier(d)})`:e`excluded.${e.identifier(d)}`,r=d=>c.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(d)}`:e`${e.identifier(d)}`,f=e.join(Object.entries(t.set(a,r)).map(([d,h])=>e`${e.identifier(d)} = ${h}`),e`, `),_=c.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)} (${i}) VALUES (${n}) ${_}`},O=u.clock??(()=>Date.now()),M=u.idGenerator??(()=>crypto.randomUUID()),j=u.cdc??!1,K=u.auth??{identity:null,userId:null},B=async(t,i,n,a)=>{j&&await _i(o,O(),t,i,n,a,c)},Te=u.scheduler??Ut,Re=Jt();let we=0,Se;const F=async()=>(Se??=(async()=>{await di(o,l,c),await li(o,l,c),await $i(o,l,c),await Pt(o,c),await pt(o,l,c),j&&await wi(o,c)})().catch(t=>{throw Se=void 0,t}),Se),te=async(t,i)=>{await F();const n=await Xt(o,c,l,t,Re);if(!(i!==void 0&&n!==i))return n},ie=new Map,qe=async(t,i)=>{const n=z(t,i);return(await A(o,c,c.tableExists(n))).length>0},_e=async(t,i)=>{const n=`${t}::${i.name}`,a=ie.get(n);if(a!==void 0)return a;if(!await qe(t,i.name))return ie.set(n,!1),!1;const r=l.tables[t];if(!r)return ie.set(n,!1),!1;const f=i.by??[],_=new Map;await nt(o,c,r,t,h=>{if(i.where&&!Oe(h,i.where))return;const s=V(f,h);Bt(_,s,i,h)});const d=z(t,i.name);await I(o,c,e`DELETE FROM ${e.identifier(d)}`);for(const[h,s]of _)await I(o,c,e`INSERT INTO ${e.identifier(d)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${h}, ${s.value}, ${s.count})`);return ie.set(n,!0),!0},st=async(t,i,n)=>{const a=de(i.op),r=i.field??"",f=[];for(const h of i.by??[]){const s=H(n[h]??null);f.push(s===null?e`${x(h)} IS NULL`:e`${x(h)} = ${s}`)}for(const[h,s]of Object.entries(i.where??{})){const p=s!==null&&typeof s=="object"&&!Array.isArray(s)?s.eq:s,m=H(p);f.push(m===null?e`${x(h)} IS NULL`:e`${x(h)} = ${m}`)}const _=e`SELECT ${e.raw(a)}(${x(r)}) AS value FROM ${e.identifier(t)}`,d=await A(o,c,f.length>0?e`${_} WHERE ${e.join(f,e` AND `)}`:_);return ee(d[0]?.value)},We=async(t,i)=>{await I(o,c,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${i} AND ${e.identifier("__count__")} <= 0`)},ct=async(t,i,n,a)=>{const r=z(t,i.name),{op:f}=i,_=i.field??"",d=n&&(!i.where||Oe(n,i.where))?n:void 0,h=a&&(!i.where||Oe(a,i.where))?a:void 0;if(!(!d&&!h)){if(f==="count"){const s=new Set;for(const[p,m]of[[d,-1],[h,1]]){if(!p)continue;const g=V(i.by??[],p);s.add(g),await I(o,c,R({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(b,S)=>({__count__:e`${S("__count__")} + ${b("__count__")}`,__value__:e`${S("__value__")} + ${b("__value__")}`}),table:r,values:[g,m,m]}))}for(const p of s)await We(r,p);return}if(f==="sum"||f==="avg"){const s=new Set;for(const[p,m]of[[d,-1],[h,1]]){if(!p)continue;const g=Ce(p[_]);if(g===void 0)continue;const b=V(i.by??[],p);s.add(b),await I(o,c,R({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,k)=>({__count__:e`${k("__count__")} + ${S("__count__")}`,__value__:e`COALESCE(${k("__value__")}, 0) + ${S("__value__")}`}),table:r,values:[b,m*g,m]}))}for(const p of s)await We(r,p);return}if(d){const s=V(i.by??[],d),p=Ce(d[_]),m=(await A(o,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${s}`))[0],g=ee(m?.value),b=(m?.count??0)-1;if(b<=0)await I(o,c,e`DELETE FROM ${e.identifier(r)} WHERE ${e.identifier("__key__")} = ${s}`);else if(m&&p!==void 0&&g!==null&&p===g){const S=await st(t,i,d);await I(o,c,e`UPDATE ${e.identifier(r)} SET ${e.identifier("__value__")} = ${S}, ${e.identifier("__count__")} = ${b} WHERE ${e.identifier("__key__")} = ${s}`)}else await I(o,c,e`UPDATE ${e.identifier(r)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${s}`)}if(h){const s=V(i.by??[],h),p=Ce(h[_]);if(p===void 0)await I(o,c,R({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(m,g)=>({__count__:e`${g("__count__")} + 1`}),table:r,values:[s,null,1]}));else{const m=f==="min"?"MIN":"MAX";await I(o,c,R({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(g,b)=>({__count__:e`${b("__count__")} + 1`,__value__:e`${e.raw(m)}(COALESCE(${b("__value__")}, ${g("__value__")}), ${g("__value__")})`}),table:r,values:[s,p,1]}))}}}},he=async t=>{const i=l.tables[t]?.aggregateIndexes;if(!(!i||i.length===0))for(const n of i)await _e(t,n)},ne=async(t,i,n)=>{const a=l.tables[t]?.aggregateIndexes;if(!(!a||a.length===0))for(const r of a){const f=`${t}::${r.name}`;(ie.get(f)??await qe(t,r.name))&&await ct(t,r,i,n)}},ae=new Map,je=async(t,i)=>{const n=X(t,i);return(await A(o,c,c.tableExists(n))).length>0},Ae=async(t,i)=>{const n=`${t}::rank::${i.name}`,a=ae.get(n);if(a!==void 0)return a;if(!await je(t,i.name))return ae.set(n,!1),!1;const r=l.tables[t];if(!r)return ae.set(n,!1),!1;const f=X(t,i.name);await I(o,c,e`DELETE FROM ${e.identifier(f)}`);const _=i.sortBy.map((s,p)=>Q(p)),d=e.join(["__id__","__partition__",..._].map(s=>e`${e.identifier(s)}`),e`, `),h=[];await nt(o,c,r,t,s=>{if(i.where&&!it(s,i.where))return;const p=be(i.partitionBy??[],s),m=i.sortBy.map(g=>H(s[g.field]??null));h.push([s._id,p,...m])});for(const s of h){const p=e.join(s.map(m=>e`${m}`),e`, `);await I(o,c,e`INSERT INTO ${e.identifier(f)} (${d}) VALUES (${p})`)}return ae.set(n,!0),!0},pe=async t=>{const i=l.tables[t]?.rankIndexes;if(!(!i||i.length===0))for(const n of i)await Ae(t,n)},J=async(t,i,n,a)=>{const r=l.tables[t],f=r?.rankIndexes;if(!f||f.length===0)return;const _=r?.softDeleteMode?.field,d=_===void 0||a===void 0?void 0:a[_],h=d!=null;for(const s of f){if(n!==void 0&&a!==void 0&&ei(s,n,a))continue;const p=`${t}::rank::${s.name}`;if(!(ae.get(p)??await je(t,s.name)))continue;const m=X(t,s.name);if(n&&await I(o,c,e`DELETE FROM ${e.identifier(m)} WHERE ${e.identifier("__id__")} = ${i}`),a&&!h){if(s.where&&!it(a,s.where))continue;const g=s.sortBy.map((L,G)=>Q(G)),b=e.join(["__id__","__partition__",...g].map(L=>e`${e.identifier(L)}`),e`, `),S=be(s.partitionBy??[],a),k=s.sortBy.map(L=>H(a[L.field]??null)),D=e.join([i,S,...k].map(L=>e`${L}`),e`, `);await I(o,c,e`INSERT INTO ${e.identifier(m)} (${b}) VALUES (${D})`)}}},oe=ht({dialect:c,exec:o,schema:l}),Be=new Set;for(const[t,i]of Object.entries(l.tables))for(const n of Object.values(i.triggerMap??{}))Be.add(`${t} ${n.timing} ${n.op}`);const U=(t,i,n)=>Be.has(`${t} ${i} ${n}`);let Fe;const P=async(t,i,n)=>{if(we+=1,we>at)throw we-=1,new fe(`trigger recursion exceeded ${String(at)} levels on "${n.table}" — check for a self-triggering write`,"trigger");try{await qt({ctx:Fe,event:n,op:i,schema:l,tableName:n.table,timing:t})}finally{we-=1}},dt=async(t,i)=>{try{await I(o,c,i)}catch(n){throw v(n)?new fe(`unique constraint violation on "${t}"`,"unique"):n}},me=async(t,i)=>(await A(o,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${i}`))[0],Ee=async(t,i,n,a)=>{if(a===void 0)return;const r=e.join(Object.keys(a).map(d=>T(e`${e.identifier(d)}`,a[d])),e` AND `),f=i==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${n} WHERE ${r}`:e`DELETE FROM ${e.identifier(t)} WHERE ${r}`,_=()=>{throw new fe(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(c.supportsReturning)(await A(o,c,e`${f} RETURNING ${e.identifier("id")}`)).length===0&&_();else{const d=await I(o,c,f);(c.affectedRows?c.affectedRows(d??{rowsAffected:0}):0)===0&&_()}}catch(d){throw v(d)?new fe(`unique constraint violation on "${t}"`,"unique"):d}},lt=(t,i,n,a)=>{const r=Object.keys(t.shape);return{columns:["id","_creationTime",...r],values:[i,n,...r.map(f=>H(a[f]??null))]}},ut=async(t,i,n,a)=>{const r=Wt(i,n.op,n.field,a.by,a.where);if(!r||!await _e(t,r.index))return;const f=z(t,r.index.name),_=Object.keys(r.partial);if(_.length===(r.index.by??[]).length&&_.length>0){const d=V(r.index.by??[],r.partial),h=await A(o,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(f)} WHERE ${e.identifier("__key__")} = ${d}`);if(h.length===0)return[];const s=h[0];return[{key:{...r.partial},value:Le(n.op,{count:s.count,value:ee(s.value)})}]}return _.length>0?void 0:(await A(o,c,e`SELECT ${e.identifier("__key__")} AS key, ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(f)}`)).map(d=>{const h=d;return{key:JSON.parse(h.key),value:Le(n.op,{count:h.count,value:ee(h.value)})}})},Ue=t=>{const i=l.tables[t]?.shardMode?.kind;return i==="shardBy"||i==="root"},Pe=t=>{throw new N("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`)},He=(t,i)=>Ue(t)?$?$(t,i):Pe(t):W.findMany(t,i),ye=(t,i,n)=>Ze(t,{fetcher:He,maxRelationKeys:E,relationBaseWhere:n,schema:l,tableName:i}),ft=Vt(async(t,i)=>{const n=e.join(i.map(f=>e`${f}`),e`, `),a=await A(o,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${n})`),r=new Map;for(const f of a){const{id:_}=f;typeof _=="string"&&r.set(_,f)}return r}),W={async aggregate(t,i){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);if(await F(),de(i.op),i.op==="count")return W.count(t,{baseWhere:i.baseWhere,relationBaseWhere:i.relationBaseWhere,restrictsCounts:i.restrictsCounts,where:i.where});if(!i.field)throw new N("INTERNAL",`aggregate(${t}, { op: "${i.op}" }): "field" is required for non-count reducers`);const a=le(n.softDeleteMode,void 0),r=q(q(i.baseWhere,i.where),a),f=await ye(r,t,i.relationBaseWhere),_=f!==r;if(n.aggregateIndexes&&!i.baseWhere&&!_&&!a){const m=Dt(n.aggregateIndexes,i.op,i.field,i.where);if(m&&await _e(t,m.index)){const g=V(m.index.by??[],m.key),b=z(t,m.index.name),S=(await A(o,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(b)} WHERE ${e.identifier("__key__")} = ${g}`))[0];return Le(i.op,S===void 0?void 0:{count:S.count,value:ee(S.value)})}}const d=ue(f,y),h=e.raw(de(i.op)),s=e`SELECT ${h}(${x(i.field)}) AS value FROM ${e.identifier(t)}`,p=(await A(o,c,d?e`${s} WHERE ${d}`:s))[0]?.value;return p==null?null:Number(p)},async count(t,i){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);await F();const a=xt(i);if(a.restrictsCounts)throw new Xe(t);const r=le(n.softDeleteMode,void 0),f=q(q(a.baseWhere,a.where),r),_=await ye(f,t,a.relationBaseWhere),d=_!==f;if(n.aggregateIndexes&&!a.baseWhere&&!d&&!r){const m=Mt(n.aggregateIndexes,a.where);if(m&&await _e(t,m.index)){const g=V(m.index.by??[],m.key),b=z(t,m.index.name),S=await A(o,c,e`SELECT ${e.identifier("__value__")} AS value FROM ${e.identifier(b)} WHERE ${e.identifier("__key__")} = ${g}`);return Number(S[0]?.value??0)}}const h=ue(_,y),s=e`SELECT COUNT(*) AS count FROM ${e.identifier(t)}`,p=await A(o,c,h?e`${s} WHERE ${h}`:s);return Number(p[0]?.count??0)},async delete(t,i,n){const a=await te(t,i);if(!a)return;const r=l.tables[a];if(!r)return;const f=await me(a,t),_=Z(r,f),d=n?.hard===!0,h=!d&&r.softDeleteMode?r.softDeleteMode.field:void 0;if(!(h&&(!_||_[h]!==null&&_[h]!==void 0))){if(U(a,"before","delete")&&await P("before","delete",{id:t,op:"delete",previous:_??void 0,table:a}),await kt({deletedId:t,deletedReference:s=>_?.[s],findHolders:async(s,p,m)=>{if(l.tables[s]?.shardMode?.kind==="shardBy")throw new N("INTERNAL",`cross-backend cascade from global '${a}' into shardBy '${s}' is not supported — would require Query Coordinator fan-out across shards`);return(await W.findMany(s,{includeDeleted:d,where:{[p]:m}})).page},onCascade:(s,p)=>W.delete(p,void 0,n),onRestrict:s=>{throw new fe(s,"restrict")},onSetNull:(s,p,m)=>W.patch(p,{[m]:null}),schema:l,tableName:a}),await he(a),await pe(a),h&&_){const s={..._,[h]:O()},p=e.join(Object.keys(r.shape).map(m=>e`${e.identifier(m)} = ${H(s[m]??null)}`),e`, `);await Ee(a,"UPDATE",p,f),await ne(a,_,s),await J(a,t,_,void 0),await oe(a,t,s,_),await B(a,t,"update",s),U(a,"after","delete")&&await P("after","delete",{id:t,op:"delete",previous:_,table:a});return}await Ee(a,"DELETE",void 0,f),Re.delete(t),await ne(a,_??void 0,void 0),await J(a,t,_??void 0,void 0),await oe(a,t,void 0),await B(a,t,"delete"),U(a,"after","delete")&&await P("after","delete",{id:t,op:"delete",previous:_??void 0,table:a})}},async findFirst(t,i={}){return(await W.findMany(t,{...i,limit:1})).page[0]??null},async findFirstOrThrow(t,i={}){const n=await W.findFirst(t,i);if(n===null)throw new Ct(`findFirstOrThrow: no "${t}" document matched`);return n},async findMany(t,i={}){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);await F();const a=It(i.orderBy),r=i.cursor?Lt(a,Je(i.cursor)):void 0,f=He,_=async(L,G,ge,re)=>{if(Ue(L))return w?jt(w,L,G,ge,re):Pe(L);const Y=l.tables[L];if(!Y)throw new N("INTERNAL",`unknown table: ${L}`);const C=le(Y.softDeleteMode,void 0),se={[G]:{in:ge}},$t=q(q(se,re),C),wt=await ye($t,L,void 0),Ke=ue(wt,y),Ve=x(G);let ce=e`SELECT ${Ve} AS __fk__, COUNT(*) AS count FROM ${e.identifier(L)}`;Ke&&(ce=e`${ce} WHERE ${Ke}`),ce=e`${ce} GROUP BY ${Ve}`;const _t=await A(o,c,ce),Ge=new Map;for(const Ye of _t)Ge.set(Ye.__fk__,Number(Ye.count??0));return Ge};let d=q(i.baseWhere,i.where);d=q(d,le(n.softDeleteMode,i.includeDeleted)),d=await Ze(d,{fetcher:f,maxRelationKeys:E,relationBaseWhere:i.relationBaseWhere,schema:l,tableName:t}),r&&(d=d?{AND:[d,r]}:r);const h=ue(d,y),s=Yt(a);let p=e`SELECT * FROM ${e.identifier(t)}`;h&&(p=e`${p} WHERE ${h}`),p=e`${p} ORDER BY ${s}`;const m=typeof i.limit=="number"?Math.max(0,Math.floor(i.limit)):void 0;m!==void 0&&(p=e`${p} LIMIT ${e.raw(String(m+1))}`);const g=await A(o,c,p),b=Ht(n,g);if(m===void 0)return i.with&&await et({fetcher:f,groupedCounter:_,parents:b,schema:l,tableName:t,with:i.with}),{continueCursor:null,isDone:!0,page:tt(b,i.select,i.with)};const S=b.length>m,k=S?b.slice(0,m):b,D=k.at(-1);return i.with&&await et({fetcher:f,groupedCounter:_,parents:k,schema:l,tableName:t,with:i.with}),{continueCursor:S&&D?Ot(D,a):null,isDone:!S,page:tt(k,i.select,i.with)}},async get(t,i){const n=await te(t,i);if(!n)return null;const a=l.tables[n];return a?Z(a,await ft.load(n,t)):null},async groupBy(t,i){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);await F();const a=i.agg??{op:"count"};if(de(a.op),a.op!=="count"&&!a.field)throw new N("INTERNAL",`groupBy(${t}, { agg: { op: "${a.op}" } }): "field" is required for non-count reducers`);const r=le(n.softDeleteMode,void 0),f=q(q(i.baseWhere,i.where),r),_=await ye(f,t,i.relationBaseWhere),d=_!==f;if(n.aggregateIndexes&&!i.baseWhere&&!d&&!r){const b=await ut(t,n.aggregateIndexes,a,i);if(b!==void 0)return b}const h=ue(_,y),s=i.by.map(b=>e`${x(b)} AS ${e.identifier(b)}`);if(a.op==="count")s.push(e`COUNT(*) AS value`);else{if(!a.field)throw new N("INTERNAL",`groupBy(${t}, { agg: { op: "${a.op}" } }): "field" is required for non-count reducers`);s.push(e`${e.raw(de(a.op))}(${x(a.field)}) AS value`)}const p=e.join(i.by.map(b=>x(b)),e`, `);let m=e`SELECT ${e.join(s,e`, `)} FROM ${e.identifier(t)}`;h&&(m=e`${m} WHERE ${h}`),m=e`${m} GROUP BY ${p}`;const g=await A(o,c,m);return Zt(i.by,g)},async insert(t,i,n){const a=l.tables[t];if(!a)throw new N("INTERNAL",`unknown table: ${t}`);await F();const r=zt(a,i,K);Ie(a,r);let f,_=!0;n?.clientId!==void 0?(At(n.clientId),f=n.clientId):n?.allowExplicitId&&typeof r._id=="string"?f=r._id:(f=M(),_=!1);const d=n?.allowExplicitId&&typeof r._creationTime=="number"?r._creationTime:O(),h={...r,_creationTime:d,_id:f};U(t,"before","insert")&&await P("before","insert",{doc:{...h},id:f,op:"insert",table:t}),await he(t),await pe(t);const{columns:s,values:p}=lt(a,f,d,r),m=e.join(s.map(b=>e`${e.identifier(b)}`),e`, `),g=e.join(p.map(b=>e`${b}`),e`, `);return await dt(t,e`INSERT INTO ${e.identifier(t)} (${m}) VALUES (${g})`),_&&Re.set(f,t),await ne(t,void 0,h),await J(t,f,void 0,h),await oe(t,f,h),await B(t,f,"insert",h),U(t,"after","insert")&&await P("after","insert",{doc:h,id:f,op:"insert",table:t}),f},normalizeId(t,i){return St(l,t,i)},async patch(t,i,n){const a=await te(t,n);if(!a)throw new N("INTERNAL",`document not found: ${t}`);const r=l.tables[a];if(!r)throw new N("INTERNAL",`document not found: ${t}`);const f=await me(a,t),_=Z(r,f);if(!_)throw new N("INTERNAL",`document not found: ${t}`);const d={..._,...i,_id:t};ot(r,i,d,K),Ie(r,d,!0),U(a,"before","update")&&await P("before","update",{doc:{...d},id:t,op:"update",previous:_,table:a}),await he(a),await pe(a);const h=Object.keys(r.shape),s=e.join(h.map(p=>e`${e.identifier(p)} = ${H(d[p]??null)}`),e`, `);await Ee(a,"UPDATE",s,f),await ne(a,_,d),await J(a,t,_,d),await oe(a,t,d,_),await B(a,t,"update",d),U(a,"after","update")&&await P("after","update",{doc:d,id:t,op:"update",previous:_,table:a})},async restore(t,i){const n=await te(t,i);if(!n)throw new N("INTERNAL",`document not found: ${t}`);const a=l.tables[n],r=a?.softDeleteMode?.field;if(!a||!r)throw new N("INTERNAL",`ctx.db.restore: table "${n}" is not a .softDelete() table`);const f=await me(n,t),_=f?.[r]!==null&&f?.[r]!==void 0;if(await W.patch(t,{[r]:null},i),_){const d=Z(a,f);d!==null&&await J(n,t,void 0,{...d,[r]:null})}},query(t){const i=l.tables[t];if(!i)throw new N("INTERNAL",`unknown table: ${t}`);const n="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",a=[],r=d=>a.every(h=>h(d)),f=async(d,h)=>{await F();const s=a.length>0,p=await bt(o,c,i,t,d,Nt(s?void 0:h));if(!s)return h===void 0&&vt(p),p;const m=p.filter(g=>r(g));return h===void 0?m:m.slice(0,h)},_=d=>{const h={async*[Symbol.asyncIterator](){if(!d)throw new N("INTERNAL",n);yield*await f(d,void 0)},async collect(){if(!d)throw new N("INTERNAL",n);return f(d,void 0)},filter(s){if(!d)throw new N("INTERNAL",n);return a.push(s),h},async first(){if(!d)throw new N("INTERNAL",n);return(await f(d,1))[0]??null},order(){return h},async paginate(s){if(!d)throw new N("INTERNAL",n);const p=yt(s);return gt(await f(d,Tt(p)),p)},async take(s){if(!d)throw new N("INTERNAL",n);return f(d,s)},async unique(){if(!d)throw new N("INTERNAL",n);const s=await f(d,2);if(s.length>1)throw new Ft(`unique() on table "${t}" matched ${String(s.length)} documents; expected at most one`);return s[0]??null},withGeoIndex(){throw new N("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new N("INTERNAL",n)},withSearchIndex(s,p){const m=(i.searchIndexes??[]).find(b=>b.name===s);if(!m)throw new N("INTERNAL",`unknown search index "${s}" on table "${t}"`);const g={definition:m,field:m.field,filters:[],hasQuery:!1,indexName:s,query:""};if(p(mt(g,t,Et(m.language))),!g.hasQuery)throw new N("INTERNAL",`search index "${s}" on table "${t}" requires a .search(field, query) call`);return _(g)}};return h};return _(void 0)},async rank(t,i,n){const a=l.tables[t];if(!a)throw new N("INTERNAL",`unknown table: ${t}`);const r=a.rankIndexes?.find(D=>D.name===i);if(!r)throw new N("INTERNAL",`unknown rankIndex "${i}" on table "${t}"`);if(n.restrictsCounts)throw new Xe(t);if(await F(),!await Ae(t,r))return null;const f=typeof n.row=="string"?n.row:n.row._id;if(!f)return null;const _=X(t,r.name),d=r.sortBy.map((D,L)=>Q(L)),h=e.join([e`${e.identifier("__partition__")}`,...d.map(D=>e`${e.identifier(D)}`)],e`, `),s=(await A(o,c,e`SELECT ${h} FROM ${e.identifier(_)} WHERE ${e.identifier("__id__")} = ${f}`))[0];if(!s)return null;const p=s.__partition__,m=q(n.baseWhere,n.where);ze(m,l,t,"rank");const g=Qe(r,m);if(g&&be(r.partitionBy??[],g)!==p)return null;const b=ti(c.name,r,d,s,f),S=await A(o,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(_)} WHERE ${e.identifier("__partition__")} = ${p}${b?e` AND (${b})`:e``}`),k=await A(o,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(_)} WHERE ${e.identifier("__partition__")} = ${p}`);return{position:Number(S[0]?.c??0)+1,total:Number(k[0]?.c??0)}},async rankPage(t,i,n={}){ze(q(n.baseWhere,n.where),l,t,"rankPage");const a=l.tables[t];if(!a)throw new N("INTERNAL",`unknown table: ${t}`);const r=a.rankIndexes?.find(C=>C.name===i);if(!r)throw new N("INTERNAL",`unknown rankIndex "${i}" on table "${t}"`);if(await F(),!await Ae(t,r))return{continueCursor:null,isDone:!0,page:[]};const f=X(t,r.name),_=r.sortBy.map((C,se)=>Q(se)),d=Math.max(1,Math.min(1e3,Math.floor(n.take??100))),h=q(n.baseWhere,n.where),s=Qe(r,h),p=ni(r,_),m=e.join(p.map(C=>e`${e.identifier(C.column)} ${e.raw(C.direction==="desc"?"DESC":"ASC")}`),e`, `),g=[];if(s&&g.push(e`${e.identifier("__partition__")} = ${be(r.partitionBy??[],s)}`),n.cursor){const C=ii(c.name,p,Je(n.cursor));C!==void 0&&g.push(C)}const b=e.join([e`${e.identifier($e)}`,e`${e.identifier("__partition__")}`,..._.map(C=>e`${e.identifier(C)}`)],e`, `);let S=e`SELECT ${b} FROM ${e.identifier(f)}`;g.length>0&&(S=e`${S} WHERE ${e.join(g,e` AND `)}`),S=e`${S} ORDER BY ${m} LIMIT ${e.raw(String(d+1))}`;const k=await A(o,c,S),D=k.length>d,L=D?k.slice(0,d):k,G=L.map(C=>C[$e]),ge=await ai(o,c,a,t,G);let re=null;const Y=L.at(-1);if(D&&Y!==void 0){const C=[Y.__partition__,..._.map(se=>Y[se]),Y[$e]];re=oi(C)}return{continueCursor:re,isDone:!D,page:ge}},async replace(t,i,n,a){const r=await te(t,n);if(!r)throw new N("INTERNAL",`document not found: ${t}`);const f=l.tables[r];if(!f)throw new N("INTERNAL",`document not found: ${t}`);const _=await me(r,t);if(_===void 0)throw new N("INTERNAL",`document not found: ${t}`);const d=Rt(l,r,"update")||(f.aggregateIndexes??[]).length>0||(f.rankIndexes??[]).length>0?Z(f,_)??void 0:void 0,h=a?.allowExplicitId&&typeof i._creationTime=="number"?i._creationTime:O(),s={...i,_creationTime:h,_id:t};ot(f,i,s,K),Ie(f,s),U(r,"before","update")&&await P("before","update",{doc:{...s},id:t,op:"update",previous:d,table:r}),await he(r),await pe(r);const p=Object.keys(f.shape),m=e.join([e`${e.identifier("_creationTime")} = ${h}`,...p.map(g=>e`${e.identifier(g)} = ${H(s[g]??null)}`)],e`, `);await Ee(r,"UPDATE",m,_),await ne(r,d,s),await J(r,t,d,s),await oe(r,t,s,d),await B(r,t,"update",s),U(r,"after","update")&&await P("after","update",{doc:s,id:t,op:"update",previous:d,table:r})}};return Fe={db:W,scheduler:Te},W};export{Ai as backfillSqlSearchIndexes,Ti as createSqlCtxDb,Li as decodeGlobalRow,Ni as readSqlCdcChanges,li as runSqlAggregateMigrations,wi as runSqlCdcMigration,di as runSqlGlobalTableMigrations,$i as runSqlRankMigrations,pt as runSqlSearchMigrations,vi as trimSqlCdcChanges};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/sql-store",
3
- "version": "1.0.0-alpha.56",
3
+ "version": "1.0.0-alpha.57",
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.9",
54
- "@lunora/shard-engine": "1.0.0-alpha.2",
53
+ "@lunora/errors": "1.0.0-alpha.10",
54
+ "@lunora/shard-engine": "1.0.0-alpha.3",
55
55
  "drizzle-orm": "^0.45.2"
56
56
  },
57
57
  "engines": {
@@ -1 +0,0 @@
1
- import{LunoraError as N}from"@lunora/errors";import{F as wt,B as ht,T as Et,a as pt,N as mt,_ as yt,v as bt,D as gt,b as Nt,C as Tt}from"./ctx-db-search-CSETWaAQ.mjs";import{A as Ri}from"./ctx-db-search-CSETWaAQ.mjs";import{aggregateTableName as K,rankTableName as G,hasTrigger as vt,runRowValidators as Se,assertFlatPredicate as Ge,mergeWhere as M,sortColumnName as V,resolveRankPartition as Ye,encodePartitionKey as me,decodeCursor as Qe,RANK_TIEBREAK as le,CountRlsUnsupportedError as Xe,normalizeIdStructurally as Rt,assertValidClientId as St,aggregateSqlFunction as oe,softDeleteScope as se,compileWhereSql as ce,normalizeOrderKeys as At,buildSeekWhere as It,resolveRelationPredicates as Je,resolveWith as Ze,applySelect as et,encodeCursor as Lt,NotFoundError as Ot,applyOnDelete as Ct,ConflictError as de,normalizeCountArgument as kt,selectIndexForCount as xt,encodeAggregateKey as U,selectIndexForAggregate as Mt,readAggregateValue as Ae,runTriggers as Dt,matchesRankStaticWhere as tt,selectIndexForGroupBy as qt,fanOutScalarCounts as Wt,matchesStaticWhere as Ie,foldAggregateTally as Ft,coerceAggregateNumber as Le,NotUniqueError as jt,throwingScheduler as Bt}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{migrateSearchState as Ut}from"./SEARCH_STATE_TABLE-CtJTyVzp.mjs";import{queryAll as R,queryRun as A,createIndexIfNotExists as Ce,decodeRow as Y,serializeColumnValue as B,columnRefSql as k,decodeRows as Pt,forEachRowPaged as it}from"./decodeGlobalRow-DhFrSrmu.mjs";import{decodeGlobalRow as Ai}from"./decodeGlobalRow-DhFrSrmu.mjs";import{effectiveColumnKind as ye}from"./decodeBigint-DfiI8pkL.mjs";const Ht=(u,$)=>{if(u.size<$)return;const _=u.keys().next().value;_!==void 0&&u.delete(_)},Kt=new Set(["_id","id"]),ke=(u,$,_)=>u==="postgres"?e`${$} IS NOT DISTINCT FROM ${_}`:u==="mysql"?e`${$} <=> ${_}`:e`${$} IS ${_}`,Vt=u=>{const $=u.map(_=>e`${k(_.field)} ${e.raw(_.direction==="desc"?"DESC":"ASC")}`);return u.some(_=>Kt.has(_.field))||$.push(e`${k("id")} ASC`),e.join($,e`, `)},nt=50,xe=u=>{const $=[];for(const[_,r]of Object.entries(u.shape)){const m=r._meta?.column;m&&$.push([_,m])}return $},zt=(u,$,_)=>{const r={...$};for(const[m,l]of xe(u)){if(l.serverDefault){r[m]=l.serverDefault({auth:_});continue}r[m]===void 0&&(l.defaultFn?r[m]=l.defaultFn():"defaultValue"in l&&(r[m]=l.defaultValue))}return r},at=(u,$,_,r)=>{for(const[m,l]of xe(u)){if(l.serverDefault){m in $&&(_[m]=l.serverDefault({auth:r}));continue}l.onUpdateFn&&!(m in $)&&(_[m]=l.onUpdateFn())}},Gt=128,Yt=()=>{const u=new Map;return{delete:$=>{u.delete($)},get:$=>{const _=u.get($);if(_!==void 0)return u.delete($),u.set($,_),_},set:($,_)=>{u.has($)?u.delete($):Ht(u,Gt),u.set($,_)}}},Qt=async(u,$,_,r,m)=>{const l=m.get(r);if(l!==void 0)return l;const c=[];for(const[g,S]of Object.entries(_.tables))S.shardMode!==void 0&&S.shardMode.kind!=="global"||c.push(g);const T=await Promise.all(c.map(async g=>({found:(await R(u,$,e`SELECT 1 FROM ${e.identifier(g)} WHERE ${e.identifier("id")} = ${r} LIMIT 1`)).length>0,tableName:g})));for(const g of T)if(g.found)return m.set(r,g.tableName),g.tableName},Q=u=>u==null?null:Number(u),Xt=(u,$)=>$.map(_=>{const r={};for(const m of u)r[m]=_[m]??null;return{key:r,value:Q(_.value)}}),Jt=(u,$,_)=>[...u.partitionBy??[],...u.sortBy.map(r=>r.field),...u.where?Object.keys(u.where):[]].every(r=>$[r]===_[r]),rt=u=>u.length===1?u[0]:e`(${e.join(u,e` AND `)})`,Zt=(u,$,_,r,m)=>{const l=[];for(let c=0;c<_.length+1;c+=1){const T=_.slice(0,c).map(I=>ke(u,e`${e.identifier(I)}`,r[I])),g=_[c],S=$.sortBy[c];c<_.length&&g!==void 0&&S!==void 0?T.push(e`${e.identifier(g)} ${e.raw(S.direction==="desc"?">":"<")} ${r[g]}`):T.push(e`${e.identifier(le)} < ${m}`),l.push(rt(T))}return l.length>0?e.join(l,e` OR `):void 0},ei=(u,$,_)=>{if(_.length!==$.length)return;const r=[];for(const[m,l]of $.entries()){const c=[];for(let T=0;T<m;T+=1){const g=$[T];g!==void 0&&c.push(ke(u,e`${e.identifier(g.column)}`,_[T]))}c.push(e`${e.identifier(l.column)} ${e.raw(l.direction==="desc"?"<":">")} ${_[m]}`),r.push(rt(c))}return e`(${e.join(r,e` OR `)})`},ti=(u,$)=>{if(u.sortBy.length===0)throw new N("INTERNAL",`rankIndex "${u.name}" requires at least one "sortBy" column for stable pagination`);const _=[{column:"__partition__",direction:"asc"}];for(const[r,m]of u.sortBy.entries())_.push({column:$[r]??V(r),direction:m.direction});return _.push({column:le,direction:"asc"}),_},ii=async(u,$,_,r,m)=>{const l=[];for(let S=0;S<m.length;S+=50)l.push(m.slice(S,S+50));const c=await Promise.all(l.map(async S=>{const I=e.join(S.map(D=>e`${D}`),e`, `);return R(u,$,e`SELECT * FROM ${e.identifier(r)} WHERE ${e.identifier("id")} IN (${I})`)})),T=new Map;for(const S of c)for(const I of S)T.set(I.id,I);const g=[];for(const S of m){const I=Y(_,T.get(S));I&&g.push(I)}return g},ni=u=>{const $=JSON.stringify(u),_=new TextEncoder().encode($);let r="";for(const m of _)r+=String.fromCodePoint(m);return btoa(r)},ai=(u,$)=>$.columnType(ye(u)),ri=(u,$)=>{const _=[];for(const[m,l]of Object.entries(u.shape)){if(!l._meta?.column)continue;const c=l._meta.column.notNull&&l.kind!=="optional"?" NOT NULL":"";_.push(e`${e.identifier(m)} ${e.raw(`${ai(l,$)}${c}`)}`)}const r=$.frameworkColumns().map(m=>e`${e.identifier(m.name)} ${e.raw(m.type)}`);return e.join([...r,..._],e`, `)},oi=async(u,$,_,r)=>{const m=l=>{const c=k(l),T=_.shape[l],g=T&&r.indexKeyPrefix?r.indexKeyPrefix(ye(T)):void 0;return g===void 0?c:e`${c}(${e.raw(String(g))})`};for(const l of _.indexes){const c=e.join(l.fields.map(T=>m(T)),e`, `);await Ce(u,r,{columns:c,name:`${$}_${l.name}`,table:$,unique:l.unique??!1})}for(const[l,c]of xe(_))c.unique&&await Ce(u,r,{columns:m(l),name:`${$}_unique_${l}`,table:$,unique:!0})},si=async(u,$,_)=>{for(const[r,m]of Object.entries($.tables)){if(m.shardMode?.kind!=="global")continue;const l=ri(m,_);await A(u,_,e`CREATE TABLE IF NOT EXISTS ${e.identifier(r)} (${l})`),await oi(u,r,m,_)}},ci=async(u,$,_)=>{const{integer:r,key:m,real:l}=_.companionTypes;for(const[c,T]of Object.entries($.tables)){const g=T.aggregateIndexes;if(!(!g||g.length===0))for(const S of g){const I=K(c,S.name);await A(u,_,e`CREATE TABLE IF NOT EXISTS ${e.identifier(I)} (${e.identifier("__key__")} ${e.raw(m)} PRIMARY KEY, ${e.identifier("__value__")} ${e.raw(l)}, ${e.identifier("__count__")} ${e.raw(r)} NOT NULL DEFAULT 0)`),_.name==="sqlite"&&((await R(u,_,e`PRAGMA table_info(${e.identifier(I)})`)).some(D=>D.name==="__count__")||await A(u,_,e`ALTER TABLE ${e.identifier(I)} ADD COLUMN ${e.identifier("__count__")} ${e.raw(r)} NOT NULL DEFAULT 0`))}}},Oe=(u,$,_,r)=>{const m=u.name==="mysql"&&r?e`${e.identifier($)}(191)`:e`${e.identifier($)}`;return e`${m} ${e.raw(_)}`},di=(u,$,_)=>{const r=[Oe(u,"__partition__","ASC",!0)];for(const[m,l]of $.sortBy.entries()){const c=_.shape[l.field],T=c!==void 0&&u.indexKeyPrefix?.(ye(c))!==void 0;r.push(Oe(u,V(m),l.direction==="desc"?"DESC":"ASC",T))}return r.push(Oe(u,"__id__","ASC",!0)),r},li=(u,$,_)=>$.sortBy.map((r,m)=>{const l=_.shape[r.field],c=u.columnType(l?ye(l):void 0);return e`${e.identifier(V(m))} ${e.raw(c)}`}),ui=async(u,$,_)=>{const{key:r}=_.companionTypes;for(const[m,l]of Object.entries($.tables)){const c=l.rankIndexes;if(!(!c||c.length===0))for(const T of c){const g=G(m,T.name),S=li(_,T,l),I=S.length>0?e`, ${e.join(S,e`, `)}`:e``;await A(u,_,e`CREATE TABLE IF NOT EXISTS ${e.identifier(g)} (${e.identifier("__id__")} ${e.raw(r)} PRIMARY KEY, ${e.identifier("__partition__")} ${e.raw(r)} NOT NULL${I})`);const D=di(_,T,l),ge=`${m}__rank_${T.name}__btree`;await Ce(u,_,{columns:e.join(D,e`, `),name:ge,table:g,unique:!1})}}},be="__cdc_log",fi=async(u,$)=>{const{autoincrementPrimaryKey:_,key:r,real:m,text:l}=$.companionTypes;await A(u,$,e`CREATE TABLE IF NOT EXISTS ${e.identifier(be)} (${e.identifier("seq")} ${e.raw(_)}, ${e.identifier("ts")} ${e.raw(m)} NOT NULL, ${e.identifier("table")} ${e.raw(r)} NOT NULL, ${e.identifier("id")} ${e.raw(r)} NOT NULL, ${e.identifier("op")} ${e.raw(r)} NOT NULL, ${e.identifier("doc")} ${e.raw(l)})`)},_i=async(u,$,_,r,m,l,c)=>{await A(u,c,e`INSERT INTO ${e.identifier(be)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${$}, ${_}, ${r}, ${m}, ${l===void 0?null:JSON.stringify(l)})`)},bi=async(u,$,_)=>{const r=$.sinceSeq??0,m=Math.max(1,Math.min($.limit??1e3,1e4)),l=(await R(u,_,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(be)} WHERE seq > ${r} ORDER BY seq ASC LIMIT ${e.raw(String(m))}`)).map(c=>{const{doc:T}=c,g={id:String(c.id),op:String(c.op),seq:Number(c.seq),table:String(c.table),ts:Number(c.ts)};return typeof T=="string"?{...g,doc:JSON.parse(T)}:g});return{changes:l,cursor:l.at(-1)?.seq??r}},gi=async(u,$,_)=>{await A(u,_,e`DELETE FROM ${e.identifier(be)} WHERE ${e.identifier("seq")} <= ${$}`)},Ni=u=>{const{crossShardCounter:$,crossShardReader:_,exec:r,maxRelationKeys:m,schema:l}=u,{dialect:c}=u,{isUniqueViolation:T}=c,g={fieldRef:k,serialize:B,...c.name==="mysql"?{likeContains:(t,i)=>e`${t} LIKE CONCAT('%', ${i}, '%') ESCAPE '\\\\'`}:{}},S=(t,i)=>ke(c.name,t,i),I=t=>{const i=e.join(t.columns.map(d=>e`${e.identifier(d)}`),e`, `),n=e.join(t.values.map(d=>e`${d}`),e`, `),a=d=>c.name==="mysql"?e`VALUES(${e.identifier(d)})`:e`excluded.${e.identifier(d)}`,o=d=>c.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(d)}`:e`${e.identifier(d)}`,f=e.join(Object.entries(t.set(a,o)).map(([d,h])=>e`${e.identifier(d)} = ${h}`),e`, `),w=c.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)} (${i}) VALUES (${n}) ${w}`},D=u.clock??(()=>Date.now()),ge=u.idGenerator??(()=>crypto.randomUUID()),Me=u.cdc??!1,Ne=u.auth??{identity:null,userId:null},X=async(t,i,n,a)=>{Me&&await _i(r,D(),t,i,n,a,c)},ot=u.scheduler??Bt,Te=Yt();let ue=0,ve;const W=async()=>(ve??=(async()=>{await si(r,l,c),await ci(r,l,c),await ui(r,l,c),await Ut(r,c),await ht(r,l,c),Me&&await fi(r,c)})().catch(t=>{throw ve=void 0,t}),ve),J=async(t,i)=>{await W();const n=await Qt(r,c,l,t,Te);if(!(i!==void 0&&n!==i))return n},Z=new Map,De=async(t,i)=>{const n=K(t,i);return(await R(r,c,c.tableExists(n))).length>0},fe=async(t,i)=>{const n=`${t}::${i.name}`,a=Z.get(n);if(a!==void 0)return a;if(!await De(t,i.name))return Z.set(n,!1),!1;const o=l.tables[t];if(!o)return Z.set(n,!1),!1;const f=i.by??[],w=new Map;await it(r,c,o,t,h=>{if(i.where&&!Ie(h,i.where))return;const s=U(f,h);Ft(w,s,i,h)});const d=K(t,i.name);await A(r,c,e`DELETE FROM ${e.identifier(d)}`);for(const[h,s]of w)await A(r,c,e`INSERT INTO ${e.identifier(d)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${h}, ${s.value}, ${s.count})`);return Z.set(n,!0),!0},st=async(t,i,n)=>{const a=oe(i.op),o=i.field??"",f=[];for(const h of i.by??[]){const s=B(n[h]??null);f.push(s===null?e`${k(h)} IS NULL`:e`${k(h)} = ${s}`)}for(const[h,s]of Object.entries(i.where??{})){const E=s!==null&&typeof s=="object"&&!Array.isArray(s)?s.eq:s,p=B(E);f.push(p===null?e`${k(h)} IS NULL`:e`${k(h)} = ${p}`)}const w=e`SELECT ${e.raw(a)}(${k(o)}) AS value FROM ${e.identifier(t)}`,d=await R(r,c,f.length>0?e`${w} WHERE ${e.join(f,e` AND `)}`:w);return Q(d[0]?.value)},qe=async(t,i)=>{await A(r,c,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${i} AND ${e.identifier("__count__")} <= 0`)},ct=async(t,i,n,a)=>{const o=K(t,i.name),{op:f}=i,w=i.field??"",d=n&&(!i.where||Ie(n,i.where))?n:void 0,h=a&&(!i.where||Ie(a,i.where))?a:void 0;if(!(!d&&!h)){if(f==="count"){const s=new Set;for(const[E,p]of[[d,-1],[h,1]]){if(!E)continue;const y=U(i.by??[],E);s.add(y),await A(r,c,I({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(b,v)=>({__count__:e`${v("__count__")} + ${b("__count__")}`,__value__:e`${v("__value__")} + ${b("__value__")}`}),table:o,values:[y,p,p]}))}for(const E of s)await qe(o,E);return}if(f==="sum"||f==="avg"){const s=new Set;for(const[E,p]of[[d,-1],[h,1]]){if(!E)continue;const y=Le(E[w]);if(y===void 0)continue;const b=U(i.by??[],E);s.add(b),await A(r,c,I({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(v,C)=>({__count__:e`${C("__count__")} + ${v("__count__")}`,__value__:e`COALESCE(${C("__value__")}, 0) + ${v("__value__")}`}),table:o,values:[b,p*y,p]}))}for(const E of s)await qe(o,E);return}if(d){const s=U(i.by??[],d),E=Le(d[w]),p=(await R(r,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(o)} WHERE ${e.identifier("__key__")} = ${s}`))[0],y=Q(p?.value),b=(p?.count??0)-1;if(b<=0)await A(r,c,e`DELETE FROM ${e.identifier(o)} WHERE ${e.identifier("__key__")} = ${s}`);else if(p&&E!==void 0&&y!==null&&E===y){const v=await st(t,i,d);await A(r,c,e`UPDATE ${e.identifier(o)} SET ${e.identifier("__value__")} = ${v}, ${e.identifier("__count__")} = ${b} WHERE ${e.identifier("__key__")} = ${s}`)}else await A(r,c,e`UPDATE ${e.identifier(o)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${s}`)}if(h){const s=U(i.by??[],h),E=Le(h[w]);if(E===void 0)await A(r,c,I({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(p,y)=>({__count__:e`${y("__count__")} + 1`}),table:o,values:[s,null,1]}));else{const p=f==="min"?"MIN":"MAX";await A(r,c,I({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(y,b)=>({__count__:e`${b("__count__")} + 1`,__value__:e`${e.raw(p)}(COALESCE(${b("__value__")}, ${y("__value__")}), ${y("__value__")})`}),table:o,values:[s,E,1]}))}}}},_e=async t=>{const i=l.tables[t]?.aggregateIndexes;if(!(!i||i.length===0))for(const n of i)await fe(t,n)},ee=async(t,i,n)=>{const a=l.tables[t]?.aggregateIndexes;if(!(!a||a.length===0))for(const o of a){const f=`${t}::${o.name}`;(Z.get(f)??await De(t,o.name))&&await ct(t,o,i,n)}},te=new Map,We=async(t,i)=>{const n=G(t,i);return(await R(r,c,c.tableExists(n))).length>0},Re=async(t,i)=>{const n=`${t}::rank::${i.name}`,a=te.get(n);if(a!==void 0)return a;if(!await We(t,i.name))return te.set(n,!1),!1;const o=l.tables[t];if(!o)return te.set(n,!1),!1;const f=G(t,i.name);await A(r,c,e`DELETE FROM ${e.identifier(f)}`);const w=i.sortBy.map((s,E)=>V(E)),d=e.join(["__id__","__partition__",...w].map(s=>e`${e.identifier(s)}`),e`, `),h=[];await it(r,c,o,t,s=>{if(i.where&&!tt(s,i.where))return;const E=me(i.partitionBy??[],s),p=i.sortBy.map(y=>B(s[y.field]??null));h.push([s._id,E,...p])});for(const s of h){const E=e.join(s.map(p=>e`${p}`),e`, `);await A(r,c,e`INSERT INTO ${e.identifier(f)} (${d}) VALUES (${E})`)}return te.set(n,!0),!0},$e=async t=>{const i=l.tables[t]?.rankIndexes;if(!(!i||i.length===0))for(const n of i)await Re(t,n)},z=async(t,i,n,a)=>{const o=l.tables[t],f=o?.rankIndexes;if(!f||f.length===0)return;const w=o?.softDeleteMode?.field,d=w===void 0||a===void 0?void 0:a[w],h=d!=null;for(const s of f){if(n!==void 0&&a!==void 0&&Jt(s,n,a))continue;const E=`${t}::rank::${s.name}`;if(!(te.get(E)??await We(t,s.name)))continue;const p=G(t,s.name);if(n&&await A(r,c,e`DELETE FROM ${e.identifier(p)} WHERE ${e.identifier("__id__")} = ${i}`),a&&!h){if(s.where&&!tt(a,s.where))continue;const y=s.sortBy.map((L,P)=>V(P)),b=e.join(["__id__","__partition__",...y].map(L=>e`${e.identifier(L)}`),e`, `),v=me(s.partitionBy??[],a),C=s.sortBy.map(L=>B(a[L.field]??null)),x=e.join([i,v,...C].map(L=>e`${L}`),e`, `);await A(r,c,e`INSERT INTO ${e.identifier(p)} (${b}) VALUES (${x})`)}}},ie=wt({dialect:c,exec:r,schema:l}),Fe=new Set;for(const[t,i]of Object.entries(l.tables))for(const n of Object.values(i.triggerMap??{}))Fe.add(`${t} ${n.timing} ${n.op}`);const F=(t,i,n)=>Fe.has(`${t} ${i} ${n}`);let je;const j=async(t,i,n)=>{if(ue+=1,ue>nt)throw ue-=1,new de(`trigger recursion exceeded ${String(nt)} levels on "${n.table}" — check for a self-triggering write`,"trigger");try{await Dt({ctx:je,event:n,op:i,schema:l,tableName:n.table,timing:t})}finally{ue-=1}},dt=async(t,i)=>{try{await A(r,c,i)}catch(n){throw T(n)?new de(`unique constraint violation on "${t}"`,"unique"):n}},we=async(t,i)=>(await R(r,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${i}`))[0],he=async(t,i,n,a)=>{if(a===void 0)return;const o=e.join(Object.keys(a).map(d=>S(e`${e.identifier(d)}`,a[d])),e` AND `),f=i==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${n} WHERE ${o}`:e`DELETE FROM ${e.identifier(t)} WHERE ${o}`,w=()=>{throw new de(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(c.supportsReturning)(await R(r,c,e`${f} RETURNING ${e.identifier("id")}`)).length===0&&w();else{const d=await A(r,c,f);(c.affectedRows?c.affectedRows(d??{rowsAffected:0}):0)===0&&w()}}catch(d){throw T(d)?new de(`unique constraint violation on "${t}"`,"unique"):d}},lt=(t,i,n,a)=>{const o=Object.keys(t.shape);return{columns:["id","_creationTime",...o],values:[i,n,...o.map(f=>B(a[f]??null))]}},ut=async(t,i,n,a)=>{const o=qt(i,n.op,n.field,a.by,a.where);if(!o||!await fe(t,o.index))return;const f=K(t,o.index.name),w=Object.keys(o.partial);if(w.length===(o.index.by??[]).length&&w.length>0){const d=U(o.index.by??[],o.partial),h=await R(r,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(f)} WHERE ${e.identifier("__key__")} = ${d}`);if(h.length===0)return[];const s=h[0];return[{key:{...o.partial},value:Ae(n.op,{count:s.count,value:Q(s.value)})}]}return w.length>0?void 0:(await R(r,c,e`SELECT ${e.identifier("__key__")} AS key, ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(f)}`)).map(d=>{const h=d;return{key:JSON.parse(h.key),value:Ae(n.op,{count:h.count,value:Q(h.value)})}})},Be=t=>{const i=l.tables[t]?.shardMode?.kind;return i==="shardBy"||i==="root"},Ue=t=>{throw new N("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`)},Pe=(t,i)=>Be(t)?_?_(t,i):Ue(t):q.findMany(t,i),Ee=(t,i,n)=>Je(t,{fetcher:Pe,maxRelationKeys:m,relationBaseWhere:n,schema:l,tableName:i}),q={async aggregate(t,i){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);if(await W(),oe(i.op),i.op==="count")return q.count(t,{baseWhere:i.baseWhere,relationBaseWhere:i.relationBaseWhere,restrictsCounts:i.restrictsCounts,where:i.where});if(!i.field)throw new N("INTERNAL",`aggregate(${t}, { op: "${i.op}" }): "field" is required for non-count reducers`);const a=se(n.softDeleteMode,void 0),o=M(M(i.baseWhere,i.where),a),f=await Ee(o,t,i.relationBaseWhere),w=f!==o;if(n.aggregateIndexes&&!i.baseWhere&&!w&&!a){const p=Mt(n.aggregateIndexes,i.op,i.field,i.where);if(p&&await fe(t,p.index)){const y=U(p.index.by??[],p.key),b=K(t,p.index.name),v=(await R(r,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(b)} WHERE ${e.identifier("__key__")} = ${y}`))[0];return Ae(i.op,v===void 0?void 0:{count:v.count,value:Q(v.value)})}}const d=ce(f,g),h=e.raw(oe(i.op)),s=e`SELECT ${h}(${k(i.field)}) AS value FROM ${e.identifier(t)}`,E=(await R(r,c,d?e`${s} WHERE ${d}`:s))[0]?.value;return E==null?null:Number(E)},async count(t,i){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);await W();const a=kt(i);if(a.restrictsCounts)throw new Xe(t);const o=se(n.softDeleteMode,void 0),f=M(M(a.baseWhere,a.where),o),w=await Ee(f,t,a.relationBaseWhere),d=w!==f;if(n.aggregateIndexes&&!a.baseWhere&&!d&&!o){const p=xt(n.aggregateIndexes,a.where);if(p&&await fe(t,p.index)){const y=U(p.index.by??[],p.key),b=K(t,p.index.name),v=await R(r,c,e`SELECT ${e.identifier("__value__")} AS value FROM ${e.identifier(b)} WHERE ${e.identifier("__key__")} = ${y}`);return Number(v[0]?.value??0)}}const h=ce(w,g),s=e`SELECT COUNT(*) AS count FROM ${e.identifier(t)}`,E=await R(r,c,h?e`${s} WHERE ${h}`:s);return Number(E[0]?.count??0)},async delete(t,i,n){const a=await J(t,i);if(!a)return;const o=l.tables[a];if(!o)return;const f=await we(a,t),w=Y(o,f),d=n?.hard===!0,h=!d&&o.softDeleteMode?o.softDeleteMode.field:void 0;if(!(h&&(!w||w[h]!==null&&w[h]!==void 0))){if(F(a,"before","delete")&&await j("before","delete",{id:t,op:"delete",previous:w??void 0,table:a}),await Ct({deletedId:t,deletedReference:s=>w?.[s],findHolders:async(s,E,p)=>{if(l.tables[s]?.shardMode?.kind==="shardBy")throw new N("INTERNAL",`cross-backend cascade from global '${a}' into shardBy '${s}' is not supported — would require Query Coordinator fan-out across shards`);return(await q.findMany(s,{includeDeleted:d,where:{[E]:p}})).page},onCascade:(s,E)=>q.delete(E,void 0,n),onRestrict:s=>{throw new de(s,"restrict")},onSetNull:(s,E,p)=>q.patch(E,{[p]:null}),schema:l,tableName:a}),await _e(a),await $e(a),h&&w){const s={...w,[h]:D()},E=e.join(Object.keys(o.shape).map(p=>e`${e.identifier(p)} = ${B(s[p]??null)}`),e`, `);await he(a,"UPDATE",E,f),await ee(a,w,s),await z(a,t,w,void 0),await ie(a,t,s,w),await X(a,t,"update",s),F(a,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:w,table:a});return}await he(a,"DELETE",void 0,f),Te.delete(t),await ee(a,w??void 0,void 0),await z(a,t,w??void 0,void 0),await ie(a,t,void 0),await X(a,t,"delete"),F(a,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:w??void 0,table:a})}},async findFirst(t,i={}){return(await q.findMany(t,{...i,limit:1})).page[0]??null},async findFirstOrThrow(t,i={}){const n=await q.findFirst(t,i);if(n===null)throw new Ot(`findFirstOrThrow: no "${t}" document matched`);return n},async findMany(t,i={}){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);await W();const a=At(i.orderBy),o=i.cursor?It(a,Qe(i.cursor)):void 0,f=Pe,w=async(L,P,pe,ne)=>{if(Be(L))return $?Wt($,L,P,pe,ne):Ue(L);const H=l.tables[L];if(!H)throw new N("INTERNAL",`unknown table: ${L}`);const O=se(H.softDeleteMode,void 0),ae={[P]:{in:pe}},ft=M(M(ae,ne),O),_t=await Ee(ft,L,void 0),He=ce(_t,g),Ke=k(P);let re=e`SELECT ${Ke} AS __fk__, COUNT(*) AS count FROM ${e.identifier(L)}`;He&&(re=e`${re} WHERE ${He}`),re=e`${re} GROUP BY ${Ke}`;const $t=await R(r,c,re),Ve=new Map;for(const ze of $t)Ve.set(ze.__fk__,Number(ze.count??0));return Ve};let d=M(i.baseWhere,i.where);d=M(d,se(n.softDeleteMode,i.includeDeleted)),d=await Je(d,{fetcher:f,maxRelationKeys:m,relationBaseWhere:i.relationBaseWhere,schema:l,tableName:t}),o&&(d=d?{AND:[d,o]}:o);const h=ce(d,g),s=Vt(a);let E=e`SELECT * FROM ${e.identifier(t)}`;h&&(E=e`${E} WHERE ${h}`),E=e`${E} ORDER BY ${s}`;const p=typeof i.limit=="number"?Math.max(0,Math.floor(i.limit)):void 0;p!==void 0&&(E=e`${E} LIMIT ${e.raw(String(p+1))}`);const y=await R(r,c,E),b=Pt(n,y);if(p===void 0)return i.with&&await Ze({fetcher:f,groupedCounter:w,parents:b,schema:l,tableName:t,with:i.with}),{continueCursor:null,isDone:!0,page:et(b,i.select,i.with)};const v=b.length>p,C=v?b.slice(0,p):b,x=C.at(-1);return i.with&&await Ze({fetcher:f,groupedCounter:w,parents:C,schema:l,tableName:t,with:i.with}),{continueCursor:v&&x?Lt(x,a):null,isDone:!v,page:et(C,i.select,i.with)}},async get(t,i){const n=await J(t,i);if(!n)return null;const a=l.tables[n];if(!a)return null;const o=await R(r,c,e`SELECT * FROM ${e.identifier(n)} WHERE ${e.identifier("id")} = ${t}`);return Y(a,o[0])},async groupBy(t,i){const n=l.tables[t];if(!n)throw new N("INTERNAL",`unknown table: ${t}`);await W();const a=i.agg??{op:"count"};if(oe(a.op),a.op!=="count"&&!a.field)throw new N("INTERNAL",`groupBy(${t}, { agg: { op: "${a.op}" } }): "field" is required for non-count reducers`);const o=se(n.softDeleteMode,void 0),f=M(M(i.baseWhere,i.where),o),w=await Ee(f,t,i.relationBaseWhere),d=w!==f;if(n.aggregateIndexes&&!i.baseWhere&&!d&&!o){const b=await ut(t,n.aggregateIndexes,a,i);if(b!==void 0)return b}const h=ce(w,g),s=i.by.map(b=>e`${k(b)} AS ${e.identifier(b)}`);if(a.op==="count")s.push(e`COUNT(*) AS value`);else{if(!a.field)throw new N("INTERNAL",`groupBy(${t}, { agg: { op: "${a.op}" } }): "field" is required for non-count reducers`);s.push(e`${e.raw(oe(a.op))}(${k(a.field)}) AS value`)}const E=e.join(i.by.map(b=>k(b)),e`, `);let p=e`SELECT ${e.join(s,e`, `)} FROM ${e.identifier(t)}`;h&&(p=e`${p} WHERE ${h}`),p=e`${p} GROUP BY ${E}`;const y=await R(r,c,p);return Xt(i.by,y)},async insert(t,i,n){const a=l.tables[t];if(!a)throw new N("INTERNAL",`unknown table: ${t}`);await W();const o=zt(a,i,Ne);Se(a,o);let f,w=!0;n?.clientId!==void 0?(St(n.clientId),f=n.clientId):n?.allowExplicitId&&typeof o._id=="string"?f=o._id:(f=ge(),w=!1);const d=n?.allowExplicitId&&typeof o._creationTime=="number"?o._creationTime:D(),h={...o,_creationTime:d,_id:f};F(t,"before","insert")&&await j("before","insert",{doc:{...h},id:f,op:"insert",table:t}),await _e(t),await $e(t);const{columns:s,values:E}=lt(a,f,d,o),p=e.join(s.map(b=>e`${e.identifier(b)}`),e`, `),y=e.join(E.map(b=>e`${b}`),e`, `);return await dt(t,e`INSERT INTO ${e.identifier(t)} (${p}) VALUES (${y})`),w&&Te.set(f,t),await ee(t,void 0,h),await z(t,f,void 0,h),await ie(t,f,h),await X(t,f,"insert",h),F(t,"after","insert")&&await j("after","insert",{doc:h,id:f,op:"insert",table:t}),f},normalizeId(t,i){return Rt(l,t,i)},async patch(t,i,n){const a=await J(t,n);if(!a)throw new N("INTERNAL",`document not found: ${t}`);const o=l.tables[a];if(!o)throw new N("INTERNAL",`document not found: ${t}`);const f=await we(a,t),w=Y(o,f);if(!w)throw new N("INTERNAL",`document not found: ${t}`);const d={...w,...i,_id:t};at(o,i,d,Ne),Se(o,d,!0),F(a,"before","update")&&await j("before","update",{doc:{...d},id:t,op:"update",previous:w,table:a}),await _e(a),await $e(a);const h=Object.keys(o.shape),s=e.join(h.map(E=>e`${e.identifier(E)} = ${B(d[E]??null)}`),e`, `);await he(a,"UPDATE",s,f),await ee(a,w,d),await z(a,t,w,d),await ie(a,t,d,w),await X(a,t,"update",d),F(a,"after","update")&&await j("after","update",{doc:d,id:t,op:"update",previous:w,table:a})},async restore(t,i){const n=await J(t,i);if(!n)throw new N("INTERNAL",`document not found: ${t}`);const a=l.tables[n],o=a?.softDeleteMode?.field;if(!a||!o)throw new N("INTERNAL",`ctx.db.restore: table "${n}" is not a .softDelete() table`);const f=await we(n,t),w=f?.[o]!==null&&f?.[o]!==void 0;if(await q.patch(t,{[o]:null},i),w){const d=Y(a,f);d!==null&&await z(n,t,void 0,{...d,[o]:null})}},query(t){const i=l.tables[t];if(!i)throw new N("INTERNAL",`unknown table: ${t}`);const n="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",a=[],o=d=>a.every(h=>h(d)),f=async(d,h)=>{await W();const s=a.length>0,E=await bt(r,c,i,t,d,gt(s?void 0:h));if(!s)return h===void 0&&Nt(E),E;const p=E.filter(y=>o(y));return h===void 0?p:p.slice(0,h)},w=d=>{const h={async*[Symbol.asyncIterator](){if(!d)throw new N("INTERNAL",n);yield*await f(d,void 0)},async collect(){if(!d)throw new N("INTERNAL",n);return f(d,void 0)},filter(s){if(!d)throw new N("INTERNAL",n);return a.push(s),h},async first(){if(!d)throw new N("INTERNAL",n);return(await f(d,1))[0]??null},order(){return h},async paginate(s){if(!d)throw new N("INTERNAL",n);const E=mt(s);return yt(await f(d,Tt(E)),E)},async take(s){if(!d)throw new N("INTERNAL",n);return f(d,s)},async unique(){if(!d)throw new N("INTERNAL",n);const s=await f(d,2);if(s.length>1)throw new jt(`unique() on table "${t}" matched ${String(s.length)} documents; expected at most one`);return s[0]??null},withGeoIndex(){throw new N("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new N("INTERNAL",n)},withSearchIndex(s,E){const p=(i.searchIndexes??[]).find(b=>b.name===s);if(!p)throw new N("INTERNAL",`unknown search index "${s}" on table "${t}"`);const y={definition:p,field:p.field,filters:[],hasQuery:!1,indexName:s,query:""};if(E(Et(y,t,pt(p.language))),!y.hasQuery)throw new N("INTERNAL",`search index "${s}" on table "${t}" requires a .search(field, query) call`);return w(y)}};return h};return w(void 0)},async rank(t,i,n){const a=l.tables[t];if(!a)throw new N("INTERNAL",`unknown table: ${t}`);const o=a.rankIndexes?.find(x=>x.name===i);if(!o)throw new N("INTERNAL",`unknown rankIndex "${i}" on table "${t}"`);if(n.restrictsCounts)throw new Xe(t);if(await W(),!await Re(t,o))return null;const f=typeof n.row=="string"?n.row:n.row._id;if(!f)return null;const w=G(t,o.name),d=o.sortBy.map((x,L)=>V(L)),h=e.join([e`${e.identifier("__partition__")}`,...d.map(x=>e`${e.identifier(x)}`)],e`, `),s=(await R(r,c,e`SELECT ${h} FROM ${e.identifier(w)} WHERE ${e.identifier("__id__")} = ${f}`))[0];if(!s)return null;const E=s.__partition__,p=M(n.baseWhere,n.where);Ge(p,l,t,"rank");const y=Ye(o,p);if(y&&me(o.partitionBy??[],y)!==E)return null;const b=Zt(c.name,o,d,s,f),v=await R(r,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(w)} WHERE ${e.identifier("__partition__")} = ${E}${b?e` AND (${b})`:e``}`),C=await R(r,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(w)} WHERE ${e.identifier("__partition__")} = ${E}`);return{position:Number(v[0]?.c??0)+1,total:Number(C[0]?.c??0)}},async rankPage(t,i,n={}){Ge(M(n.baseWhere,n.where),l,t,"rankPage");const a=l.tables[t];if(!a)throw new N("INTERNAL",`unknown table: ${t}`);const o=a.rankIndexes?.find(O=>O.name===i);if(!o)throw new N("INTERNAL",`unknown rankIndex "${i}" on table "${t}"`);if(await W(),!await Re(t,o))return{continueCursor:null,isDone:!0,page:[]};const f=G(t,o.name),w=o.sortBy.map((O,ae)=>V(ae)),d=Math.max(1,Math.min(1e3,Math.floor(n.take??100))),h=M(n.baseWhere,n.where),s=Ye(o,h),E=ti(o,w),p=e.join(E.map(O=>e`${e.identifier(O.column)} ${e.raw(O.direction==="desc"?"DESC":"ASC")}`),e`, `),y=[];if(s&&y.push(e`${e.identifier("__partition__")} = ${me(o.partitionBy??[],s)}`),n.cursor){const O=ei(c.name,E,Qe(n.cursor));O!==void 0&&y.push(O)}const b=e.join([e`${e.identifier(le)}`,e`${e.identifier("__partition__")}`,...w.map(O=>e`${e.identifier(O)}`)],e`, `);let v=e`SELECT ${b} FROM ${e.identifier(f)}`;y.length>0&&(v=e`${v} WHERE ${e.join(y,e` AND `)}`),v=e`${v} ORDER BY ${p} LIMIT ${e.raw(String(d+1))}`;const C=await R(r,c,v),x=C.length>d,L=x?C.slice(0,d):C,P=L.map(O=>O[le]),pe=await ii(r,c,a,t,P);let ne=null;const H=L.at(-1);if(x&&H!==void 0){const O=[H.__partition__,...w.map(ae=>H[ae]),H[le]];ne=ni(O)}return{continueCursor:ne,isDone:!x,page:pe}},async replace(t,i,n,a){const o=await J(t,n);if(!o)throw new N("INTERNAL",`document not found: ${t}`);const f=l.tables[o];if(!f)throw new N("INTERNAL",`document not found: ${t}`);const w=await we(o,t);if(w===void 0)throw new N("INTERNAL",`document not found: ${t}`);const d=vt(l,o,"update")||(f.aggregateIndexes??[]).length>0||(f.rankIndexes??[]).length>0?Y(f,w)??void 0:void 0,h=a?.allowExplicitId&&typeof i._creationTime=="number"?i._creationTime:D(),s={...i,_creationTime:h,_id:t};at(f,i,s,Ne),Se(f,s),F(o,"before","update")&&await j("before","update",{doc:{...s},id:t,op:"update",previous:d,table:o}),await _e(o),await $e(o);const E=Object.keys(f.shape),p=e.join([e`${e.identifier("_creationTime")} = ${h}`,...E.map(y=>e`${e.identifier(y)} = ${B(s[y]??null)}`)],e`, `);await he(o,"UPDATE",p,w),await ee(o,d,s),await z(o,t,d,s),await ie(o,t,s,d),await X(o,t,"update",s),F(o,"after","update")&&await j("after","update",{doc:s,id:t,op:"update",previous:d,table:o})}};return je={db:q,scheduler:ot},q};export{Ri as backfillSqlSearchIndexes,Ni as createSqlCtxDb,Ai as decodeGlobalRow,bi as readSqlCdcChanges,ci as runSqlAggregateMigrations,fi as runSqlCdcMigration,si as runSqlGlobalTableMigrations,ui as runSqlRankMigrations,ht as runSqlSearchMigrations,gi as trimSqlCdcChanges};