@lunora/d1 1.0.0-alpha.87 → 1.0.0-alpha.89

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.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { SchemaLike, DatabaseWriterLike } from '@lunora/shard-engine';
2
+ export { applyCdcChanges } from '@lunora/shard-engine';
2
3
  import { SqlCtxDbOptions, SqlCtxExec, createSqlCtxDb, readSqlCdcChanges, SqlDialect } from '@lunora/sql-store';
3
4
  export { type SqlCtxExec as D1Exec, type SqlCtxDbOptions, type SqlCtxExec, createSqlCtxDb } from '@lunora/sql-store';
4
5
  import { D1DatabaseLike, D1SessionLike, D1PreparedStatementLike } from '@lunora/platform';
@@ -26,8 +27,16 @@ declare const readD1CdcChanges: (exec: SqlCtxExec, options?: {
26
27
  limit?: number;
27
28
  sinceSeq?: number;
28
29
  }) => ReturnType<typeof readSqlCdcChanges>;
29
- /** Drop changelog entries at or below a checkpointed `throughSeq`. */
30
- declare const trimD1CdcChanges: (exec: SqlCtxExec, throughSeq: number) => Promise<void>;
30
+ /**
31
+ * Delete `.global()` changelog entries older than `retentionMs`, if this writer
32
+ * wins the fleet's sweep lease. See `sweepSqlCdcRetention`.
33
+ *
34
+ * Replaces the seq-based `trimD1CdcChanges`, which took a checkpoint no caller
35
+ * could compute: the log is shared across every shard and region, so no single
36
+ * caller knows a `seq` that is safe for all of them. A time window is a bound
37
+ * they can all reason about, and the lease is what stops them racing.
38
+ */
39
+ declare const sweepD1CdcRetention: (exec: SqlCtxExec, retentionMs: number, now: number) => Promise<void>;
31
40
  /** One exported row: `doc` is reconstructed from the column tuple. */
32
41
  interface ExportRow {
33
42
  doc: Record<string, unknown>;
@@ -447,4 +456,4 @@ declare const retryingExec: (exec: SqlCtxExec, options?: D1RetryOptions) => SqlC
447
456
  * table probing. The rest of the per-statement shaping is drizzle's.
448
457
  */
449
458
  declare const sqliteDialect: SqlDialect;
450
- export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1RetryOptions, D1Session, D1TimeoutError, type ExportGlobalArgs, type FacetGlobalColumnOptions, type ExportRow as GlobalExportRow, type GlobalFacetResult, type GlobalFacetValue, type GlobalFilterClause, type ImportError as GlobalImportError, type ImportResult as GlobalImportResult, type GlobalTableInfo, type GlobalTablePage, type ImportGlobalArgs, type Migration, MigrationRunner, type MigrationRunnerResult, type ReadGlobalTablePageOptions, backfillD1SearchIndexes, createD1ContextDatabase as createD1CtxDb, exportGlobalRows, facetGlobalColumn, importGlobalRows, isTransientD1Error, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges, withD1Retry };
459
+ export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1RetryOptions, D1Session, D1TimeoutError, type ExportGlobalArgs, type FacetGlobalColumnOptions, type ExportRow as GlobalExportRow, type GlobalFacetResult, type GlobalFacetValue, type GlobalFilterClause, type ImportError as GlobalImportError, type ImportResult as GlobalImportResult, type GlobalTableInfo, type GlobalTablePage, type ImportGlobalArgs, type Migration, MigrationRunner, type MigrationRunnerResult, type ReadGlobalTablePageOptions, backfillD1SearchIndexes, createD1ContextDatabase as createD1CtxDb, exportGlobalRows, facetGlobalColumn, importGlobalRows, isTransientD1Error, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, sweepD1CdcRetention, withD1Retry };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { SchemaLike, DatabaseWriterLike } from '@lunora/shard-engine';
2
+ export { applyCdcChanges } from '@lunora/shard-engine';
2
3
  import { SqlCtxDbOptions, SqlCtxExec, createSqlCtxDb, readSqlCdcChanges, SqlDialect } from '@lunora/sql-store';
3
4
  export { type SqlCtxExec as D1Exec, type SqlCtxDbOptions, type SqlCtxExec, createSqlCtxDb } from '@lunora/sql-store';
4
5
  import { D1DatabaseLike, D1SessionLike, D1PreparedStatementLike } from '@lunora/platform';
