@lunora/d1 1.0.0-alpha.52 → 1.0.0-alpha.53

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,6 +1,8 @@
1
- import { SchemaLike, DatabaseWriterLike } from '@lunora/do';
1
+ import { SchemaLike, DatabaseWriterLike } from '@lunora/shard-engine';
2
2
  import { SqlCtxDbOptions, SqlCtxExec, createSqlCtxDb, readSqlCdcChanges, SqlDialect } from '@lunora/sql-store';
3
3
  export { type SqlCtxExec as D1Exec, type SqlCtxDbOptions, type SqlCtxExec, createSqlCtxDb } from '@lunora/sql-store';
4
+ import { D1DatabaseLike, D1SessionLike, D1PreparedStatementLike } from '@lunora/platform';
5
+ export type { D1DatabaseLike, D1PreparedStatementLike, D1SessionLike } from '@lunora/platform';
4
6
  import { BatchItem, BatchResponse } from 'drizzle-orm/batch';
5
7
  import { DrizzleD1Database } from 'drizzle-orm/d1';
6
8
  /** The D1 store options — the shared store options minus `dialect` (the SQLite dialect is injected for you). */
@@ -96,34 +98,6 @@ interface D1ExecLike {
96
98
  * `errors`; the rest land.
97
99
  */
98
100
  declare const importGlobalRows: (writer: DatabaseWriterLike, schema: SchemaLike, args: ImportGlobalArgs) => Promise<ImportResult>;
99
- /**
100
- * Minimal structural projection of `D1Database` to keep the adapter
101
- * compatible with the real workers-types value as well as unit-test doubles.
102
- */
103
- interface D1DatabaseLike {
104
- batch?: (statements: D1PreparedStatementLike[]) => Promise<unknown[]>;
105
- prepare: (sql: string) => D1PreparedStatementLike;
106
- withSession: (bookmark?: string) => D1SessionLike;
107
- }
108
- interface D1SessionLike {
109
- batch?: (statements: D1PreparedStatementLike[]) => Promise<unknown[]>;
110
- getBookmark: () => string | null;
111
- prepare: (sql: string) => D1PreparedStatementLike;
112
- }
113
- interface D1PreparedStatementLike {
114
- all: <T = unknown>() => Promise<{
115
- results: T[];
116
- success: boolean;
117
- }>;
118
- bind: (...values: unknown[]) => D1PreparedStatementLike;
119
- first: <T = unknown>(column?: string) => Promise<T | null>;
120
- raw: <T = unknown>() => Promise<T[][]>;
121
- run: <T = unknown>() => Promise<{
122
- meta?: Record<string, unknown>;
123
- results?: T[];
124
- success: boolean;
125
- }>;
126
- }
127
101
  /** Thin wrapper over a `D1DatabaseSession` exposing bookmark plumbing. */
128
102
  declare class D1Session {
129
103
  private readonly session;
@@ -194,8 +168,8 @@ declare class D1Client {
194
168
  * the same session.
195
169
  *
196
170
  * A `D1DatabaseSession` exposes the same `prepare` / `batch` surface
197
- * drizzle calls into, so a single `unknown` cast lets us treat the session
198
- * as a `D1Database` for driver-construction purposes.
171
+ * drizzle calls into, so a single `unknown` cast lets us hand the session to
172
+ * the driver.
199
173
  */
200
174
  drizzleSession(bookmark?: string): DrizzleD1Database<Record<string, unknown>>;
201
175
  /**
@@ -347,4 +321,4 @@ declare class MigrationRunner {
347
321
  * table probing. The rest of the per-statement shaping is drizzle's.
348
322
  */
349
323
  declare const sqliteDialect: SqlDialect;
350
- export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1DatabaseLike, type D1PreparedStatementLike, D1Session, type D1SessionLike, 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, listGlobalTables, readD1CdcChanges, readGlobalTablePage, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges };
324
+ export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, D1Session, 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, listGlobalTables, readD1CdcChanges, readGlobalTablePage, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { SchemaLike, DatabaseWriterLike } from '@lunora/do';
1
+ import { SchemaLike, DatabaseWriterLike } from '@lunora/shard-engine';
2
2
  import { SqlCtxDbOptions, SqlCtxExec, createSqlCtxDb, readSqlCdcChanges, SqlDialect } from '@lunora/sql-store';
3
3
  export { type SqlCtxExec as D1Exec, type SqlCtxDbOptions, type SqlCtxExec, createSqlCtxDb } from '@lunora/sql-store';
4
+ import { D1DatabaseLike, D1SessionLike, D1PreparedStatementLike } from '@lunora/platform';
5
+ export type { D1DatabaseLike, D1PreparedStatementLike, D1SessionLike } from '@lunora/platform';
4
6
  import { BatchItem, BatchResponse } from 'drizzle-orm/batch';
5
7
  import { DrizzleD1Database } from 'drizzle-orm/d1';
6
8
  /** The D1 store options — the shared store options minus `dialect` (the SQLite dialect is injected for you). */
@@ -96,34 +98,6 @@ interface D1ExecLike {
96
98
  * `errors`; the rest land.
97
99
  */
98
100
  declare const importGlobalRows: (writer: DatabaseWriterLike, schema: SchemaLike, args: ImportGlobalArgs) => Promise<ImportResult>;
99
- /**
100
- * Minimal structural projection of `D1Database` to keep the adapter
101
- * compatible with the real workers-types value as well as unit-test doubles.
102
- */
103
- interface D1DatabaseLike {
104
- batch?: (statements: D1PreparedStatementLike[]) => Promise<unknown[]>;
105
- prepare: (sql: string) => D1PreparedStatementLike;
106
- withSession: (bookmark?: string) => D1SessionLike;
107
- }
108
- interface D1SessionLike {
109
- batch?: (statements: D1PreparedStatementLike[]) => Promise<unknown[]>;
110
- getBookmark: () => string | null;
111
- prepare: (sql: string) => D1PreparedStatementLike;
112
- }
113
- interface D1PreparedStatementLike {
114
- all: <T = unknown>() => Promise<{
115
- results: T[];
116
- success: boolean;
117
- }>;
118
- bind: (...values: unknown[]) => D1PreparedStatementLike;
119
- first: <T = unknown>(column?: string) => Promise<T | null>;
120
- raw: <T = unknown>() => Promise<T[][]>;
121
- run: <T = unknown>() => Promise<{
122
- meta?: Record<string, unknown>;
123
- results?: T[];
124
- success: boolean;
125
- }>;
126
- }
127
101
  /** Thin wrapper over a `D1DatabaseSession` exposing bookmark plumbing. */
128
102
  declare class D1Session {
129
103
  private readonly session;
@@ -194,8 +168,8 @@ declare class D1Client {
194
168
  * the same session.
195
169
  *
196
170
  * A `D1DatabaseSession` exposes the same `prepare` / `batch` surface
197
- * drizzle calls into, so a single `unknown` cast lets us treat the session
198
- * as a `D1Database` for driver-construction purposes.
171
+ * drizzle calls into, so a single `unknown` cast lets us hand the session to
172
+ * the driver.
199
173
  */
200
174
  drizzleSession(bookmark?: string): DrizzleD1Database<Record<string, unknown>>;
201
175
  /**
@@ -347,4 +321,4 @@ declare class MigrationRunner {
347
321
  * table probing. The rest of the per-statement shaping is drizzle's.
348
322
  */
349
323
  declare const sqliteDialect: SqlDialect;
350
- export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, type D1DatabaseLike, type D1PreparedStatementLike, D1Session, type D1SessionLike, 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, listGlobalTables, readD1CdcChanges, readGlobalTablePage, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges };
324
+ export { D1Client, type D1ContextDatabaseOptions as D1CtxDbOptions, D1Session, 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, listGlobalTables, readD1CdcChanges, readGlobalTablePage, runD1AggregateMigrations, runD1CdcMigration, runD1GlobalTableMigrations, runD1RankMigrations, runD1SearchMigrations, selectGlobalTables, sqliteDialect, trimD1CdcChanges };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{exportGlobalRows as a,importGlobalRows as o,selectGlobalTables as l}from"./packem_shared/exportGlobalRows-CmcmGZxv.mjs";import{D1Client as i,D1Session as n}from"./packem_shared/D1Client-B9m0fFLr.mjs";import{backfillD1SearchIndexes as b,createD1CtxDb as D,readD1CdcChanges as g,runD1AggregateMigrations as c,runD1CdcMigration as x,runD1GlobalTableMigrations as f,runD1RankMigrations as m,runD1SearchMigrations as p,trimD1CdcChanges as C}from"./packem_shared/backfillD1SearchIndexes-ERQf6szv.mjs";import{facetGlobalColumn as d,listGlobalTables as G,readGlobalTablePage as M}from"./packem_shared/facetGlobalColumn-R-BETSuA.mjs";import{MigrationRunner as R}from"./packem_shared/MigrationRunner-DvnPBDVT.mjs";import{default as T}from"./packem_shared/sqliteDialect-B43yA0ek.mjs";import{createSqlCtxDb as q}from"@lunora/sql-store";export{i as D1Client,n as D1Session,R as MigrationRunner,b as backfillD1SearchIndexes,D as createD1CtxDb,q as createSqlCtxDb,a as exportGlobalRows,d as facetGlobalColumn,o as importGlobalRows,G as listGlobalTables,g as readD1CdcChanges,M as readGlobalTablePage,c as runD1AggregateMigrations,x as runD1CdcMigration,f as runD1GlobalTableMigrations,m as runD1RankMigrations,p as runD1SearchMigrations,l as selectGlobalTables,T as sqliteDialect,C as trimD1CdcChanges};
1
+ import{exportGlobalRows as a,importGlobalRows as o,selectGlobalTables as l}from"./packem_shared/exportGlobalRows-SY5S9a8M.mjs";import{D1Client as i,D1Session as n}from"./packem_shared/D1Client-DeccGO7F.mjs";import{backfillD1SearchIndexes as b,createD1CtxDb as D,readD1CdcChanges as g,runD1AggregateMigrations as c,runD1CdcMigration as x,runD1GlobalTableMigrations as f,runD1RankMigrations as m,runD1SearchMigrations as p,trimD1CdcChanges as C}from"./packem_shared/backfillD1SearchIndexes-ERQf6szv.mjs";import{facetGlobalColumn as d,listGlobalTables as G,readGlobalTablePage as M}from"./packem_shared/facetGlobalColumn-R-BETSuA.mjs";import{MigrationRunner as R}from"./packem_shared/MigrationRunner-CNH8wlIl.mjs";import{default as T}from"./packem_shared/sqliteDialect-B43yA0ek.mjs";import{createSqlCtxDb as q}from"@lunora/sql-store";export{i as D1Client,n as D1Session,R as MigrationRunner,b as backfillD1SearchIndexes,D as createD1CtxDb,q as createSqlCtxDb,a as exportGlobalRows,d as facetGlobalColumn,o as importGlobalRows,G as listGlobalTables,g as readD1CdcChanges,M as readGlobalTablePage,c as runD1AggregateMigrations,x as runD1CdcMigration,f as runD1GlobalTableMigrations,m as runD1RankMigrations,p as runD1SearchMigrations,l as selectGlobalTables,T as sqliteDialect,C as trimD1CdcChanges};
@@ -0,0 +1 @@
1
+ import{drizzle as n}from"drizzle-orm/d1";import"@lunora/platform";const d=(t,e)=>{if(t.size<e)return;const s=t.keys().next().value;s!==void 0&&t.delete(s)},l=256,o=(t,e,s)=>{const r=t.get(s);if(r)return t.delete(s),t.set(s,r),r;const i=e(s);return d(t,l),t.set(s,i),i},a="first-unconstrained";class h{session;stmtCache=new Map;constructor(e){this.session=e}prepare(e){return o(this.stmtCache,s=>this.session.prepare(s),e)}async run(e,...s){return this.prepare(e).bind(...s).run()}async all(e,...s){return this.prepare(e).bind(...s).all()}async first(e,...s){return this.prepare(e).bind(...s).first()}getBookmark(){return this.session.getBookmark()??void 0}}class p{db;stmtCache=new Map;drizzleHandle;constructor(e){this.db=e}withSession(e){const s=this.db.withSession(e??a);return new h(s)}prepare(e){return o(this.stmtCache,s=>this.db.prepare(s),e)}get drizzle(){return this.drizzleHandle?this.drizzleHandle:(this.drizzleHandle=n(this.db,{logger:!1}),this.drizzleHandle)}drizzleSession(e){const s=this.db.withSession(e??a);return n(s,{logger:!1})}async batch(e){return this.drizzle.batch(e)}get raw(){return this.db}}export{p as D1Client,h as D1Session};
@@ -1,2 +1,2 @@
1
- import{LunoraError as u}from"@lunora/errors";import{sql as h}from"drizzle-orm";import{D1Client as m}from"./D1Client-B9m0fFLr.mjs";const f="__drizzle_migrations",w=`CREATE TABLE IF NOT EXISTS ${f} (id INTEGER PRIMARY KEY AUTOINCREMENT, hash TEXT NOT NULL UNIQUE, created_at NUMERIC)`,d=/\s/u,g=/^[0-9a-f]{64}$/u,p=new RegExp(String.raw`UNIQUE constraint failed:\s*${f}\.hash`,"iu"),E=c=>{const n=c.sql;let i=!1,e=!1,r=!1,o=!1,a;for(let t=0;t<n.length;t+=1){const s=n[t],l=n[t+1];if(r){s===`
2
- `&&(r=!1);continue}if(o){s==="*"&&l==="/"&&(o=!1,t+=1);continue}if(i){s==="'"&&(l==="'"?t+=1:i=!1);continue}if(e){s==='"'&&(l==='"'?t+=1:e=!1);continue}if(s==="-"&&l==="-"){r=!0,t+=1;continue}if(s==="/"&&l==="*"){o=!0,t+=1;continue}if(a!==void 0){if(s!==void 0&&!d.test(s))throw new u("INTERNAL",`Migration "${c.name}" (v${String(c.version)}) contains more than one SQL statement. Split it into separate migrations — batch() runs them atomically.`);continue}if(s==="'"){i=!0;continue}if(s==='"'){e=!0;continue}s===";"&&(a=t)}return a},S=async c=>{const n=new TextEncoder().encode(c),i=await crypto.subtle.digest("SHA-256",n);return[...new Uint8Array(i)].map(e=>e.toString(16).padStart(2,"0")).join("")};class I{client;migrations;constructor(n,i){this.client=n instanceof m?n:new m(n),this.migrations=[...i].toSorted((e,r)=>e.version-r.version),this.assertUniqueVersions(),this.assertUniqueSql()}async run(){await this.client.drizzle.run(h.raw(w));const n=await this.client.drizzle.all(h.raw(`SELECT hash FROM ${f}`)),i=new Set(n.map(a=>a.hash)),e=[],r=[],o=await Promise.all(this.migrations.map(async a=>S(a.sql)));for(const[a,t]of this.migrations.entries()){const s=o[a];if(i.has(s)){r.push({name:t.name,version:t.version});continue}await this.applyOne(t,s)?e.push({name:t.name,version:t.version}):r.push({name:t.name,version:t.version})}return{applied:e,skipped:r}}async applyOne(n,i){const e=E(n),r=(e===void 0?n.sql:n.sql.slice(0,e)).trim();if(!g.test(i))throw new u("INTERNAL",`migration "${n.name}" produced a non-hex hash; refusing to inline into SQL`);const o=`INSERT INTO ${f} (hash, created_at) VALUES ('${i}', ${String(Date.now())})`,a=[this.client.drizzle.run(h.raw(r)),this.client.drizzle.run(h.raw(o))];try{await this.client.batch(a)}catch(t){if(p.test(t instanceof Error?t.message:String(t)))return!1;throw t}return!0}assertUniqueVersions(){const n=new Set;for(const i of this.migrations){if(n.has(i.version))throw new u("INTERNAL",`Duplicate migration version ${String(i.version)}`);n.add(i.version)}}assertUniqueSql(){const n=new Map;for(const i of this.migrations){const e=n.get(i.sql);if(e!==void 0)throw new u("INTERNAL",`Migrations ${String(e)} and ${String(i.version)} have identical SQL — bump the content, not just the version.`);n.set(i.sql,i.version)}}}export{I as MigrationRunner};
1
+ import{LunoraError as u}from"@lunora/errors";import{sql as h}from"drizzle-orm";import{D1Client as m}from"./D1Client-DeccGO7F.mjs";const f="__drizzle_migrations",w=`CREATE TABLE IF NOT EXISTS ${f} (id INTEGER PRIMARY KEY AUTOINCREMENT, hash TEXT NOT NULL UNIQUE, created_at NUMERIC)`,g=/\s/u,p=/^[0-9a-f]{64}$/u,d=new RegExp(String.raw`UNIQUE constraint failed:\s*${f}\.hash`,"iu"),E=c=>{const n=c.sql;let i=!1,e=!1,r=!1,o=!1,a;for(let t=0;t<n.length;t+=1){const s=n[t],l=n[t+1];if(r){s===`
2
+ `&&(r=!1);continue}if(o){s==="*"&&l==="/"&&(o=!1,t+=1);continue}if(i){s==="'"&&(l==="'"?t+=1:i=!1);continue}if(e){s==='"'&&(l==='"'?t+=1:e=!1);continue}if(s==="-"&&l==="-"){r=!0,t+=1;continue}if(s==="/"&&l==="*"){o=!0,t+=1;continue}if(a!==void 0){if(s!==void 0&&!g.test(s))throw new u("INTERNAL",`Migration "${c.name}" (v${String(c.version)}) contains more than one SQL statement. Split it into separate migrations — batch() runs them atomically.`);continue}if(s==="'"){i=!0;continue}if(s==='"'){e=!0;continue}s===";"&&(a=t)}return a},S=async c=>{const n=new TextEncoder().encode(c),i=await crypto.subtle.digest("SHA-256",n);return[...new Uint8Array(i)].map(e=>e.toString(16).padStart(2,"0")).join("")};class I{client;migrations;constructor(n,i){this.client=n instanceof m?n:new m(n),this.migrations=[...i].toSorted((e,r)=>e.version-r.version),this.assertUniqueVersions(),this.assertUniqueSql()}async run(){await this.client.drizzle.run(h.raw(w));const n=await this.client.drizzle.all(h.raw(`SELECT hash FROM ${f}`)),i=new Set(n.map(a=>a.hash)),e=[],r=[],o=await Promise.all(this.migrations.map(async a=>S(a.sql)));for(const[a,t]of this.migrations.entries()){const s=o[a];if(i.has(s)){r.push({name:t.name,version:t.version});continue}await this.applyOne(t,s)?e.push({name:t.name,version:t.version}):r.push({name:t.name,version:t.version})}return{applied:e,skipped:r}}async applyOne(n,i){const e=E(n),r=(e===void 0?n.sql:n.sql.slice(0,e)).trim();if(!p.test(i))throw new u("INTERNAL",`migration "${n.name}" produced a non-hex hash; refusing to inline into SQL`);const o=`INSERT INTO ${f} (hash, created_at) VALUES ('${i}', ${String(Date.now())})`,a=[this.client.drizzle.run(h.raw(r)),this.client.drizzle.run(h.raw(o))];try{await this.client.batch(a)}catch(t){if(d.test(t instanceof Error?t.message:String(t)))return!1;throw t}return!0}assertUniqueVersions(){const n=new Set;for(const i of this.migrations){if(n.has(i.version))throw new u("INTERNAL",`Duplicate migration version ${String(i.version)}`);n.add(i.version)}}assertUniqueSql(){const n=new Map;for(const i of this.migrations){const e=n.get(i.sql);if(e!==void 0)throw new u("INTERNAL",`Migrations ${String(e)} and ${String(i.version)} have identical SQL — bump the content, not just the version.`);n.set(i.sql,i.version)}}}export{I as MigrationRunner};
@@ -1 +1 @@
1
- import{toErrorBody as u}from"@lunora/errors";import{runD1GlobalTableMigrations as m}from"./backfillD1SearchIndexes-ERQf6szv.mjs";import{quoteIdentifier as f}from"./quoteIdentifier-CObIFRhb.mjs";import{decodeGlobalRow as E}from"@lunora/sql-store";const R=200,g=(o,t)=>{const r=e=>o.tables[e]?.shardMode?.kind==="global";return t&&t.length>0?t.filter(e=>r(e)):Object.keys(o.tables).filter(e=>r(e))},k=(o,t,r)=>{const e=o.tables[t];return e?E(e,r):{_creationTime:r._creationTime,_id:r.id}},O=async function*(o,t,r){const e=g(t,r.tables),a=r.batchSize??R;await m(o,t);for(const i of e){const n=f(i);let c,s=!0;for(;s;){const l=c===void 0?await o.all(`SELECT * FROM ${n} ORDER BY "id" LIMIT ?`,[a]):await o.all(`SELECT * FROM ${n} WHERE "id" > ? ORDER BY "id" LIMIT ?`,[c,a]);for(const b of l)yield{doc:k(t,i,b),table:i};const d=l.at(-1);d!==void 0&&(c=String(d.id)),s=l.length===a}}},w=(o,t,r)=>{const e=o.tables[t];if(!e)return`unknown table: ${t}`;for(const[a,i]of Object.entries(e.shape)){const n=r[a],c=i.kind==="optional";if(n===void 0&&c)continue;const s=i.parse;if(typeof s=="function")try{s(n)}catch(l){const d=l instanceof Error?l.message:String(l);return`field "${a}": ${d}`}}},y=async(o,t,r,e)=>{try{return t?(await t.all(`SELECT 1 AS hit FROM ${f(r)} WHERE "id" = ? LIMIT 1`,[e])).length>0:await o.get(e)!==null}catch{return!1}},p=async(o,t,r,e,a)=>{const{doc:i,table:n}=e;if(t.tables[n]?.shardMode?.kind!=="global")return{kind:"skip"};if(!i||typeof i!="object"||Array.isArray(i))return{error:{code:"BAD_ROW",line:a,message:"row is missing or malformed `doc`",table:n},kind:"error"};const c=w(t,n,i);if(c!==void 0)return{error:{code:"VALIDATION_ERROR",line:a,message:c,table:n},kind:"error"};const s=typeof i._id=="string"?i._id:void 0;if(s!==void 0&&await y(o,r.exec,n,s))return{kind:"conflict"};try{return await o.insert(n,i,{allowExplicitId:!0}),{inserted:n,kind:"inserted"}}catch(l){const{body:d}=u(l,{fallbackCode:"INSERT_FAILED"});return{error:{code:d.code,line:a,message:d.message,table:n},kind:"error"}}},M=async(o,t,r)=>{const e=[],a={};let i=0,n=(r.startLine??1)-1;for(const c of r.rows){n+=1;const s=await p(o,t,r,c,n);switch(s.kind){case"conflict":{i+=1;break}case"error":{e.push(s.error);break}case"inserted":{a[s.inserted]=(a[s.inserted]??0)+1;break}}}return{conflicts:i,errors:e,inserted:a}};export{O as exportGlobalRows,M as importGlobalRows,g as selectGlobalTables};
1
+ import{toErrorBody as u}from"@lunora/errors";import{runD1GlobalTableMigrations as m}from"./backfillD1SearchIndexes-ERQf6szv.mjs";import{quoteIdentifier as f}from"./quoteIdentifier-CObIFRhb.mjs";import{decodeGlobalRow as E}from"@lunora/sql-store";const k=200,R=(o,t)=>{const r=e=>o.tables[e]?.shardMode?.kind==="global";return t&&t.length>0?t.filter(e=>r(e)):Object.keys(o.tables).filter(e=>r(e))},w=(o,t,r)=>{const e=o.tables[t];return e?E(e,r):{_creationTime:r._creationTime,_id:r.id}},O=async function*(o,t,r){const e=R(t,r.tables),a=r.batchSize??k;await m(o,t);for(const i of e){const n=f(i);let c,s=!0;for(;s;){const l=c===void 0?await o.all(`SELECT * FROM ${n} ORDER BY "id" LIMIT ?`,[a]):await o.all(`SELECT * FROM ${n} WHERE "id" > ? ORDER BY "id" LIMIT ?`,[c,a]);for(const b of l)yield{doc:w(t,i,b),table:i};const d=l.at(-1);d!==void 0&&(c=String(d.id)),s=l.length===a}}},y=(o,t,r)=>{const e=o.tables[t];if(!e)return`unknown table: ${t}`;for(const[a,i]of Object.entries(e.shape)){const n=r[a],c=i.kind==="optional";if(n===void 0&&c)continue;const s=i.parse;if(typeof s=="function")try{s(n)}catch(l){const d=l instanceof Error?l.message:String(l);return`field "${a}": ${d}`}}},g=async(o,t,r,e)=>{try{return t?(await t.all(`SELECT 1 AS hit FROM ${f(r)} WHERE "id" = ? LIMIT 1`,[e])).length>0:await o.get(e)!==null}catch{return!1}},p=async(o,t,r,e,a)=>{const{doc:i,table:n}=e;if(t.tables[n]?.shardMode?.kind!=="global")return{kind:"skip"};if(!i||typeof i!="object"||Array.isArray(i))return{error:{code:"BAD_ROW",line:a,message:"row is missing or malformed `doc`",table:n},kind:"error"};const c=y(t,n,i);if(c!==void 0)return{error:{code:"VALIDATION_ERROR",line:a,message:c,table:n},kind:"error"};const s=typeof i._id=="string"?i._id:void 0;if(s!==void 0&&await g(o,r.exec,n,s))return{kind:"conflict"};try{return await o.insert(n,i,{allowExplicitId:!0}),{inserted:n,kind:"inserted"}}catch(l){const{body:d}=u(l,{fallbackCode:"INSERT_FAILED"});return{error:{code:d.code,line:a,message:d.message,table:n},kind:"error"}}},M=async(o,t,r)=>{const e=[],a={};let i=0,n=(r.startLine??1)-1;for(const c of r.rows){n+=1;const s=await p(o,t,r,c,n);switch(s.kind){case"conflict":{i+=1;break}case"error":{e.push(s.error);break}case"inserted":{a[s.inserted]=(a[s.inserted]??0)+1;break}}}return{conflicts:i,errors:e,inserted:a}};export{O as exportGlobalRows,M as importGlobalRows,R as selectGlobalTables};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/d1",
3
- "version": "1.0.0-alpha.52",
3
+ "version": "1.0.0-alpha.53",
4
4
  "description": "D1 adapter for Lunora .global() tables, wrapping the Sessions API for read-your-writes",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,9 +50,10 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/do": "1.0.0-alpha.56",
54
53
  "@lunora/errors": "1.0.0-alpha.9",
55
- "@lunora/sql-store": "1.0.0-alpha.53",
54
+ "@lunora/platform": "1.0.0-alpha.1",
55
+ "@lunora/shard-engine": "1.0.0-alpha.1",
56
+ "@lunora/sql-store": "1.0.0-alpha.55",
56
57
  "drizzle-orm": "^0.45.2"
57
58
  },
58
59
  "engines": {
@@ -1 +0,0 @@
1
- import{drizzle as n}from"drizzle-orm/d1";const d=(t,e)=>{if(t.size<e)return;const s=t.keys().next().value;s!==void 0&&t.delete(s)},l=256,o=(t,e,s)=>{const r=t.get(s);if(r)return t.delete(s),t.set(s,r),r;const i=e(s);return d(t,l),t.set(s,i),i},a="first-unconstrained";class h{session;stmtCache=new Map;constructor(e){this.session=e}prepare(e){return o(this.stmtCache,s=>this.session.prepare(s),e)}async run(e,...s){return this.prepare(e).bind(...s).run()}async all(e,...s){return this.prepare(e).bind(...s).all()}async first(e,...s){return this.prepare(e).bind(...s).first()}getBookmark(){return this.session.getBookmark()??void 0}}class u{db;stmtCache=new Map;drizzleHandle;constructor(e){this.db=e}withSession(e){const s=this.db.withSession(e??a);return new h(s)}prepare(e){return o(this.stmtCache,s=>this.db.prepare(s),e)}get drizzle(){return this.drizzleHandle?this.drizzleHandle:(this.drizzleHandle=n(this.db,{logger:!1}),this.drizzleHandle)}drizzleSession(e){const s=this.db.withSession(e??a);return n(s,{logger:!1})}async batch(e){return this.drizzle.batch(e)}get raw(){return this.db}}export{u as D1Client,h as D1Session};