@lunora/sql-store 1.0.0-alpha.93 → 1.0.0-alpha.95

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,readSqlCdcChangedTables as a,readSqlCdcChanges as l,readSqlCdcFloor as t,runSqlAggregateMigrations as n,runSqlCdcMigration as i,runSqlGlobalTableMigrations as d,runSqlRankMigrations as S,sweepSqlCdcRetention as c}from"./packem_shared/createSqlCtxDb-DingV15V.mjs";import{b as q,r as g}from"./packem_shared/ctx-db-search-bQChcTta.mjs";import{SEARCH_STATE_TABLE as f,migrateSearchState as b}from"./packem_shared/SEARCH_STATE_TABLE-DA3LgCT0.mjs";import{decodeBigint as x,effectiveColumnKind as p,sqliteDecode as u,sqliteEncode as h,tryJsonParse as M}from"./packem_shared/decodeBigint-B4wY6fcF.mjs";import{decodeGlobalRow as A}from"./packem_shared/decodeGlobalRow-BKIjk_Zk.mjs";export{f as SEARCH_STATE_TABLE,q as backfillSqlSearchIndexes,o as createSqlCtxDb,x as decodeBigint,A as decodeGlobalRow,p as effectiveColumnKind,b as migrateSearchState,a as readSqlCdcChangedTables,l as readSqlCdcChanges,t as readSqlCdcFloor,n as runSqlAggregateMigrations,i as runSqlCdcMigration,d as runSqlGlobalTableMigrations,S as runSqlRankMigrations,g as runSqlSearchMigrations,u as sqliteDecode,h as sqliteEncode,c as sweepSqlCdcRetention,M as tryJsonParse};
1
+ import{createSqlCtxDb as o,readSqlCdcChangedTables as a,readSqlCdcChanges as l,readSqlCdcFloor as t,runSqlAggregateMigrations as n,runSqlCdcMigration as i,runSqlGlobalTableMigrations as d,runSqlRankMigrations as S,sweepSqlCdcRetention as c}from"./packem_shared/createSqlCtxDb-xhY9jwKc.mjs";import{d as q,r as g}from"./packem_shared/ctx-db-search-CbBX6QGY.mjs";import{SEARCH_STATE_TABLE as f,migrateSearchState as m}from"./packem_shared/SEARCH_STATE_TABLE-DA3LgCT0.mjs";import{decodeBigint as b,effectiveColumnKind as p,sqliteDecode as u,sqliteEncode as h,tryJsonParse as M}from"./packem_shared/decodeBigint-B4wY6fcF.mjs";import{decodeGlobalRow as A}from"./packem_shared/decodeGlobalRow-BKIjk_Zk.mjs";export{f as SEARCH_STATE_TABLE,q as backfillSqlSearchIndexes,o as createSqlCtxDb,b as decodeBigint,A as decodeGlobalRow,p as effectiveColumnKind,m as migrateSearchState,a as readSqlCdcChangedTables,l as readSqlCdcChanges,t as readSqlCdcFloor,n as runSqlAggregateMigrations,i as runSqlCdcMigration,d as runSqlGlobalTableMigrations,S as runSqlRankMigrations,g as runSqlSearchMigrations,u as sqliteDecode,h as sqliteEncode,c as sweepSqlCdcRetention,M as tryJsonParse};
@@ -1 +1 @@
1
- import{b as S,c as s,a as i,r as l}from"./ctx-db-search-bQChcTta.mjs";import"./SEARCH_STATE_TABLE-DA3LgCT0.mjs";import"./decodeGlobalRow-BKIjk_Zk.mjs";export{S as backfillSqlSearchIndexes,s as createSearchSync,i as runSqlSearch,l as runSqlSearchMigrations};
1
+ import{d as S,c as s,a as i,r as l}from"./ctx-db-search-CbBX6QGY.mjs";import"./SEARCH_STATE_TABLE-DA3LgCT0.mjs";import"./decodeGlobalRow-BKIjk_Zk.mjs";export{S as backfillSqlSearchIndexes,s as createSearchSync,i as runSqlSearch,l as runSqlSearchMigrations};
@@ -1,7 +1,7 @@
1
- import{LunoraError as g}from"@lunora/errors";import{c as It,r as Ct,x as At,q as Lt,R as Nt,T as kt,a as Mt,y as qt,C as Dt,I as Ot}from"./ctx-db-search-bQChcTta.mjs";import{b as Xn}from"./ctx-db-search-bQChcTta.mjs";import{literalInList as Bt,throwingScheduler as Ft,CDC_LOG_TABLE as K,cursorBelowRetainedFloor as xt,cdcTrimmedError as Wt,aggregateTableName as Q,rankTableName as ne,hasTrigger as Ut,runRowValidators as Me,assertFlatPredicate as Je,mergeWhere as D,sortColumnName as J,resolveRankPartition as Ze,encodePartitionKey as Ie,decodeCursor as et,RANK_TIEBREAK as ye,CountRlsUnsupportedError as tt,normalizeIdStructurally as Pt,assertValidClientId as jt,aggregateSqlFunction as _e,softDeleteScope as $e,compileWhereSql as he,normalizeOrderKeys as Ht,buildSeekWhere as Kt,resolveRelationPredicates as nt,resolveWith as it,relationHooks as ot,applySelect as rt,encodeCursor as Gt,NotFoundError as Vt,applyOnDelete as Yt,ConflictError as Ee,normalizeCountArgument as Xt,selectIndexForCount as zt,encodeAggregateKey as z,selectIndexForAggregate as Qt,readAggregateValue as qe,runTriggers as Jt,matchesRankStaticWhere as st,selectIndexForGroupBy as Zt,fanOutScalarCounts as en,matchesStaticWhere as De,foldAggregateTally as tn,coerceAggregateNumber as Oe,CDC_LOG_TABLE_SEQ_INDEX as nn,NotUniqueError as on}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{migrateSearchState as rn}from"./SEARCH_STATE_TABLE-DA3LgCT0.mjs";import{queryAll as I,queryRun as L,createIndexIfNotExists as Ce,decodeRow as ie,serializeColumnValue as H,columnRefSql as O,decodeRows as sn,forEachRowPaged as at,queryBatch as ct}from"./decodeGlobalRow-BKIjk_Zk.mjs";import{decodeGlobalRow as Qn}from"./decodeGlobalRow-BKIjk_Zk.mjs";import{effectiveColumnKind as Ae}from"./decodeBigint-B4wY6fcF.mjs";const an=(s,u)=>{if(s.size<u)return;const l=s.keys().next().value;l!==void 0&&s.delete(l)},dt=50,cn=(s,u={})=>{const l=u.maxBatch??dt,i=Number.isInteger(l)&&l>0?l:dt,h=new Map;let d=!1;const c=async(R,b)=>{const v=[...b.keys()];for(let N=0;N<v.length;N+=i){const M=v.slice(N,N+i);try{const x=await s(R,M);for(const G of M){const Y=x.get(G);for(const X of b.get(G)??[])X.resolve(Y)}}catch(x){for(const G of M)for(const Y of b.get(G)??[])Y.reject(x)}}},m=()=>{d=!1;const R=[...h.entries()];h.clear();for(const[b,v]of R)c(b,v).catch(()=>{})};return{async load(R,b){return new Promise((v,N)=>{let M=h.get(R);M||(M=new Map,h.set(R,M));const x=M.get(b);x?x.push({reject:N,resolve:v}):M.set(b,[{reject:N,resolve:v}]),d||(d=!0,queueMicrotask(m))})}}},dn=new Set(["_id","id"]),xe=(s,u,l)=>s==="postgres"?e`${u} IS NOT DISTINCT FROM ${l}`:s==="mysql"?e`${u} <=> ${l}`:e`${u} IS ${l}`,ln=s=>{const u=s.map(l=>e`${O(l.field)} ${e.raw(l.direction==="desc"?"DESC":"ASC")}`);return s.some(l=>dn.has(l.field))||u.push(e`${O("id")} ASC`),e.join(u,e`, `)},lt=50,We=s=>{const u=[];for(const[l,i]of Object.entries(s.shape)){const h=i._meta?.column;h&&u.push([l,h])}return u},un=(s,u,l)=>{const i={...u};for(const[h,d]of We(s)){if(d.serverDefault){i[h]=d.serverDefault({auth:l});continue}i[h]===void 0&&(d.defaultFn?i[h]=d.defaultFn():"defaultValue"in d&&(i[h]=d.defaultValue))}return i},ut=(s,u,l,i)=>{for(const[h,d]of We(s)){if(d.serverDefault){h in u&&(l[h]=d.serverDefault({auth:i}));continue}d.onUpdateFn&&!(h in u)&&(l[h]=d.onUpdateFn())}},fn=128,wn=()=>{const s=new Map;return{delete:u=>{s.delete(u)},get:u=>{const l=s.get(u);if(l!==void 0)return s.delete(u),s.set(u,l),l},set:(u,l)=>{s.has(u)?s.delete(u):an(s,fn),s.set(u,l)}}},_n=async(s,u,l,i,h)=>{const d=h.get(i);if(d!==void 0)return d;const c=Object.entries(l.tables).filter(([,R])=>R.shardMode===void 0||R.shardMode.kind==="global").map(([R])=>R),m=await Promise.all(c.map(async R=>({found:(await I(s,u,e`SELECT 1 FROM ${e.identifier(R)} WHERE ${e.identifier("id")} = ${i} LIMIT 1`)).length>0,tableName:R})));for(const R of m)if(R.found)return h.set(i,R.tableName),R.tableName},oe=s=>s==null?null:Number(s),$n=(s,u)=>u.map(l=>{const i={};for(const h of s)i[h]=l[h]??null;return{key:i,value:oe(l.value)}}),hn=(s,u,l)=>[...s.partitionBy??[],...s.sortBy.map(h=>h.field),...s.where?Object.keys(s.where):[]].every(h=>u[h]===l[h]),wt=s=>s.length===1?s[0]:e`(${e.join(s,e` AND `)})`,te=s=>e.join(s.map(u=>e`${e.identifier(u)}`),e`, `),re=s=>e.join(s.map(u=>e`${u}`),e`, `),En=(s,u,l,i,h)=>{const d=[];for(let c=0;c<l.length+1;c+=1){const m=l.slice(0,c).map(v=>xe(s,e`${e.identifier(v)}`,i[v])),R=l[c],b=u.sortBy[c];c<l.length&&R!==void 0&&b!==void 0?m.push(e`${e.identifier(R)} ${e.raw(b.direction==="desc"?">":"<")} ${i[R]}`):m.push(e`${e.identifier(ye)} < ${h}`),d.push(wt(m))}return d.length>0?e.join(d,e` OR `):void 0},yn=(s,u,l)=>{if(l.length!==u.length)return;const i=[];for(const[h,d]of u.entries()){const c=[];for(let m=0;m<h;m+=1){const R=u[m];R!==void 0&&c.push(xe(s,e`${e.identifier(R.column)}`,l[m]))}c.push(e`${e.identifier(d.column)} ${e.raw(d.direction==="desc"?"<":">")} ${l[h]}`),i.push(wt(c))}return e`(${e.join(i,e` OR `)})`},pn=(s,u)=>{if(s.sortBy.length===0)throw new g("INTERNAL",`rankIndex "${s.name}" requires at least one "sortBy" column for stable pagination`);const l=[{column:"__partition__",direction:"asc"}];for(const[i,h]of s.sortBy.entries())l.push({column:u[i]??J(i),direction:h.direction});return l.push({column:ye,direction:"asc"}),l},Rn=async(s,u,l,i,h)=>{const c=[];for(let v=0;v<h.length;v+=50)c.push(h.slice(v,v+50));const m=await Promise.all(c.map(async v=>I(s,u,e`SELECT * FROM ${e.identifier(i)} WHERE ${e.identifier("id")} IN (${re(v)})`))),R=new Map;for(const v of m)for(const N of v)R.set(N.id,N);const b=[];for(const v of h){const N=ie(l,R.get(v));N&&b.push(N)}return b},Tn=s=>{const u=JSON.stringify(s),l=new TextEncoder().encode(u);let i="";for(const h of l)i+=String.fromCodePoint(h);return btoa(i)},mn=(s,u)=>u.columnType(Ae(s)),Sn=(s,u,l)=>{const i=[];for(const[c,m]of Object.entries(u.shape)){if(!m._meta?.column)continue;const R=m._meta.column.notNull&&m.kind!=="optional"?" NOT NULL":"";i.push(e`${e.identifier(c)} ${e.raw(`${mn(m,l)}${R}`)}`)}const h=l.frameworkColumns().map(c=>e`${e.identifier(c.name)} ${e.raw(c.type)}`),d=h.length+i.length;if(l.maxTableColumns!==void 0&&d>l.maxTableColumns)throw new g("VALIDATION_ERROR",`@lunora/sql-store: global table "${s}" needs ${String(d)} columns, over this engine's ${String(l.maxTableColumns)}-column limit — split the table, or move the extra fields into one object field`);return e.join([...h,...i],e`, `)},gn=async(s,u,l,i)=>{const h=d=>{const c=O(d),m=l.shape[d],R=m&&i.indexKeyPrefix?i.indexKeyPrefix(Ae(m)):void 0;return R===void 0?c:e`${c}(${e.raw(String(R))})`};for(const d of l.indexes){const c=e.join(d.fields.map(m=>h(m)),e`, `);await Ce(s,i,{columns:c,name:`${u}_${d.name}`,table:u,unique:d.unique??!1})}for(const[d,c]of We(l))c.unique&&await Ce(s,i,{columns:h(d),name:`${u}_unique_${d}`,table:u,unique:!0})},vn=async(s,u,l)=>{for(const[i,h]of Object.entries(u.tables)){if(h.shardMode?.kind!=="global")continue;const d=Sn(i,h,l);await L(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(i)} (${d})`),await gn(s,i,h,l)}},bn=async(s,u,l)=>{const{integer:i,key:h,real:d}=l.companionTypes;for(const[c,m]of Object.entries(u.tables)){const R=m.aggregateIndexes;if(!(!R||R.length===0))for(const b of R){const v=Q(c,b.name);await L(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(v)} (${e.identifier("__key__")} ${e.raw(h)} PRIMARY KEY, ${e.identifier("__value__")} ${e.raw(d)}, ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0)`),l.name==="sqlite"&&((await I(s,l,e`PRAGMA table_info(${e.identifier(v)})`)).some(M=>M.name==="__count__")||await L(s,l,e`ALTER TABLE ${e.identifier(v)} ADD COLUMN ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0`))}}},Be=(s,u,l,i)=>{const h=s.name==="mysql"&&i?e`${e.identifier(u)}(191)`:e`${e.identifier(u)}`;return e`${h} ${e.raw(l)}`},In=(s,u,l)=>{const i=[Be(s,"__partition__","ASC",!0)];for(const[h,d]of u.sortBy.entries()){const c=l.shape[d.field],m=c!==void 0&&s.indexKeyPrefix?.(Ae(c))!==void 0;i.push(Be(s,J(h),d.direction==="desc"?"DESC":"ASC",m))}return i.push(Be(s,"__id__","ASC",!0)),i},Cn=(s,u,l)=>u.sortBy.map((i,h)=>{const d=l.shape[i.field],c=s.columnType(d?Ae(d):void 0);return e`${e.identifier(J(h))} ${e.raw(c)}`}),An=async(s,u,l)=>{const{key:i}=l.companionTypes;for(const[h,d]of Object.entries(u.tables)){const c=d.rankIndexes;if(!(!c||c.length===0))for(const m of c){const R=ne(h,m.name),b=Cn(l,m,d),v=b.length>0?e`, ${e.join(b,e`, `)}`:e``;await L(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(R)} (${e.identifier("__id__")} ${e.raw(i)} PRIMARY KEY, ${e.identifier("__partition__")} ${e.raw(i)} NOT NULL${v})`);const N=In(l,m,d),M=`${h}__rank_${m.name}__btree`;await Ce(s,l,{columns:e.join(N,e`, `),name:M,table:R,unique:!1})}}},Fe="__cdc_sweep",_t="global",Ln=6e4,Nn=1e4,kn=3e4;let ft=0;const Mn=async(s,u)=>{const{autoincrementPrimaryKey:l,key:i,real:h,text:d}=u.companionTypes;await L(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(K)} (${e.identifier("seq")} ${e.raw(l)}, ${e.identifier("ts")} ${e.raw(h)} NOT NULL, ${e.identifier("table")} ${e.raw(i)} NOT NULL, ${e.identifier("id")} ${e.raw(i)} NOT NULL, ${e.identifier("op")} ${e.raw(i)} NOT NULL, ${e.identifier("doc")} ${e.raw(d)})`);const c=u.indexKeyPrefix?.("string");await Ce(s,u,{columns:e`${c===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(c))})`}, ${e.identifier("seq")}`,name:nn,table:K,unique:!1}),await L(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(Fe)} (${e.identifier("id")} ${e.raw(i)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(h)} NOT NULL)`),await L(s,u,e`INSERT INTO ${e.identifier(Fe)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${_t}, ${0}) ${u.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},qn=async(s,u,l)=>{const i=e`UPDATE ${e.identifier(Fe)} SET ${e.identifier("lease_until")} = ${l+Ln} WHERE ${e.identifier("id")} = ${_t} AND ${e.identifier("lease_until")} <= ${l}`;if(u.supportsReturning)return(await I(s,u,e`${i} RETURNING ${e.identifier("id")}`)).length>0;const h=await L(s,u,i);return(u.affectedRows?u.affectedRows(h??{rowsAffected:0}):0)>0},Dn=async(s,u,l,i)=>{if(!await qn(s,u,i))return;const h=i-l;await L(s,u,e`
1
+ import{LunoraError as g}from"@lunora/errors";import{c as It,r as Ct,A as At,q as Lt,C as kt,R as Nt,a as Mt,T as qt,x as Dt,b as Ot}from"./ctx-db-search-CbBX6QGY.mjs";import{d as Qn}from"./ctx-db-search-CbBX6QGY.mjs";import{literalInList as Ft,throwingScheduler as Bt,CDC_LOG_TABLE as K,cursorBelowRetainedFloor as xt,cdcTrimmedError as Wt,aggregateTableName as Q,rankTableName as ne,hasTrigger as Ut,runRowValidators as Me,assertFlatPredicate as Je,mergeWhere as D,sortColumnName as J,resolveRankPartition as Ze,encodePartitionKey as Ie,decodeCursor as et,RANK_TIEBREAK as ye,CountRlsUnsupportedError as tt,normalizeIdStructurally as Pt,assertValidClientId as jt,aggregateSqlFunction as _e,softDeleteScope as $e,compileWhereSql as he,normalizeOrderKeys as Ht,buildSeekWhere as Kt,resolveRelationPredicates as nt,resolveWith as it,relationHooks as ot,applySelect as rt,encodeCursor as Gt,NotFoundError as Vt,applyOnDelete as Yt,ConflictError as Ee,normalizeCountArgument as Xt,selectIndexForCount as zt,encodeAggregateKey as z,selectIndexForAggregate as Qt,readAggregateValue as qe,runTriggers as Jt,matchesRankStaticWhere as st,CURSOR_PREFIX as Zt,selectIndexForGroupBy as en,tiebreakDirectionFor as tn,fanOutScalarCounts as nn,matchesStaticWhere as De,foldAggregateTally as on,coerceAggregateNumber as Oe,CDC_LOG_TABLE_SEQ_INDEX as rn,NotUniqueError as sn}from"@lunora/shard-engine";import{sql as e}from"drizzle-orm";import{migrateSearchState as an}from"./SEARCH_STATE_TABLE-DA3LgCT0.mjs";import{queryAll as I,queryRun as L,createIndexIfNotExists as Ce,decodeRow as ie,serializeColumnValue as H,columnRefSql as O,decodeRows as cn,forEachRowPaged as at,queryBatch as ct}from"./decodeGlobalRow-BKIjk_Zk.mjs";import{decodeGlobalRow as Zn}from"./decodeGlobalRow-BKIjk_Zk.mjs";import{effectiveColumnKind as Ae}from"./decodeBigint-B4wY6fcF.mjs";const dn=(s,u)=>{if(s.size<u)return;const l=s.keys().next().value;l!==void 0&&s.delete(l)},dt=50,ln=(s,u={})=>{const l=u.maxBatch??dt,i=Number.isInteger(l)&&l>0?l:dt,h=new Map;let d=!1;const c=async(R,b)=>{const v=[...b.keys()];for(let k=0;k<v.length;k+=i){const M=v.slice(k,k+i);try{const x=await s(R,M);for(const G of M){const Y=x.get(G);for(const X of b.get(G)??[])X.resolve(Y)}}catch(x){for(const G of M)for(const Y of b.get(G)??[])Y.reject(x)}}},m=()=>{d=!1;const R=[...h.entries()];h.clear();for(const[b,v]of R)c(b,v).catch(()=>{})};return{async load(R,b){return new Promise((v,k)=>{let M=h.get(R);M||(M=new Map,h.set(R,M));const x=M.get(b);x?x.push({reject:k,resolve:v}):M.set(b,[{reject:k,resolve:v}]),d||(d=!0,queueMicrotask(m))})}}},un=new Set(["_id","id"]),xe=(s,u,l)=>s==="postgres"?e`${u} IS NOT DISTINCT FROM ${l}`:s==="mysql"?e`${u} <=> ${l}`:e`${u} IS ${l}`,fn=s=>{const u=s.map(l=>e`${O(l.field)} ${e.raw(l.direction==="desc"?"DESC":"ASC")}`);if(!s.some(l=>un.has(l.field))){const l=tn(s);u.push(e`${O("id")} ${e.raw(l==="desc"?"DESC":"ASC")}`)}return e.join(u,e`, `)},lt=50,We=s=>{const u=[];for(const[l,i]of Object.entries(s.shape)){const h=i._meta?.column;h&&u.push([l,h])}return u},wn=(s,u,l)=>{const i={...u};for(const[h,d]of We(s)){if(d.serverDefault){i[h]=d.serverDefault({auth:l});continue}i[h]===void 0&&(d.defaultFn?i[h]=d.defaultFn():"defaultValue"in d&&(i[h]=d.defaultValue))}return i},ut=(s,u,l,i)=>{for(const[h,d]of We(s)){if(d.serverDefault){h in u&&(l[h]=d.serverDefault({auth:i}));continue}d.onUpdateFn&&!(h in u)&&(l[h]=d.onUpdateFn())}},_n=128,$n=()=>{const s=new Map;return{delete:u=>{s.delete(u)},get:u=>{const l=s.get(u);if(l!==void 0)return s.delete(u),s.set(u,l),l},set:(u,l)=>{s.has(u)?s.delete(u):dn(s,_n),s.set(u,l)}}},hn=async(s,u,l,i,h)=>{const d=h.get(i);if(d!==void 0)return d;const c=Object.entries(l.tables).filter(([,R])=>R.shardMode===void 0||R.shardMode.kind==="global").map(([R])=>R),m=await Promise.all(c.map(async R=>({found:(await I(s,u,e`SELECT 1 FROM ${e.identifier(R)} WHERE ${e.identifier("id")} = ${i} LIMIT 1`)).length>0,tableName:R})));for(const R of m)if(R.found)return h.set(i,R.tableName),R.tableName},oe=s=>s==null?null:Number(s),En=(s,u)=>u.map(l=>{const i={};for(const h of s)i[h]=l[h]??null;return{key:i,value:oe(l.value)}}),yn=(s,u,l)=>[...s.partitionBy??[],...s.sortBy.map(h=>h.field),...s.where?Object.keys(s.where):[]].every(h=>u[h]===l[h]),wt=s=>s.length===1?s[0]:e`(${e.join(s,e` AND `)})`,te=s=>e.join(s.map(u=>e`${e.identifier(u)}`),e`, `),re=s=>e.join(s.map(u=>e`${u}`),e`, `),pn=(s,u,l,i,h)=>{const d=[];for(let c=0;c<l.length+1;c+=1){const m=l.slice(0,c).map(v=>xe(s,e`${e.identifier(v)}`,i[v])),R=l[c],b=u.sortBy[c];c<l.length&&R!==void 0&&b!==void 0?m.push(e`${e.identifier(R)} ${e.raw(b.direction==="desc"?">":"<")} ${i[R]}`):m.push(e`${e.identifier(ye)} < ${h}`),d.push(wt(m))}return d.length>0?e.join(d,e` OR `):void 0},Rn=(s,u,l)=>{if(l.length!==u.length)return;const i=[];for(const[h,d]of u.entries()){const c=[];for(let m=0;m<h;m+=1){const R=u[m];R!==void 0&&c.push(xe(s,e`${e.identifier(R.column)}`,l[m]))}c.push(e`${e.identifier(d.column)} ${e.raw(d.direction==="desc"?"<":">")} ${l[h]}`),i.push(wt(c))}return e`(${e.join(i,e` OR `)})`},Tn=(s,u)=>{if(s.sortBy.length===0)throw new g("INTERNAL",`rankIndex "${s.name}" requires at least one "sortBy" column for stable pagination`);const l=[{column:"__partition__",direction:"asc"}];for(const[i,h]of s.sortBy.entries())l.push({column:u[i]??J(i),direction:h.direction});return l.push({column:ye,direction:"asc"}),l},mn=async(s,u,l,i,h)=>{const c=[];for(let v=0;v<h.length;v+=50)c.push(h.slice(v,v+50));const m=await Promise.all(c.map(async v=>I(s,u,e`SELECT * FROM ${e.identifier(i)} WHERE ${e.identifier("id")} IN (${re(v)})`))),R=new Map;for(const v of m)for(const k of v)R.set(k.id,k);const b=[];for(const v of h){const k=ie(l,R.get(v));k&&b.push(k)}return b},Sn=s=>{const u=JSON.stringify(s),l=new TextEncoder().encode(u);let i="";for(const h of l)i+=String.fromCodePoint(h);return Zt+btoa(i)},gn=(s,u)=>u.columnType(Ae(s)),vn=(s,u,l)=>{const i=[];for(const[c,m]of Object.entries(u.shape)){if(!m._meta?.column)continue;const R=m._meta.column.notNull&&m.kind!=="optional"?" NOT NULL":"";i.push(e`${e.identifier(c)} ${e.raw(`${gn(m,l)}${R}`)}`)}const h=l.frameworkColumns().map(c=>e`${e.identifier(c.name)} ${e.raw(c.type)}`),d=h.length+i.length;if(l.maxTableColumns!==void 0&&d>l.maxTableColumns)throw new g("VALIDATION_ERROR",`@lunora/sql-store: global table "${s}" needs ${String(d)} columns, over this engine's ${String(l.maxTableColumns)}-column limit — split the table, or move the extra fields into one object field`);return e.join([...h,...i],e`, `)},bn=async(s,u,l,i)=>{const h=d=>{const c=O(d),m=l.shape[d],R=m&&i.indexKeyPrefix?i.indexKeyPrefix(Ae(m)):void 0;return R===void 0?c:e`${c}(${e.raw(String(R))})`};for(const d of l.indexes){const c=e.join(d.fields.map(m=>h(m)),e`, `);await Ce(s,i,{columns:c,name:`${u}_${d.name}`,table:u,unique:d.unique??!1})}for(const[d,c]of We(l))c.unique&&await Ce(s,i,{columns:h(d),name:`${u}_unique_${d}`,table:u,unique:!0})},In=async(s,u,l)=>{for(const[i,h]of Object.entries(u.tables)){if(h.shardMode?.kind!=="global")continue;const d=vn(i,h,l);await L(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(i)} (${d})`),await bn(s,i,h,l)}},Cn=async(s,u,l)=>{const{integer:i,key:h,real:d}=l.companionTypes;for(const[c,m]of Object.entries(u.tables)){const R=m.aggregateIndexes;if(!(!R||R.length===0))for(const b of R){const v=Q(c,b.name);await L(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(v)} (${e.identifier("__key__")} ${e.raw(h)} PRIMARY KEY, ${e.identifier("__value__")} ${e.raw(d)}, ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0)`),l.name==="sqlite"&&((await I(s,l,e`PRAGMA table_info(${e.identifier(v)})`)).some(M=>M.name==="__count__")||await L(s,l,e`ALTER TABLE ${e.identifier(v)} ADD COLUMN ${e.identifier("__count__")} ${e.raw(i)} NOT NULL DEFAULT 0`))}}},Fe=(s,u,l,i)=>{const h=s.name==="mysql"&&i?e`${e.identifier(u)}(191)`:e`${e.identifier(u)}`;return e`${h} ${e.raw(l)}`},An=(s,u,l)=>{const i=[Fe(s,"__partition__","ASC",!0)];for(const[h,d]of u.sortBy.entries()){const c=l.shape[d.field],m=c!==void 0&&s.indexKeyPrefix?.(Ae(c))!==void 0;i.push(Fe(s,J(h),d.direction==="desc"?"DESC":"ASC",m))}return i.push(Fe(s,"__id__","ASC",!0)),i},Ln=(s,u,l)=>u.sortBy.map((i,h)=>{const d=l.shape[i.field],c=s.columnType(d?Ae(d):void 0);return e`${e.identifier(J(h))} ${e.raw(c)}`}),kn=async(s,u,l)=>{const{key:i}=l.companionTypes;for(const[h,d]of Object.entries(u.tables)){const c=d.rankIndexes;if(!(!c||c.length===0))for(const m of c){const R=ne(h,m.name),b=Ln(l,m,d),v=b.length>0?e`, ${e.join(b,e`, `)}`:e``;await L(s,l,e`CREATE TABLE IF NOT EXISTS ${e.identifier(R)} (${e.identifier("__id__")} ${e.raw(i)} PRIMARY KEY, ${e.identifier("__partition__")} ${e.raw(i)} NOT NULL${v})`);const k=An(l,m,d),M=`${h}__rank_${m.name}__btree`;await Ce(s,l,{columns:e.join(k,e`, `),name:M,table:R,unique:!1})}}},Be="__cdc_sweep",_t="global",Nn=6e4,Mn=1e4,qn=3e4;let ft=0;const Dn=async(s,u)=>{const{autoincrementPrimaryKey:l,key:i,real:h,text:d}=u.companionTypes;await L(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(K)} (${e.identifier("seq")} ${e.raw(l)}, ${e.identifier("ts")} ${e.raw(h)} NOT NULL, ${e.identifier("table")} ${e.raw(i)} NOT NULL, ${e.identifier("id")} ${e.raw(i)} NOT NULL, ${e.identifier("op")} ${e.raw(i)} NOT NULL, ${e.identifier("doc")} ${e.raw(d)})`);const c=u.indexKeyPrefix?.("string");await Ce(s,u,{columns:e`${c===void 0?e`${e.identifier("table")}`:e`${e.identifier("table")}(${e.raw(String(c))})`}, ${e.identifier("seq")}`,name:rn,table:K,unique:!1}),await L(s,u,e`CREATE TABLE IF NOT EXISTS ${e.identifier(Be)} (${e.identifier("id")} ${e.raw(i)} NOT NULL PRIMARY KEY, ${e.identifier("lease_until")} ${e.raw(h)} NOT NULL)`),await L(s,u,e`INSERT INTO ${e.identifier(Be)} (${e.identifier("id")}, ${e.identifier("lease_until")}) VALUES (${_t}, ${0}) ${u.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${e.identifier("id")} = ${e.identifier("id")}`:e`ON CONFLICT(${e.identifier("id")}) DO NOTHING`}`)},On=async(s,u,l)=>{const i=e`UPDATE ${e.identifier(Be)} SET ${e.identifier("lease_until")} = ${l+Nn} WHERE ${e.identifier("id")} = ${_t} AND ${e.identifier("lease_until")} <= ${l}`;if(u.supportsReturning)return(await I(s,u,e`${i} RETURNING ${e.identifier("id")}`)).length>0;const h=await L(s,u,i);return(u.affectedRows?u.affectedRows(h??{rowsAffected:0}):0)>0},Fn=async(s,u,l,i)=>{if(!await On(s,u,i))return;const h=i-l;await L(s,u,e`
2
2
  DELETE FROM ${e.identifier(K)} WHERE ${e.identifier("seq")} IN (
3
3
  SELECT ${e.identifier("seq")} FROM (
4
- SELECT ${e.identifier("seq")} FROM ${e.identifier(K)} WHERE ${e.identifier("ts")} <= ${h} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Nn))}
4
+ SELECT ${e.identifier("seq")} FROM ${e.identifier(K)} WHERE ${e.identifier("ts")} <= ${h} ORDER BY ${e.identifier("seq")} ASC LIMIT ${e.raw(String(Mn))}
5
5
  ) AS ${e.identifier("expired")}
6
6
  )
7
- `)},$t=async(s,u)=>{const l=await I(s,u,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(K)}`),i=Number(l[0]?.seq??Number.NaN);return Number.isFinite(i)?i:void 0},On=async(s,u,l,i,h,d,c)=>{await L(s,c,e`INSERT INTO ${e.identifier(K)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${u}, ${l}, ${i}, ${h}, ${d===void 0?null:JSON.stringify(d)})`)},Kn=async(s,u,l)=>{const i=u.sinceSeq??0,h=Math.max(1,Math.min(u.limit??1e3,1e4)),d=await $t(s,l);if(d!==void 0&&xt(d,i))throw Wt(d,i,"global");const m=(await I(s,l,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(K)} WHERE seq > ${i} ORDER BY seq ASC LIMIT ${e.raw(String(h))}`)).map(R=>{const{doc:b}=R,v={id:String(R.id),op:String(R.op),seq:Number(R.seq),table:String(R.table),ts:Number(R.ts)};return typeof b=="string"?{...v,doc:JSON.parse(b)}:v});return{changes:m,cursor:m.at(-1)?.seq??i}},Bn=async(s,u,l,i={})=>{if(i.cursorOnly){const R=await I(s,l,e`SELECT MAX(seq) AS seq FROM ${e.identifier(K)}`),b=Number(R[0]?.seq??u);return{cursor:Number.isFinite(b)?b:u,tables:[]}}const h=await I(s,l,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq FROM ${e.identifier(K)} WHERE seq > ${u} GROUP BY ${e.identifier("table")}`);let d=u;const c=[];for(const R of h){const b=Number(R.seq);Number.isFinite(b)&&b>d&&(d=b),c.push(String(R.table))}const m=i.retained===!0?await $t(s,l):void 0;return{cursor:d,tables:c,...m===void 0?{}:{floor:m}}},Gn=s=>{const{crossShardCounter:u,crossShardReader:l,exec:i,maxRelationKeys:h,schema:d}=s,{dialect:c}=s,{isUniqueViolation:m}=c,R={fieldRef:O,serialize:H,...c.name==="mysql"?{containsExpr:(t,n)=>e`LOCATE(${n}, ${t}) > 0`}:{},...c.name==="postgres"?{containsExpr:(t,n)=>e`strpos(${t}, ${n}) > 0`}:{},...c.name==="sqlite"?{}:{inList:Bt}},b=(t,n)=>xe(c.name,t,n),v=t=>{const n=te(t.columns),o=re(t.values),r=f=>c.name==="mysql"?e`VALUES(${e.identifier(f)})`:e`excluded.${e.identifier(f)}`,a=f=>c.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(f)}`:e`${e.identifier(f)}`,_=e.join(Object.entries(t.set(r,a)).map(([f,y])=>e`${e.identifier(f)} = ${y}`),e`, `),E=c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${_}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${_}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${o}) ${E}`},N=s.clock??(()=>Date.now()),M=s.idGenerator??(()=>crypto.randomUUID()),x=s.cdc??!1,G=typeof s.cdcRetentionMs=="number"&&Number.isFinite(s.cdcRetentionMs)&&s.cdcRetentionMs>0?s.cdcRetentionMs:void 0,Y=s.auth??{identity:null,userId:null},X=async(t,n,o,r)=>{if(!x||(await On(i,N(),t,n,o,r,c),G===void 0))return;const a=N();if(!(a-ft<kn)){ft=a;try{await Dn(i,c,G,a)}catch{}}},ht=s.scheduler??Ft,Le=wn();let pe=0,Ne;const W=async()=>(Ne??=(async()=>{await vn(i,d,c),await bn(i,d,c),await An(i,d,c),await rn(i,c),await Ct(i,d,c),x&&await Mn(i,c)})().catch(t=>{throw Ne=void 0,t}),Ne),se=async(t,n)=>{await W();const o=await _n(i,c,d,t,Le);if(!(n!==void 0&&o!==n))return o},ae=new Map,Ue=async(t,n)=>{const o=Q(t,n);return(await I(i,c,c.tableExists(o))).length>0},Re=async(t,n)=>{const o=`${t}::${n.name}`,r=ae.get(o);if(r!==void 0)return r;if(!await Ue(t,n.name))return ae.set(o,!1),!1;const _=d.tables[t];if(!_)return ae.set(o,!1),!1;const E=n.by??[],f=new Map;await at(i,c,_,t,$=>{if(n.where&&!De($,n.where))return;const p=z(E,$);tn(f,p,n,$)});const y=Q(t,n.name);await L(i,c,e`DELETE FROM ${e.identifier(y)}`);const w=[];for(const[$,p]of f)w.push(e`INSERT INTO ${e.identifier(y)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${$}, ${p.value}, ${p.count})`);return await ct(i,c,w),ae.set(o,!0),!0},Et=async(t,n,o)=>{const r=_e(n.op),a=n.field??"",_=[];for(const y of n.by??[]){const w=H(o[y]??null);_.push(w===null?e`${O(y)} IS NULL`:e`${O(y)} = ${w}`)}for(const[y,w]of Object.entries(n.where??{})){const $=w!==null&&typeof w=="object"&&!Array.isArray(w)?w.eq:w,p=H($);_.push(p===null?e`${O(y)} IS NULL`:e`${O(y)} = ${p}`)}const E=e`SELECT ${e.raw(r)}(${O(a)}) AS value FROM ${e.identifier(t)}`,f=await I(i,c,_.length>0?e`${E} WHERE ${e.join(_,e` AND `)}`:E);return oe(f[0]?.value)},yt=async(t,n)=>{await L(i,c,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`)},pt=async(t,n,o,r)=>{const a=Q(t,n.name),{op:_}=n,E=n.field??"",f=o&&(!n.where||De(o,n.where))?o:void 0,y=r&&(!n.where||De(r,n.where))?r:void 0;if(!(!f&&!y)){if(_==="count"||_==="sum"||_==="avg"){const w=new Set;for(const[$,p]of[[f,-1],[y,1]]){if(!$)continue;const S=_==="count"?1:Oe($[E]);if(S===void 0)continue;const T=z(n.by??[],$);w.add(T),await L(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(A,C)=>({__count__:e`${C("__count__")} + ${A("__count__")}`,__value__:_==="count"?e`${C("__value__")} + ${A("__value__")}`:e`COALESCE(${C("__value__")}, 0) + ${A("__value__")}`}),table:a,values:[T,p*S,p]}))}for(const $ of w)await yt(a,$);return}if(f){const w=z(n.by??[],f),$=Oe(f[E]),S=(await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`))[0],T=oe(S?.value),A=(S?.count??0)-1;if(A<=0)await L(i,c,e`DELETE FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`);else if(S&&$!==void 0&&T!==null&&$===T){const C=await Et(t,n,f);await L(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__value__")} = ${C}, ${e.identifier("__count__")} = ${A} WHERE ${e.identifier("__key__")} = ${w}`)}else await L(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${w}`)}if(y){const w=z(n.by??[],y),$=Oe(y[E]);if($===void 0)await L(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(p,S)=>({__count__:e`${S("__count__")} + 1`}),table:a,values:[w,null,1]}));else{const p=_==="min"?"MIN":"MAX";await L(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,T)=>({__count__:e`${T("__count__")} + 1`,__value__:e`${e.raw(p)}(COALESCE(${T("__value__")}, ${S("__value__")}), ${S("__value__")})`}),table:a,values:[w,$,1]}))}}}},Te=async t=>{const n=d.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const o of n)await Re(t,o)},ce=async(t,n,o)=>{const r=d.tables[t]?.aggregateIndexes;if(!(!r||r.length===0))for(const a of r){const _=`${t}::${a.name}`;(ae.get(_)??await Ue(t,a.name))&&await pt(t,a,n,o)}},de=new Map,Pe=async(t,n)=>{const o=ne(t,n);return(await I(i,c,c.tableExists(o))).length>0},ke=async(t,n)=>{const o=`${t}::rank::${n.name}`,r=de.get(o);if(r!==void 0)return r;if(!await Pe(t,n.name))return de.set(o,!1),!1;const _=d.tables[t];if(!_)return de.set(o,!1),!1;const E=ne(t,n.name);await L(i,c,e`DELETE FROM ${e.identifier(E)}`);const f=n.sortBy.map((p,S)=>J(S)),y=te(["__id__","__partition__",...f]),w=[];await at(i,c,_,t,p=>{if(n.where&&!st(p,n.where))return;const S=Ie(n.partitionBy??[],p),T=n.sortBy.map(A=>H(p[A.field]??null));w.push([p._id,S,...T])});const $=w.map(p=>e`INSERT INTO ${e.identifier(E)} (${y}) VALUES (${re(p)})`);return await ct(i,c,$),de.set(o,!0),!0},me=async t=>{const n=d.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const o of n)await ke(t,o)},Z=async(t,n,o,r)=>{const a=d.tables[t],_=a?.rankIndexes;if(!_||_.length===0)return;const E=a?.softDeleteMode?.field,f=E===void 0||r===void 0?void 0:r[E],y=f!=null;for(const w of _){if(o!==void 0&&r!==void 0&&hn(w,o,r))continue;const $=`${t}::rank::${w.name}`;if(!(de.get($)??await Pe(t,w.name)))continue;const T=ne(t,w.name);if(o&&await L(i,c,e`DELETE FROM ${e.identifier(T)} WHERE ${e.identifier("__id__")} = ${n}`),r&&!y){if(w.where&&!st(r,w.where))continue;const A=w.sortBy.map((B,V)=>J(V)),C=te(["__id__","__partition__",...A]),F=Ie(w.partitionBy??[],r),k=w.sortBy.map(B=>H(r[B.field]??null));await L(i,c,e`INSERT INTO ${e.identifier(T)} (${C}) VALUES (${re([n,F,...k])})`)}}},le=It({dialect:c,exec:i,schema:d}),je=new Set;for(const[t,n]of Object.entries(d.tables))for(const o of Object.values(n.triggerMap??{}))je.add(`${t} ${o.timing} ${o.op}`);const P=(t,n,o)=>je.has(`${t} ${n} ${o}`);let He;const j=async(t,n,o)=>{if(pe+=1,pe>lt)throw pe-=1,new Ee(`trigger recursion exceeded ${String(lt)} levels on "${o.table}" — check for a self-triggering write`,"trigger");try{await Jt({ctx:He,event:o,op:n,schema:d,tableName:o.table,timing:t})}finally{pe-=1}},Rt=async(t,n)=>{try{await L(i,c,n)}catch(o){throw m(o)?new Ee(`unique constraint violation on "${t}"`,"unique"):o}},Se=async(t,n)=>(await I(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],ge=async(t,n,o,r)=>{if(r===void 0)return;const a=e.join(Object.keys(r).map(f=>b(e`${e.identifier(f)}`,r[f])),e` AND `),_=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${o} WHERE ${a}`:e`DELETE FROM ${e.identifier(t)} WHERE ${a}`,E=()=>{throw new Ee(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(c.supportsReturning)(await I(i,c,e`${_} RETURNING ${e.identifier("id")}`)).length===0&&E();else{const f=await L(i,c,_);(c.affectedRows?c.affectedRows(f??{rowsAffected:0}):0)===0&&E()}}catch(f){throw m(f)?new Ee(`unique constraint violation on "${t}"`,"unique"):f}},Tt=(t,n,o,r)=>{const a=Object.keys(t.shape);return{columns:["id","_creationTime",...a],values:[n,o,...a.map(_=>H(r[_]??null))]}},mt=async(t,n,o,r)=>{const a=Zt(n,o.op,o.field,r.by,r.where);if(!a||!await Re(t,a.index))return;const E=Q(t,a.index.name),f=Object.keys(a.partial);if(f.length===(a.index.by??[]).length&&f.length>0){const w=z(a.index.by??[],a.partial),$=await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)} WHERE ${e.identifier("__key__")} = ${w}`);if($.length===0)return[];const p=$[0];return[{key:{...a.partial},value:qe(o.op,{count:p.count,value:oe(p.value)})}]}return f.length>0?void 0:(await I(i,c,e`SELECT ${e.identifier("__key__")} AS key, ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)}`)).map(w=>{const $=w;return{key:JSON.parse($.key),value:qe(o.op,{count:$.count,value:oe($.value)})}})},Ke=t=>{const n=d.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},Ge=t=>{throw new g("INTERNAL",`cross-backend relation: a global table cannot load the shard-local relation '${t}' (it spans every shard) — wire a cross-shard reader to support it`)},St=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new g("MASK_UNSUPPORTED",`masking cannot follow a nested \`with\` across the cross-shard relation hop to "${t}" — the nested rows are hydrated on the serving shard, where the mask policy does not exist. Read the nested relation at its own (masked) call site instead.`);const o={};if(n?.relationBaseWhere)for(const r of Object.keys(d.tables)){const a=n.relationBaseWhere(r);a!==void 0&&(o[r]=a)}return{orderBy:n?.orderBy,relationPolicies:o,where:D(n?.baseWhere,n?.where),with:n?.with}},Ve=(t,n)=>Ke(t)?l?l(t,St(t,n)):Ge(t):U.findMany(t,n),ve=(t,n,o)=>nt(t,{fetcher:Ve,maxRelationKeys:h,relationBaseWhere:o,schema:d,tableName:n}),gt=cn(async(t,n)=>{const o=await I(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${re(n)})`),r=new Map;for(const a of o){const{id:_}=a;typeof _=="string"&&r.set(_,a)}return r}),U={async cdcChangedTables(t,n){if(x)try{return await W(),await Bn(i,t,c,{...n,retained:G!==void 0})}catch{return}},async aggregate(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);if(await W(),_e(n.op),n.op==="count")return U.count(t,{baseWhere:n.baseWhere,relationBaseWhere:n.relationBaseWhere,restrictsCounts:n.restrictsCounts,where:n.where});if(!n.field)throw new g("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const r=$e(o.softDeleteMode,void 0),a=D(D(n.baseWhere,n.where),r),_=await ve(a,t,n.relationBaseWhere),E=_!==a;if(o.aggregateIndexes&&!n.baseWhere&&!E&&!r){const S=Qt(o.aggregateIndexes,n.op,n.field,n.where);if(S&&await Re(t,S.index)){const A=z(S.index.by??[],S.key),C=Q(t,S.index.name),k=(await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(C)} WHERE ${e.identifier("__key__")} = ${A}`))[0];return qe(n.op,k===void 0?void 0:{count:k.count,value:oe(k.value)})}}const f=he(_,R),y=e.raw(_e(n.op)),w=e`SELECT ${y}(${O(n.field)}) AS value FROM ${e.identifier(t)}`,p=(await I(i,c,f?e`${w} WHERE ${f}`:w))[0]?.value;return p==null?null:Number(p)},async count(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Xt(n);if(r.restrictsCounts)throw new tt(t);const a=$e(o.softDeleteMode,void 0),_=D(D(r.baseWhere,r.where),a),E=await ve(_,t,r.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!r.baseWhere&&!f&&!a){const p=zt(o.aggregateIndexes,r.where);if(p&&await Re(t,p.index)){const T=z(p.index.by??[],p.key),A=Q(t,p.index.name),C=await I(i,c,e`SELECT ${e.identifier("__value__")} AS value FROM ${e.identifier(A)} WHERE ${e.identifier("__key__")} = ${T}`);return Number(C[0]?.value??0)}}const y=he(E,R),w=e`SELECT COUNT(*) AS count FROM ${e.identifier(t)}`,$=await I(i,c,y?e`${w} WHERE ${y}`:w);return Number($[0]?.count??0)},async delete(t,n,o){const r=await se(t,n);if(!r)return;const a=d.tables[r];if(!a)return;const _=await Se(r,t),E=ie(a,_),f=o?.hard===!0,y=!f&&a.softDeleteMode?a.softDeleteMode.field:void 0;if(!(y&&(!E||E[y]!==null&&E[y]!==void 0))){if(P(r,"before","delete")&&await j("before","delete",{id:t,op:"delete",previous:E??void 0,table:r}),await Yt({deletedId:t,deletedReference:w=>E?.[w],findHolders:async(w,$,p)=>{if(d.tables[w]?.shardMode?.kind==="shardBy")throw new g("INTERNAL",`cross-backend cascade from global '${r}' into shardBy '${w}' is not supported — would require Query Coordinator fan-out across shards`);return(await U.findMany(w,{includeDeleted:f,where:{[$]:p}})).page},onCascade:(w,$)=>U.delete($,void 0,o),onRestrict:w=>{throw new Ee(w,"restrict")},onSetNull:(w,$,p)=>U.patch($,{[p]:null}),schema:d,tableName:r}),await Te(r),await me(r),y&&E){const w={...E,[y]:N()},$=e.join(Object.keys(a.shape).map(p=>e`${e.identifier(p)} = ${H(w[p]??null)}`),e`, `);await ge(r,"UPDATE",$,_),await ce(r,E,w),await Z(r,t,E,void 0),await le(r,t,w,E),await X(r,t,"update",w),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E,table:r});return}await ge(r,"DELETE",void 0,_),Le.delete(t),await ce(r,E??void 0,void 0),await Z(r,t,E??void 0,void 0),await le(r,t,void 0),await X(r,t,"delete"),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E??void 0,table:r})}},async findFirst(t,n={}){return(await U.findMany(t,{...n,limit:1})).page[0]??null},async findFirstOrThrow(t,n={}){const o=await U.findFirst(t,n);if(o===null)throw new Vt(`findFirstOrThrow: no "${t}" document matched`);return o},async findMany(t,n={}){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Ht(n.orderBy),a=n.cursor?Kt(r,et(n.cursor)):void 0,_=Ve,E=async(k,B,V,be)=>{if(Ke(k))return u?en(u,k,B,V,be):Ge(k);const ue=d.tables[k];if(!ue)throw new g("INTERNAL",`unknown table: ${k}`);const ee=$e(ue.softDeleteMode,void 0),q={[B]:{in:V}},fe=D(D(q,be),ee),vt=await ve(fe,k,void 0),Ye=he(vt,R),Xe=O(B);let we=e`SELECT ${Xe} AS __fk__, COUNT(*) AS count FROM ${e.identifier(k)}`;Ye&&(we=e`${we} WHERE ${Ye}`),we=e`${we} GROUP BY ${Xe}`;const bt=await I(i,c,we),ze=new Map;for(const Qe of bt)ze.set(Qe.__fk__,Number(Qe.count??0));return ze};let f=D(n.baseWhere,n.where);f=D(f,$e(o.softDeleteMode,n.includeDeleted)),f=await nt(f,{fetcher:_,maxRelationKeys:h,relationBaseWhere:n.relationBaseWhere,schema:d,tableName:t}),a&&(f=f?{AND:[f,a]}:a);const y=he(f,R),w=ln(r);let $=e`SELECT * FROM ${e.identifier(t)}`;y&&($=e`${$} WHERE ${y}`),$=e`${$} ORDER BY ${w}`;const p=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;p!==void 0&&($=e`${$} LIMIT ${e.raw(String(p+1))}`);const S=await I(i,c,$),T=sn(o,S);if(p===void 0)return n.with&&await it({fetcher:_,groupedCounter:E,parents:T,...ot(n),schema:d,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:rt(T,n.select,n.with)};const A=T.length>p,C=A?T.slice(0,p):T,F=C.at(-1);return n.with&&await it({fetcher:_,groupedCounter:E,parents:C,...ot(n),schema:d,tableName:t,with:n.with}),{continueCursor:A&&F?Gt(F,r):null,isDone:!A,page:rt(C,n.select,n.with)}},async get(t,n){const o=await se(t,n);if(!o)return null;const r=d.tables[o];return r?ie(r,await gt.load(o,t)):null},async groupBy(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=n.agg??{op:"count"};if(_e(r.op),r.op!=="count"&&!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);const a=$e(o.softDeleteMode,void 0),_=D(D(n.baseWhere,n.where),a),E=await ve(_,t,n.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!n.baseWhere&&!f&&!a){const T=await mt(t,o.aggregateIndexes,r,n);if(T!==void 0)return T}const y=he(E,R),w=n.by.map(T=>e`${O(T)} AS ${e.identifier(T)}`);if(r.op==="count")w.push(e`COUNT(*) AS value`);else{if(!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);w.push(e`${e.raw(_e(r.op))}(${O(r.field)}) AS value`)}const $=e.join(n.by.map(T=>O(T)),e`, `);let p=e`SELECT ${e.join(w,e`, `)} FROM ${e.identifier(t)}`;y&&(p=e`${p} WHERE ${y}`),p=e`${p} GROUP BY ${$}`;const S=await I(i,c,p);return $n(n.by,S)},async insert(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);await W();const a=un(r,n,Y);Me(r,a);let _,E=!0;o?.clientId!==void 0?(jt(o.clientId),_=o.clientId):o?.allowExplicitId&&typeof a._id=="string"?_=a._id:(_=M(),E=!1);const f=o?.allowExplicitId&&typeof a._creationTime=="number"?a._creationTime:N(),y={...a,_creationTime:f,_id:_};P(t,"before","insert")&&await j("before","insert",{doc:{...y},id:_,op:"insert",table:t}),await Te(t),await me(t);const{columns:w,values:$}=Tt(r,_,f,a);return await Rt(t,e`INSERT INTO ${e.identifier(t)} (${te(w)}) VALUES (${re($)})`),E&&Le.set(_,t),await ce(t,void 0,y),await Z(t,_,void 0,y),await le(t,_,y),await X(t,_,"insert",y),P(t,"after","insert")&&await j("after","insert",{doc:y,id:_,op:"insert",table:t}),_},normalizeId(t,n){return Pt(d,t,n)},async patch(t,n,o){const r=await se(t,o);if(!r)throw new g("INTERNAL",`document not found: ${t}`);const a=d.tables[r];if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=await Se(r,t),E=ie(a,_);if(!E)throw new g("INTERNAL",`document not found: ${t}`);const f={...E,...n,_id:t};ut(a,n,f,Y),Me(a,f,!0),P(r,"before","update")&&await j("before","update",{doc:{...f},id:t,op:"update",previous:E,table:r}),await Te(r),await me(r);const y=Object.keys(a.shape),w=e.join(y.map($=>e`${e.identifier($)} = ${H(f[$]??null)}`),e`, `);await ge(r,"UPDATE",w,_),await ce(r,E,f),await Z(r,t,E,f),await le(r,t,f,E),await X(r,t,"update",f),P(r,"after","update")&&await j("after","update",{doc:f,id:t,op:"update",previous:E,table:r})},async restore(t,n){const o=await se(t,n);if(!o)throw new g("INTERNAL",`document not found: ${t}`);const r=d.tables[o],a=r?.softDeleteMode?.field;if(!r||!a)throw new g("INTERNAL",`ctx.db.restore: table "${o}" is not a .softDelete() table`);const _=await Se(o,t),E=_?.[a]!==null&&_?.[a]!==void 0;if(await U.patch(t,{[a]:null},n),E){const f=ie(r,_);f!==null&&await Z(o,t,void 0,{...f,[a]:null})}},query(t){const n=d.tables[t];if(!n)throw new g("INTERNAL",`unknown table: ${t}`);const o="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",r=[],a=f=>r.every(y=>y(f)),_=async(f,y)=>{await W();const w=r.length>0,$=await Mt(i,c,n,t,f,qt(w?void 0:y));if(!w)return y===void 0&&Dt($),$;const p=$.filter(S=>a(S));return y===void 0?p:p.slice(0,y)},E=f=>{const y={async*[Symbol.asyncIterator](){if(!f)throw new g("INTERNAL",o);yield*await _(f,void 0)},async collect(){if(!f)throw new g("INTERNAL",o);return _(f,void 0)},async collectWithScores(){throw new g("INTERNAL",`collectWithScores() is not supported on \`.global()\` tables (table "${t}") — relevance scores are not yet surfaced on this backend; use .collect() instead`)},filter(w){return r.push(w),y},async first(){if(!f)throw new g("INTERNAL",o);return(await _(f,1))[0]??null},order(){return y},async paginate(w){if(!f)throw new g("INTERNAL",o);const $=Nt(w);return kt(await _(f,Ot($)),$)},async take(w){if(!f)throw new g("INTERNAL",o);return _(f,w)},async unique(){if(!f)throw new g("INTERNAL",o);const w=await _(f,2);if(w.length>1)throw new on(`unique() on table "${t}" matched ${String(w.length)} documents; expected at most one`);return w[0]??null},withGeoIndex(){throw new g("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new g("INTERNAL",o)},withSearchIndex(w,$){const p=(n.searchIndexes??[]).find(T=>T.name===w);if(!p)throw new g("INTERNAL",`unknown search index "${w}" on table "${t}"`);const S={definition:p,field:p.field,filters:[],hasQuery:!1,indexName:w,query:""};if($(At(S,t,Lt(p.language))),!S.hasQuery)throw new g("INTERNAL",`search index "${w}" on table "${t}" requires a .search(field, query) call`);return E(S)}};return y};return E(void 0)},async rank(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(B=>B.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(o.restrictsCounts)throw new tt(t);if(await W(),!await ke(t,a))return null;const E=typeof o.row=="string"?o.row:o.row._id;if(!E)return null;const f=ne(t,a.name),y=a.sortBy.map((B,V)=>J(V)),w=te(["__partition__",...y]),p=(await I(i,c,e`SELECT ${w} FROM ${e.identifier(f)} WHERE ${e.identifier("__id__")} = ${E}`))[0];if(!p)return null;const S=p.__partition__,T=D(o.baseWhere,o.where);Je(T,d,t,"rank");const A=Ze(a,T);if(A&&Ie(a.partitionBy??[],A)!==S)return null;const C=En(c.name,a,y,p,E),F=await I(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}${C?e` AND (${C})`:e``}`),k=await I(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}`);return{position:Number(F[0]?.c??0)+1,total:Number(k[0]?.c??0)}},async rankPage(t,n,o={}){Je(D(o.baseWhere,o.where),d,t,"rankPage");const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(q=>q.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await W(),!await ke(t,a))return{continueCursor:null,isDone:!0,page:[]};const E=ne(t,a.name),f=a.sortBy.map((q,fe)=>J(fe)),y=Math.max(1,Math.min(1e3,Math.floor(o.take??100))),w=D(o.baseWhere,o.where),$=Ze(a,w),p=pn(a,f),S=e.join(p.map(q=>e`${e.identifier(q.column)} ${e.raw(q.direction==="desc"?"DESC":"ASC")}`),e`, `),T=[];if($&&T.push(e`${e.identifier("__partition__")} = ${Ie(a.partitionBy??[],$)}`),o.cursor){const q=yn(c.name,p,et(o.cursor));q!==void 0&&T.push(q)}const A=te([ye,"__partition__",...f]);let C=e`SELECT ${A} FROM ${e.identifier(E)}`;T.length>0&&(C=e`${C} WHERE ${e.join(T,e` AND `)}`),C=e`${C} ORDER BY ${S} LIMIT ${e.raw(String(y+1))}`;const F=await I(i,c,C),k=F.length>y,B=k?F.slice(0,y):F,V=B.map(q=>q[ye]),be=await Rn(i,c,r,t,V);let ue=null;const ee=B.at(-1);if(k&&ee!==void 0){const q=[ee.__partition__,...f.map(fe=>ee[fe]),ee[ye]];ue=Tn(q)}return{continueCursor:ue,isDone:!k,page:be}},async replace(t,n,o,r){const a=await se(t,o);if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=d.tables[a];if(!_)throw new g("INTERNAL",`document not found: ${t}`);const E=await Se(a,t);if(E===void 0)throw new g("INTERNAL",`document not found: ${t}`);const y=Ut(d,a,"update")||(_.aggregateIndexes??[]).length>0||(_.rankIndexes??[]).length>0?ie(_,E)??void 0:void 0,w=r?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:N(),$={...n,_creationTime:w,_id:t};ut(_,n,$,Y),Me(_,$),P(a,"before","update")&&await j("before","update",{doc:{...$},id:t,op:"update",previous:y,table:a}),await Te(a),await me(a);const p=Object.keys(_.shape),S=e.join([e`${e.identifier("_creationTime")} = ${w}`,...p.map(T=>e`${e.identifier(T)} = ${H($[T]??null)}`)],e`, `);await ge(a,"UPDATE",S,E),await ce(a,y,$),await Z(a,t,y,$),await le(a,t,$,y),await X(a,t,"update",$),P(a,"after","update")&&await j("after","update",{doc:$,id:t,op:"update",previous:y,table:a})}};return He={db:U,scheduler:ht},U};export{Xn as backfillSqlSearchIndexes,Gn as createSqlCtxDb,Qn as decodeGlobalRow,Bn as readSqlCdcChangedTables,Kn as readSqlCdcChanges,$t as readSqlCdcFloor,bn as runSqlAggregateMigrations,Mn as runSqlCdcMigration,vn as runSqlGlobalTableMigrations,An as runSqlRankMigrations,Ct as runSqlSearchMigrations,Dn as sweepSqlCdcRetention};
7
+ `)},$t=async(s,u)=>{const l=await I(s,u,e`SELECT MIN(${e.identifier("seq")}) AS ${e.identifier("seq")} FROM ${e.identifier(K)}`),i=Number(l[0]?.seq??Number.NaN);return Number.isFinite(i)?i:void 0},Bn=async(s,u,l,i,h,d,c)=>{await L(s,c,e`INSERT INTO ${e.identifier(K)} (${e.identifier("ts")}, ${e.identifier("table")}, ${e.identifier("id")}, ${e.identifier("op")}, ${e.identifier("doc")}) VALUES (${u}, ${l}, ${i}, ${h}, ${d===void 0?null:JSON.stringify(d)})`)},Vn=async(s,u,l)=>{const i=u.sinceSeq??0,h=Math.max(1,Math.min(u.limit??1e3,1e4)),d=await $t(s,l);if(d!==void 0&&xt(d,i))throw Wt(d,i,"global");const m=(await I(s,l,e`SELECT seq, ts, ${e.identifier("table")}, id, op, doc FROM ${e.identifier(K)} WHERE seq > ${i} ORDER BY seq ASC LIMIT ${e.raw(String(h))}`)).map(R=>{const{doc:b}=R,v={id:String(R.id),op:String(R.op),seq:Number(R.seq),table:String(R.table),ts:Number(R.ts)};return typeof b=="string"?{...v,doc:JSON.parse(b)}:v});return{changes:m,cursor:m.at(-1)?.seq??i}},xn=async(s,u,l,i={})=>{if(i.cursorOnly){const R=await I(s,l,e`SELECT MAX(seq) AS seq FROM ${e.identifier(K)}`),b=Number(R[0]?.seq??u);return{cursor:Number.isFinite(b)?b:u,tables:[]}}const h=await I(s,l,e`SELECT ${e.identifier("table")} AS ${e.identifier("table")}, MAX(seq) AS seq FROM ${e.identifier(K)} WHERE seq > ${u} GROUP BY ${e.identifier("table")}`);let d=u;const c=[];for(const R of h){const b=Number(R.seq);Number.isFinite(b)&&b>d&&(d=b),c.push(String(R.table))}const m=i.retained===!0?await $t(s,l):void 0;return{cursor:d,tables:c,...m===void 0?{}:{floor:m}}},Yn=s=>{const{crossShardCounter:u,crossShardReader:l,exec:i,maxRelationKeys:h,schema:d}=s,{dialect:c}=s,{isUniqueViolation:m}=c,R={fieldRef:O,serialize:H,...c.name==="mysql"?{containsExpr:(t,n)=>e`LOCATE(${n}, ${t}) > 0`}:{},...c.name==="postgres"?{containsExpr:(t,n)=>e`strpos(${t}, ${n}) > 0`}:{},...c.name==="sqlite"?{}:{inList:Ft}},b=(t,n)=>xe(c.name,t,n),v=t=>{const n=te(t.columns),o=re(t.values),r=f=>c.name==="mysql"?e`VALUES(${e.identifier(f)})`:e`excluded.${e.identifier(f)}`,a=f=>c.name==="postgres"?e`${e.identifier(t.table)}.${e.identifier(f)}`:e`${e.identifier(f)}`,_=e.join(Object.entries(t.set(r,a)).map(([f,y])=>e`${e.identifier(f)} = ${y}`),e`, `),E=c.name==="mysql"?e`ON DUPLICATE KEY UPDATE ${_}`:e`ON CONFLICT(${e.identifier(t.conflictKey)}) DO UPDATE SET ${_}`;return e`INSERT INTO ${e.identifier(t.table)} (${n}) VALUES (${o}) ${E}`},k=s.clock??(()=>Date.now()),M=s.idGenerator??(()=>crypto.randomUUID()),x=s.cdc??!1,G=typeof s.cdcRetentionMs=="number"&&Number.isFinite(s.cdcRetentionMs)&&s.cdcRetentionMs>0?s.cdcRetentionMs:void 0,Y=s.auth??{identity:null,userId:null},X=async(t,n,o,r)=>{if(!x||(await Bn(i,k(),t,n,o,r,c),G===void 0))return;const a=k();if(!(a-ft<qn)){ft=a;try{await Fn(i,c,G,a)}catch{}}},ht=s.scheduler??Bt,Le=$n();let pe=0,ke;const W=async()=>(ke??=(async()=>{await In(i,d,c),await Cn(i,d,c),await kn(i,d,c),await an(i,c),await Ct(i,d,c),x&&await Dn(i,c)})().catch(t=>{throw ke=void 0,t}),ke),se=async(t,n)=>{await W();const o=await hn(i,c,d,t,Le);if(!(n!==void 0&&o!==n))return o},ae=new Map,Ue=async(t,n)=>{const o=Q(t,n);return(await I(i,c,c.tableExists(o))).length>0},Re=async(t,n)=>{const o=`${t}::${n.name}`,r=ae.get(o);if(r!==void 0)return r;if(!await Ue(t,n.name))return ae.set(o,!1),!1;const _=d.tables[t];if(!_)return ae.set(o,!1),!1;const E=n.by??[],f=new Map;await at(i,c,_,t,$=>{if(n.where&&!De($,n.where))return;const p=z(E,$);on(f,p,n,$)});const y=Q(t,n.name);await L(i,c,e`DELETE FROM ${e.identifier(y)}`);const w=[];for(const[$,p]of f)w.push(e`INSERT INTO ${e.identifier(y)} (${e.identifier("__key__")}, ${e.identifier("__value__")}, ${e.identifier("__count__")}) VALUES (${$}, ${p.value}, ${p.count})`);return await ct(i,c,w),ae.set(o,!0),!0},Et=async(t,n,o)=>{const r=_e(n.op),a=n.field??"",_=[];for(const y of n.by??[]){const w=H(o[y]??null);_.push(w===null?e`${O(y)} IS NULL`:e`${O(y)} = ${w}`)}for(const[y,w]of Object.entries(n.where??{})){const $=w!==null&&typeof w=="object"&&!Array.isArray(w)?w.eq:w,p=H($);_.push(p===null?e`${O(y)} IS NULL`:e`${O(y)} = ${p}`)}const E=e`SELECT ${e.raw(r)}(${O(a)}) AS value FROM ${e.identifier(t)}`,f=await I(i,c,_.length>0?e`${E} WHERE ${e.join(_,e` AND `)}`:E);return oe(f[0]?.value)},yt=async(t,n)=>{await L(i,c,e`DELETE FROM ${e.identifier(t)} WHERE ${e.identifier("__key__")} = ${n} AND ${e.identifier("__count__")} <= 0`)},pt=async(t,n,o,r)=>{const a=Q(t,n.name),{op:_}=n,E=n.field??"",f=o&&(!n.where||De(o,n.where))?o:void 0,y=r&&(!n.where||De(r,n.where))?r:void 0;if(!(!f&&!y)){if(_==="count"||_==="sum"||_==="avg"){const w=new Set;for(const[$,p]of[[f,-1],[y,1]]){if(!$)continue;const S=_==="count"?1:Oe($[E]);if(S===void 0)continue;const T=z(n.by??[],$);w.add(T),await L(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(A,C)=>({__count__:e`${C("__count__")} + ${A("__count__")}`,__value__:_==="count"?e`${C("__value__")} + ${A("__value__")}`:e`COALESCE(${C("__value__")}, 0) + ${A("__value__")}`}),table:a,values:[T,p*S,p]}))}for(const $ of w)await yt(a,$);return}if(f){const w=z(n.by??[],f),$=Oe(f[E]),S=(await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`))[0],T=oe(S?.value),A=(S?.count??0)-1;if(A<=0)await L(i,c,e`DELETE FROM ${e.identifier(a)} WHERE ${e.identifier("__key__")} = ${w}`);else if(S&&$!==void 0&&T!==null&&$===T){const C=await Et(t,n,f);await L(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__value__")} = ${C}, ${e.identifier("__count__")} = ${A} WHERE ${e.identifier("__key__")} = ${w}`)}else await L(i,c,e`UPDATE ${e.identifier(a)} SET ${e.identifier("__count__")} = ${e.identifier("__count__")} - 1 WHERE ${e.identifier("__key__")} = ${w}`)}if(y){const w=z(n.by??[],y),$=Oe(y[E]);if($===void 0)await L(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(p,S)=>({__count__:e`${S("__count__")} + 1`}),table:a,values:[w,null,1]}));else{const p=_==="min"?"MIN":"MAX";await L(i,c,v({columns:["__key__","__value__","__count__"],conflictKey:"__key__",set:(S,T)=>({__count__:e`${T("__count__")} + 1`,__value__:e`${e.raw(p)}(COALESCE(${T("__value__")}, ${S("__value__")}), ${S("__value__")})`}),table:a,values:[w,$,1]}))}}}},Te=async t=>{const n=d.tables[t]?.aggregateIndexes;if(!(!n||n.length===0))for(const o of n)await Re(t,o)},ce=async(t,n,o)=>{const r=d.tables[t]?.aggregateIndexes;if(!(!r||r.length===0))for(const a of r){const _=`${t}::${a.name}`;(ae.get(_)??await Ue(t,a.name))&&await pt(t,a,n,o)}},de=new Map,Pe=async(t,n)=>{const o=ne(t,n);return(await I(i,c,c.tableExists(o))).length>0},Ne=async(t,n)=>{const o=`${t}::rank::${n.name}`,r=de.get(o);if(r!==void 0)return r;if(!await Pe(t,n.name))return de.set(o,!1),!1;const _=d.tables[t];if(!_)return de.set(o,!1),!1;const E=ne(t,n.name);await L(i,c,e`DELETE FROM ${e.identifier(E)}`);const f=n.sortBy.map((p,S)=>J(S)),y=te(["__id__","__partition__",...f]),w=[];await at(i,c,_,t,p=>{if(n.where&&!st(p,n.where))return;const S=Ie(n.partitionBy??[],p),T=n.sortBy.map(A=>H(p[A.field]??null));w.push([p._id,S,...T])});const $=w.map(p=>e`INSERT INTO ${e.identifier(E)} (${y}) VALUES (${re(p)})`);return await ct(i,c,$),de.set(o,!0),!0},me=async t=>{const n=d.tables[t]?.rankIndexes;if(!(!n||n.length===0))for(const o of n)await Ne(t,o)},Z=async(t,n,o,r)=>{const a=d.tables[t],_=a?.rankIndexes;if(!_||_.length===0)return;const E=a?.softDeleteMode?.field,f=E===void 0||r===void 0?void 0:r[E],y=f!=null;for(const w of _){if(o!==void 0&&r!==void 0&&yn(w,o,r))continue;const $=`${t}::rank::${w.name}`;if(!(de.get($)??await Pe(t,w.name)))continue;const T=ne(t,w.name);if(o&&await L(i,c,e`DELETE FROM ${e.identifier(T)} WHERE ${e.identifier("__id__")} = ${n}`),r&&!y){if(w.where&&!st(r,w.where))continue;const A=w.sortBy.map((F,V)=>J(V)),C=te(["__id__","__partition__",...A]),B=Ie(w.partitionBy??[],r),N=w.sortBy.map(F=>H(r[F.field]??null));await L(i,c,e`INSERT INTO ${e.identifier(T)} (${C}) VALUES (${re([n,B,...N])})`)}}},le=It({dialect:c,exec:i,schema:d}),je=new Set;for(const[t,n]of Object.entries(d.tables))for(const o of Object.values(n.triggerMap??{}))je.add(`${t} ${o.timing} ${o.op}`);const P=(t,n,o)=>je.has(`${t} ${n} ${o}`);let He;const j=async(t,n,o)=>{if(pe+=1,pe>lt)throw pe-=1,new Ee(`trigger recursion exceeded ${String(lt)} levels on "${o.table}" — check for a self-triggering write`,"trigger");try{await Jt({ctx:He,event:o,op:n,schema:d,tableName:o.table,timing:t})}finally{pe-=1}},Rt=async(t,n)=>{try{await L(i,c,n)}catch(o){throw m(o)?new Ee(`unique constraint violation on "${t}"`,"unique"):o}},Se=async(t,n)=>(await I(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} = ${n}`))[0],ge=async(t,n,o,r)=>{if(r===void 0)return;const a=e.join(Object.keys(r).map(f=>b(e`${e.identifier(f)}`,r[f])),e` AND `),_=n==="UPDATE"?e`UPDATE ${e.identifier(t)} SET ${o} WHERE ${a}`:e`DELETE FROM ${e.identifier(t)} WHERE ${a}`,E=()=>{throw new Ee(`optimistic concurrency conflict on "${t}" — the row changed during this mutation; refetch and retry`,"occ")};try{if(c.supportsReturning)(await I(i,c,e`${_} RETURNING ${e.identifier("id")}`)).length===0&&E();else{const f=await L(i,c,_);(c.affectedRows?c.affectedRows(f??{rowsAffected:0}):0)===0&&E()}}catch(f){throw m(f)?new Ee(`unique constraint violation on "${t}"`,"unique"):f}},Tt=(t,n,o,r)=>{const a=Object.keys(t.shape);return{columns:["id","_creationTime",...a],values:[n,o,...a.map(_=>H(r[_]??null))]}},mt=async(t,n,o,r)=>{const a=en(n,o.op,o.field,r.by,r.where);if(!a||!await Re(t,a.index))return;const E=Q(t,a.index.name),f=Object.keys(a.partial);if(f.length===(a.index.by??[]).length&&f.length>0){const w=z(a.index.by??[],a.partial),$=await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)} WHERE ${e.identifier("__key__")} = ${w}`);if($.length===0)return[];const p=$[0];return[{key:{...a.partial},value:qe(o.op,{count:p.count,value:oe(p.value)})}]}return f.length>0?void 0:(await I(i,c,e`SELECT ${e.identifier("__key__")} AS key, ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(E)}`)).map(w=>{const $=w;return{key:JSON.parse($.key),value:qe(o.op,{count:$.count,value:oe($.value)})}})},Ke=t=>{const n=d.tables[t]?.shardMode?.kind;return n==="shardBy"||n==="root"},Ge=t=>{throw new g("INTERNAL",`cross-backend relation: a global table cannot load the shard-local relation '${t}' (it spans every shard) — wire a cross-shard reader to support it`)},St=(t,n)=>{if(n?.relationMask!==void 0&&n.with!==void 0&&Object.keys(n.with).length>0)throw new g("MASK_UNSUPPORTED",`masking cannot follow a nested \`with\` across the cross-shard relation hop to "${t}" — the nested rows are hydrated on the serving shard, where the mask policy does not exist. Read the nested relation at its own (masked) call site instead.`);const o={};if(n?.relationBaseWhere)for(const r of Object.keys(d.tables)){const a=n.relationBaseWhere(r);a!==void 0&&(o[r]=a)}return{orderBy:n?.orderBy,relationPolicies:o,where:D(n?.baseWhere,n?.where),with:n?.with}},Ve=(t,n)=>Ke(t)?l?l(t,St(t,n)):Ge(t):U.findMany(t,n),ve=(t,n,o)=>nt(t,{fetcher:Ve,maxRelationKeys:h,relationBaseWhere:o,schema:d,tableName:n}),gt=ln(async(t,n)=>{const o=await I(i,c,e`SELECT * FROM ${e.identifier(t)} WHERE ${e.identifier("id")} IN (${re(n)})`),r=new Map;for(const a of o){const{id:_}=a;typeof _=="string"&&r.set(_,a)}return r}),U={async cdcChangedTables(t,n){if(x)try{return await W(),await xn(i,t,c,{...n,retained:G!==void 0})}catch{return}},async aggregate(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);if(await W(),_e(n.op),n.op==="count")return U.count(t,{baseWhere:n.baseWhere,relationBaseWhere:n.relationBaseWhere,restrictsCounts:n.restrictsCounts,where:n.where});if(!n.field)throw new g("INTERNAL",`aggregate(${t}, { op: "${n.op}" }): "field" is required for non-count reducers`);const r=$e(o.softDeleteMode,void 0),a=D(D(n.baseWhere,n.where),r),_=await ve(a,t,n.relationBaseWhere),E=_!==a;if(o.aggregateIndexes&&!n.baseWhere&&!E&&!r){const S=Qt(o.aggregateIndexes,n.op,n.field,n.where);if(S&&await Re(t,S.index)){const A=z(S.index.by??[],S.key),C=Q(t,S.index.name),N=(await I(i,c,e`SELECT ${e.identifier("__value__")} AS value, ${e.identifier("__count__")} AS count FROM ${e.identifier(C)} WHERE ${e.identifier("__key__")} = ${A}`))[0];return qe(n.op,N===void 0?void 0:{count:N.count,value:oe(N.value)})}}const f=he(_,R),y=e.raw(_e(n.op)),w=e`SELECT ${y}(${O(n.field)}) AS value FROM ${e.identifier(t)}`,p=(await I(i,c,f?e`${w} WHERE ${f}`:w))[0]?.value;return p==null?null:Number(p)},async count(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Xt(n);if(r.restrictsCounts)throw new tt(t);const a=$e(o.softDeleteMode,void 0),_=D(D(r.baseWhere,r.where),a),E=await ve(_,t,r.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!r.baseWhere&&!f&&!a){const p=zt(o.aggregateIndexes,r.where);if(p&&await Re(t,p.index)){const T=z(p.index.by??[],p.key),A=Q(t,p.index.name),C=await I(i,c,e`SELECT ${e.identifier("__value__")} AS value FROM ${e.identifier(A)} WHERE ${e.identifier("__key__")} = ${T}`);return Number(C[0]?.value??0)}}const y=he(E,R),w=e`SELECT COUNT(*) AS count FROM ${e.identifier(t)}`,$=await I(i,c,y?e`${w} WHERE ${y}`:w);return Number($[0]?.count??0)},async delete(t,n,o){const r=await se(t,n);if(!r)return;const a=d.tables[r];if(!a)return;const _=await Se(r,t),E=ie(a,_),f=o?.hard===!0,y=!f&&a.softDeleteMode?a.softDeleteMode.field:void 0;if(!(y&&(!E||E[y]!==null&&E[y]!==void 0))){if(P(r,"before","delete")&&await j("before","delete",{id:t,op:"delete",previous:E??void 0,table:r}),await Yt({deletedId:t,deletedReference:w=>E?.[w],findHolders:async(w,$,p)=>{if(d.tables[w]?.shardMode?.kind==="shardBy")throw new g("INTERNAL",`cross-backend cascade from global '${r}' into shardBy '${w}' is not supported — would require Query Coordinator fan-out across shards`);return(await U.findMany(w,{includeDeleted:f,where:{[$]:p}})).page},onCascade:(w,$)=>U.delete($,void 0,o),onRestrict:w=>{throw new Ee(w,"restrict")},onSetNull:(w,$,p)=>U.patch($,{[p]:null}),schema:d,tableName:r}),await Te(r),await me(r),y&&E){const w={...E,[y]:k()},$=e.join(Object.keys(a.shape).map(p=>e`${e.identifier(p)} = ${H(w[p]??null)}`),e`, `);await ge(r,"UPDATE",$,_),await ce(r,E,w),await Z(r,t,E,void 0),await le(r,t,w,E),await X(r,t,"update",w),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E,table:r});return}await ge(r,"DELETE",void 0,_),Le.delete(t),await ce(r,E??void 0,void 0),await Z(r,t,E??void 0,void 0),await le(r,t,void 0),await X(r,t,"delete"),P(r,"after","delete")&&await j("after","delete",{id:t,op:"delete",previous:E??void 0,table:r})}},async findFirst(t,n={}){return(await U.findMany(t,{...n,limit:1})).page[0]??null},async findFirstOrThrow(t,n={}){const o=await U.findFirst(t,n);if(o===null)throw new Vt(`findFirstOrThrow: no "${t}" document matched`);return o},async findMany(t,n={}){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=Ht(n.orderBy),a=n.cursor?Kt(r,et(n.cursor)):void 0,_=Ve,E=async(N,F,V,be)=>{if(Ke(N))return u?nn(u,N,F,V,be):Ge(N);const ue=d.tables[N];if(!ue)throw new g("INTERNAL",`unknown table: ${N}`);const ee=$e(ue.softDeleteMode,void 0),q={[F]:{in:V}},fe=D(D(q,be),ee),vt=await ve(fe,N,void 0),Ye=he(vt,R),Xe=O(F);let we=e`SELECT ${Xe} AS __fk__, COUNT(*) AS count FROM ${e.identifier(N)}`;Ye&&(we=e`${we} WHERE ${Ye}`),we=e`${we} GROUP BY ${Xe}`;const bt=await I(i,c,we),ze=new Map;for(const Qe of bt)ze.set(Qe.__fk__,Number(Qe.count??0));return ze};let f=D(n.baseWhere,n.where);f=D(f,$e(o.softDeleteMode,n.includeDeleted)),f=await nt(f,{fetcher:_,maxRelationKeys:h,relationBaseWhere:n.relationBaseWhere,schema:d,tableName:t}),a&&(f=f?{AND:[f,a]}:a);const y=he(f,R),w=fn(r);let $=e`SELECT * FROM ${e.identifier(t)}`;y&&($=e`${$} WHERE ${y}`),$=e`${$} ORDER BY ${w}`;const p=typeof n.limit=="number"?Math.max(0,Math.floor(n.limit)):void 0;p!==void 0&&($=e`${$} LIMIT ${e.raw(String(p+1))}`);const S=await I(i,c,$),T=cn(o,S);if(p===void 0)return n.with&&await it({fetcher:_,groupedCounter:E,parents:T,...ot(n),schema:d,tableName:t,with:n.with}),{continueCursor:null,isDone:!0,page:rt(T,n.select,n.with)};const A=T.length>p,C=A?T.slice(0,p):T,B=C.at(-1);return n.with&&await it({fetcher:_,groupedCounter:E,parents:C,...ot(n),schema:d,tableName:t,with:n.with}),{continueCursor:A&&B?Gt(B,r):null,isDone:!A,page:rt(C,n.select,n.with)}},async get(t,n){const o=await se(t,n);if(!o)return null;const r=d.tables[o];return r?ie(r,await gt.load(o,t)):null},async groupBy(t,n){const o=d.tables[t];if(!o)throw new g("INTERNAL",`unknown table: ${t}`);await W();const r=n.agg??{op:"count"};if(_e(r.op),r.op!=="count"&&!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);const a=$e(o.softDeleteMode,void 0),_=D(D(n.baseWhere,n.where),a),E=await ve(_,t,n.relationBaseWhere),f=E!==_;if(o.aggregateIndexes&&!n.baseWhere&&!f&&!a){const T=await mt(t,o.aggregateIndexes,r,n);if(T!==void 0)return T}const y=he(E,R),w=n.by.map(T=>e`${O(T)} AS ${e.identifier(T)}`);if(r.op==="count")w.push(e`COUNT(*) AS value`);else{if(!r.field)throw new g("INTERNAL",`groupBy(${t}, { agg: { op: "${r.op}" } }): "field" is required for non-count reducers`);w.push(e`${e.raw(_e(r.op))}(${O(r.field)}) AS value`)}const $=e.join(n.by.map(T=>O(T)),e`, `);let p=e`SELECT ${e.join(w,e`, `)} FROM ${e.identifier(t)}`;y&&(p=e`${p} WHERE ${y}`),p=e`${p} GROUP BY ${$}`;const S=await I(i,c,p);return En(n.by,S)},async insert(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);await W();const a=wn(r,n,Y);Me(r,a);let _,E=!0;o?.clientId!==void 0?(jt(o.clientId),_=o.clientId):o?.allowExplicitId&&typeof a._id=="string"?_=a._id:(_=M(),E=!1);const f=o?.allowExplicitId&&typeof a._creationTime=="number"?a._creationTime:k(),y={...a,_creationTime:f,_id:_};P(t,"before","insert")&&await j("before","insert",{doc:{...y},id:_,op:"insert",table:t}),await Te(t),await me(t);const{columns:w,values:$}=Tt(r,_,f,a);return await Rt(t,e`INSERT INTO ${e.identifier(t)} (${te(w)}) VALUES (${re($)})`),E&&Le.set(_,t),await ce(t,void 0,y),await Z(t,_,void 0,y),await le(t,_,y),await X(t,_,"insert",y),P(t,"after","insert")&&await j("after","insert",{doc:y,id:_,op:"insert",table:t}),_},normalizeId(t,n){return Pt(d,t,n)},async patch(t,n,o){const r=await se(t,o);if(!r)throw new g("INTERNAL",`document not found: ${t}`);const a=d.tables[r];if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=await Se(r,t),E=ie(a,_);if(!E)throw new g("INTERNAL",`document not found: ${t}`);const f={...E,...n,_id:t};ut(a,n,f,Y),Me(a,f,!0),P(r,"before","update")&&await j("before","update",{doc:{...f},id:t,op:"update",previous:E,table:r}),await Te(r),await me(r);const y=Object.keys(a.shape),w=e.join(y.map($=>e`${e.identifier($)} = ${H(f[$]??null)}`),e`, `);await ge(r,"UPDATE",w,_),await ce(r,E,f),await Z(r,t,E,f),await le(r,t,f,E),await X(r,t,"update",f),P(r,"after","update")&&await j("after","update",{doc:f,id:t,op:"update",previous:E,table:r})},async restore(t,n){const o=await se(t,n);if(!o)throw new g("INTERNAL",`document not found: ${t}`);const r=d.tables[o],a=r?.softDeleteMode?.field;if(!r||!a)throw new g("INTERNAL",`ctx.db.restore: table "${o}" is not a .softDelete() table`);const _=await Se(o,t),E=_?.[a]!==null&&_?.[a]!==void 0;if(await U.patch(t,{[a]:null},n),E){const f=ie(r,_);f!==null&&await Z(o,t,void 0,{...f,[a]:null})}},query(t){const n=d.tables[t];if(!n)throw new g("INTERNAL",`unknown table: ${t}`);const o="the legacy query()/withIndex() reader is not available on the D1 (global) backend; use findMany",r=[],a=f=>r.every(y=>y(f)),_=async(f,y)=>{await W();const w=r.length>0,$=await Mt(i,c,n,t,f,qt(w?void 0:y));if(!w)return y===void 0&&Dt($),$;const p=$.filter(S=>a(S));return y===void 0?p:p.slice(0,y)},E=f=>{const y={async*[Symbol.asyncIterator](){if(!f)throw new g("INTERNAL",o);yield*await _(f,void 0)},async collect(){if(!f)throw new g("INTERNAL",o);return _(f,void 0)},async collectWithScores(){throw new g("INTERNAL",`collectWithScores() is not supported on \`.global()\` tables (table "${t}") — relevance scores are not yet surfaced on this backend; use .collect() instead`)},filter(w){return r.push(w),y},async first(){if(!f)throw new g("INTERNAL",o);return(await _(f,1))[0]??null},order(){return y},async paginate(w){if(!f)throw new g("INTERNAL",o);const $=kt(w);return Nt(await _(f,Ot($)),$)},async take(w){if(!f)throw new g("INTERNAL",o);return _(f,w)},async unique(){if(!f)throw new g("INTERNAL",o);const w=await _(f,2);if(w.length>1)throw new sn(`unique() on table "${t}" matched ${String(w.length)} documents; expected at most one`);return w[0]??null},withGeoIndex(){throw new g("INTERNAL",`geo indexes are not supported on \`.global()\` tables (table "${t}") — geospatial queries run only on sharded tables`)},withIndex(){throw new g("INTERNAL",o)},withSearchIndex(w,$){const p=(n.searchIndexes??[]).find(T=>T.name===w);if(!p)throw new g("INTERNAL",`unknown search index "${w}" on table "${t}"`);const S={definition:p,field:p.field,filters:[],hasQuery:!1,indexName:w,query:""};if($(At(S,t,Lt(p.language))),!S.hasQuery)throw new g("INTERNAL",`search index "${w}" on table "${t}" requires a .search(field, query) call`);return E(S)}};return y};return E(void 0)},async rank(t,n,o){const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(F=>F.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(o.restrictsCounts)throw new tt(t);if(await W(),!await Ne(t,a))return null;const E=typeof o.row=="string"?o.row:o.row._id;if(!E)return null;const f=ne(t,a.name),y=a.sortBy.map((F,V)=>J(V)),w=te(["__partition__",...y]),p=(await I(i,c,e`SELECT ${w} FROM ${e.identifier(f)} WHERE ${e.identifier("__id__")} = ${E}`))[0];if(!p)return null;const S=p.__partition__,T=D(o.baseWhere,o.where);Je(T,d,t,"rank");const A=Ze(a,T);if(A&&Ie(a.partitionBy??[],A)!==S)return null;const C=pn(c.name,a,y,p,E),B=await I(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}${C?e` AND (${C})`:e``}`),N=await I(i,c,e`SELECT COUNT(*) AS c FROM ${e.identifier(f)} WHERE ${e.identifier("__partition__")} = ${S}`);return{position:Number(B[0]?.c??0)+1,total:Number(N[0]?.c??0)}},async rankPage(t,n,o={}){Je(D(o.baseWhere,o.where),d,t,"rankPage");const r=d.tables[t];if(!r)throw new g("INTERNAL",`unknown table: ${t}`);const a=r.rankIndexes?.find(q=>q.name===n);if(!a)throw new g("INTERNAL",`unknown rankIndex "${n}" on table "${t}"`);if(await W(),!await Ne(t,a))return{continueCursor:null,isDone:!0,page:[]};const E=ne(t,a.name),f=a.sortBy.map((q,fe)=>J(fe)),y=Math.max(1,Math.min(1e3,Math.floor(o.take??100))),w=D(o.baseWhere,o.where),$=Ze(a,w),p=Tn(a,f),S=e.join(p.map(q=>e`${e.identifier(q.column)} ${e.raw(q.direction==="desc"?"DESC":"ASC")}`),e`, `),T=[];if($&&T.push(e`${e.identifier("__partition__")} = ${Ie(a.partitionBy??[],$)}`),o.cursor){const q=Rn(c.name,p,et(o.cursor));q!==void 0&&T.push(q)}const A=te([ye,"__partition__",...f]);let C=e`SELECT ${A} FROM ${e.identifier(E)}`;T.length>0&&(C=e`${C} WHERE ${e.join(T,e` AND `)}`),C=e`${C} ORDER BY ${S} LIMIT ${e.raw(String(y+1))}`;const B=await I(i,c,C),N=B.length>y,F=N?B.slice(0,y):B,V=F.map(q=>q[ye]),be=await mn(i,c,r,t,V);let ue=null;const ee=F.at(-1);if(N&&ee!==void 0){const q=[ee.__partition__,...f.map(fe=>ee[fe]),ee[ye]];ue=Sn(q)}return{continueCursor:ue,isDone:!N,page:be}},async replace(t,n,o,r){const a=await se(t,o);if(!a)throw new g("INTERNAL",`document not found: ${t}`);const _=d.tables[a];if(!_)throw new g("INTERNAL",`document not found: ${t}`);const E=await Se(a,t);if(E===void 0)throw new g("INTERNAL",`document not found: ${t}`);const y=Ut(d,a,"update")||(_.aggregateIndexes??[]).length>0||(_.rankIndexes??[]).length>0?ie(_,E)??void 0:void 0,w=r?.allowExplicitId&&typeof n._creationTime=="number"?n._creationTime:k(),$={...n,_creationTime:w,_id:t};ut(_,n,$,Y),Me(_,$),P(a,"before","update")&&await j("before","update",{doc:{...$},id:t,op:"update",previous:y,table:a}),await Te(a),await me(a);const p=Object.keys(_.shape),S=e.join([e`${e.identifier("_creationTime")} = ${w}`,...p.map(T=>e`${e.identifier(T)} = ${H($[T]??null)}`)],e`, `);await ge(a,"UPDATE",S,E),await ce(a,y,$),await Z(a,t,y,$),await le(a,t,$,y),await X(a,t,"update",$),P(a,"after","update")&&await j("after","update",{doc:$,id:t,op:"update",previous:y,table:a})}};return He={db:U,scheduler:ht},U};export{Qn as backfillSqlSearchIndexes,Yn as createSqlCtxDb,Zn as decodeGlobalRow,xn as readSqlCdcChangedTables,Vn as readSqlCdcChanges,$t as readSqlCdcFloor,Cn as runSqlAggregateMigrations,Dn as runSqlCdcMigration,In as runSqlGlobalTableMigrations,kn as runSqlRankMigrations,Ct as runSqlSearchMigrations,Fn as sweepSqlCdcRetention};
@@ -0,0 +1 @@
1
+ import{sql as t}from"drizzle-orm";import{migrateSearchState as Z,readSearchBackfillState as P,writeSearchBackfillState as I}from"./SEARCH_STATE_TABLE-DA3LgCT0.mjs";import{LunoraError as h}from"@lunora/errors";import{unionAll as ee}from"@lunora/shard-engine";import{queryRun as S,decodeRows as z,queryAll as D,queryBatch as ne,createIndexIfNotExists as U,columnRefSql as F,serializeColumnValue as te,forEachRowPaged as ie}from"./decodeGlobalRow-BKIjk_Zk.mjs";const oe=["de","en","es","fr","it","nl","none","pt"],re=e=>oe.includes(e),se="a an and are as at be but by for if in into is it no not of on or such that the their then there these they this to was will with",ae="aber als am an auch auf aus bei bin bis bist da dass der den des dem die das denn dir du ein eine für hat ich im in ist mit nicht noch nur oder sich sie sind über und von vor war wie wir zu zum zur",ce="a al como con de del el en es la las lo los mas no o para pero por que se su sus un una uno y ya",ue="au aux avec ce ces dans de des du elle en et eux il je la le les leur lui ma mais me même mes moi mon ne nos notre nous on ou par pas pour qu que qui sa se ses son sur ta te tes toi ton tu un une vos votre vous y",fe="a ai al alla anche che chi ci coi col come con da dal degli dei del della di do e ed gli ha hai hanno i il in la le lo ma mi ne nei nel non o per più quale quanto se si sono su sul tra un una uno vi",de="aan al als bij dan dat de der deze die dit door een en er het hij ij in is je kan me men met mij na naar niet nog nu of om ons ook op over te tot uit van voor was wat we wij zij zijn zo",le="a ao aos as até com como da das de do dos e em entre era essa esse esta este eu foi há isso já mais mas me mesmo meu na nas no nos num numa o os ou para pela pelo por qual que quem se sem seu só sua também te tem um uma você",me=/[\u0300-\u036F]/gu,$e=/[\u0080-\u{10FFFF}]/u,he=/[\p{L}\p{N}]+/gu,W=e=>$e.test(e)?e.normalize("NFD").replaceAll(me,"").normalize("NFC").toLowerCase():e.toLowerCase(),g=e=>new Set(W(e).split(" ")),we={de:g(ae),en:g(se),es:g(ce),fr:g(ue),it:g(fe),nl:g(de),none:new Set,pt:g(le)},Se=2,pe=256,M=new Map,y=e=>{const n=e!==void 0&&re(e)?e:"none",i=M.get(n);if(i)return i;const o=we[n],r=a=>{const c=(W(a).match(he)??[]).filter(u=>u.length<=pe);return o.size===0?c:c.filter(u=>!o.has(u))},s={document:r,profile:`${n}-v${String(Se)}`,query:a=>{const c=r(a);return c.filter((u,f)=>c.lastIndexOf(u)===f)}};return M.set(n,s),s},Ee=(e,n)=>e.profile!==n?{cursor:void 0,finished:!1,wipe:e.cursor!==void 0||e.done}:{cursor:e.cursor,finished:e.done,wipe:!1},ge=e=>{const n=atob(e),i=Uint8Array.from(n,o=>o.codePointAt(0)??0);return new TextDecoder().decode(i)},_e=()=>new h("BAD_REQUEST","invalid cursor"),j=16,B=8,w=1024,v=(e,n)=>n.query(e),ye=(e,n)=>{if(!n)return{exact:!0,lower:e,upper:e};const i=[...e].at(-1)??"",o=(i.codePointAt(0)??0)+1;if(o>=55296&&o<=57343||o>1114111)return{exact:!0,lower:e,upper:e};const r=e.slice(0,e.length-i.length);return{exact:!1,lower:e,upper:r+String.fromCodePoint(o)}},ze=(e,n,i)=>{const o={eq:(r,s)=>{if(!e.definition.filterFields?.includes(r))throw new h("INTERNAL",`field "${r}" is not a filter field of search index "${e.indexName}" on table "${n}"`);if(e.filters.length>=B)throw new h("BAD_REQUEST",`search index "${e.indexName}" on table "${n}": at most ${String(B)} .eq() filters are supported per search query`);return e.filters.push({field:r,value:s}),o},search:(r,s)=>{const a=e;if(r!==a.definition.field)throw new h("INTERNAL",`search index "${a.indexName}" on table "${n}" indexes "${a.definition.field}", not "${r}"`);const c=v(s,i).length;if(c>j)throw new h("BAD_REQUEST",`search index "${a.indexName}" on table "${n}": at most ${String(j)} search terms are supported (got ${String(c)})`);return a.field=r,a.query=s,a.hasQuery=!0,o}};return o},We=e=>{if(e.length>w)throw new h("BAD_REQUEST",`more than ${String(w)} documents match this search — narrow it with filters or read it a page at a time with .paginate()`)},Qe=e=>Math.min(e.offset+e.numItems+1,w),Te=e=>btoa(`search:${String(e)}`),Ne=e=>{let n;try{n=ge(e)}catch{return}if(!n.startsWith("search:"))return;const i=Number(n.slice(7));return Number.isInteger(i)&&i>=0?i:void 0},Ge=e=>{if(typeof e.endCursor=="string")throw new h("BAD_REQUEST","bounded (endCursor) pagination is not supported on search queries — relevance order has no stable range boundary");if(!Number.isFinite(e.numItems))throw new h("BAD_REQUEST",`search pagination needs a finite numItems, got ${String(e.numItems)}`);const n=Math.max(0,Math.floor(e.numItems)),i=e.cursor?Ne(e.cursor):0;if(i===void 0)throw _e();if(i+n>=w)throw new h("BAD_REQUEST",`search pagination reaches the ${String(w)}-document limit (offset ${String(i)} + ${String(n)} requested) — a page must end below the cap so the probe row that answers \`hasMore\` still fits: retry with numItems ${String(Math.max(1,w-i-1))} or fewer, or narrow the query or the filters instead`);return{numItems:n,offset:i}},Ve=(e,n)=>{const i=n.offset+n.numItems,o=n.numItems>0&&e.length>i;return{continueCursor:o?Te(i):null,isDone:!o,page:e.slice(n.offset,i)}},Je=e=>{if(e===void 0)return w+1;if(!Number.isFinite(e))return w;const n=Math.max(0,Math.floor(e));if(n>w)throw new h("BAD_REQUEST",`search returns at most ${String(w)} documents (asked for ${String(n)}) — narrow the query or paginate instead`);return n},Ie=(e,n)=>{if(!n.includes("."))return e[n];let i=e;for(const o of n.split(".")){if(i===null||typeof i!="object"||Array.isArray(i))return;i=i[o]}return i},R=(e,n)=>`${e}__fts_${n}`,ve="__text__",l="__id__",T="__token__",L="__n__",Re=1e3,Q=(e,n)=>n.document(e),C=(e,n)=>Ie(e,n),Ae=e=>typeof e=="string"?e:e==null?"":typeof e=="number"||typeof e=="bigint"||typeof e=="boolean"?String(e):JSON.stringify(e)??"",be=(e,n,i)=>e!==void 0&&n!==void 0&&C(e,i.field)===C(n,i.field),Le=(e,n)=>Q(Ae(C(e,n.field)),y(n.language)).slice(0,Re),O=(e,n)=>Le(e,n).join(" "),Ce=(e,n)=>{const i=new Map;for(const o of Q(e,n))i.set(o,(i.get(o)??0)+1);return i},A=async(e,n,i,o)=>{await S(e,n,t`DELETE FROM ${t.identifier(i)} WHERE ${t.identifier(l)} = ${o}`)},b=(e,n)=>e.name==="mysql"?t`${t.identifier(n)}(191)`:e.textPatternOperatorClass===void 0?t`${t.identifier(n)}`:t`${t.identifier(n)} ${t.raw(e.textPatternOperatorClass)}`,k=50,De=(e,n)=>n?t`${t.identifier(T)} LIKE ${`${e}%`}`:t`${t.identifier(T)} = ${e}`,G=(e,n)=>{const i=n.filters.map(o=>t`m.${F(o.field)} = ${te(o.value)}`);return e.softDeleteMode&&i.push(t`m.${F(e.softDeleteMode.field)} IS NULL`),i},V=async(e,n,i,o,r,s,a)=>{const c=G(i,r);let u=t`SELECT m.* FROM (${a}) s JOIN ${t.identifier(o)} m ON m.${t.identifier("id")} = s.${t.identifier(l)}`;return c.length>0&&(u=t`${u} WHERE ${t.join(c,t` AND `)}`),u=t`${u} ORDER BY s.${t.identifier("__score__")} DESC, m.${t.identifier("_creationTime")} DESC, m.${t.identifier("id")} ASC LIMIT ${t.raw(String(s))}`,z(i,await D(e,n,u))},Oe=async(e,n,i,o,r,s)=>{const a=v(r.query,y(r.definition.language));if(a.length===0)return[];const c=R(o,r.indexName),u=a.length-1,f=a.map((d,_)=>De(d,_===u)),m=t.join(f,t` OR `),$=f.map(d=>t`SUM(CASE WHEN ${d} THEN ${t.identifier(L)} ELSE 0 END)`),E=t.join($.map(d=>t`${d} > 0`),t` AND `),p=t`SELECT ${t.identifier(l)}, ${t.join($,t` + `)} AS ${t.identifier("__score__")} FROM ${t.identifier(c)} WHERE ${m} GROUP BY ${t.identifier(l)} HAVING ${E}`;return V(e,n,i,o,r,s,p)},qe=async(e,n,i,o,r,s)=>{const a=v(r.query,y(r.definition.language));if(a.length===0)return[];const c=R(o,r.indexName),u=`${c}__vocab`,f=a.length-1,m=a.map((p,d)=>{const _=ye(p,d===f),K=_.exact?t`${t.identifier("term")} = ${_.lower}`:t`${t.identifier("term")} >= ${_.lower} AND ${t.identifier("term")} < ${_.upper}`;return t`SELECT ${t.identifier("doc")}, ${t.raw(String(d))} AS ${t.identifier("__term__")}, COUNT(*) AS ${t.identifier("__n__")} FROM ${t.identifier(u)} WHERE ${K} GROUP BY ${t.identifier("doc")}`}),$=a.map((p,d)=>t`SUM(CASE WHEN u.${t.identifier("__term__")} = ${t.raw(String(d))} THEN u.${t.identifier("__n__")} ELSE 0 END)`),E=t`SELECT f.${t.identifier(l)} AS ${t.identifier(l)}, ${t.join($,t` + `)} AS ${t.identifier("__score__")} FROM (${ee(m)}) u JOIN ${t.identifier(c)} f ON f.rowid = u.${t.identifier("doc")} GROUP BY f.${t.identifier(l)} HAVING ${t.join($.map(p=>t`${p} > 0`),t` AND `)}`;return V(e,n,i,o,r,s,E)},xe=async(e,n,i,o,r,s)=>{const a=n.nativeTextSearch,c=v(r.query,y(r.definition.language));if(!a||c.length===0)return[];const u=R(o,r.indexName),f=[a.matches(u,c),...G(i,r)],m=t`SELECT m.* FROM ${t.identifier(u)} JOIN ${t.identifier(o)} m ON m.${t.identifier("id")} = ${t.identifier(u)}.${t.identifier(l)} WHERE ${t.join(f,t` AND `)} ORDER BY ${a.rank(u,c)} DESC, m.${t.identifier("_creationTime")} DESC, m.${t.identifier("id")} ASC LIMIT ${t.raw(String(s))}`;return z(i,await D(e,n,m))},Ue={ensureCompanion:async(e,n,i)=>{const{integer:o,key:r}=n.companionTypes;await S(e,n,t`CREATE TABLE IF NOT EXISTS ${t.identifier(i)} (${t.identifier(T)} ${t.raw(r)} NOT NULL, ${t.identifier(l)} ${t.raw(r)} NOT NULL, ${t.identifier(L)} ${t.raw(o)} NOT NULL)`),await U(e,n,{columns:t`${b(n,T)}, ${b(n,l)}`,name:`${i}__btree`,table:i,unique:!1}),await U(e,n,{columns:b(n,l),name:`${i}__by_id`,table:i,unique:!1})},indexDocument:async(e,n,i,o,r,s)=>{await A(e,n,i,o);const a=[...Ce(O(r,s),y(s.language))],c=t.join([T,l,L].map(f=>t.identifier(f)),t`, `),u=[];for(let f=0;f<a.length;f+=k){const m=t.join(a.slice(f,f+k).map(([$,E])=>t`(${$}, ${o}, ${E})`),t`, `);u.push(t`INSERT INTO ${t.identifier(i)} (${c}) VALUES ${m}`)}await ne(e,n,u)},name:"inverted",runSearch:Oe},Fe={ensureCompanion:async(e,n,i)=>{await S(e,n,t`CREATE VIRTUAL TABLE IF NOT EXISTS ${t.identifier(i)} USING fts5(${t.identifier(ve)}, ${t.identifier(l)} UNINDEXED)`),await S(e,n,t`CREATE VIRTUAL TABLE IF NOT EXISTS ${t.identifier(`${i}__vocab`)} USING fts5vocab(${t.identifier(i)}, ${t.raw("instance")})`)},indexDocument:async(e,n,i,o,r,s)=>{await A(e,n,i,o),await S(e,n,t`INSERT INTO ${t.identifier(i)} (${t.identifier("__text__")}, ${t.identifier(l)}) VALUES (${O(r,s)}, ${o})`)},name:"fts5",runSearch:qe},Me={ensureCompanion:async(e,n,i)=>{const o=n.nativeTextSearch;if(o){await S(e,n,o.createCompanion(i,n.companionTypes.key));for(const r of o.createIndexes(i))await S(e,n,r)}},indexDocument:async(e,n,i,o,r,s)=>{const a=n.nativeTextSearch;a&&(await A(e,n,i,o),await S(e,n,a.indexDocument(i,o,O(r,s))))},name:"native",runSearch:xe},N=(e,n)=>e.strategy==="native"&&n.nativeTextSearch!==void 0?Me:n.supportsFts5?Fe:Ue,J=(e,n)=>`${y(e.language).profile}/${N(e,n).name}`,q=function*(e){for(const[n,i]of Object.entries(e.tables)){const o=i.searchIndexes;if(!(i.shardMode!==void 0&&i.shardMode.kind!=="global"||!o))for(const r of o)yield[n,i,r]}},x=(e,n)=>R(e,n.name),Xe=async(e,n,i,o,r,s)=>N(r.definition,n).runSearch(e,n,i,o,r,s),H=200,X=async(e,n,i,o,r)=>{const s=x(o,r),a=N(r,n),c=J(r,n),u=Ee(await P(e,n,s),c);if(u.finished)return!0;if(u.wipe&&(await S(e,n,t`DELETE FROM ${t.identifier(s)}`),await I(e,n,s,void 0,!1,c)),(await D(e,n,n.tableExists(o))).length===0)return await I(e,n,s,void 0,!0,c),!0;let m=0,$=u.cursor;await ie(e,n,i,o,async p=>{m+=1;const d=p._id;typeof d=="string"&&($=d,await a.indexDocument(e,n,s,d,p,r))},{after:u.cursor,limit:H});const E=m<H;return await I(e,n,s,$,E,c),E},Y=async(e,n,i)=>{await Z(e,i);for(const[o,,r]of q(n)){const s=x(o,r),a=J(r,i),c=await P(e,i,s);c.profile!==void 0&&c.profile!==a&&(await S(e,i,t`DROP TABLE IF EXISTS ${t.identifier(s)}`),await I(e,i,s,void 0,!1,a)),await N(r,i).ensureCompanion(e,i,s)}},Ye=async(e,n,i)=>{await Y(e,n,i);for(const[o,r,s]of q(n))s.staged||await X(e,i,r,o,s)},Ke=async(e,n,i)=>{await Y(e,n,i);for(const[o,r,s]of q(n)){let a=!1;for(;!a;)a=await X(e,i,r,o,s)}},Ze=e=>{const{dialect:n,exec:i,schema:o}=e;return async(r,s,a,c)=>{const u=o.tables[r]?.searchIndexes;if(!(!u||u.length===0))for(const f of u){if(be(c,a,f))continue;const m=x(r,f);if(a){await N(f,n).indexDocument(i,n,m,s,a,f);continue}await A(i,n,m,s)}}};export{ze as A,Ge as C,Ve as R,Je as T,Xe as a,Qe as b,Ze as c,Ke as d,y as q,Ye as r,We as x};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/sql-store",
3
- "version": "1.0.0-alpha.93",
3
+ "version": "1.0.0-alpha.95",
4
4
  "description": "Internal dialect-parameterized SQL store core for Lunora .global() backends (D1, PlanetScale)",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@lunora/errors": "1.0.0-alpha.24",
54
- "@lunora/shard-engine": "1.0.0-alpha.41",
54
+ "@lunora/shard-engine": "1.0.0-alpha.43",
55
55
  "drizzle-orm": "^0.45.2"
56
56
  },
57
57
  "engines": {
@@ -1 +0,0 @@
1
- import{sql as t}from"drizzle-orm";import{migrateSearchState as Z,readSearchBackfillState as P,writeSearchBackfillState as I}from"./SEARCH_STATE_TABLE-DA3LgCT0.mjs";import{LunoraError as h}from"@lunora/errors";import{unionAll as ee}from"@lunora/shard-engine";import{queryRun as S,decodeRows as z,queryAll as D,queryBatch as ne,createIndexIfNotExists as F,columnRefSql as U,serializeColumnValue as te,forEachRowPaged as ie}from"./decodeGlobalRow-BKIjk_Zk.mjs";const oe=["de","en","es","fr","it","nl","none","pt"],re=e=>oe.includes(e),se="a an and are as at be but by for if in into is it no not of on or such that the their then there these they this to was will with",ae="aber als am an auch auf aus bei bin bis bist da dass der den des dem die das denn dir du ein eine für hat ich im in ist mit nicht noch nur oder sich sie sind über und von vor war wie wir zu zum zur",ce="a al como con de del el en es la las lo los mas no o para pero por que se su sus un una uno y ya",ue="au aux avec ce ces dans de des du elle en et eux il je la le les leur lui ma mais me même mes moi mon ne nos notre nous on ou par pas pour qu que qui sa se ses son sur ta te tes toi ton tu un une vos votre vous y",fe="a ai al alla anche che chi ci coi col come con da dal degli dei del della di do e ed gli ha hai hanno i il in la le lo ma mi ne nei nel non o per più quale quanto se si sono su sul tra un una uno vi",de="aan al als bij dan dat de der deze die dit door een en er het hij ij in is je kan me men met mij na naar niet nog nu of om ons ook op over te tot uit van voor was wat we wij zij zijn zo",le="a ao aos as até com como da das de do dos e em entre era essa esse esta este eu foi há isso já mais mas me mesmo meu na nas no nos num numa o os ou para pela pelo por qual que quem se sem seu só sua também te tem um uma você",me=/[\u0300-\u036F]/gu,$e=/[\u0080-\u{10FFFF}]/u,he=/[\p{L}\p{N}]+/gu,W=e=>$e.test(e)?e.normalize("NFD").replaceAll(me,"").normalize("NFC").toLowerCase():e.toLowerCase(),g=e=>new Set(W(e).split(" ")),we={de:g(ae),en:g(se),es:g(ce),fr:g(ue),it:g(fe),nl:g(de),none:new Set,pt:g(le)},Se=2,pe=256,M=new Map,y=e=>{const n=e!==void 0&&re(e)?e:"none",i=M.get(n);if(i)return i;const o=we[n],r=a=>{const c=(W(a).match(he)??[]).filter(u=>u.length<=pe);return o.size===0?c:c.filter(u=>!o.has(u))},s={document:r,profile:`${n}-v${String(Se)}`,query:a=>{const c=r(a);return c.filter((u,f)=>c.lastIndexOf(u)===f)}};return M.set(n,s),s},Ee=(e,n)=>e.profile!==n?{cursor:void 0,finished:!1,wipe:e.cursor!==void 0||e.done}:{cursor:e.cursor,finished:e.done,wipe:!1},ge=/[\u0080-\u{10FFFF}]/u,_e=e=>{if(!ge.test(e))return btoa(e);const n=new TextEncoder().encode(e);let i="";for(const o of n)i+=String.fromCodePoint(o);return btoa(i)},ye=e=>{const n=atob(e),i=Uint8Array.from(n,o=>o.codePointAt(0)??0);return new TextDecoder().decode(i)},Te=()=>new h("BAD_REQUEST","invalid cursor"),j=16,B=8,w=1024,v=(e,n)=>n.query(e),Ne=(e,n)=>{if(!n)return{exact:!0,lower:e,upper:e};const i=[...e].at(-1)??"",o=(i.codePointAt(0)??0)+1;if(o>=55296&&o<=57343||o>1114111)return{exact:!0,lower:e,upper:e};const r=e.slice(0,e.length-i.length);return{exact:!1,lower:e,upper:r+String.fromCodePoint(o)}},Qe=(e,n,i)=>{const o={eq:(r,s)=>{if(!e.definition.filterFields?.includes(r))throw new h("INTERNAL",`field "${r}" is not a filter field of search index "${e.indexName}" on table "${n}"`);if(e.filters.length>=B)throw new h("BAD_REQUEST",`search index "${e.indexName}" on table "${n}": at most ${String(B)} .eq() filters are supported per search query`);return e.filters.push({field:r,value:s}),o},search:(r,s)=>{const a=e;if(r!==a.definition.field)throw new h("INTERNAL",`search index "${a.indexName}" on table "${n}" indexes "${a.definition.field}", not "${r}"`);const c=v(s,i).length;if(c>j)throw new h("BAD_REQUEST",`search index "${a.indexName}" on table "${n}": at most ${String(j)} search terms are supported (got ${String(c)})`);return a.field=r,a.query=s,a.hasQuery=!0,o}};return o},Ge=e=>{if(e.length>w)throw new h("BAD_REQUEST",`more than ${String(w)} documents match this search — narrow it with filters or read it a page at a time with .paginate()`)},Ve=e=>Math.min(e.offset+e.numItems+1,w),Ie=e=>_e(`search:${String(e)}`),ve=e=>{let n;try{n=ye(e)}catch{return}if(!n.startsWith("search:"))return;const i=Number(n.slice(7));return Number.isInteger(i)&&i>=0?i:void 0},Je=e=>{if(typeof e.endCursor=="string")throw new h("BAD_REQUEST","bounded (endCursor) pagination is not supported on search queries — relevance order has no stable range boundary");if(!Number.isFinite(e.numItems))throw new h("BAD_REQUEST",`search pagination needs a finite numItems, got ${String(e.numItems)}`);const n=Math.max(0,Math.floor(e.numItems)),i=e.cursor?ve(e.cursor):0;if(i===void 0)throw Te();if(i+n>=w)throw new h("BAD_REQUEST",`search pagination reaches the ${String(w)}-document limit (offset ${String(i)} + ${String(n)} requested) — a page must end below the cap so the probe row that answers \`hasMore\` still fits: retry with numItems ${String(Math.max(1,w-i-1))} or fewer, or narrow the query or the filters instead`);return{numItems:n,offset:i}},Xe=(e,n)=>{const i=n.offset+n.numItems,o=n.numItems>0&&e.length>i;return{continueCursor:o?Ie(i):null,isDone:!o,page:e.slice(n.offset,i)}},Ye=e=>{if(e===void 0)return w+1;if(!Number.isFinite(e))return w;const n=Math.max(0,Math.floor(e));if(n>w)throw new h("BAD_REQUEST",`search returns at most ${String(w)} documents (asked for ${String(n)}) — narrow the query or paginate instead`);return n},be=(e,n)=>{if(!n.includes("."))return e[n];let i=e;for(const o of n.split(".")){if(i===null||typeof i!="object"||Array.isArray(i))return;i=i[o]}return i},b=(e,n)=>`${e}__fts_${n}`,Re="__text__",l="__id__",T="__token__",C="__n__",Ae=1e3,Q=(e,n)=>n.document(e),L=(e,n)=>be(e,n),Ce=e=>typeof e=="string"?e:e==null?"":typeof e=="number"||typeof e=="bigint"||typeof e=="boolean"?String(e):JSON.stringify(e)??"",Le=(e,n,i)=>e!==void 0&&n!==void 0&&L(e,i.field)===L(n,i.field),De=(e,n)=>Q(Ce(L(e,n.field)),y(n.language)).slice(0,Ae),O=(e,n)=>De(e,n).join(" "),Oe=(e,n)=>{const i=new Map;for(const o of Q(e,n))i.set(o,(i.get(o)??0)+1);return i},R=async(e,n,i,o)=>{await S(e,n,t`DELETE FROM ${t.identifier(i)} WHERE ${t.identifier(l)} = ${o}`)},A=(e,n)=>e.name==="mysql"?t`${t.identifier(n)}(191)`:e.textPatternOperatorClass===void 0?t`${t.identifier(n)}`:t`${t.identifier(n)} ${t.raw(e.textPatternOperatorClass)}`,k=50,qe=(e,n)=>n?t`${t.identifier(T)} LIKE ${`${e}%`}`:t`${t.identifier(T)} = ${e}`,G=(e,n)=>{const i=n.filters.map(o=>t`m.${U(o.field)} = ${te(o.value)}`);return e.softDeleteMode&&i.push(t`m.${U(e.softDeleteMode.field)} IS NULL`),i},V=async(e,n,i,o,r,s,a)=>{const c=G(i,r);let u=t`SELECT m.* FROM (${a}) s JOIN ${t.identifier(o)} m ON m.${t.identifier("id")} = s.${t.identifier(l)}`;return c.length>0&&(u=t`${u} WHERE ${t.join(c,t` AND `)}`),u=t`${u} ORDER BY s.${t.identifier("__score__")} DESC, m.${t.identifier("_creationTime")} DESC, m.${t.identifier("id")} ASC LIMIT ${t.raw(String(s))}`,z(i,await D(e,n,u))},xe=async(e,n,i,o,r,s)=>{const a=v(r.query,y(r.definition.language));if(a.length===0)return[];const c=b(o,r.indexName),u=a.length-1,f=a.map((d,_)=>qe(d,_===u)),m=t.join(f,t` OR `),$=f.map(d=>t`SUM(CASE WHEN ${d} THEN ${t.identifier(C)} ELSE 0 END)`),E=t.join($.map(d=>t`${d} > 0`),t` AND `),p=t`SELECT ${t.identifier(l)}, ${t.join($,t` + `)} AS ${t.identifier("__score__")} FROM ${t.identifier(c)} WHERE ${m} GROUP BY ${t.identifier(l)} HAVING ${E}`;return V(e,n,i,o,r,s,p)},Fe=async(e,n,i,o,r,s)=>{const a=v(r.query,y(r.definition.language));if(a.length===0)return[];const c=b(o,r.indexName),u=`${c}__vocab`,f=a.length-1,m=a.map((p,d)=>{const _=Ne(p,d===f),K=_.exact?t`${t.identifier("term")} = ${_.lower}`:t`${t.identifier("term")} >= ${_.lower} AND ${t.identifier("term")} < ${_.upper}`;return t`SELECT ${t.identifier("doc")}, ${t.raw(String(d))} AS ${t.identifier("__term__")}, COUNT(*) AS ${t.identifier("__n__")} FROM ${t.identifier(u)} WHERE ${K} GROUP BY ${t.identifier("doc")}`}),$=a.map((p,d)=>t`SUM(CASE WHEN u.${t.identifier("__term__")} = ${t.raw(String(d))} THEN u.${t.identifier("__n__")} ELSE 0 END)`),E=t`SELECT f.${t.identifier(l)} AS ${t.identifier(l)}, ${t.join($,t` + `)} AS ${t.identifier("__score__")} FROM (${ee(m)}) u JOIN ${t.identifier(c)} f ON f.rowid = u.${t.identifier("doc")} GROUP BY f.${t.identifier(l)} HAVING ${t.join($.map(p=>t`${p} > 0`),t` AND `)}`;return V(e,n,i,o,r,s,E)},Ue=async(e,n,i,o,r,s)=>{const a=n.nativeTextSearch,c=v(r.query,y(r.definition.language));if(!a||c.length===0)return[];const u=b(o,r.indexName),f=[a.matches(u,c),...G(i,r)],m=t`SELECT m.* FROM ${t.identifier(u)} JOIN ${t.identifier(o)} m ON m.${t.identifier("id")} = ${t.identifier(u)}.${t.identifier(l)} WHERE ${t.join(f,t` AND `)} ORDER BY ${a.rank(u,c)} DESC, m.${t.identifier("_creationTime")} DESC, m.${t.identifier("id")} ASC LIMIT ${t.raw(String(s))}`;return z(i,await D(e,n,m))},Me={ensureCompanion:async(e,n,i)=>{const{integer:o,key:r}=n.companionTypes;await S(e,n,t`CREATE TABLE IF NOT EXISTS ${t.identifier(i)} (${t.identifier(T)} ${t.raw(r)} NOT NULL, ${t.identifier(l)} ${t.raw(r)} NOT NULL, ${t.identifier(C)} ${t.raw(o)} NOT NULL)`),await F(e,n,{columns:t`${A(n,T)}, ${A(n,l)}`,name:`${i}__btree`,table:i,unique:!1}),await F(e,n,{columns:A(n,l),name:`${i}__by_id`,table:i,unique:!1})},indexDocument:async(e,n,i,o,r,s)=>{await R(e,n,i,o);const a=[...Oe(O(r,s),y(s.language))],c=t.join([T,l,C].map(f=>t.identifier(f)),t`, `),u=[];for(let f=0;f<a.length;f+=k){const m=t.join(a.slice(f,f+k).map(([$,E])=>t`(${$}, ${o}, ${E})`),t`, `);u.push(t`INSERT INTO ${t.identifier(i)} (${c}) VALUES ${m}`)}await ne(e,n,u)},name:"inverted",runSearch:xe},je={ensureCompanion:async(e,n,i)=>{await S(e,n,t`CREATE VIRTUAL TABLE IF NOT EXISTS ${t.identifier(i)} USING fts5(${t.identifier(Re)}, ${t.identifier(l)} UNINDEXED)`),await S(e,n,t`CREATE VIRTUAL TABLE IF NOT EXISTS ${t.identifier(`${i}__vocab`)} USING fts5vocab(${t.identifier(i)}, ${t.raw("instance")})`)},indexDocument:async(e,n,i,o,r,s)=>{await R(e,n,i,o),await S(e,n,t`INSERT INTO ${t.identifier(i)} (${t.identifier("__text__")}, ${t.identifier(l)}) VALUES (${O(r,s)}, ${o})`)},name:"fts5",runSearch:Fe},Be={ensureCompanion:async(e,n,i)=>{const o=n.nativeTextSearch;if(o){await S(e,n,o.createCompanion(i,n.companionTypes.key));for(const r of o.createIndexes(i))await S(e,n,r)}},indexDocument:async(e,n,i,o,r,s)=>{const a=n.nativeTextSearch;a&&(await R(e,n,i,o),await S(e,n,a.indexDocument(i,o,O(r,s))))},name:"native",runSearch:Ue},N=(e,n)=>e.strategy==="native"&&n.nativeTextSearch!==void 0?Be:n.supportsFts5?je:Me,J=(e,n)=>`${y(e.language).profile}/${N(e,n).name}`,q=function*(e){for(const[n,i]of Object.entries(e.tables)){const o=i.searchIndexes;if(!(i.shardMode!==void 0&&i.shardMode.kind!=="global"||!o))for(const r of o)yield[n,i,r]}},x=(e,n)=>b(e,n.name),Ke=async(e,n,i,o,r,s)=>N(r.definition,n).runSearch(e,n,i,o,r,s),H=200,X=async(e,n,i,o,r)=>{const s=x(o,r),a=N(r,n),c=J(r,n),u=Ee(await P(e,n,s),c);if(u.finished)return!0;if(u.wipe&&(await S(e,n,t`DELETE FROM ${t.identifier(s)}`),await I(e,n,s,void 0,!1,c)),(await D(e,n,n.tableExists(o))).length===0)return await I(e,n,s,void 0,!0,c),!0;let m=0,$=u.cursor;await ie(e,n,i,o,async p=>{m+=1;const d=p._id;typeof d=="string"&&($=d,await a.indexDocument(e,n,s,d,p,r))},{after:u.cursor,limit:H});const E=m<H;return await I(e,n,s,$,E,c),E},Y=async(e,n,i)=>{await Z(e,i);for(const[o,,r]of q(n)){const s=x(o,r),a=J(r,i),c=await P(e,i,s);c.profile!==void 0&&c.profile!==a&&(await S(e,i,t`DROP TABLE IF EXISTS ${t.identifier(s)}`),await I(e,i,s,void 0,!1,a)),await N(r,i).ensureCompanion(e,i,s)}},Ze=async(e,n,i)=>{await Y(e,n,i);for(const[o,r,s]of q(n))s.staged||await X(e,i,r,o,s)},en=async(e,n,i)=>{await Y(e,n,i);for(const[o,r,s]of q(n)){let a=!1;for(;!a;)a=await X(e,i,r,o,s)}},nn=e=>{const{dialect:n,exec:i,schema:o}=e;return async(r,s,a,c)=>{const u=o.tables[r]?.searchIndexes;if(!(!u||u.length===0))for(const f of u){if(Le(c,a,f))continue;const m=x(r,f);if(a){await N(f,n).indexDocument(i,n,m,s,a,f);continue}await R(i,n,m,s)}}};export{Ge as C,Ve as I,Je as R,Xe as T,Ke as a,en as b,nn as c,y as q,Ze as r,Qe as x,Ye as y};