@@ -26,8 +27,16 @@ declare const readD1CdcChanges: (exec: SqlCtxExec, options?: {
26
27
  limit?: number;
27
28
  sinceSeq?: number;
28
29
  }) => ReturnType<typeof readSqlCdcChanges>;
29
- /** Drop changelog entries at or below a checkpointed `throughSeq`. */
30
- declare const trimD1CdcChanges: (exec: SqlCtxExec, throughSeq: number) => Promise<void>;
30
+ /**
31
+ * Delete `.global()` changelog entries older than `retentionMs`, if this writer
32
+ * wins the fleet's sweep lease. See `sweepSqlCdcRetention`.
33
+ *
34
+ * Replaces the seq-based `trimD1CdcChanges`, which took a checkpoint no caller
35
+ * could compute: the log is shared across every shard and region, so no single
36
+ * caller knows a `seq` that is safe for all of them. A time window is a bound
37
+ * they can all reason about, and the lease is what stops them racing.
38
+ */
39
+ declare const sweepD1CdcRetention: (exec: SqlCtxExec, retentionMs: number, now: number) => Promise<void>;
31
40
  /** One exported row: `doc` is reconstructed from the column tuple. */
32
41
  interface ExportRow {
33
42
  doc: Record<string, unknown>;
@@ -447,4 +456,4 @@ declare const retryingExec: (exec: SqlCtxExec, options?: D1RetryOptions) => SqlC
447
456
  * table probing. The rest of the per-statement shaping is drizzle's.
448
457
  */
449
458
  declare const sqliteDialect: SqlDialect;
450
- export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1RetryOptions, D1Session, D1TimeoutError, type ExportGlobalArgs, type FacetGlobalColumnOptions, type ExportRow as GlobalExportRow, type GlobalFacetResult, type GlobalFacetValue, type GlobalFilterClause, type ImportError as GlobalImportError, type ImportResult as GlobalImportResult, type GlobalTableInfo, type GlobalTablePage, type ImportGlobalArgs, type Migration, MigrationRunner, type MigrationRunnerResult, type ReadGlobalTablePageOptions, backfillD1SearchIndexes, createD1ContextDatabase as createD1CtxDb, exportGlobalRows, facetGlobalColumn, importGlobalRows, isTransientD1Error, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges, withD1Retry };
459
+ export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1RetryOptions, D1Session, D1TimeoutError, type ExportGlobalArgs, type FacetGlobalColumnOptions, type ExportRow as GlobalExportRow, type GlobalFacetResult, type GlobalFacetValue, type GlobalFilterClause, type ImportError as GlobalImportError, type ImportResult as GlobalImportResult, type GlobalTableInfo, type GlobalTablePage, type ImportGlobalArgs, type Migration, MigrationRunner, type MigrationRunnerResult, type ReadGlobalTablePageOptions, backfillD1SearchIndexes, createD1ContextDatabase as createD1CtxDb, exportGlobalRows, facetGlobalColumn, importGlobalRows, isTransientD1Error, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, sweepD1CdcRetention, withD1Retry };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{exportGlobalRows as o,importGlobalRows as a,selectGlobalTables as t}from"./packem_shared/exportGlobalRows-Cc8cXltm.mjs";import{D1Client as i,D1Session as n}from"./packem_shared/D1Client-CzS0Qfa6.mjs";import{backfillD1SearchIndexes as D,createD1CtxDb as b,readD1CdcChanges as g,runD1AggregateMigrations as x,runD1CdcMigration as c,runD1GlobalTableMigrations as m,runD1RankMigrations as f,runD1SearchMigrations as p,trimD1CdcChanges as u}from"./packem_shared/backfillD1SearchIndexes-By6bbCLe.mjs";import{facetGlobalColumn as d,listGlobalTables as G,readGlobalTablePage as M}from"./packem_shared/facetGlobalColumn-D1npxpva.mjs";import{MigrationRunner as h}from"./packem_shared/MigrationRunner-SadkIbU5.mjs";import{D1TimeoutError as S,isTransientD1Error as w,retryingExec as E,withD1Retry as k}from"./packem_shared/D1TimeoutError-D4YUqZPk.mjs";import{default as y}from"./packem_shared/sqliteDialect-DZoYJOa-.mjs";import{createSqlCtxDb as I}from"@lunora/sql-store";export{i as D1Client,n as D1Session,S as D1TimeoutError,h as MigrationRunner,D as backfillD1SearchIndexes,b as createD1CtxDb,I as createSqlCtxDb,o as exportGlobalRows,d as facetGlobalColumn,a as importGlobalRows,w as isTransientD1Error,G as listGlobalTables,g as readD1CdcChanges,M as readGlobalTablePage,E as retryingExec,x as runD1AggregateMigrations,c as runD1CdcMigration,m as runD1GlobalTableMigrations,f as runD1RankMigrations,p as runD1SearchMigrations,t as selectGlobalTables,y as sqliteDialect,u as trimD1CdcChanges,k as withD1Retry};
1
+ import{exportGlobalRows as o,importGlobalRows as t,selectGlobalTables as a}from"./packem_shared/exportGlobalRows-CZ8_RtFF.mjs";import{D1Client as i,D1Session as n}from"./packem_shared/D1Client-CzS0Qfa6.mjs";import{backfillD1SearchIndexes as D,createD1CtxDb as b,readD1CdcChanges as p,runD1AggregateMigrations as x,runD1CdcMigration as c,runD1GlobalTableMigrations as g,runD1RankMigrations as f,runD1SearchMigrations as m,sweepD1CdcRetention as C}from"./packem_shared/backfillD1SearchIndexes-Cmdl902w.mjs";import{facetGlobalColumn as d,listGlobalTables as G,readGlobalTablePage as M}from"./packem_shared/facetGlobalColumn-BPToW_z0.mjs";import{MigrationRunner as T}from"./packem_shared/MigrationRunner-SadkIbU5.mjs";import{D1TimeoutError as w,isTransientD1Error as S,retryingExec as y,withD1Retry as E}from"./packem_shared/D1TimeoutError-D4YUqZPk.mjs";import{default as q}from"./packem_shared/sqliteDialect-DZoYJOa-.mjs";import{applyCdcChanges as I}from"@lunora/shard-engine";import{createSqlCtxDb as j}from"@lunora/sql-store";export{i as D1Client,n as D1Session,w as D1TimeoutError,T as MigrationRunner,I as applyCdcChanges,D as backfillD1SearchIndexes,b as createD1CtxDb,j as createSqlCtxDb,o as exportGlobalRows,d as facetGlobalColumn,t as importGlobalRows,S as isTransientD1Error,G as listGlobalTables,p as readD1CdcChanges,M as readGlobalTablePage,y as retryingExec,x as runD1AggregateMigrations,c as runD1CdcMigration,g as runD1GlobalTableMigrations,f as runD1RankMigrations,m as runD1SearchMigrations,a as selectGlobalTables,q as sqliteDialect,C as sweepD1CdcRetention,E as withD1Retry};
@@ -0,0 +1 @@
1
+ import{backfillSqlSearchIndexes as r,createSqlCtxDb as o,readSqlCdcChanges as i,runSqlAggregateMigrations as c,runSqlCdcMigration as s,runSqlGlobalTableMigrations as l,runSqlRankMigrations as g,runSqlSearchMigrations as D,sweepSqlCdcRetention as S}from"@lunora/sql-store";import{createSqlCtxDb as w,decodeGlobalRow as G}from"@lunora/sql-store";import n from"./sqliteDialect-DZoYJOa-.mjs";const b=e=>o({...e,dialect:n}),q=(e,t)=>l(e,t,n),u=(e,t)=>c(e,t,n),M=(e,t)=>g(e,t,n),x=(e,t)=>D(e,t,n),h=(e,t)=>r(e,t,n),p=e=>s(e,n),f=(e,t={})=>i(e,t,n),m=(e,t,a)=>S(e,n,t,a);export{h as backfillD1SearchIndexes,b as createD1CtxDb,w as createSqlCtxDb,G as decodeGlobalRow,f as readD1CdcChanges,u as runD1AggregateMigrations,p as runD1CdcMigration,q as runD1GlobalTableMigrations,M as runD1RankMigrations,x as runD1SearchMigrations,m as sweepD1CdcRetention};
@@ -1 +1 @@
1
- import{toErrorBody as u}from"@lunora/errors";import{runD1GlobalTableMigrations as p}from"./backfillD1SearchIndexes-By6bbCLe.mjs";import{quoteIdentifier as f}from"./quoteIdentifier-CObIFRhb.mjs";import{decodeGlobalRow as w}from"@lunora/sql-store";const E=200,R=(i,o)=>{const e=t=>i.tables[t]?.shardMode?.kind==="global";return o&&o.length>0?o.filter(t=>e(t)):Object.keys(i.tables).filter(t=>e(t))},m=(i,o,e)=>{const t=i.tables[o];return t?w(t,e):{_creationTime:e._creationTime,_id:e.id}},O=async function*(i,o,e){const t=R(o,e.tables),s=e.batchSize??E;await p(i,o);for(const r of t){const n=f(r);let c,l=!0;for(;l;){const a=c===void 0?await i.all(`SELECT * FROM ${n} ORDER BY "id" LIMIT ?`,[s]):await i.all(`SELECT * FROM ${n} WHERE "id" > ? ORDER BY "id" LIMIT ?`,[c,s]);for(const b of a)yield{doc:m(o,r,b),table:r};const d=a.at(-1);d!==void 0&&(c=String(d.id)),l=a.length===s}}},k=(i,o,e)=>{const t=i.tables[o];if(!t)return`unknown table: ${o}`;for(const[s,r]of Object.entries(t.shape)){const n=e[s],c=r.kind==="optional";if(n===void 0&&c)continue;const l=r.parse;if(typeof l=="function")try{l(n)}catch(a){const d=a instanceof Error?a.message:String(a);return`field "${s}": ${d}`}}},g=async(i,o,e,t)=>{try{return o?(await o.all(`SELECT 1 AS hit FROM ${f(e)} WHERE "id" = ? LIMIT 1`,[t])).length>0:await i.get(t)!==null}catch{return!1}},y=async(i,o,e,t,s)=>{const{doc:r,table:n}=t;if(o.tables[n]?.shardMode?.kind!=="global")return{kind:"skip"};if(!r||typeof r!="object"||Array.isArray(r))return{error:{code:"BAD_ROW",line:s,message:"row is missing or malformed `doc`",table:n},kind:"error"};const c=k(o,n,r);if(c!==void 0)return{error:{code:"VALIDATION_ERROR",line:s,message:c,table:n},kind:"error"};const l=typeof r._id=="string"?r._id:void 0;if(l!==void 0&&await g(i,e.exec,n,l))return{kind:"conflict"};try{return await i.insert(n,r,{allowExplicitId:!0}),{inserted:n,kind:"inserted"}}catch(a){const{body:d}=u(a,{fallbackCode:"INSERT_FAILED"});return{error:{code:d.code,line:s,message:d.message,table:n},kind:"error"}}},v=async(i,o,e)=>{const t=[],s={};let r=0,n=(e.startLine??1)-1;for(const c of e.rows){n+=1;const l=c.line??n,a=await y(i,o,e,c,l);switch(a.kind){case"conflict":{r+=1;break}case"error":{t.push(a.error);break}case"inserted":{s[a.inserted]=(s[a.inserted]??0)+1;break}}}return{conflicts:r,errors:t,inserted:s}};export{O as exportGlobalRows,v as importGlobalRows,R as selectGlobalTables};
1
+ import{toErrorBody as u}from"@lunora/errors";import{runD1GlobalTableMigrations as p}from"./backfillD1SearchIndexes-Cmdl902w.mjs";import{quoteIdentifier as f}from"./quoteIdentifier-CObIFRhb.mjs";import{decodeGlobalRow as w}from"@lunora/sql-store";const E=200,R=(i,o)=>{const e=t=>i.tables[t]?.shardMode?.kind==="global";return o&&o.length>0?o.filter(t=>e(t)):Object.keys(i.tables).filter(t=>e(t))},m=(i,o,e)=>{const t=i.tables[o];return t?w(t,e):{_creationTime:e._creationTime,_id:e.id}},O=async function*(i,o,e){const t=R(o,e.tables),s=e.batchSize??E;await p(i,o);for(const r of t){const n=f(r);let c,l=!0;for(;l;){const a=c===void 0?await i.all(`SELECT * FROM ${n} ORDER BY "id" LIMIT ?`,[s]):await i.all(`SELECT * FROM ${n} WHERE "id" > ? ORDER BY "id" LIMIT ?`,[c,s]);for(const b of a)yield{doc:m(o,r,b),table:r};const d=a.at(-1);d!==void 0&&(c=String(d.id)),l=a.length===s}}},k=(i,o,e)=>{const t=i.tables[o];if(!t)return`unknown table: ${o}`;for(const[s,r]of Object.entries(t.shape)){const n=e[s],c=r.kind==="optional";if(n===void 0&&c)continue;const l=r.parse;if(typeof l=="function")try{l(n)}catch(a){const d=a instanceof Error?a.message:String(a);return`field "${s}": ${d}`}}},g=async(i,o,e,t)=>{try{return o?(await o.all(`SELECT 1 AS hit FROM ${f(e)} WHERE "id" = ? LIMIT 1`,[t])).length>0:await i.get(t)!==null}catch{return!1}},y=async(i,o,e,t,s)=>{const{doc:r,table:n}=t;if(o.tables[n]?.shardMode?.kind!=="global")return{kind:"skip"};if(!r||typeof r!="object"||Array.isArray(r))return{error:{code:"BAD_ROW",line:s,message:"row is missing or malformed `doc`",table:n},kind:"error"};const c=k(o,n,r);if(c!==void 0)return{error:{code:"VALIDATION_ERROR",line:s,message:c,table:n},kind:"error"};const l=typeof r._id=="string"?r._id:void 0;if(l!==void 0&&await g(i,e.exec,n,l))return{kind:"conflict"};try{return await i.insert(n,r,{allowExplicitId:!0}),{inserted:n,kind:"inserted"}}catch(a){const{body:d}=u(a,{fallbackCode:"INSERT_FAILED"});return{error:{code:d.code,line:s,message:d.message,table:n},kind:"error"}}},v=async(i,o,e)=>{const t=[],s={};let r=0,n=(e.startLine??1)-1;for(const c of e.rows){n+=1;const l=c.line??n,a=await y(i,o,e,c,l);switch(a.kind){case"conflict":{r+=1;break}case"error":{t.push(a.error);break}case"inserted":{s[a.inserted]=(s[a.inserted]??0)+1;break}}}return{conflicts:r,errors:t,inserted:s}};export{O as exportGlobalRows,v as importGlobalRows,R as selectGlobalTables};
@@ -1 +1 @@
1
- import{LunoraError as E}from"@lunora/errors";import{runD1GlobalTableMigrations as T}from"./backfillD1SearchIndexes-By6bbCLe.mjs";import{quoteIdentifier as i}from"./quoteIdentifier-CObIFRhb.mjs";import{decodeGlobalRow as O}from"@lunora/sql-store";const R=50,p=500,I=30,$=200,M=(t,a,n)=>Math.min(Math.max(t,a),n),C=/^sqlite_|^_cf_|^d1_|^__cdc|__agg_|__rank_|__fts_/u,y=t=>C.test(t),b=/password|secret|token|hash|salt|credential/iu,v=async t=>(await t.all("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name",[])).map(n=>String(n.name)).filter(n=>!y(n)),S=async(t,a,n)=>{if(await T(t,a),!(await v(t)).includes(n))throw new E("UNKNOWN_TABLE",`unknown table: ${n}`,{status:404})},N=async(t,a,n="",o=[])=>{const s=await t.all(`SELECT COUNT(*) AS c FROM ${a}${n}`,o);return Number(s[0]?.c??0)},h=(t,a,n)=>t.tables[a]!==void 0&&n==="_id"?"id":n,A=(t,a,n,o)=>{const s=[],r=[];for(const e of o??[]){if(!n.includes(e.column))throw new E("UNKNOWN_COLUMN",`unknown column: ${e.column}`,{status:404});if(t.tables[a]===void 0&&b.test(e.column))throw new E("FORBIDDEN",`cannot filter on a redacted column: ${e.column}`,{status:403});const l=i(h(t,a,e.column));e.value===null||e.value===void 0?s.push(`${l} IS NULL`):(s.push(`${l} = ?`),r.push(e.value))}return{params:r,where:s.length>0?` WHERE ${s.join(" AND ")}`:""}},g=(t,a,n)=>{const o=t.tables[a];if(o)return O(o,n);const s={};for(const[r,e]of Object.entries(n))s[r]=e!=null&&b.test(r)?"•••":e;return s},L=async(t,a,n)=>{const o=a.tables[n];return o?["_id","_creationTime",...Object.keys(o.shape)]:(await t.all(`PRAGMA table_info(${i(n)})`,[])).map(r=>String(r.name))},U=async(t,a,n)=>{if(a.tables[n])return;const o=await t.all(`PRAGMA foreign_key_list(${i(n)})`,[]);if(o.length===0)return;const s={};for(const r of o){const e=String(r.from),l=String(r.table);s[e]??=l}return s},q=async(t,a)=>{await T(t,a);const n=await v(t);return Promise.all(n.map(async o=>({name:o,rowCount:await N(t,i(o))})))},D=async(t,a,n)=>{const{table:o}=n;await S(t,a,o);const s=M(Math.trunc(n.limit??R),1,p),r=Math.max(0,Math.trunc(n.offset??0)),e=i(o),l=await L(t,a,o),{params:w,where:u}=A(a,o,l,n.filters),f=await N(t,e,u,w),m=(await t.all(`SELECT * FROM ${e}${u} LIMIT ? OFFSET ?`,[...w,s,r])).map(c=>g(a,o,c)),_=await U(t,a,o);return _===void 0?{columns:l,rows:m,total:f}:{columns:l,refs:_,rows:m,total:f}},B=async(t,a,n)=>{const{column:o,table:s}=n;await S(t,a,s);const r=await L(t,a,s);if(!r.includes(o))throw new E("UNKNOWN_COLUMN",`unknown column: ${o}`,{status:404});const e=i(s),{params:l,where:w}=A(a,s,r,n.filters);if(a.tables[s]===void 0&&b.test(o)){const c=await N(t,e,w,l);return{truncated:!1,values:c===0?[]:[{count:c,value:"•••"}]}}const u=M(Math.trunc(n.limit??I),1,$),f=i(h(a,s,o)),d=await t.all(`SELECT ${f} AS value, COUNT(*) AS count FROM ${e}${w} GROUP BY ${f} ORDER BY count DESC LIMIT ?`,[...l,u+1]),m=d.length>u,_=m?d.slice(0,u):d;return{truncated:m,values:_.map(c=>({count:Number(c.count),value:c.value}))}};export{B as facetGlobalColumn,q as listGlobalTables,D as readGlobalTablePage};
1
+ import{LunoraError as E}from"@lunora/errors";import{runD1GlobalTableMigrations as T}from"./backfillD1SearchIndexes-Cmdl902w.mjs";import{quoteIdentifier as i}from"./quoteIdentifier-CObIFRhb.mjs";import{decodeGlobalRow as O}from"@lunora/sql-store";const R=50,p=500,I=30,$=200,M=(t,a,n)=>Math.min(Math.max(t,a),n),C=/^sqlite_|^_cf_|^d1_|^__cdc|__agg_|__rank_|__fts_/u,y=t=>C.test(t),b=/password|secret|token|hash|salt|credential/iu,v=async t=>(await t.all("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name",[])).map(n=>String(n.name)).filter(n=>!y(n)),S=async(t,a,n)=>{if(await T(t,a),!(await v(t)).includes(n))throw new E("UNKNOWN_TABLE",`unknown table: ${n}`,{status:404})},N=async(t,a,n="",o=[])=>{const s=await t.all(`SELECT COUNT(*) AS c FROM ${a}${n}`,o);return Number(s[0]?.c??0)},h=(t,a,n)=>t.tables[a]!==void 0&&n==="_id"?"id":n,A=(t,a,n,o)=>{const s=[],r=[];for(const e of o??[]){if(!n.includes(e.column))throw new E("UNKNOWN_COLUMN",`unknown column: ${e.column}`,{status:404});if(t.tables[a]===void 0&&b.test(e.column))throw new E("FORBIDDEN",`cannot filter on a redacted column: ${e.column}`,{status:403});const l=i(h(t,a,e.column));e.value===null||e.value===void 0?s.push(`${l} IS NULL`):(s.push(`${l} = ?`),r.push(e.value))}return{params:r,where:s.length>0?` WHERE ${s.join(" AND ")}`:""}},g=(t,a,n)=>{const o=t.tables[a];if(o)return O(o,n);const s={};for(const[r,e]of Object.entries(n))s[r]=e!=null&&b.test(r)?"•••":e;return s},L=async(t,a,n)=>{const o=a.tables[n];return o?["_id","_creationTime",...Object.keys(o.shape)]:(await t.all(`PRAGMA table_info(${i(n)})`,[])).map(r=>String(r.name))},U=async(t,a,n)=>{if(a.tables[n])return;const o=await t.all(`PRAGMA foreign_key_list(${i(n)})`,[]);if(o.length===0)return;const s={};for(const r of o){const e=String(r.from),l=String(r.table);s[e]??=l}return s},q=async(t,a)=>{await T(t,a);const n=await v(t);return Promise.all(n.map(async o=>({name:o,rowCount:await N(t,i(o))})))},D=async(t,a,n)=>{const{table:o}=n;await S(t,a,o);const s=M(Math.trunc(n.limit??R),1,p),r=Math.max(0,Math.trunc(n.offset??0)),e=i(o),l=await L(t,a,o),{params:w,where:u}=A(a,o,l,n.filters),f=await N(t,e,u,w),m=(await t.all(`SELECT * FROM ${e}${u} LIMIT ? OFFSET ?`,[...w,s,r])).map(c=>g(a,o,c)),_=await U(t,a,o);return _===void 0?{columns:l,rows:m,total:f}:{columns:l,refs:_,rows:m,total:f}},B=async(t,a,n)=>{const{column:o,table:s}=n;await S(t,a,s);const r=await L(t,a,s);if(!r.includes(o))throw new E("UNKNOWN_COLUMN",`unknown column: ${o}`,{status:404});const e=i(s),{params:l,where:w}=A(a,s,r,n.filters);if(a.tables[s]===void 0&&b.test(o)){const c=await N(t,e,w,l);return{truncated:!1,values:c===0?[]:[{count:c,value:"•••"}]}}const u=M(Math.trunc(n.limit??I),1,$),f=i(h(a,s,o)),d=await t.all(`SELECT ${f} AS value, COUNT(*) AS count FROM ${e}${w} GROUP BY ${f} ORDER BY count DESC LIMIT ?`,[...l,u+1]),m=d.length>u,_=m?d.slice(0,u):d;return{truncated:m,values:_.map(c=>({count:Number(c.count),value:c.value}))}};export{B as facetGlobalColumn,q as listGlobalTables,D as readGlobalTablePage};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/d1",
3
- "version": "1.0.0-alpha.87",
3
+ "version": "1.0.0-alpha.89",
4
4
  "description": "D1 adapter for Lunora .global() tables, wrapping the Sessions API for read-your-writes",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,10 +50,10 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/errors": "1.0.0-alpha.22",
54
- "@lunora/platform": "1.0.0-alpha.17",
55
- "@lunora/shard-engine": "1.0.0-alpha.37",
56
- "@lunora/sql-store": "1.0.0-alpha.89",
53
+ "@lunora/errors": "1.0.0-alpha.24",
54
+ "@lunora/platform": "1.0.0-alpha.18",
55
+ "@lunora/shard-engine": "1.0.0-alpha.39",
56
+ "@lunora/sql-store": "1.0.0-alpha.91",
57
57
  "drizzle-orm": "^0.45.2"
58
58
  },
59
59
  "engines": {
@@ -1 +0,0 @@
1
- import{backfillSqlSearchIndexes as n,createSqlCtxDb as e,readSqlCdcChanges as o,runSqlAggregateMigrations as i,runSqlCdcMigration as c,runSqlGlobalTableMigrations as s,runSqlRankMigrations as l,runSqlSearchMigrations as g,trimSqlCdcChanges as D}from"@lunora/sql-store";import{createSqlCtxDb as G,decodeGlobalRow as R}from"@lunora/sql-store";import t from"./sqliteDialect-DZoYJOa-.mjs";const d=a=>e({...a,dialect:t}),b=(a,r)=>s(a,r,t),q=(a,r)=>i(a,r,t),u=(a,r)=>l(a,r,t),M=(a,r)=>g(a,r,t),h=(a,r)=>n(a,r,t),x=a=>c(a,t),m=(a,r={})=>o(a,r,t),f=(a,r)=>D(a,r,t);export{h as backfillD1SearchIndexes,d as createD1CtxDb,G as createSqlCtxDb,R as decodeGlobalRow,m as readD1CdcChanges,q as runD1AggregateMigrations,x as runD1CdcMigration,b as runD1GlobalTableMigrations,u as runD1RankMigrations,M as runD1SearchMigrations,f as trimD1CdcChanges};