@earth-app/collegedb 1.2.0 → 1.2.2
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/README.md +111 -0
- package/dist/index.js +9 -9
- package/dist/index.js.map +5 -5
- package/dist/kvmap.d.ts.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/providers-memory.d.ts +90 -24
- package/dist/providers-memory.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -689,6 +689,117 @@ The in-memory providers are intentionally simple to avoid dependencies:
|
|
|
689
689
|
|
|
690
690
|
For production use, migrate to appropriate providers (D1, Redis, PostgreSQL, etc.). For testing/development, these limitations are intentional to keep the implementation lightweight and zero-dependency.
|
|
691
691
|
|
|
692
|
+
### Advanced In-Memory Example: `run`, `all`, `insert`, and Aggregates
|
|
693
|
+
|
|
694
|
+
The in-memory SQL emulator supports a useful subset of SQLite syntax — enough to drive routing tests for real-world ORM-style code. The example below exercises the full routing stack (`run`, `all`, `first`, `insert`, `insertShard`, `runShard`, `countAllShards`, `allAllShardsGlobal`) entirely in-process without spinning up a database container.
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
import {
|
|
698
|
+
allAllShardsGlobal,
|
|
699
|
+
countAllShards,
|
|
700
|
+
createInMemoryKVProvider,
|
|
701
|
+
createInMemorySQLProvider,
|
|
702
|
+
first,
|
|
703
|
+
initialize,
|
|
704
|
+
insert,
|
|
705
|
+
insertShard,
|
|
706
|
+
resetConfig,
|
|
707
|
+
run,
|
|
708
|
+
runShard
|
|
709
|
+
} from '@earth-app/collegedb';
|
|
710
|
+
|
|
711
|
+
resetConfig();
|
|
712
|
+
|
|
713
|
+
initialize({
|
|
714
|
+
kv: createInMemoryKVProvider(),
|
|
715
|
+
shards: {
|
|
716
|
+
'db-east': createInMemorySQLProvider(),
|
|
717
|
+
'db-west': createInMemorySQLProvider(),
|
|
718
|
+
'db-central': createInMemorySQLProvider()
|
|
719
|
+
},
|
|
720
|
+
strategy: 'hash',
|
|
721
|
+
hashShardMappings: false,
|
|
722
|
+
disableAutoMigration: true
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
// 1. Schema setup: replicate the same DDL on every shard.
|
|
726
|
+
for (const shard of ['db-east', 'db-west', 'db-central']) {
|
|
727
|
+
await runShard(
|
|
728
|
+
shard,
|
|
729
|
+
`CREATE TABLE IF NOT EXISTS users (
|
|
730
|
+
id TEXT PRIMARY KEY,
|
|
731
|
+
name TEXT NOT NULL,
|
|
732
|
+
email TEXT UNIQUE,
|
|
733
|
+
created_at INTEGER
|
|
734
|
+
)`
|
|
735
|
+
);
|
|
736
|
+
await runShard(
|
|
737
|
+
shard,
|
|
738
|
+
`CREATE TABLE IF NOT EXISTS tickets (
|
|
739
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
740
|
+
user_id TEXT NOT NULL,
|
|
741
|
+
subject TEXT NOT NULL,
|
|
742
|
+
created_at INTEGER
|
|
743
|
+
)`
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// 2. Routed inserts: CollegeDB picks the shard from a stable hash of the
|
|
748
|
+
// primary key, then records the mapping in KV.
|
|
749
|
+
await run('user-1', 'INSERT INTO users (id, name, email, created_at) VALUES (?, ?, ?, ?)', [
|
|
750
|
+
'user-1',
|
|
751
|
+
'Alice',
|
|
752
|
+
'alice@example.com',
|
|
753
|
+
Date.now()
|
|
754
|
+
]);
|
|
755
|
+
|
|
756
|
+
// 3. AUTOINCREMENT inserts: `insert()` allocates the shard and captures the
|
|
757
|
+
// generated id, storing it as a mapping so routed reads find the row.
|
|
758
|
+
const ticketA = await insert('INSERT INTO tickets (user_id, subject, created_at) VALUES (?, ?, ?)', [
|
|
759
|
+
'user-1',
|
|
760
|
+
'Cannot log in',
|
|
761
|
+
Date.now()
|
|
762
|
+
]);
|
|
763
|
+
|
|
764
|
+
// 4. Pinned inserts: `insertShard()` writes to a specific shard, still
|
|
765
|
+
// capturing the generated id mapping.
|
|
766
|
+
const ticketB = await insertShard('db-west', 'INSERT INTO tickets (user_id, subject, created_at) VALUES (?, ?, ?) RETURNING id', [
|
|
767
|
+
'user-1',
|
|
768
|
+
'Mobile sync is slow',
|
|
769
|
+
Date.now()
|
|
770
|
+
]);
|
|
771
|
+
|
|
772
|
+
// 5. Routed reads: `first` and `all` resolve the shard from the mapping.
|
|
773
|
+
const user = await first<{ id: string; name: string; email: string }>('user-1', 'SELECT id, name, email FROM users WHERE id = ?', [
|
|
774
|
+
'user-1'
|
|
775
|
+
]);
|
|
776
|
+
|
|
777
|
+
const ticket = await first<{ id: number; subject: string }>(String(ticketA.generatedId), 'SELECT id, subject FROM tickets WHERE id = ?', [
|
|
778
|
+
ticketA.generatedId
|
|
779
|
+
]);
|
|
780
|
+
|
|
781
|
+
// 6. Cross-shard aggregates: the emulator evaluates COUNT/MAX/MIN/SUM/AVG and
|
|
782
|
+
// COALESCE during SELECT, so utility queries like `SELECT COALESCE(MAX(id),
|
|
783
|
+
// 0) + 1 AS next FROM tickets` work the same way they do in production.
|
|
784
|
+
const totals = await countAllShards('tickets');
|
|
785
|
+
|
|
786
|
+
const recentTickets = await allAllShardsGlobal<{ id: number; subject: string; created_at: number }>(
|
|
787
|
+
'SELECT id, subject, created_at FROM tickets WHERE user_id = ?',
|
|
788
|
+
['user-1'],
|
|
789
|
+
{ sortBy: 'created_at', sortDirection: 'desc', limit: 10 }
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
console.log({ user, ticket, ticketB: ticketB.generatedId, totals, recent: recentTickets.results });
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
What this example demonstrates:
|
|
796
|
+
|
|
797
|
+
- **Routing through `run`, `first`, `all`, and `insert` works end-to-end** without a real database. The hash strategy assigns each new primary key to a shard the same way it would in production.
|
|
798
|
+
- **Auto-increment + RETURNING** are honored. `insert()` captures the generated id from either provider metadata or `RETURNING id` rows.
|
|
799
|
+
- **Aggregate SQL is evaluated** (`COUNT(*)`, `MIN`, `MAX`, `SUM`, `AVG`, `COALESCE`, simple arithmetic), and **compound `WHERE`** with `AND` / `OR` / parens / `LIKE` / `IS NULL` is honored on UPDATE, DELETE, and SELECT.
|
|
800
|
+
- **Cross-shard fanout helpers** (`countAllShards`, `allAllShardsGlobal`) operate over the in-memory store exactly as they would over D1/Postgres/MySQL.
|
|
801
|
+
- **No data leaks between tests**: call `resetConfig()` (and instantiate fresh providers) to start each test with a clean state.
|
|
802
|
+
|
|
692
803
|
### Migrating from In-Memory to Production Providers
|
|
693
804
|
|
|
694
805
|
When ready to migrate from testing to production:
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
var jY=Object.defineProperty;var AY=(J)=>J;function VY(J,Y){this[J]=AY.bind(null,Y)}var xJ=(J,Y)=>{for(var Z in Y)jY(J,Z,{get:Y[Z],enumerable:!0,configurable:!0,set:VY.bind(Y,Z)})};var UJ=(J,Y)=>()=>(J&&(Y=J(J=0)),Y);var j;var q=UJ(()=>{j=class j extends Error{code;constructor(J,Y){super(J);if(this.name="CollegeDBError",this.code=Y,Error.captureStackTrace)Error.captureStackTrace(this,j)}}});var HJ={};xJ(HJ,{KVShardMapper:()=>K});class K{kv;hashKeys;hashCache=new Map;mappingCache=new Map;knownShardsCache={shards:null,expiresAt:0};mappingCacheTtlMs;knownShardsCacheTtlMs;constructor(J,Y={}){this.kv=J,this.hashKeys=Y.hashShardMappings??!0,this.mappingCacheTtlMs=Y.mappingCacheTtlMs??LY,this.knownShardsCacheTtlMs=Y.knownShardsCacheTtlMs??EY}getCachedMapping(J){let Y=this.mappingCache.get(J);if(!Y)return;if(Y.expiresAt<Date.now()){this.mappingCache.delete(J);return}return Y.mapping}setCachedMapping(J,Y){if(this.mappingCache.size>50000){let Z=this.mappingCache.keys().next().value;if(Z)this.mappingCache.delete(Z)}this.mappingCache.set(J,{mapping:Y,expiresAt:Date.now()+this.mappingCacheTtlMs})}async cacheMappingForKeys(J,Y){let Z=await Promise.all(J.map(($)=>this.hashKey($)));for(let $ of Z)this.setCachedMapping($,Y)}getCachedKnownShards(){if(this.knownShardsCache.shards&&this.knownShardsCache.expiresAt>=Date.now())return[...this.knownShardsCache.shards];return null}setCachedKnownShards(J){this.knownShardsCache.shards=[...J],this.knownShardsCache.expiresAt=Date.now()+this.knownShardsCacheTtlMs}async hashKey(J){if(!this.hashKeys)return J;let Y=this.hashCache.get(J);if(Y)return Y;let $=new TextEncoder().encode(J),X=await crypto.subtle.digest("SHA-256",$),W=new Uint8Array(X),G=Array.from(W).map((U)=>U.toString(16).padStart(2,"0")).join("");if(this.hashCache.size<1e4)this.hashCache.set(J,G);return G}async getShardMapping(J){let Y=await this.hashKey(J),Z=this.getCachedMapping(Y);if(Z!==void 0)return Z;let $=`${N}${Y}`,X=await this.kv.get($,"json");if(X)return this.setCachedMapping(Y,X),X;let W=await this.kv.get(`${k}${Y}`,"json");if(W){let G={shard:W.shard,createdAt:W.createdAt,updatedAt:W.updatedAt,originalKey:this.hashKeys?void 0:J};if(this.setCachedMapping(Y,G),this.hashKeys)for(let U of W.keys)this.setCachedMapping(U,G);return G}return this.setCachedMapping(Y,null),null}async setShardMapping(J,Y,Z=[]){let $=[J,...Z],X=Date.now(),W={shard:Y,createdAt:X,updatedAt:X,originalKey:this.hashKeys?void 0:J};if($.length===1){let G=await this.hashKey(J),U=`${N}${G}`;await this.kv.put(U,JSON.stringify(W)),this.setCachedMapping(G,W)}else{let G=await this.hashKey(J),U=`${k}${G}`,H=this.hashKeys?await Promise.all($.map((F)=>this.hashKey(F))):$,_={shard:Y,createdAt:X,updatedAt:X,keys:H};await this.kv.put(U,JSON.stringify(_));let O=$.map(async(F)=>{let A=await this.hashKey(F),E=`${N}${A}`,I={shard:Y,createdAt:X,updatedAt:X,originalKey:this.hashKeys?void 0:F};return this.kv.put(E,JSON.stringify(I))});await Promise.all(O),await this.cacheMappingForKeys($,W)}}async updateShardMapping(J,Y){let Z=await this.getShardMapping(J);if(!Z)throw new j(`No existing mapping found for primary key: ${J}`,"MAPPING_NOT_FOUND");let $=await this.hashKey(J),X=`${N}${$}`,W=`${k}${$}`,G=await this.kv.get(W,"json");if(G){let U=Date.now(),H={...G,shard:Y,updatedAt:U};await this.kv.put(W,JSON.stringify(H));let _=G.keys.length>0?this.hashKeys?G.keys:G.keys:[await this.hashKey(J)],O=_.map(async(A)=>{let E=`${N}${A}`,I={...Z,shard:Y,updatedAt:U};return this.kv.put(E,JSON.stringify(I))});await Promise.all(O);let F={...Z,shard:Y,updatedAt:U};if(this.hashKeys)for(let A of _)this.setCachedMapping(A,F);this.setCachedMapping($,F)}else{let U={...Z,shard:Y,updatedAt:Date.now()};await this.kv.put(X,JSON.stringify(U)),this.setCachedMapping($,U)}}async deleteShardMapping(J){let Y=await this.hashKey(J),Z=`${N}${Y}`,$=`${k}${Y}`,X=await this.kv.get($,"json");if(X){await this.kv.delete($);let W=X.keys.length>0?this.hashKeys?X.keys:X.keys:[await this.hashKey(J)],G=W.map(async(U)=>{let H=`${N}${U}`;return this.kv.delete(H)});if(await Promise.all(G),this.hashKeys)for(let U of W)this.setCachedMapping(U,null);this.setCachedMapping(Y,null)}else await this.kv.delete(Z),this.setCachedMapping(Y,null)}async getKnownShards(){let J=this.getCachedKnownShards();if(J)return J;let Z=await this.kv.get(vJ,"json")||[];return this.setCachedKnownShards(Z),Z}async setKnownShards(J){if(!J||J.length===0)return;let Y=[...new Set(J.filter(Boolean))];if(Y.length===0)return;await this.kv.put(vJ,JSON.stringify(Y)),this.setCachedKnownShards(Y)}async addKnownShard(J){if(!J)return;let Y=await this.getKnownShards();if(!Y.includes(J))Y.push(J),await this.setKnownShards(Y)}async getKeysForShard(J){let Y=[],Z=await this.kv.list({prefix:N});for(let X of Z.keys){let W=await this.kv.get(X.name,"json");if(W?.shard===J){let G=X.name.replace(N,"");if(W.originalKey)Y.push(W.originalKey);else if(!this.hashKeys)Y.push(G)}}let $=await this.kv.list({prefix:k});for(let X of $.keys){let W=await this.kv.get(X.name,"json");if(W?.shard===J)Y.push(...W.keys)}return[...new Set(Y)]}async getShardKeyCounts(){let J={},Y=await this.kv.list({prefix:N});for(let $ of Y.keys){let X=await this.kv.get($.name,"json");if(X)J[X.shard]=(J[X.shard]||0)+1}let Z=await this.kv.list({prefix:k});for(let $ of Z.keys){let X=await this.kv.get($.name,"json");if(X)J[X.shard]=(J[X.shard]||0)+X.keys.length}return J}async clearAllMappings(){let Y=(await this.kv.list({prefix:N})).keys.map((X)=>this.kv.delete(X.name)),$=(await this.kv.list({prefix:k})).keys.map((X)=>this.kv.delete(X.name));await Promise.all([...Y,...$]),this.mappingCache.clear()}async addLookupKeys(J,Y){let Z=await this.getShardMapping(J);if(!Z)throw new j(`No existing mapping found for primary key: ${J}`,"MAPPING_NOT_FOUND");let $=await this.hashKey(J),X=`${k}${$}`,W=await this.kv.get(X,"json"),G=[J,...Y],U=Date.now();if(!W){let O=this.hashKeys?await Promise.all(G.map((F)=>this.hashKey(F))):G;W={shard:Z.shard,createdAt:Z.createdAt,updatedAt:U,keys:O}}else{let O=this.hashKeys?await Promise.all(G.map((F)=>this.hashKey(F))):G;W={...W,updatedAt:U,keys:[...new Set([...W.keys,...O])]}}await this.kv.put(X,JSON.stringify(W));let H=Y.map(async(O)=>{let F=await this.hashKey(O),A=`${N}${F}`,E={shard:Z.shard,createdAt:Z.createdAt,updatedAt:U,originalKey:this.hashKeys?void 0:O};return this.kv.put(A,JSON.stringify(E))});await Promise.all(H);let _={shard:Z.shard,createdAt:Z.createdAt,updatedAt:U,originalKey:Z.originalKey};await this.cacheMappingForKeys([J,...Y],_)}async setShardMappingsBatch(J,Y={}){if(J.length===0)return;let Z=Math.max(1,Y.concurrency??25),$=0,X=Array(Math.min(Z,J.length)).fill(null).map(async()=>{while($<J.length){let W=$++,G=J[W];if(!G)continue;await this.setShardMapping(G.primaryKey,G.shard,G.additionalKeys||[])}});await Promise.all(X)}async getAllLookupKeys(J){let Y=await this.hashKey(J),Z=`${k}${Y}`,$=await this.kv.get(Z,"json");if($)return $.keys;let X=await this.getShardMapping(J);if(X)return X.originalKey?[X.originalKey]:[J];throw new j(`No mapping found for key: ${J}`,"MAPPING_NOT_FOUND")}}var N="shard:",k="multikey:",vJ="known_shards",LY=30000,EY=1e4;var c=UJ(()=>{q()});var r={};xJ(r,{validateTableForSharding:()=>a,schemaExists:()=>FJ,migrateRecord:()=>SJ,listTables:()=>p,integrateExistingDatabase:()=>fJ,dropSchema:()=>qJ,discoverExistingRecordsWithColumns:()=>t,discoverExistingPrimaryKeys:()=>i,createSchemaAcrossShards:()=>kJ,createSchema:()=>OJ,createMappingsForExistingKeys:()=>KJ,clearShardMigrationCache:()=>yJ,clearMigrationCache:()=>pJ,checkMigrationNeeded:()=>hJ,autoDetectAndMigrate:()=>bJ});async function CJ(J,Y,Z){if(J.length===0)return;let $=Math.max(1,Math.min(Y,J.length)),X=0,W=Array($).fill(null).map(async()=>{while(X<J.length){let G=X++,U=J[G];if(U===void 0)continue;await Z(U,G)}});await Promise.all(W)}function IY(J,Y,Z,$){let X=Z.length;switch($){case"hash":{let W=0;for(let U=0;U<J.length;U++){let H=J.charCodeAt(U);W=(W<<5)-W+H,W=W&W}let G=Math.abs(W)%X;return Z[G]}case"random":return Z[Math.floor(Math.random()*X)];default:return Z[Y%X]}}async function OJ(J,Y){let Z=Y.split(";").map(($)=>$.trim()).filter(($)=>$.length>0&&!$.startsWith("--"));for(let $ of Z)try{await J.prepare($).run()}catch(X){throw console.error("Failed to execute schema statement:",$,X),new j(`Schema migration failed: ${X}`,"SCHEMA_MIGRATION_FAILED")}}async function kJ(J,Y){let Z=Object.entries(J).map(([$,X])=>{return OJ(X,Y).catch((W)=>{throw new j(`Failed to create schema on shard ${$}: ${W.message}`,"SCHEMA_CREATION_FAILED")})});await Promise.all(Z)}async function FJ(J,Y){try{return await J.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind(Y).first()!==null}catch{return!1}}async function qJ(J,...Y){for(let Z of Y)try{await J.prepare(`DROP TABLE IF EXISTS ${Z}`).run()}catch($){console.error(`Failed to drop table ${Z}:`,$)}}async function p(J){try{return(await J.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all()).results.map((Z)=>Z.name)}catch{return[]}}async function SJ(J,Y,Z,$){let X=await J.prepare(`SELECT * FROM ${$} WHERE id = ?`).bind(Z).first();if(!X)throw new j(`Record with primary key ${Z} not found in source database`,"RECORD_NOT_FOUND");if(!await FJ(Y,$))await OJ(Y,$);let W=Object.keys(X),G=W.map(()=>"?").join(", "),U=W.map((_)=>X[_]),H=`INSERT OR REPLACE INTO ${$} (${W.join(", ")}) VALUES (${G})`;await Y.prepare(H).bind(...U).run(),await J.prepare(`DELETE FROM ${$} WHERE id = ?`).bind(Z).run()}async function i(J,Y,Z="id"){try{return(await J.prepare(`SELECT ${Z} FROM ${Y}`).all()).results.map((X)=>String(X[Z]))}catch($){throw new j(`Failed to discover primary keys in table ${Y}: ${$}`,"DISCOVERY_FAILED")}}async function t(J,Y,Z="id"){try{let $=`${Y}_columns`,X;if(_J.has($))X=_J.get($).map((H)=>H.name);else{let _=(await J.prepare(`PRAGMA table_info(${Y})`).all()).results.map((O)=>({name:O.name,type:O.type}));_J.set($,_),X=_.map((O)=>O.name)}let W=[Z];if(X.includes("username"))W.push("username");if(X.includes("email"))W.push("email");if(X.includes("name"))W.push("name");let G=`SELECT ${W.join(", ")} FROM ${Y}`;return(await J.prepare(G).all()).results}catch($){throw new j(`Failed to discover records with columns in table ${Y}: ${$}`,"DISCOVERY_FAILED")}}async function KJ(J,Y,Z,$,X={}){if(J.length===0||Y.length===0)return;let W=Math.max(1,X.concurrency??25),G=J.map((U,H)=>({primaryKey:U,shard:IY(U,H,Y,Z)}));await $.setShardMappingsBatch(G,{concurrency:W})}async function a(J,Y,Z){let $=[],X=0;try{if(!await J.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind(Y).first())return $.push(`Table '${Y}' does not exist`),{isValid:!1,tableName:Y,primaryKeyColumn:Z,recordCount:0,issues:$};if(!(await J.prepare(`PRAGMA table_info(${Y})`).all()).results.some((_)=>_.name===Z&&_.pk===1))$.push(`Primary key column '${Z}' not found or not set as primary key`);if(X=(await J.prepare(`SELECT COUNT(*) as count FROM ${Y}`).first())?.count||0,X===0)$.push(`Table '${Y}' is empty`)}catch(W){$.push(`Database validation error: ${W}`)}return{isValid:$.length===0,tableName:Y,primaryKeyColumn:Z,recordCount:X,issues:$}}async function fJ(J,Y,Z,$={}){let{tables:X,primaryKeyColumn:W="id",strategy:G="hash",addShardMappingsTable:U=!0,dryRun:H=!1,migrateOtherColumns:_=!1,concurrency:O=25}=$,F=Math.max(1,O),A=[],E=0,I=0,M=0;try{let V=(X||await p(J)).filter((L)=>L!=="shard_mappings");for(let L of V)try{let z=await a(J,L,W);if(!z.isValid){A.push(`Table ${L}: ${z.issues.join(", ")}`);continue}if(_){let R=await t(J,L,W);if(R.length===0){A.push(`Table ${L} has no records to process`);continue}if(!H){let P=R.map((Q)=>{let WJ=String(Q[W]),h=[];if(Q.username&&typeof Q.username==="string")h.push(`username:${Q.username}`);if(Q.email&&typeof Q.email==="string")h.push(`email:${Q.email}`);if(Q.name&&typeof Q.name==="string")h.push(`name:${Q.name}`);return{primaryKey:WJ,shard:Y,additionalKeys:h}});await Z.setShardMappingsBatch(P,{concurrency:F}),M+=P.length}I+=R.length}else{let R=await i(J,L,W);if(R.length===0){A.push(`Table ${L} has no records to process`);continue}if(!H){let P=R.map((Q)=>({primaryKey:Q,shard:Y}));await Z.setShardMappingsBatch(P,{concurrency:F}),M+=P.length}I+=R.length}E++}catch(z){A.push(`Failed to process table ${L}: ${z}`)}if(U&&!H){if(!(await p(J)).includes("shard_mappings"))await J.prepare(`
|
|
1
|
+
var y6=Object.defineProperty;var g6=(J)=>J;function p6(J,$){this[J]=g6.bind(null,$)}var nJ=(J,$)=>{for(var X in $)y6(J,X,{get:$[X],enumerable:!0,configurable:!0,set:p6.bind($,X)})};var RJ=(J,$)=>()=>(J&&($=J(J=0)),$);var j;var b=RJ(()=>{j=class j extends Error{code;constructor(J,$){super(J);if(this.name="CollegeDBError",this.code=$,Error.captureStackTrace)Error.captureStackTrace(this,j)}}});var NJ={};nJ(NJ,{KVShardMapper:()=>y});async function c(J,$,X){if(J.length===0)return;let Y=Math.max(1,Math.min($,J.length)),Z=0,G=Array(Y).fill(null).map(async()=>{while(Z<J.length){let H=Z++,U=J[H];if(U===void 0)continue;await X(U)}});await Promise.all(G)}class y{kv;hashKeys;hashCache=new Map;mappingCache=new Map;knownShardsCache={shards:null,expiresAt:0};mappingCacheTtlMs;knownShardsCacheTtlMs;constructor(J,$={}){this.kv=J,this.hashKeys=$.hashShardMappings??!0,this.mappingCacheTtlMs=$.mappingCacheTtlMs??m6,this.knownShardsCacheTtlMs=$.knownShardsCacheTtlMs??u6}getCachedMapping(J){let $=this.mappingCache.get(J);if(!$)return;if($.expiresAt<Date.now()){this.mappingCache.delete(J);return}return $.mapping}setCachedMapping(J,$){if(this.mappingCache.size>50000){let X=this.mappingCache.keys().next().value;if(X)this.mappingCache.delete(X)}this.mappingCache.set(J,{mapping:$,expiresAt:Date.now()+this.mappingCacheTtlMs})}async cacheMappingForKeys(J,$){let X=await Promise.all(J.map((Y)=>this.hashKey(Y)));for(let Y of X)this.setCachedMapping(Y,$)}getCachedKnownShards(){if(this.knownShardsCache.shards&&this.knownShardsCache.expiresAt>=Date.now())return[...this.knownShardsCache.shards];return null}setCachedKnownShards(J){this.knownShardsCache.shards=[...J],this.knownShardsCache.expiresAt=Date.now()+this.knownShardsCacheTtlMs}async hashKey(J){if(!this.hashKeys)return J;let $=this.hashCache.get(J);if($)return $;let Y=new TextEncoder().encode(J),Z=await crypto.subtle.digest("SHA-256",Y),G=new Uint8Array(Z),H=Array.from(G).map((U)=>U.toString(16).padStart(2,"0")).join("");if(this.hashCache.size<1e4)this.hashCache.set(J,H);return H}async getShardMapping(J){let $=await this.hashKey(J),X=this.getCachedMapping($);if(X!==void 0)return X;let Y=`${k}${$}`,Z=await this.kv.get(Y,"json");if(Z)return this.setCachedMapping($,Z),Z;let G=await this.kv.get(`${f}${$}`,"json");if(G){let H={shard:G.shard,createdAt:G.createdAt,updatedAt:G.updatedAt,originalKey:this.hashKeys?void 0:J};if(this.setCachedMapping($,H),this.hashKeys)for(let U of G.keys)this.setCachedMapping(U,H);return H}return this.setCachedMapping($,null),null}async setShardMapping(J,$,X=[]){let Y=[J,...X],Z=Date.now(),G={shard:$,createdAt:Z,updatedAt:Z,originalKey:this.hashKeys?void 0:J};if(Y.length===1){let H=await this.hashKey(J),U=`${k}${H}`;await this.kv.put(U,JSON.stringify(G)),this.setCachedMapping(H,G)}else{let H=await this.hashKey(J),U=`${f}${H}`,_=this.hashKeys?await Promise.all(Y.map((O)=>this.hashKey(O))):Y,F={shard:$,createdAt:Z,updatedAt:Z,keys:_};await this.kv.put(U,JSON.stringify(F));let W=Y.map(async(O)=>{let A=await this.hashKey(O),Q=`${k}${A}`,z={shard:$,createdAt:Z,updatedAt:Z,originalKey:this.hashKeys?void 0:O};return this.kv.put(Q,JSON.stringify(z))});await Promise.all(W),await this.cacheMappingForKeys(Y,G)}}async updateShardMapping(J,$){let X=await this.getShardMapping(J);if(!X)throw new j(`No existing mapping found for primary key: ${J}`,"MAPPING_NOT_FOUND");let Y=await this.hashKey(J),Z=`${k}${Y}`,G=`${f}${Y}`,H=await this.kv.get(G,"json");if(H){let U=Date.now(),_={...H,shard:$,updatedAt:U};await this.kv.put(G,JSON.stringify(_));let F=H.keys.length>0?H.keys:[await this.hashKey(J)],W=F.map(async(A)=>{let Q=`${k}${A}`,z={...X,shard:$,updatedAt:U};return this.kv.put(Q,JSON.stringify(z))});await Promise.all(W);let O={...X,shard:$,updatedAt:U};for(let A of F)if(this.hashKeys)this.setCachedMapping(A,O);else this.setCachedMapping(await this.hashKey(A),O);this.setCachedMapping(Y,O)}else{let U={...X,shard:$,updatedAt:Date.now()};await this.kv.put(Z,JSON.stringify(U)),this.setCachedMapping(Y,U)}}async deleteShardMapping(J){let $=await this.hashKey(J),X=`${k}${$}`,Y=`${f}${$}`,Z=await this.kv.get(Y,"json");if(Z){await this.kv.delete(Y);let G=Z.keys.length>0?Z.keys:[await this.hashKey(J)],H=G.map(async(U)=>{let _=`${k}${U}`;return this.kv.delete(_)});await Promise.all(H);for(let U of G)if(this.hashKeys)this.setCachedMapping(U,null);else this.setCachedMapping(await this.hashKey(U),null);this.setCachedMapping($,null)}else await this.kv.delete(X),this.setCachedMapping($,null)}async getKnownShards(){let J=this.getCachedKnownShards();if(J)return J;let X=await this.kv.get(sJ,"json")||[];return this.setCachedKnownShards(X),X}async setKnownShards(J){if(!J||J.length===0)return;let $=[...new Set(J.filter(Boolean))];if($.length===0)return;await this.kv.put(sJ,JSON.stringify($)),this.setCachedKnownShards($)}async addKnownShard(J){if(!J)return;let $=await this.getKnownShards();if(!$.includes(J))$.push(J),await this.setKnownShards($)}async getKeysForShard(J){let $=[],X=new Set,Y=(H)=>{if(!X.has(H))X.add(H),$.push(H)},Z=await this.kv.list({prefix:k});await c(Z.keys,u,async(H)=>{let U=await this.kv.get(H.name,"json");if(U?.shard!==J)return;if(U.originalKey)Y(U.originalKey);else if(!this.hashKeys)Y(H.name.replace(k,""))});let G=await this.kv.list({prefix:f});return await c(G.keys,u,async(H)=>{let U=await this.kv.get(H.name,"json");if(U?.shard===J)for(let _ of U.keys)Y(_)}),$}async getShardKeyCounts(){let J={},$=await this.kv.list({prefix:k});await c($.keys,u,async(Y)=>{let Z=await this.kv.get(Y.name,"json");if(Z)J[Z.shard]=(J[Z.shard]||0)+1});let X=await this.kv.list({prefix:f});return await c(X.keys,u,async(Y)=>{let Z=await this.kv.get(Y.name,"json");if(Z)J[Z.shard]=(J[Z.shard]||0)+Z.keys.length}),J}async clearAllMappings(){let[J,$]=await Promise.all([this.kv.list({prefix:k}),this.kv.list({prefix:f})]);await Promise.all([c(J.keys,u,async(X)=>{await this.kv.delete(X.name)}),c($.keys,u,async(X)=>{await this.kv.delete(X.name)})]),this.mappingCache.clear(),this.hashCache.clear(),this.knownShardsCache.shards=null,this.knownShardsCache.expiresAt=0}async addLookupKeys(J,$){let X=await this.getShardMapping(J);if(!X)throw new j(`No existing mapping found for primary key: ${J}`,"MAPPING_NOT_FOUND");let Y=await this.hashKey(J),Z=`${f}${Y}`,G=await this.kv.get(Z,"json"),H=[J,...$],U=Date.now();if(!G){let W=this.hashKeys?await Promise.all(H.map((O)=>this.hashKey(O))):H;G={shard:X.shard,createdAt:X.createdAt,updatedAt:U,keys:W}}else{let W=this.hashKeys?await Promise.all(H.map((O)=>this.hashKey(O))):H;G={...G,updatedAt:U,keys:[...new Set([...G.keys,...W])]}}await this.kv.put(Z,JSON.stringify(G));let _=$.map(async(W)=>{let O=await this.hashKey(W),A=`${k}${O}`,Q={shard:X.shard,createdAt:X.createdAt,updatedAt:U,originalKey:this.hashKeys?void 0:W};return this.kv.put(A,JSON.stringify(Q))});await Promise.all(_);let F={shard:X.shard,createdAt:X.createdAt,updatedAt:U,originalKey:X.originalKey};await this.cacheMappingForKeys([J,...$],F)}async setShardMappingsBatch(J,$={}){if(J.length===0)return;let X=Math.max(1,$.concurrency??25),Y=0,Z=Array(Math.min(X,J.length)).fill(null).map(async()=>{while(Y<J.length){let G=Y++,H=J[G];if(!H)continue;await this.setShardMapping(H.primaryKey,H.shard,H.additionalKeys||[])}});await Promise.all(Z)}async getAllLookupKeys(J){let $=await this.hashKey(J),X=`${f}${$}`,Y=await this.kv.get(X,"json");if(Y)return Y.keys;let Z=await this.getShardMapping(J);if(Z)return Z.originalKey?[Z.originalKey]:[J];throw new j(`No mapping found for key: ${J}`,"MAPPING_NOT_FOUND")}}var k="shard:",f="multikey:",sJ="known_shards",m6=30000,u6=1e4,u=32;var JJ=RJ(()=>{b()});var AJ={};nJ(AJ,{validateTableForSharding:()=>OJ,schemaExists:()=>rJ,migrateRecord:()=>J6,listTables:()=>d,integrateExistingDatabase:()=>X6,dropSchema:()=>eJ,discoverExistingRecordsWithColumns:()=>WJ,discoverExistingPrimaryKeys:()=>FJ,createSchemaAcrossShards:()=>aJ,createSchema:()=>tJ,createMappingsForExistingKeys:()=>$6,clearShardMigrationCache:()=>H6,clearMigrationCache:()=>G6,checkMigrationNeeded:()=>Z6,autoDetectAndMigrate:()=>Y6});async function iJ(J,$,X){if(J.length===0)return;let Y=Math.max(1,Math.min($,J.length)),Z=0,G=Array(Y).fill(null).map(async()=>{while(Z<J.length){let H=Z++,U=J[H];if(U===void 0)continue;await X(U,H)}});await Promise.all(G)}function c6(J,$,X,Y){let Z=X.length;switch(Y){case"hash":{let G=0;for(let U=0;U<J.length;U++){let _=J.charCodeAt(U);G=(G<<5)-G+_,G=G&G}let H=Math.abs(G)%Z;return X[H]}case"random":return X[Math.floor(Math.random()*Z)];default:return X[$%Z]}}async function tJ(J,$){let X=$.split(";").map((Y)=>Y.trim()).filter((Y)=>Y.length>0&&!Y.startsWith("--"));for(let Y of X)try{await J.prepare(Y).run()}catch(Z){throw console.error("Failed to execute schema statement:",Y,Z),new j(`Schema migration failed: ${Z}`,"SCHEMA_MIGRATION_FAILED")}}async function aJ(J,$){let X=Object.entries(J).map(([Y,Z])=>{return tJ(Z,$).catch((G)=>{throw new j(`Failed to create schema on shard ${Y}: ${G.message}`,"SCHEMA_CREATION_FAILED")})});await Promise.all(X)}async function rJ(J,$){try{return await J.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind($).first()!==null}catch{return!1}}async function eJ(J,...$){for(let X of $)try{await J.prepare(`DROP TABLE IF EXISTS ${X}`).run()}catch(Y){console.error(`Failed to drop table ${X}:`,Y)}}async function d(J){try{return(await J.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all()).results.map((X)=>X.name)}catch{return[]}}async function J6(J,$,X,Y){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(Y))throw new j(`Invalid table name for migration: ${Y}`,"INVALID_TABLE_NAME");let Z=await J.prepare(`SELECT * FROM ${Y} WHERE id = ?`).bind(X).first();if(!Z)throw new j(`Record with primary key ${X} not found in source database`,"RECORD_NOT_FOUND");let G=Object.keys(Z);if(G.length===0)throw new j(`Source record for ${X} has no columns`,"EMPTY_SOURCE_RECORD");let H=G.map(()=>"?").join(", "),U=G.map((F)=>Z[F]),_=`INSERT OR REPLACE INTO ${Y} (${G.join(", ")}) VALUES (${H})`;await $.prepare(_).bind(...U).run(),await J.prepare(`DELETE FROM ${Y} WHERE id = ?`).bind(X).run()}async function FJ(J,$,X="id"){try{return(await J.prepare(`SELECT ${X} FROM ${$}`).all()).results.map((Z)=>String(Z[X]))}catch(Y){throw new j(`Failed to discover primary keys in table ${$}: ${Y}`,"DISCOVERY_FAILED")}}async function WJ(J,$,X="id"){try{let Y=`${$}_columns`,Z;if(CJ.has(Y))Z=CJ.get(Y).map((_)=>_.name);else{let F=(await J.prepare(`PRAGMA table_info(${$})`).all()).results.map((W)=>({name:W.name,type:W.type}));CJ.set(Y,F),Z=F.map((W)=>W.name)}let G=[X];if(Z.includes("username"))G.push("username");if(Z.includes("email"))G.push("email");if(Z.includes("name"))G.push("name");let H=`SELECT ${G.join(", ")} FROM ${$}`;return(await J.prepare(H).all()).results}catch(Y){throw new j(`Failed to discover records with columns in table ${$}: ${Y}`,"DISCOVERY_FAILED")}}async function $6(J,$,X,Y,Z={}){if(J.length===0||$.length===0)return;let G=Math.max(1,Z.concurrency??25),H=J.map((U,_)=>({primaryKey:U,shard:c6(U,_,$,X)}));await Y.setShardMappingsBatch(H,{concurrency:G})}async function OJ(J,$,X){let Y=[],Z=0;try{if(!await J.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind($).first())return Y.push(`Table '${$}' does not exist`),{isValid:!1,tableName:$,primaryKeyColumn:X,recordCount:0,issues:Y};if(!(await J.prepare(`PRAGMA table_info(${$})`).all()).results.some((F)=>F.name===X&&F.pk===1))Y.push(`Primary key column '${X}' not found or not set as primary key`);if(Z=(await J.prepare(`SELECT COUNT(*) as count FROM ${$}`).first())?.count||0,Z===0)Y.push(`Table '${$}' is empty`)}catch(G){Y.push(`Database validation error: ${G}`)}return{isValid:Y.length===0,tableName:$,primaryKeyColumn:X,recordCount:Z,issues:Y}}async function X6(J,$,X,Y={}){let{tables:Z,primaryKeyColumn:G="id",strategy:H="hash",addShardMappingsTable:U=!0,dryRun:_=!1,migrateOtherColumns:F=!1,concurrency:W=25}=Y,O=Math.max(1,W),A=[],Q=0,z=0,T=0;try{let E=(Z||await d(J)).filter((P)=>P!=="shard_mappings");for(let P of E)try{let M=await OJ(J,P,G);if(!M.isValid){A.push(`Table ${P}: ${M.issues.join(", ")}`);continue}if(F){let D=await WJ(J,P,G);if(D.length===0){A.push(`Table ${P} has no records to process`);continue}if(!_){let V=D.map((L)=>{let C=String(L[G]),h=[];if(L.username&&typeof L.username==="string")h.push(`username:${L.username}`);if(L.email&&typeof L.email==="string")h.push(`email:${L.email}`);if(L.name&&typeof L.name==="string")h.push(`name:${L.name}`);return{primaryKey:C,shard:$,additionalKeys:h}});await X.setShardMappingsBatch(V,{concurrency:O}),T+=V.length}z+=D.length}else{let D=await FJ(J,P,G);if(D.length===0){A.push(`Table ${P} has no records to process`);continue}if(!_){let V=D.map((L)=>({primaryKey:L,shard:$}));await X.setShardMappingsBatch(V,{concurrency:O}),T+=V.length}z+=D.length}Q++}catch(M){A.push(`Failed to process table ${P}: ${M}`)}if(U&&!_){if(!(await d(J)).includes("shard_mappings"))await J.prepare(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS shard_mappings (
|
|
3
3
|
primary_key TEXT PRIMARY KEY,
|
|
4
4
|
shard_name TEXT NOT NULL,
|
|
5
5
|
created_at INTEGER NOT NULL,
|
|
6
6
|
updated_at INTEGER NOT NULL
|
|
7
|
-
);`.trim()).run()}if(!
|
|
8
|
-
SELECT ${
|
|
9
|
-
ORDER BY ${
|
|
10
|
-
LIMIT ?`.trim()).bind(
|
|
7
|
+
);`.trim()).run()}if(!_)await X.addKnownShard($)}catch(B){A.push(`Integration failed: ${B}`)}return{success:A.length===0||A.length>0&&Q>0,shardName:$,tablesProcessed:Q,totalRecords:z,mappingsCreated:T,issues:A}}async function Y6(J,$,X,Y={}){let{primaryKeyColumn:Z="id",tablesToCheck:G,skipCache:H=!1,maxRecordsToCheck:U=1000,migrateOtherColumns:_=!1,concurrency:F=X.migrationConcurrency??25}=Y,W=Math.max(1,F),O=`${$}_migration_check`;if(!H&&g.has(O))return{migrationNeeded:!1,migrationPerformed:!1,recordsMigrated:0,tablesProcessed:0,issues:[]};let A=[],Q=0,z=0,T=!1,B=!1;try{let{KVShardMapper:E}=await Promise.resolve().then(() => (JJ(),NJ)),P=new E(X.kv,{hashShardMappings:X.hashShardMappings,mappingCacheTtlMs:X.mappingCacheTtlMs,knownShardsCacheTtlMs:X.knownShardsCacheTtlMs}),M=await d(J),D=G||M.filter((V)=>V!=="shard_mappings"&&!V.startsWith("sqlite_")&&V!=="sqlite_sequence");if(D.length===0)return g.set(O,!0),{migrationNeeded:!1,migrationPerformed:!1,recordsMigrated:0,tablesProcessed:0,issues:[]};for(let V of D)try{let L=await OJ(J,V,Z);if(!L.isValid||L.recordCount===0)continue;let C=Math.min(U,L.recordCount),h=await J.prepare(`
|
|
8
|
+
SELECT ${Z} FROM ${V}
|
|
9
|
+
ORDER BY ${Z}
|
|
10
|
+
LIMIT ?`.trim()).bind(C).all(),I=0,IJ=h.results.slice(0,10).map(async(S)=>{let v=String(S[Z]);return{key:v,mapping:await P.getShardMapping(v)}}),m=await Promise.all(IJ);for(let S of m)if(!S.mapping)I++,T=!0;if(I>0){if(X.debug)console.log(`Auto-migrating table ${V} in shard ${$} (${L.recordCount} records)`);if(_){let S=await WJ(J,V,Z),v=[];if(await iJ(S,W,async(w)=>{let BJ=String(w[Z]);if(await P.getShardMapping(BJ))return;let _J=[];if(w.username&&typeof w.username==="string")_J.push(`username:${w.username}`);if(w.email&&typeof w.email==="string")_J.push(`email:${w.email}`);if(w.name&&typeof w.name==="string")_J.push(`name:${w.name}`);v.push({primaryKey:BJ,shard:$,additionalKeys:_J})}),v.length>0)await P.setShardMappingsBatch(v,{concurrency:W});Q+=v.length}else{let S=await FJ(J,V,Z),v=[];if(await iJ(S,W,async(w)=>{if(!await P.getShardMapping(w))v.push({primaryKey:w,shard:$})}),v.length>0)await P.setShardMappingsBatch(v,{concurrency:W});Q+=v.length}if(z++,B=!0,X.debug)console.log(`Auto-migrated ${Q} records from table ${V}`)}}catch(L){A.push(`Auto-migration failed for table ${V}: ${L}`)}if(B){if(await P.addKnownShard($),!M.includes("shard_mappings"))await J.prepare(`CREATE TABLE IF NOT EXISTS shard_mappings (
|
|
11
11
|
primary_key TEXT PRIMARY KEY,
|
|
12
12
|
shard_name TEXT NOT NULL,
|
|
13
13
|
created_at INTEGER NOT NULL,
|
|
14
14
|
updated_at INTEGER NOT NULL
|
|
15
15
|
);
|
|
16
|
-
`).run()}if(f.set(F,!0),C&&Z.debug)console.log(`Auto-migration completed for shard ${Y}: ${E} records from ${I} tables`)}catch(V){A.push(`Auto-migration error: ${V}`)}return{migrationNeeded:M,migrationPerformed:C,recordsMigrated:E,tablesProcessed:I,issues:A}}async function hJ(J,Y,Z){let $=`${Y}_migration_check`;if(f.has($))return!1;try{let X=await p(J);if(X.includes("shard_mappings"))return f.set($,!0),!1;let{KVShardMapper:G}=await Promise.resolve().then(() => (c(),HJ)),U=new G(Z.kv,{hashShardMappings:Z.hashShardMappings,mappingCacheTtlMs:Z.mappingCacheTtlMs,knownShardsCacheTtlMs:Z.knownShardsCacheTtlMs}),H=X.filter((_)=>_!=="shard_mappings"&&!_.startsWith("sqlite_")&&_!=="sqlite_sequence");for(let _ of H.slice(0,3))try{if(((await J.prepare(`SELECT COUNT(*) as count FROM ${_} LIMIT 1`).first())?.count||0)>0){let A=await J.prepare(`SELECT id FROM ${_} LIMIT 1`).first();if(A){let E=String(A.id);if(!await U.getShardMapping(E))return!0}}}catch{continue}return!1}catch{return!1}}function pJ(){f.clear()}function yJ(J){let Y=`${J}_migration_check`;f.delete(Y)}var f,_J;var d=UJ(()=>{q();f=new Map,_J=new Map});q();c();var o=null,y=null,m=new Map,u=0;function v(J){if(!y)y=new K(J.kv,{hashShardMappings:J.hashShardMappings,mappingCacheTtlMs:J.mappingCacheTtlMs,knownShardsCacheTtlMs:J.knownShardsCacheTtlMs});return y}function QY(J){o=J,y=new K(J.kv,{hashShardMappings:J.hashShardMappings,mappingCacheTtlMs:J.mappingCacheTtlMs,knownShardsCacheTtlMs:J.knownShardsCacheTtlMs}),m.clear(),u=0;try{let Y=v(J);Promise.resolve().then(async()=>{let Z=await Y.getKnownShards(),$=Array.from(new Set([...Z,...Object.keys(J.shards)]));await Y.setKnownShards($)}).catch(()=>{return})}catch{}if(J.shards&&Object.keys(J.shards).length>0&&!J.disableAutoMigration)cJ(J).catch((Y)=>{console.warn("Background auto-migration failed:",Y)})}async function mJ(J){o=J,y=new K(J.kv,{hashShardMappings:J.hashShardMappings,mappingCacheTtlMs:J.mappingCacheTtlMs,knownShardsCacheTtlMs:J.knownShardsCacheTtlMs}),m.clear(),u=0;try{let Y=v(J),Z=await Y.getKnownShards(),$=Array.from(new Set([...Z,...Object.keys(J.shards)]));await Y.setKnownShards($)}catch{}if(J.shards&&Object.keys(J.shards).length>0&&!J.disableAutoMigration)try{await cJ(J)}catch(Y){console.warn("Auto migration failed:",Y)}}async function PY(J,Y){return await mJ(J),await Y()}async function cJ(J){try{let{autoDetectAndMigrate:Y}=await Promise.resolve().then(() => (d(),r)),Z=Object.keys(J.shards);if(J.debug)console.log(`\uD83D\uDD0D Checking ${Z.length} shards for existing data...`);let $=Z.map(async(G)=>{let U=J.shards[G];if(!U)return null;try{let H=await Y(U,G,J,{maxRecordsToCheck:1000});return{shardName:G,...H}}catch(H){return console.warn(`Auto-migration failed for shard ${G}:`,H),null}}),W=(await Promise.all($)).filter((G)=>G?.migrationPerformed);if(J.debug)if(W.length>0){let G=W.reduce((U,H)=>U+(H?.recordsMigrated||0),0);console.log(`\uD83C\uDF89 Auto-migration completed! Migrated ${G} records across ${W.length} shards`),W.forEach((U)=>{if(U)console.log(` ✅ ${U.shardName}: ${U.recordsMigrated} records from ${U.tablesProcessed} tables`)})}else console.log("✅ All shards ready - no migration needed")}catch(Y){console.warn("Background auto-migration setup failed:",Y)}}function TY(){o=null,y=null,m.clear(),u=0}function T(){if(!o)throw new j("CollegeDB not initialized. Call initialize() first.","NOT_INITIALIZED");return o}function DY(J){let Y=J.trim().toUpperCase();if(Y.startsWith("SELECT")||Y.startsWith("VALUES")||Y.startsWith("TABLE")||Y.startsWith("PRAGMA")||Y.startsWith("EXPLAIN")||Y.startsWith("WITH")||Y.startsWith("SHOW"))return"read";return"write"}function dJ(J,Y){let Z=J.strategy||"hash";if(typeof Z==="string")return Z;let $=Z;return $[Y]||$.write||$.read||"hash"}function RY(J,Y){if(J===Y)return 0;let Z={wnam:{lat:37.7749,lon:-122.4194},enam:{lat:40.7128,lon:-74.006},weur:{lat:51.5074,lon:-0.1278},eeur:{lat:52.52,lon:13.405},apac:{lat:35.6762,lon:139.6503},oc:{lat:-33.8688,lon:151.2093},me:{lat:25.2048,lon:55.2708},af:{lat:-26.2041,lon:28.0473}},$=Z[J],X=Z[Y],W=$.lat-X.lat,G=$.lon-X.lon;return Math.sqrt(W*W+G*G)}function zY(J){let Y=J.cf;if(!Y||!Y.country)return"wnam";let{country:Z,continent:$}=Y;if(["US","CA","MX"].includes(Z)){let X=Y.region||Y.regionCode||"",W=Y.timezone||"";if(X.includes("CA")||X.includes("WA")||X.includes("OR")||X.includes("NV")||X.includes("AZ")||X.includes("UT")||W.includes("Pacific")||W.includes("America/Los_Angeles"))return"wnam";return"enam"}if(["GL","PM","BM"].includes(Z))return"enam";if(["GB","IE","FR","ES","PT","NL","BE","LU","CH","AT","IT"].includes(Z))return"weur";if(["DE","PL","CZ","SK","HU","SI","HR","BA","RS","ME","MK","AL","BG","RO","MD","UA","BY","LT","LV","EE","FI","SE","NO","DK","IS"].includes(Z))return"eeur";if(Z==="RU")return"eeur";if(["JP","KR","CN","HK","TW","MO","MN","KP"].includes(Z))return"apac";if(["TH","VN","SG","MY","ID","PH","BN","KH","LA","MM","TL","IN","PK","BD","LK","NP","BT","MV","AF"].includes(Z))return"apac";if(["AU","NZ","PG","FJ","NC","VU","SB","WS","TO","KI","NR","PW","FM","MH","TV"].includes(Z))return"oc";if(["AE","SA","QA","KW","BH","OM","YE","IQ","IR","SY","LB","JO","IL","PS","TR","CY"].includes(Z))return"me";if($==="AF"||["EG","LY","TN","DZ","MA","SD","SS","ET","ER","DJ","SO"].includes(Z))return"af";if(["KZ","UZ","TM","TJ","KG"].includes(Z))return"eeur";if($==="SA"||["BR","AR","CL","PE","CO","VE","EC","BO","PY","UY","GY","SR","GF"].includes(Z))return"enam";if(["GT","BZ","SV","HN","NI","CR","PA","CU","JM","HT","DO","PR","TT","BB","GD","VC","LC","DM","AG","KN"].includes(Z))return"enam";return"wnam"}function MY(J){if(typeof J==="string")return J;return J.region||"wnam"}async function e(J){try{let[Y,Z]=await Promise.all([J.prepare("PRAGMA page_count").first(),J.prepare("PRAGMA page_size").first()]);if(!Y?.page_count||!Z?.page_size)throw new j("Failed to retrieve database size information","SIZE_QUERY_FAILED");return Y.page_count*Z.page_size}catch(Y){throw new j(`Failed to get database size: ${Y instanceof Error?Y.message:"Unknown error"}`,"SIZE_QUERY_FAILED")}}async function BY(J,Y){let Z=Math.max(0,Y.sizeCacheTtlMs??30000),$=m.get(J);if($&&$.expiresAt>=Date.now())return $.size;let X=Y.shards[J];if(!X)throw new j(`Shard ${J} not found in configuration`,"SHARD_NOT_FOUND");let W=await e(X);if(Z>0)m.set(J,{size:W,expiresAt:Date.now()+Z});return W}async function oJ(J,Y){if(typeof Y.maxDatabaseSize!=="number"||!Number.isFinite(Y.maxDatabaseSize)||Y.maxDatabaseSize<=0)return J;let Z=Y.maxDatabaseSize,X=(await Promise.allSettled(J.map(async(W)=>{let G=await BY(W,Y);return{shard:W,size:G,withinLimit:G<Z}}))).filter((W)=>W.status==="fulfilled"&&W.value.withinLimit).map((W)=>W.value.shard);if(X.length===0){if(Y.debug)console.warn("All shards exceed maxDatabaseSize limit. Allowing allocation to prevent failure.");return J}if(Y.debug&&X.length<J.length){let W=J.filter((G)=>!X.includes(G));console.log(`Excluded ${W.length} shards due to size limits: ${W.join(", ")}`)}return X}function wY(J,Y,Z,$){let X=Y.filter((O)=>Z[O]);if(X.length===0){let O=0;for(let A=0;A<$.length;A++){let E=$.charCodeAt(A);O=(O<<5)-O+E,O=O&O}let F=Math.abs(O)%Y.length;return Y[F]}let W=X.map((O)=>{let F=Z[O],A=RY(J,MY(F)),E=typeof F==="object"?F.priority||1:1,I=A-E*0.1;return{shard:O,score:I,distance:A,priority:E}});W.sort((O,F)=>O.score-F.score);let G=W[0].score,U=W.filter((O)=>Math.abs(O.score-G)<0.01);if(U.length===1)return U[0].shard;let H=0;for(let O=0;O<$.length;O++){let F=$.charCodeAt(O);H=(H<<5)-H+F,H=H&H}let _=Math.abs(H)%U.length;return U[_].shard}function g(J,Y,Z,$){switch(J){case"hash":{let X=0;for(let G=0;G<Y.length;G++){let U=Y.charCodeAt(G);X=(X<<5)-X+U,X=X&X}let W=Math.abs(X)%Z.length;return Z[W]||Z[0]}case"location":{if(!$.targetRegion)return g("hash",Y,Z,$);return wY($.targetRegion,Z,$.shardLocations||{},Y)}case"random":return Z[Math.floor(Math.random()*Z.length)]||Z[0];default:return g("hash",Y,Z,$)}}async function nJ(J,Y="write"){let Z=T(),$=v(Z),X=await $.getShardMapping(J);if(X)return X.shard;let W=Object.keys(Z.shards);if(W.length===0)throw new j("No shards configured","NO_SHARDS");let G=await oJ(W,Z),U,H=dJ(Z,Y);if(Z.coordinator)try{let _=Z.coordinator.idFromName("default"),F=await Z.coordinator.get(_).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:J,strategy:H,operationType:Y,targetRegion:Z.targetRegion,shardLocations:Z.shardLocations,availableShards:G})});if(F.ok)U=(await F.json()).shard;else U=g(H,J,G,Z)}catch(_){console.warn("Coordinator allocation failed, falling back to local strategy:",_),U=g(H,J,G,Z)}else U=g(H,J,G,Z);return await $.setShardMapping(J,U),U}async function NY(J,Y="write"){let Z=T(),$=await nJ(J,Y),X=Z.shards[$];if(!X)throw new j(`Shard ${$} not found in configuration`,"SHARD_NOT_FOUND");return X}async function xY(J,Y){let{createSchema:Z}=await Promise.resolve().then(() => (d(),r));await Z(J,Y)}async function JJ(J,Y){let Z=DY(Y);return(await NY(J,Z)).prepare(Y)}async function lJ(J,Y,Z=[]){let X=await(await JJ(J,Y)).bind(...Z).run();if(!X.success)throw new j(`Query failed: ${X.error||"Unknown error"}`,"QUERY_FAILED");return X}function vY(J){let Y=J.results[0];if(Y&&typeof Y==="object"){for(let $ of["id","ID","Id","rowid","ROWID","RowId","last_row_id","lastInsertId","insertId"]){let X=Y[$];if(X!==void 0&&X!==null)return X}for(let[$,X]of Object.entries(Y)){let W=$.toLowerCase();if((W==="id"||W==="rowid")&&(typeof X==="number"||typeof X==="string"))return X}for(let $ of Object.values(Y))if(typeof $==="number"||typeof $==="string")return $}let Z=J.meta.last_row_id;if(Z!==void 0&&Z!==null)return Z;return}function CY(){return`insert:${Date.now()}:${Math.random().toString(36).slice(2)}`}async function kY(){let J=T(),Y=Object.keys(J.shards);if(Y.length===0)throw new j("No shards configured","NO_SHARDS");let Z=await oJ(Y,J);if(Z.length===0)throw new j("No shards available for insert","NO_SHARDS");let $=dJ(J,"write"),X=CY();if(J.coordinator)try{let W=J.coordinator.idFromName("default"),U=await J.coordinator.get(W).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:X,strategy:$,operationType:"write",targetRegion:J.targetRegion,shardLocations:J.shardLocations,availableShards:Z})});if(U.ok)return(await U.json()).shard}catch(W){console.warn("Coordinator allocation for insert failed, falling back to local strategy:",W)}if($==="round-robin"){let W=Z[u%Z.length];return u=(u+1)%Z.length,W}return g($,X,Z,J)}async function sJ(J,Y,Z=[]){let $=T();if(!$.shards[J])throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");let W=/\breturning\b/i.test(Y)?await YJ(J,Y,Z):await jJ(J,Y,Z),G=vY(W);if(G===void 0)throw new j("Insert did not return a generated primary key","GENERATED_KEY_UNAVAILABLE");return await v($).setShardMapping(String(G),J),{...W,generatedId:G}}async function qY(J,Y=[]){let Z=await kY();return await sJ(Z,J,Y)}async function SY(J,Y,Z=[]){return await sJ(J,Y,Z)}async function iJ(J,Y,Z=[]){let X=await(await JJ(J,Y)).bind(...Z).all();if(!X.success)throw new j(`Query failed: ${X.error||"Unknown error"}`,"QUERY_FAILED");return X}async function tJ(J,Y,Z=[]){return await(await JJ(J,Y)).bind(...Z).first()}async function KY(J,Y,Z=[],$=50){let X=T(),G=await v(X).getShardMapping(J);if(G){if(X.shards[G.shard]){let _=await YJ(G.shard,Y,Z);if(_.success&&_.results.length>0)return _}}let U=await ZJ(Y,Z,$);return rJ(U)}async function fY(J,Y,Z=[],$=50){let X=T(),G=await v(X).getShardMapping(J);if(G){if(X.shards[G.shard]){let _=await AJ(G.shard,Y,Z);if(_!==null)return _}}return(await JY(Y,Z,$)).find((H)=>H!==null)??null}async function bY(J,Y,Z){let $=T();if(!$.shards[Y])throw new j(`Shard ${Y} not found in configuration`,"SHARD_NOT_FOUND");let X=v($),W=await X.getShardMapping(J);if(!W)throw new j(`No existing mapping found for primary key: ${J}`,"MAPPING_NOT_FOUND");if(W.shard!==Y){let{migrateRecord:G}=await Promise.resolve().then(() => (d(),r)),U=$.shards[W.shard],H=$.shards[Y];if(!U||!H)throw new j("Source or target shard not available","SHARD_UNAVAILABLE");await G(U,H,J,Z)}await X.updateShardMapping(J,Y)}async function hY(){let J=T();if(J.coordinator)try{let Y=J.coordinator.idFromName("default"),$=await J.coordinator.get(Y).fetch("http://coordinator/shards");if($.ok)return await $.json()}catch(Y){console.warn("Failed to get shards from coordinator:",Y)}try{let Z=await v(J).getKnownShards(),$=new Set([...Object.keys(J.shards),...Z]);return Array.from($)}catch{return Object.keys(J.shards)}}async function pY(){let J=T();if(J.coordinator)try{let X=J.coordinator.idFromName("default"),G=await J.coordinator.get(X).fetch("http://coordinator/stats");if(G.ok)return await G.json()}catch(X){console.warn("Failed to get stats from coordinator:",X)}let Y=v(J),Z=await Y.getShardKeyCounts(),$=Object.keys(J.shards);try{let X=await Y.getKnownShards();$=Array.from(new Set([...$,...X]))}catch{}return $.map((X)=>({binding:X,count:Z[X]||0}))}async function jJ(J,Y,Z=[]){let X=T().shards[J];if(!X)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");let W=await X.prepare(Y).bind(...Z).run();if(!W.success)throw new j(`Query failed: ${W.error||"Unknown error"}`,"QUERY_FAILED");return W}async function YJ(J,Y,Z=[]){let X=T().shards[J];if(!X)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");return await X.prepare(Y).bind(...Z).all()}async function AJ(J,Y,Z=[]){let X=T().shards[J];if(!X)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");return await X.prepare(Y).bind(...Z).first()}async function aJ(J,Y=[],Z=50){let $=T(),X=[];for(let[G,U]of Object.entries($.shards)){if(!G||!U){console.error(`Shard ${G??"<null>"} not found, skipping`);continue}X.push(()=>U.prepare(J).bind(...Y).run().catch((H)=>{return console.error(`Error executing query on shard ${G}:`,H),{success:!1,results:[],error:H instanceof Error?H.message:String(H),meta:{duration:0}}}))}let W=[];for(let G=0;G<X.length;G+=Z){let U=X.slice(G,G+Z).map((H)=>H());W.push(...await Promise.all(U))}return W}async function ZJ(J,Y=[],Z=50){let $=T(),X=[];for(let[G,U]of Object.entries($.shards)){if(!G||!U){console.error(`Shard ${G??"<null>"} not found, skipping`);continue}X.push(()=>U.prepare(J).bind(...Y).all().catch((H)=>{return console.error(`Error executing query on shard ${G}:`,H),{success:!1,results:[],error:H instanceof Error?H.message:String(H),meta:{duration:0}}}))}let W=[];for(let G=0;G<X.length;G+=Z){let U=X.slice(G,G+Z).map((H)=>H());W.push(...await Promise.all(U))}return W}function n(J,Y=50){if(!Number.isFinite(J??Y))return Y;return Math.max(1,Math.floor(J??Y))}function yY(J){if(!Number.isFinite(J??0))return 0;return Math.max(0,Math.floor(J??0))}function uY(J){if(J===void 0)return;if(!Number.isFinite(J))return;return Math.max(0,Math.floor(J))}function uJ(J,Y){if(typeof Y==="function")return Y(J);if(!Y||typeof J!=="object"||J===null)return;return J[String(Y)]}function gY(J,Y){if(J===Y)return 0;if(J===null||J===void 0)return 1;if(Y===null||Y===void 0)return-1;if(typeof J==="number"&&typeof Y==="number")return J-Y;if(typeof J==="bigint"&&typeof Y==="bigint")return J<Y?-1:1;if(J instanceof Date&&Y instanceof Date)return J.getTime()-Y.getTime();if(typeof J==="boolean"&&typeof Y==="boolean")return Number(J)-Number(Y);return String(J).localeCompare(String(Y),void 0,{numeric:!0,sensitivity:"base"})}function rJ(J){let Y=J.flatMap((W)=>W.results||[]),Z=J.filter((W)=>!W.success),$=J.reduce((W,G)=>W+(G.meta?.duration||0),0);if(Z.length===0)return{success:!0,results:Y,meta:{duration:$}};let X=Z.map((W)=>W.error||"Unknown shard query error").filter(Boolean).join("; ");return{success:!1,results:Y,error:X||"One or more shard queries failed",meta:{duration:$}}}async function eJ(J,Y=[],Z={}){let $=n(Z.batchSize),X=yY(Z.offset),W=uY(Z.limit),G=rJ(await ZJ(J,Y,$)),U=G.results;if(Z.filter)U=U.filter((O)=>Z.filter?.(O));if(Z.comparator)U=[...U].sort(Z.comparator);else if(Z.sortBy){let O=Z.sortDirection==="desc"?-1:1;U=[...U].sort((F,A)=>{let E=uJ(F,Z.sortBy),I=uJ(A,Z.sortBy);return gY(E,I)*O})}let H=W===void 0?void 0:X+W,_=U.slice(X,H);return{...G,results:_}}async function JY(J,Y=[],Z=50){let $=T(),X=[];for(let[G,U]of Object.entries($.shards)){if(!G||!U){console.error(`Shard ${G??"<null>"} not found, skipping`);continue}X.push(()=>U.prepare(J).bind(...Y).first().catch((H)=>{return console.error(`Error executing query on shard ${G}:`,H),null}))}let W=[];for(let G=0;G<X.length;G+=Z){let U=X.slice(G,G+Z).map((H)=>H());W.push(...await Promise.all(U))}return W}async function mY(J,Y=[],Z={}){return(await eJ(J,Y,{...Z,limit:1})).results[0]??null}async function cY(){let J=T();if(await v(J).clearAllMappings(),m.clear(),J.coordinator)try{let Z=J.coordinator.idFromName("default");await J.coordinator.get(Z).fetch("http://coordinator/flush",{method:"POST"})}catch(Z){console.warn("Failed to flush coordinator:",Z)}}async function dY(J){let Z=T().shards[J];if(!Z)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");return await e(Z)}var oY=/^[A-Za-z_][A-Za-z0-9_]*$/;function b(J){let Y=J.trim();if(!Y)throw new j("Identifier cannot be empty","INVALID_IDENTIFIER");let Z=Y.split(".").map(($)=>$.trim());if(Z.some(($)=>!$||!oY.test($)))throw new j(`Invalid SQL identifier: ${J}`,"INVALID_IDENTIFIER");return Z.map(($)=>`"${$}"`).join(".")}function gJ(J){return J.toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"")}function nY(J){if(typeof J==="string")return[{name:J}];if(!Array.isArray(J)||J.length===0)throw new j("At least one index column is required","INVALID_INDEX_COLUMNS");return J.map((Y)=>{if(typeof Y==="string")return{name:Y};if(!Y?.name)throw new j("Index column name is required","INVALID_INDEX_COLUMNS");return{name:Y.name,order:Y.order,collate:Y.collate}})}function VJ(J,Y,Z={}){let $=nY(Y),X=b(J),W=Z.indexName?Z.indexName:["idx",gJ(J),...$.map((F)=>gJ(F.name))].filter(Boolean).join("_").slice(0,120),G=b(W||"idx_auto"),U=$.map((F)=>{let A=b(F.name),E=F.order?` ${F.order}`:"",I=F.collate?` COLLATE ${b(F.collate).replace(/"/g,"")}`:"";return`${A}${I}${E}`}).join(", "),H=Z.ifNotExists===!1?"":" IF NOT EXISTS",_=Z.unique?"UNIQUE ":"",O=Z.where?.trim()?` WHERE ${Z.where.trim()}`:"";return`CREATE ${_}INDEX${H} ${G} ON ${X} (${U})${O}`}async function lY(J,Y,Z,$={}){let X=VJ(Y,Z,$);return lJ(J,X)}async function sY(J,Y,Z,$={}){let X=VJ(Y,Z,$);return jJ(J,X)}async function iY(J,Y,Z={}){let $=VJ(J,Y,Z);return aJ($,[],n(Z.batchSize))}function LJ(J,Y="query-plan"){switch(Y){case"raw":return`EXPLAIN ${J}`;case"analyze":return`EXPLAIN ANALYZE ${J}`;case"query-plan":default:return`EXPLAIN QUERY PLAN ${J}`}}async function tY(J,Y,Z=[],$={}){return iJ(J,LJ(Y,$.mode),Z)}async function aY(J,Y,Z=[],$={}){return YJ(J,LJ(Y,$.mode),Z)}async function rY(J,Y=[],Z={}){return ZJ(LJ(J,Z.mode),Y,n(Z.batchSize))}async function eY(J,Y){let Z=b(Y),$=await tJ(J,`SELECT COUNT(*) AS row_count FROM ${Z}`);if(!$||$.row_count===void 0||$.row_count===null)return 0;return Number($.row_count)||0}async function JZ(J,Y){let Z=b(Y),$=await AJ(J,`SELECT COUNT(*) AS row_count FROM ${Z}`);if(!$||$.row_count===void 0||$.row_count===null)return 0;return Number($.row_count)||0}async function YZ(J,Y=50){let Z=T(),$=n(Y),W=`SELECT COUNT(*) AS row_count FROM ${b(J)}`,G=[];for(let[_,O]of Object.entries(Z.shards)){if(!_||!O)continue;G.push(async()=>{try{let F=await O.prepare(W).first(),A=Number(F?.row_count??0);return{shard:_,count:Number.isFinite(A)?A:0,success:!0}}catch(F){return{shard:_,count:null,success:!1,error:F instanceof Error?F.message:String(F)}}})}let U=[];for(let _=0;_<G.length;_+=$){let O=G.slice(_,_+$).map((F)=>F());U.push(...await Promise.all(O))}return{total:U.reduce((_,O)=>_+(O.count??0),0),shards:U}}async function ZZ(J){let Y=T(),Z=await nJ(J,"read"),$=Y.shards[Z];if(!$)throw new j(`Shard ${Z} not found in configuration`,"SHARD_NOT_FOUND");return e($)}async function YY(J=50){let Y=T(),Z=n(J),$=[];for(let[W,G]of Object.entries(Y.shards)){if(!W||!G)continue;$.push(async()=>{try{return{shard:W,size:await e(G),success:!0}}catch(U){return{shard:W,size:null,success:!1,error:U instanceof Error?U.message:String(U)}}})}let X=[];for(let W=0;W<$.length;W+=Z){let G=$.slice(W,W+Z).map((U)=>U());X.push(...await Promise.all(G))}return X}async function $Z(J=50){return(await YY(J)).reduce((Z,$)=>Z+($.size??0),0)}q();class ZY{state;constructor(J){this.state=J}async getState(){return await this.state.storage.get("coordinator_state")||{knownShards:[],shardStats:{},strategy:"round-robin",roundRobinIndex:0}}async saveState(J){await this.state.storage.put("coordinator_state",J)}async fetch(J){let Z=new URL(J.url).pathname,$=J.method;try{switch(`${$} ${Z}`){case"GET /shards":return this.handleListShards();case"POST /shards":return this.handleAddShard(J);case"DELETE /shards":return this.handleRemoveShard(J);case"GET /stats":return this.handleGetStats();case"POST /stats":return this.handleUpdateStats(J);case"POST /allocate":return this.handleAllocateShard(J);case"POST /flush":return this.handleFlush();case"GET /health":return new Response("OK",{status:200});default:return new Response("Not Found",{status:404})}}catch(X){return console.error("ShardCoordinator error:",X),new Response("Internal Server Error",{status:500})}}async handleListShards(){let J=await this.getState();return new Response(JSON.stringify(J.knownShards),{headers:{"Content-Type":"application/json"}})}async handleAddShard(J){let{shard:Y}=await J.json();if(!Y||typeof Y!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Z=await this.getState();if(!Z.knownShards.includes(Y))Z.knownShards.push(Y),Z.shardStats[Y]={binding:Y,count:0,lastUpdated:Date.now()},await this.saveState(Z);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleRemoveShard(J){let{shard:Y}=await J.json();if(!Y||typeof Y!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Z=await this.getState(),$=Z.knownShards.indexOf(Y);if($>-1){if(Z.knownShards.splice($,1),delete Z.shardStats[Y],Z.roundRobinIndex>=Z.knownShards.length)Z.roundRobinIndex=0;await this.saveState(Z)}return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleGetStats(){let J=await this.getState(),Y=Object.values(J.shardStats);return new Response(JSON.stringify(Y),{headers:{"Content-Type":"application/json"}})}async handleUpdateStats(J){let{shard:Y,count:Z}=await J.json();if(!Y||typeof Y!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});if(Z===void 0||typeof Z!=="number")return new Response(JSON.stringify({error:"Missing or invalid count parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let $=await this.getState();if($.shardStats[Y])$.shardStats[Y].count=Z,$.shardStats[Y].lastUpdated=Date.now(),await this.saveState($);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleAllocateShard(J){let{primaryKey:Y,strategy:Z,operationType:$,availableShards:X}=await J.json();if(!Y||typeof Y!=="string")return new Response(JSON.stringify({error:"Missing or invalid primaryKey parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let W=await this.getState(),G=X||W.knownShards;if(G.length===0)return new Response(JSON.stringify({error:"No shards available"}),{status:400,headers:{"Content-Type":"application/json"}});let U=this.resolveStrategy(W.strategy,Z,$||"write"),H=this.selectShard(Y,W,U,G);if(U==="round-robin")W.roundRobinIndex=(W.roundRobinIndex+1)%G.length,await this.saveState(W);return new Response(JSON.stringify({shard:H}),{headers:{"Content-Type":"application/json"}})}async handleFlush(){return await this.state.storage.deleteAll(),new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}resolveStrategy(J,Y,Z="write"){if(Y)return Y;if(typeof J==="string")return J;return J[Z]}selectShard(J,Y,Z,$){let X=$||Y.knownShards;if(X.length===0)throw new j("No shards available","NO_SHARDS");switch(Z){case"round-robin":return X[Y.roundRobinIndex]??X[0];case"random":return X[Math.floor(Math.random()*X.length)];case"hash":{let W=0;for(let U=0;U<J.length;U++){let H=J.charCodeAt(U);W=(W<<5)-W+H,W=W&W}let G=Math.abs(W)%X.length;return X[G]}case"location":{let W=Y.targetRegion,G=Y.shardLocations||{},U=X.filter((V)=>G[V]);if(!W||U.length===0){let V=0;for(let z=0;z<J.length;z++){let R=J.charCodeAt(z);V=(V<<5)-V+R,V=V&V}let L=Math.abs(V)%X.length;return X[L]}let H={wnam:{lat:37.7749,lon:-122.4194},enam:{lat:40.7357,lon:-74.1724},weur:{lat:51.5074,lon:-0.1278},eeur:{lat:52.2297,lon:21.0122},apac:{lat:35.6762,lon:139.6503},oc:{lat:-33.8688,lon:151.2093},me:{lat:25.2048,lon:55.2708},af:{lat:-26.2041,lon:28.0473}},_=(V,L)=>(L in V),O=(V)=>_(H,V)?V:"wnam",F=(V,L)=>{let z=H[O(V)],R=H[O(L)],P=z.lat-R.lat,Q=z.lon-R.lon;return Math.sqrt(P*P+Q*Q)},A=U.map((V)=>{let L=G[V],z=F(W,L.region),R=L.priority||1;return{shard:V,score:z-R*0.1}});A.sort((V,L)=>V.score-L.score);let E=A[0].score,I=A.filter((V)=>Math.abs(V.score-E)<0.01);if(I.length===1)return I[0].shard;let M=0;for(let V=0;V<J.length;V++){let L=J.charCodeAt(V);M=(M<<5)-M+L,M=M&M}let C=Math.abs(M)%I.length;return I[C].shard}default:return X[0]}}async incrementShardCount(J){let Y=await this.getState();if(Y.shardStats[J])Y.shardStats[J].count++,Y.shardStats[J].lastUpdated=Date.now(),await this.saveState(Y)}async decrementShardCount(J){let Y=await this.getState();if(Y.shardStats[J]&&Y.shardStats[J].count>0)Y.shardStats[J].count--,Y.shardStats[J].lastUpdated=Date.now(),await this.saveState(Y)}}q();c();q();var XZ=500;function WY(J,Y={}){let Z=Y.scanCount??XZ;return{async get($,X="text"){let W=await J.get($);if(W===null)return null;if(X!=="json")return W;try{return JSON.parse(W)}catch(G){throw new j(`Failed to parse JSON from Redis for key ${$}: ${G instanceof Error?G.message:String(G)}`,"KV_JSON_PARSE_FAILED")}},async put($,X){await J.set($,X)},async delete($){await J.del($)},async list($){let X=$?.prefix??"",W=`${X}*`,G=$?.cursor??"0",U=$?.limit,H=[];do{let _=await jZ(J,G,W,Z);G=_.cursor;for(let O of _.keys){if(!X||O.startsWith(X))H.push(O);if(U&&H.length>=U)break}if(U&&H.length>=U)break}while(G!=="0");return{keys:H.map((_)=>({name:_})),cursor:G,list_complete:G==="0"}}}}function WZ(J,Y={}){return WY(J,Y)}function GY(J,Y){if(Y)return XJ(J,Y);return{prepare(Z){return new DJ(J,Z)}}}function UY(J,Y){if(Y)return XJ(J,Y);return{prepare(Z){return new RJ(J,Z)}}}function GZ(J,Y){if(Y)return XJ(J,Y);return{prepare(Z){return new zJ(J,Z)}}}function XJ(J,Y){return{prepare(Z){return new MJ(J,Y,Z)}}}function UZ(J){return{async get(Y,Z="text"){let $=await EZ(J,Y);if($===null||$===void 0)return null;if(Z==="json"){if(typeof $==="string")try{return JSON.parse($)}catch(X){throw new j(`Failed to parse JSON from NuxtHub KV for key ${Y}: ${X instanceof Error?X.message:String(X)}`,"KV_JSON_PARSE_FAILED")}return $}return typeof $==="string"?$:JSON.stringify($)},async put(Y,Z){await IZ(J,Y,Z)},async delete(Y){await QZ(J,Y)},async list(Y){let Z=Y?.prefix??"",$=await PZ(J,Z);return{keys:(typeof Y?.limit==="number"?$.slice(0,Y.limit):$).map((W)=>({name:W})),list_complete:!0}}}}function HZ(J,Y){return GY({query:async($,X=[])=>{let W=Y(J.connectionString);if(typeof W.connect==="function")await W.connect();try{return await W.query($,X)}finally{if(typeof W.release==="function")W.release();else if(typeof W.end==="function")await W.end()}}})}function _Z(J,Y){return UY({execute:async($,X=[])=>{let W=Y(J.connectionString);try{if(typeof W.execute==="function")return await W.execute($,X);if(typeof W.query==="function")return await W.query($,X);throw new j("Hyperdrive MySQL client is missing execute/query methods","MYSQL_CLIENT_INVALID")}finally{if(typeof W.end==="function")await W.end();else if(typeof W.close==="function")await W.close();else if(typeof W.destroy==="function")W.destroy()}}})}function OZ(J){if(!J||typeof J!=="object")return!1;return typeof J.prepare==="function"}function FZ(J){if(!J||typeof J!=="object")return!1;let Y=J;return typeof Y.get==="function"&&typeof Y.put==="function"&&typeof Y.delete==="function"&&typeof Y.list==="function"}class DJ{client;sql;bindings;constructor(J,Y,Z=[]){this.client=J,this.sql=Y,this.bindings=Z}bind(...J){return new DJ(this.client,this.sql,J)}async run(){let J=Date.now(),Y=TJ(this.sql),Z=await this.client.query(Y,this.bindings);return{success:!0,results:Z.rows??[],meta:x(J,{changes:typeof Z.rowCount==="number"?Z.rowCount:void 0,command:Z.command})}}async all(){let J=Date.now(),Y=TJ(this.sql),Z=await this.client.query(Y,this.bindings);return{success:!0,results:Z.rows??[],meta:x(J,{changes:typeof Z.rowCount==="number"?Z.rowCount:void 0,command:Z.command})}}async first(){let J=TJ(this.sql);return(await this.client.query(J,this.bindings)).rows?.[0]??null}}class RJ{client;sql;bindings;constructor(J,Y,Z=[]){this.client=J,this.sql=Y,this.bindings=Z}bind(...J){return new RJ(this.client,this.sql,J)}async run(){let J=Date.now(),Y=await EJ(this.client,this.sql,this.bindings);if(Array.isArray(Y))return{success:!0,results:Y,meta:x(J)};let Z=Y;return{success:!0,results:[],meta:x(J,{changes:Z.affectedRows,last_row_id:Z.insertId,warningStatus:Z.warningStatus})}}async all(){let J=Date.now(),Y=await EJ(this.client,this.sql,this.bindings);return{success:!0,results:Array.isArray(Y)?Y:[],meta:x(J,{changes:!Array.isArray(Y)?Y.affectedRows:void 0})}}async first(){let J=await EJ(this.client,this.sql,this.bindings);if(!Array.isArray(J)||J.length===0)return null;return J[0]}}class zJ{client;sql;bindings;constructor(J,Y,Z=[]){this.client=J,this.sql=Y,this.bindings=Z}bind(...J){return new zJ(this.client,this.sql,J)}async run(){let J=Date.now();if(typeof this.client.execute==="function"){let X=await this.client.execute(this.sql,this.bindings);return{success:!0,results:PJ(X),meta:x(J)}}let Y=this.client.prepare?.(this.sql);if(!Y||typeof Y.run!=="function")throw new j("SQLite client must expose execute() or prepare().run()","SQLITE_CLIENT_INVALID");let $=await Y.run(...this.bindings)??{};return{success:!0,results:[],meta:x(J,{changes:$J($.changes),last_row_id:$.lastInsertRowid??$.lastID})}}async all(){let J=Date.now();if(typeof this.client.execute==="function"){let $=await this.client.execute(this.sql,this.bindings);return{success:!0,results:PJ($),meta:x(J)}}let Y=this.client.prepare?.(this.sql);if(!Y||typeof Y.all!=="function")throw new j("SQLite client must expose execute() or prepare().all()","SQLITE_CLIENT_INVALID");let Z=await Y.all(...this.bindings);return{success:!0,results:Array.isArray(Z)?Z:[],meta:x(J)}}async first(){if(typeof this.client.execute==="function"){let Y=await this.client.execute(this.sql,this.bindings);return PJ(Y)[0]??null}let J=this.client.prepare?.(this.sql);if(!J)throw new j("SQLite client must expose execute() or prepare().get()","SQLITE_CLIENT_INVALID");if(typeof J.get==="function"){let Y=await J.get(...this.bindings);return Y===void 0||Y===null?null:Y}if(typeof J.all==="function"){let Y=await J.all(...this.bindings);if(!Array.isArray(Y)||Y.length===0)return null;let Z=Y[0];return Z===void 0||Z===null?null:Z}throw new j("SQLite prepare() result must expose get() or all()","SQLITE_CLIENT_INVALID")}}class MJ{client;sqlTag;sqlText;bindings;constructor(J,Y,Z,$=[]){this.client=J,this.sqlTag=Y,this.sqlText=Z,this.bindings=$}bind(...J){return new MJ(this.client,this.sqlTag,this.sqlText,J)}async run(){let J=Date.now(),Y=IJ(this.sqlTag,this.sqlText,this.bindings),Z=await AZ(this.client,Y);return{success:!0,results:QJ(Z),meta:x(J,XY(Z))}}async all(){let J=Date.now(),Y=IJ(this.sqlTag,this.sqlText,this.bindings),Z=await HY(this.client,Y);return{success:!0,results:QJ(Z),meta:x(J,XY(Z))}}async first(){let J=IJ(this.sqlTag,this.sqlText,this.bindings),Y=await VZ(this.client,J),Z=QJ(Y);if(Z.length>0)return Z[0]??null;if(Y&&typeof Y==="object"&&"row"in Y){let $=Y.row;return $===void 0||$===null?null:$}if(Y&&typeof Y==="object"&&!Array.isArray(Y)&&!("rows"in Y)&&!("results"in Y)&&!("data"in Y))return Y;return null}}async function jZ(J,Y,Z,$){try{let X=await J.scan(Y,{MATCH:Z,COUNT:$});return $Y(X)}catch{let X=await J.scan(Y,"MATCH",Z,"COUNT",String($));return $Y(X)}}function $Y(J){if(Array.isArray(J))return{cursor:String(J[0]??"0"),keys:Array.isArray(J[1])?J[1]:[]};return{cursor:String(J.cursor??"0"),keys:Array.isArray(J.keys)?J.keys:[]}}async function EJ(J,Y,Z){if(typeof J.execute==="function"){let $=await J.execute(Y,Z);if(Array.isArray($))return $[0];return $}if(typeof J.query==="function"){let $=await J.query(Y,Z);if(Array.isArray($))return $[0];return $}throw new j("MySQL client must expose execute() or query()","MYSQL_CLIENT_INVALID")}async function AZ(J,Y){if(typeof J.run==="function")return await J.run(Y);if(typeof J.execute==="function")return await J.execute(Y);if(typeof J.all==="function")return await J.all(Y);throw new j("Drizzle client must expose run(), execute(), or all()","DRIZZLE_CLIENT_INVALID")}async function HY(J,Y){if(typeof J.all==="function")return await J.all(Y);if(typeof J.execute==="function")return await J.execute(Y);if(typeof J.run==="function")return await J.run(Y);throw new j("Drizzle client must expose all(), execute(), or run()","DRIZZLE_CLIENT_INVALID")}async function VZ(J,Y){if(typeof J.get==="function")return await J.get(Y);return await HY(J,Y)}function IJ(J,Y,Z){let $=LZ(Y),X=$.length-1;if(X!==Z.length)throw new j(`Drizzle binding mismatch: expected ${X} bindings, received ${Z.length}`,"DRIZZLE_BINDINGS_MISMATCH");if(X===0)return J.raw(Y);let W=typeof J.empty==="function"?J.empty():J.raw("");for(let G=0;G<$.length;G++){let U=$[G];if(U)W.append(J.raw(U));if(G<X)W.append(J`${Z[G]}`)}return W}function LZ(J){let Y=[],Z=0,$=!1,X=!1,W=!1,G=!1;for(let U=0;U<J.length;U++){let H=J[U],_=U+1<J.length?J[U+1]:"";if(W){if(H===`
|
|
17
|
-
`)
|
|
18
|
-
`)G=!1;continue}if(U){if(Z+=_,_==="*"&&O==="/")Z+="/",H++,U=!1;continue}if(!X&&!W){if(_==="-"&&O==="-"){Z+="--",H++,G=!0;continue}if(_==="/"&&O==="*"){Z+="/*",H++,U=!0;continue}}if(_==="'"&&!W){X=!X,Z+=_;continue}if(_==='"'&&!X){W=!W,Z+=_;continue}if(_==="?"&&!X&&!W){$++,Z+=`$${$}`;continue}Z+=_}if(l.set(J,Z),l.size>5000){let H=l.keys().next().value;if(H)l.delete(H)}return Z}q();class D{static tokenize(J){return J.trim().split(/\s+/).map((Y)=>Y.toLowerCase())}static extractTableName(J){let Y=this.tokenize(J);if(Y[0]==="create"&&Y[1]==="table"){let W=2;if(Y[W]==="if")W+=3;return Y[W]??null}if(Y[0]==="drop"&&Y[1]==="table"){let W=2;if(Y[W]==="if")W+=2;return Y[W]??null}let Z=Y.indexOf("from"),$=Y.indexOf("into"),X=Y.indexOf("update");if(Z>=0&&Z+1<Y.length)return Y[Z+1]??null;if($>=0&&$+1<Y.length)return Y[$+1]??null;if(X>=0&&X+1<Y.length)return Y[X+1]??null;return null}static isSelect(J){return this.tokenize(J)[0]==="select"}static isInsert(J){return this.tokenize(J)[0]==="insert"}static isCreateTable(J){let Y=this.tokenize(J);return Y[0]==="create"&&Y[1]==="table"}static isDropTable(J){let Y=this.tokenize(J);return Y[0]==="drop"&&Y[1]==="table"}static isDelete(J){return this.tokenize(J)[0]==="delete"}static isUpdate(J){return this.tokenize(J)[0]==="update"}static hasIdWhereClause(J){return J.includes("WHERE")&&J.includes("id")}static hasAutoIncrement(J){return J.includes("AUTOINCREMENT")||J.includes("AUTO_INCREMENT")||J.includes("GENERATED BY DEFAULT AS IDENTITY")}static hasReturning(J){return J.includes("RETURNING")}}class BJ{tables=new Map;schemas=new Map;autoIncrementCounters=new Map;lastInsertRowId=null;prepare(J){return new _Y(this,J)}async executeStatement(J,Y){let Z=Date.now();try{if(D.isCreateTable(J))return await this.handleCreateTable(J,Y);if(D.isDropTable(J))return await this.handleDropTable(J,Y);if(D.isInsert(J))return await this.handleInsert(J,Y);if(D.isUpdate(J))return await this.handleUpdate(J,Y);if(D.isDelete(J))return await this.handleDelete(J,Y);if(D.isSelect(J))return await this.handleSelect(J,Y);return{success:!0,results:[],meta:{duration:Date.now()-Z}}}catch($){let X=$ instanceof Error?$.message:String($);return{success:!1,results:[],meta:{duration:Date.now()-Z},error:X}}}async executeQuery(J,Y){let Z=Date.now();try{if(D.isSelect(J))return await this.handleSelect(J,Y);return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Use executeStatement for non-SELECT queries"}}catch($){let X=$ instanceof Error?$.message:String($);return{success:!1,results:[],meta:{duration:Date.now()-Z},error:X}}}async handleCreateTable(J,Y){let Z=Date.now(),$=D.extractTableName(J);if(!$)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Could not extract table name"};let X=new Map,W=J.match(/\((.*)\)/s);if(!W||!W[1])return this.tables.set($,new Map),this.schemas.set($,X),{success:!0,results:[],meta:{duration:Date.now()-Z}};let G=W[1],U=/(\w+)\s+([A-Z_]+)(\s+[^,)]*)?/gi,H;while((H=U.exec(G))!==null){let _=H[1]||"",O=H[2]||"",F=H[3]||"";X.set(_,{name:_,type:O,isPrimaryKey:F.includes("PRIMARY KEY"),isAutoIncrement:F.includes("AUTOINCREMENT")||F.includes("AUTO_INCREMENT")||F.includes("GENERATED BY DEFAULT AS IDENTITY")})}if(this.tables.set($,new Map),this.schemas.set($,X),D.hasAutoIncrement(J))this.autoIncrementCounters.set($,0);return{success:!0,results:[],meta:{duration:Date.now()-Z}}}async handleDropTable(J,Y){let Z=Date.now(),$=D.extractTableName(J);if(!$)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Could not extract table name"};return this.tables.delete($),this.schemas.delete($),this.autoIncrementCounters.delete($),{success:!0,results:[],meta:{duration:Date.now()-Z}}}async handleInsert(J,Y){let Z=Date.now(),$=D.extractTableName(J);if(!$)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Could not extract table name"};if(!this.tables.has($))this.tables.set($,new Map);let X=this.tables.get($),W=this.schemas.get($),G=Y[0];if(!G)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"No primary key value provided"};let U={};if(W){let O=0;for(let[F,A]of W)if(O<Y.length)U[F]=Y[O],O++}else for(let O=0;O<Y.length;O++)if(O===0)U.id=Y[O];else U[`column_${O}`]=Y[O];return X.set(String(G),U),this.lastInsertRowId=G,{success:!0,results:D.hasReturning(J)?[U]:[],meta:{duration:Date.now()-Z,last_row_id:G,changes:1}}}async handleUpdate(J,Y){let Z=Date.now(),$=D.extractTableName(J);if(!$)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Could not extract table name"};if(!this.tables.has($))return{success:!1,results:[],meta:{duration:Date.now()-Z},error:`Table ${$} not found`};let X=this.tables.get($);if(!D.hasIdWhereClause(J))return{success:!0,results:[],meta:{duration:Date.now()-Z,changes:0}};let W=Y[Y.length-1],G=X.get(String(W));if(!G)return{success:!0,results:[],meta:{duration:Date.now()-Z,changes:0}};for(let U=0;U<Y.length-1;U++){let H=this.extractSetColumnName(J,U);if(H)G[H]=Y[U]}return{success:!0,results:[],meta:{duration:Date.now()-Z,changes:1}}}extractSetColumnName(J,Y){let Z=J.match(/SET\s+([^W]+?)(?:WHERE|$)/i);if(!Z||!Z[1])return null;return Z[1].split(",").map((W)=>{let G=W.match(/(\w+)\s*=/);return G&&G[1]?G[1]:null})[Y]??null}async handleDelete(J,Y){let Z=Date.now(),$=D.extractTableName(J);if(!$)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Could not extract table name"};if(!this.tables.has($))return{success:!0,results:[],meta:{duration:Date.now()-Z,changes:0}};let X=this.tables.get($);if(!D.hasIdWhereClause(J)){let U=X.size;return X.clear(),{success:!0,results:[],meta:{duration:Date.now()-Z,changes:U}}}let W=Y[0],G=X.has(String(W));if(G)X.delete(String(W));return{success:!0,results:[],meta:{duration:Date.now()-Z,changes:G?1:0}}}async handleSelect(J,Y){let Z=Date.now(),$=D.extractTableName(J);if(!$)return{success:!1,results:[],meta:{duration:Date.now()-Z},error:"Could not extract table name"};if(!this.tables.has($))return{success:!0,results:[],meta:{duration:Date.now()-Z}};let X=this.tables.get($);if(J.includes("COUNT(*)")){let U=J.match(/COUNT\(\*\)\s+as\s+(\w+)/i)?.[1]??"COUNT(*)",H={};return H[U]=X.size,{success:!0,results:[H],meta:{duration:Date.now()-Z}}}let W=Array.from(X.values());if(D.hasIdWhereClause(J)&&Y.length>0){let G=Y[0],U=X.get(String(G));W=U?[U]:[]}return{success:!0,results:W,meta:{duration:Date.now()-Z}}}}class _Y{database;sql;bindings=[];constructor(J,Y){this.database=J;this.sql=Y}bind(...J){return this.bindings=J,this}async run(){return await this.database.executeStatement(this.sql,this.bindings)}async all(){return await this.database.executeQuery(this.sql,this.bindings)}async first(){return(await this.database.executeQuery(this.sql,this.bindings)).results[0]||null}}class wJ{store=new Map;expirations=new Map;async get(J,Y="text"){let Z=this.expirations.get(J);if(Z&&Z<Date.now())return this.store.delete(J),this.expirations.delete(J),null;let $=this.store.get(J);if($===void 0)return null;if(Y==="json")try{return JSON.parse($)}catch(X){throw new j(`Failed to parse JSON from KV for key ${J}: ${X instanceof Error?X.message:String(X)}`,"KV_JSON_PARSE_FAILED")}return $}async put(J,Y,Z){if(this.store.set(J,Y),Z?.expirationTtl)this.expirations.set(J,Date.now()+Z.expirationTtl*1000);else this.expirations.delete(J)}async delete(J){this.store.delete(J),this.expirations.delete(J)}async list(J){let Y=J?.prefix??"",Z=J?.limit??1000,$=J?.cursor?parseInt(J.cursor,10):0,X=Date.now();for(let[_,O]of this.expirations)if(O<X)this.store.delete(_),this.expirations.delete(_);let W=Array.from(this.store.keys()).filter((_)=>_.startsWith(Y)),G=W.slice($,$+Z).map((_)=>({name:_})),U=$+Z,H=U>=W.length;return{keys:G,cursor:H?void 0:String(U),list_complete:H}}clear(){this.store.clear(),this.expirations.clear()}size(){return this.store.size}}function TZ(){return new BJ}function DZ(){return new wJ}d();export{a as validateTableForSharding,FJ as schemaExists,jJ as runShard,aJ as runAllShards,lJ as run,TY as resetConfig,bY as reassignShard,JJ as prepare,SJ as migrateRecord,p as listTables,hY as listKnownShards,OZ as isSQLDatabase,FZ as isKVStorage,fJ as integrateExistingDatabase,SY as insertShard,qY as insert,mJ as initializeAsync,QY as initialize,sY as indexShard,iY as indexAllShards,lY as index,$Z as getTotalDatabaseSize,pY as getShardStats,YY as getDatabaseSizesAllShards,dY as getDatabaseSizeForShard,ZZ as getDatabaseSizeForKey,zY as getClosestRegionFromIP,cY as flush,AJ as firstShard,fY as firstByLookupKey,mY as firstAllShardsGlobal,JY as firstAllShards,tJ as first,aY as explainShard,rY as explainAllShards,tY as explain,qJ as dropSchema,t as discoverExistingRecordsWithColumns,i as discoverExistingPrimaryKeys,WZ as createValkeyKVProvider,kJ as createSchemaAcrossShards,xY as createSchema,GZ as createSQLiteProvider,WY as createRedisKVProvider,GY as createPostgreSQLProvider,UZ as createNuxtHubKVProvider,UY as createMySQLProvider,KJ as createMappingsForExistingKeys,TZ as createInMemorySQLProvider,DZ as createInMemoryKVProvider,HZ as createHyperdrivePostgresProvider,_Z as createHyperdriveMySQLProvider,XJ as createDrizzleSQLProvider,JZ as countShard,YZ as countAllShards,eY as count,PY as collegedb,yJ as clearShardMigrationCache,pJ as clearMigrationCache,hJ as checkMigrationNeeded,bJ as autoDetectAndMigrate,YJ as allShard,KY as allByLookupKey,eJ as allAllShardsGlobal,ZJ as allAllShards,iJ as all,ZY as ShardCoordinator,K as KVShardMapper,BJ as InMemorySQLDatabase,wJ as InMemoryKVStorage,j as CollegeDBError};
|
|
16
|
+
`).run()}if(g.set(O,!0),B&&X.debug)console.log(`Auto-migration completed for shard ${$}: ${Q} records from ${z} tables`)}catch(E){A.push(`Auto-migration error: ${E}`)}return{migrationNeeded:T,migrationPerformed:B,recordsMigrated:Q,tablesProcessed:z,issues:A}}async function Z6(J,$,X){let Y=`${$}_migration_check`;if(g.has(Y))return!1;try{let Z=await d(J);if(Z.includes("shard_mappings"))return g.set(Y,!0),!1;let{KVShardMapper:H}=await Promise.resolve().then(() => (JJ(),NJ)),U=new H(X.kv,{hashShardMappings:X.hashShardMappings,mappingCacheTtlMs:X.mappingCacheTtlMs,knownShardsCacheTtlMs:X.knownShardsCacheTtlMs}),_=Z.filter((F)=>F!=="shard_mappings"&&!F.startsWith("sqlite_")&&F!=="sqlite_sequence");for(let F of _.slice(0,3))try{if(((await J.prepare(`SELECT COUNT(*) as count FROM ${F} LIMIT 1`).first())?.count||0)>0){let A=await J.prepare(`SELECT id FROM ${F} LIMIT 1`).first();if(A){let Q=String(A.id);if(!await U.getShardMapping(Q))return!0}}}catch{continue}return!1}catch{return!1}}function G6(){g.clear()}function H6(J){let $=`${J}_migration_check`;g.delete($)}var g,CJ;var $J=RJ(()=>{b();g=new Map,CJ=new Map});b();JJ();var XJ=null,l=null,s=new Map,o=0;function q(J){if(!l)l=new y(J.kv,{hashShardMappings:J.hashShardMappings,mappingCacheTtlMs:J.mappingCacheTtlMs,knownShardsCacheTtlMs:J.knownShardsCacheTtlMs});return l}function d6(J){XJ=J,l=new y(J.kv,{hashShardMappings:J.hashShardMappings,mappingCacheTtlMs:J.mappingCacheTtlMs,knownShardsCacheTtlMs:J.knownShardsCacheTtlMs}),s.clear(),o=0;try{let $=q(J);Promise.resolve().then(async()=>{let X=await $.getKnownShards(),Y=Array.from(new Set([...X,...Object.keys(J.shards)]));await $.setKnownShards(Y)}).catch(()=>{return})}catch{}if(J.shards&&Object.keys(J.shards).length>0&&!J.disableAutoMigration)W6(J).catch(($)=>{console.warn("Background auto-migration failed:",$)})}async function F6(J){XJ=J,l=new y(J.kv,{hashShardMappings:J.hashShardMappings,mappingCacheTtlMs:J.mappingCacheTtlMs,knownShardsCacheTtlMs:J.knownShardsCacheTtlMs}),s.clear(),o=0;try{let $=q(J),X=await $.getKnownShards(),Y=Array.from(new Set([...X,...Object.keys(J.shards)]));await $.setKnownShards(Y)}catch{}if(J.shards&&Object.keys(J.shards).length>0&&!J.disableAutoMigration)try{await W6(J)}catch($){console.warn("Auto migration failed:",$)}}async function l6(J,$){return await F6(J),await $()}async function W6(J){try{let{autoDetectAndMigrate:$}=await Promise.resolve().then(() => ($J(),AJ)),X=Object.keys(J.shards);if(J.debug)console.log(`\uD83D\uDD0D Checking ${X.length} shards for existing data...`);let Y=X.map(async(H)=>{let U=J.shards[H];if(!U)return null;try{let _=await $(U,H,J,{maxRecordsToCheck:1000});return{shardName:H,..._}}catch(_){return console.warn(`Auto-migration failed for shard ${H}:`,_),null}}),G=(await Promise.all(Y)).filter((H)=>H?.migrationPerformed);if(J.debug)if(G.length>0){let H=G.reduce((U,_)=>U+(_?.recordsMigrated||0),0);console.log(`\uD83C\uDF89 Auto-migration completed! Migrated ${H} records across ${G.length} shards`),G.forEach((U)=>{if(U)console.log(` ✅ ${U.shardName}: ${U.recordsMigrated} records from ${U.tablesProcessed} tables`)})}else console.log("✅ All shards ready - no migration needed")}catch($){console.warn("Background auto-migration setup failed:",$)}}function o6(){XJ=null,l=null,s.clear(),o=0}function R(){if(!XJ)throw new j("CollegeDB not initialized. Call initialize() first.","NOT_INITIALIZED");return XJ}function n6(J){let $=J.trim().toUpperCase();if($.startsWith("SELECT")||$.startsWith("VALUES")||$.startsWith("TABLE")||$.startsWith("PRAGMA")||$.startsWith("EXPLAIN")||$.startsWith("WITH")||$.startsWith("SHOW"))return"read";return"write"}function O6(J,$){let X=J.strategy||"hash";if(typeof X==="string")return X;let Y=X;return Y[$]||Y.write||Y.read||"hash"}function s6(J,$){if(J===$)return 0;let X={wnam:{lat:37.7749,lon:-122.4194},enam:{lat:40.7128,lon:-74.006},weur:{lat:51.5074,lon:-0.1278},eeur:{lat:52.52,lon:13.405},apac:{lat:35.6762,lon:139.6503},oc:{lat:-33.8688,lon:151.2093},me:{lat:25.2048,lon:55.2708},af:{lat:-26.2041,lon:28.0473}},Y=X[J],Z=X[$],G=Y.lat-Z.lat,H=Y.lon-Z.lon;return Math.sqrt(G*G+H*H)}function i6(J){let $=J.cf;if(!$||!$.country)return"wnam";let{country:X,continent:Y}=$;if(["US","CA","MX"].includes(X)){let Z=$.region||$.regionCode||"",G=$.timezone||"";if(Z.includes("CA")||Z.includes("WA")||Z.includes("OR")||Z.includes("NV")||Z.includes("AZ")||Z.includes("UT")||G.includes("Pacific")||G.includes("America/Los_Angeles"))return"wnam";return"enam"}if(["GL","PM","BM"].includes(X))return"enam";if(["GB","IE","FR","ES","PT","NL","BE","LU","CH","AT","IT"].includes(X))return"weur";if(["DE","PL","CZ","SK","HU","SI","HR","BA","RS","ME","MK","AL","BG","RO","MD","UA","BY","LT","LV","EE","FI","SE","NO","DK","IS"].includes(X))return"eeur";if(X==="RU")return"eeur";if(["JP","KR","CN","HK","TW","MO","MN","KP"].includes(X))return"apac";if(["TH","VN","SG","MY","ID","PH","BN","KH","LA","MM","TL","IN","PK","BD","LK","NP","BT","MV","AF"].includes(X))return"apac";if(["AU","NZ","PG","FJ","NC","VU","SB","WS","TO","KI","NR","PW","FM","MH","TV"].includes(X))return"oc";if(["AE","SA","QA","KW","BH","OM","YE","IQ","IR","SY","LB","JO","IL","PS","TR","CY"].includes(X))return"me";if(Y==="AF"||["EG","LY","TN","DZ","MA","SD","SS","ET","ER","DJ","SO"].includes(X))return"af";if(["KZ","UZ","TM","TJ","KG"].includes(X))return"eeur";if(Y==="SA"||["BR","AR","CL","PE","CO","VE","EC","BO","PY","UY","GY","SR","GF"].includes(X))return"enam";if(["GT","BZ","SV","HN","NI","CR","PA","CU","JM","HT","DO","PR","TT","BB","GD","VC","LC","DM","AG","KN"].includes(X))return"enam";return"wnam"}function t6(J){if(typeof J==="string")return J;return J.region||"wnam"}async function jJ(J){try{let[$,X]=await Promise.all([J.prepare("PRAGMA page_count").first(),J.prepare("PRAGMA page_size").first()]);if(!$?.page_count||!X?.page_size)throw new j("Failed to retrieve database size information","SIZE_QUERY_FAILED");return $.page_count*X.page_size}catch($){throw new j(`Failed to get database size: ${$ instanceof Error?$.message:"Unknown error"}`,"SIZE_QUERY_FAILED")}}async function a6(J,$){let X=Math.max(0,$.sizeCacheTtlMs??30000),Y=s.get(J);if(Y&&Y.expiresAt>=Date.now())return Y.size;let Z=$.shards[J];if(!Z)throw new j(`Shard ${J} not found in configuration`,"SHARD_NOT_FOUND");let G=await jJ(Z);if(X>0)s.set(J,{size:G,expiresAt:Date.now()+X});return G}async function A6(J,$){if(typeof $.maxDatabaseSize!=="number"||!Number.isFinite($.maxDatabaseSize)||$.maxDatabaseSize<=0)return J;let X=$.maxDatabaseSize,Z=(await Promise.allSettled(J.map(async(G)=>{let H=await a6(G,$);return{shard:G,size:H,withinLimit:H<X}}))).filter((G)=>G.status==="fulfilled"&&G.value.withinLimit).map((G)=>G.value.shard);if(Z.length===0){if($.debug)console.warn("All shards exceed maxDatabaseSize limit. Allowing allocation to prevent failure.");return J}if($.debug&&Z.length<J.length){let G=J.filter((H)=>!Z.includes(H));console.log(`Excluded ${G.length} shards due to size limits: ${G.join(", ")}`)}return Z}function r6(J,$,X,Y){let Z=$.filter((W)=>X[W]);if(Z.length===0){let W=0;for(let A=0;A<Y.length;A++){let Q=Y.charCodeAt(A);W=(W<<5)-W+Q,W=W&W}let O=Math.abs(W)%$.length;return $[O]}let G=Z.map((W)=>{let O=X[W],A=s6(J,t6(O)),Q=typeof O==="object"?O.priority||1:1,z=A-Q*0.1;return{shard:W,score:z,distance:A,priority:Q}});G.sort((W,O)=>W.score-O.score);let H=G[0].score,U=G.filter((W)=>Math.abs(W.score-H)<0.01);if(U.length===1)return U[0].shard;let _=0;for(let W=0;W<Y.length;W++){let O=Y.charCodeAt(W);_=(_<<5)-_+O,_=_&_}let F=Math.abs(_)%U.length;return U[F].shard}function n(J,$,X,Y){switch(J){case"hash":{let Z=0;for(let H=0;H<$.length;H++){let U=$.charCodeAt(H);Z=(Z<<5)-Z+U,Z=Z&Z}let G=Math.abs(Z)%X.length;return X[G]||X[0]}case"location":{if(!Y.targetRegion)return n("hash",$,X,Y);return r6(Y.targetRegion,X,Y.shardLocations||{},$)}case"random":return X[Math.floor(Math.random()*X.length)]||X[0];default:return n("hash",$,X,Y)}}async function j6(J,$="write"){let X=R(),Y=q(X),Z=await Y.getShardMapping(J);if(Z)return Z.shard;let G=Object.keys(X.shards);if(G.length===0)throw new j("No shards configured","NO_SHARDS");let H=await A6(G,X),U,_=O6(X,$);if(X.coordinator)try{let F=X.coordinator.idFromName("default"),O=await X.coordinator.get(F).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:J,strategy:_,operationType:$,targetRegion:X.targetRegion,shardLocations:X.shardLocations,availableShards:H})});if(O.ok)U=(await O.json()).shard;else U=n(_,J,H,X)}catch(F){console.warn("Coordinator allocation failed, falling back to local strategy:",F),U=n(_,J,H,X)}else U=n(_,J,H,X);return await Y.setShardMapping(J,U),U}async function e6(J,$="write"){let X=R(),Y=await j6(J,$),Z=X.shards[Y];if(!Z)throw new j(`Shard ${Y} not found in configuration`,"SHARD_NOT_FOUND");return Z}async function J7(J,$){let{createSchema:X}=await Promise.resolve().then(() => ($J(),AJ));await X(J,$)}async function LJ(J,$){let X=n6($);return(await e6(J,X)).prepare($)}async function L6(J,$,X=[]){let Z=await(await LJ(J,$)).bind(...X).run();if(!Z.success)throw new j(`Query failed: ${Z.error||"Unknown error"}`,"QUERY_FAILED");return Z}function $7(J){let $=J.results[0];if($&&typeof $==="object"){for(let Y of["id","ID","Id","rowid","ROWID","RowId","last_row_id","lastInsertId","insertId"]){let Z=$[Y];if(Z!==void 0&&Z!==null)return Z}for(let[Y,Z]of Object.entries($)){let G=Y.toLowerCase();if((G==="id"||G==="rowid")&&(typeof Z==="number"||typeof Z==="string"))return Z}for(let Y of Object.values($))if(typeof Y==="number"||typeof Y==="string")return Y}let X=J.meta.last_row_id;if(X!==void 0&&X!==null)return X;return}function X7(){return`insert:${Date.now()}:${Math.random().toString(36).slice(2)}`}async function Y7(){let J=R(),$=Object.keys(J.shards);if($.length===0)throw new j("No shards configured","NO_SHARDS");let X=await A6($,J);if(X.length===0)throw new j("No shards available for insert","NO_SHARDS");let Y=O6(J,"write"),Z=X7();if(J.coordinator)try{let G=J.coordinator.idFromName("default"),U=await J.coordinator.get(G).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:Z,strategy:Y,operationType:"write",targetRegion:J.targetRegion,shardLocations:J.shardLocations,availableShards:X})});if(U.ok)return(await U.json()).shard}catch(G){console.warn("Coordinator allocation for insert failed, falling back to local strategy:",G)}if(Y==="round-robin"){let G=X[o%X.length];return o=(o+1)%X.length,G}return n(Y,Z,X,J)}async function Q6(J,$,X=[]){let Y=R();if(!Y.shards[J])throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");let G=/\breturning\b/i.test($)?await QJ(J,$,X):await wJ(J,$,X),H=$7(G);if(H===void 0)throw new j("Insert did not return a generated primary key","GENERATED_KEY_UNAVAILABLE");return await q(Y).setShardMapping(String(H),J),{...G,generatedId:H}}async function Z7(J,$=[]){let X=await Y7();return await Q6(X,J,$)}async function G7(J,$,X=[]){return await Q6(J,$,X)}async function V6(J,$,X=[]){let Z=await(await LJ(J,$)).bind(...X).all();if(!Z.success)throw new j(`Query failed: ${Z.error||"Unknown error"}`,"QUERY_FAILED");return Z}async function E6(J,$,X=[]){return await(await LJ(J,$)).bind(...X).first()}async function H7(J,$,X=[],Y=50){let Z=R(),H=await q(Z).getShardMapping(J);if(H){if(Z.shards[H.shard]){let F=await QJ(H.shard,$,X);if(F.success&&F.results.length>0)return F}}let U=await VJ($,X,Y);return T6(U)}async function U7(J,$,X=[],Y=50){let Z=R(),H=await q(Z).getShardMapping(J);if(H){if(Z.shards[H.shard]){let F=await vJ(H.shard,$,X);if(F!==null)return F}}return(await z6($,X,Y)).find((_)=>_!==null)??null}async function _7(J,$,X){let Y=R();if(!Y.shards[$])throw new j(`Shard ${$} not found in configuration`,"SHARD_NOT_FOUND");let Z=q(Y),G=await Z.getShardMapping(J);if(!G)throw new j(`No existing mapping found for primary key: ${J}`,"MAPPING_NOT_FOUND");if(G.shard!==$){let{migrateRecord:H}=await Promise.resolve().then(() => ($J(),AJ)),U=Y.shards[G.shard],_=Y.shards[$];if(!U||!_)throw new j("Source or target shard not available","SHARD_UNAVAILABLE");await H(U,_,J,X)}await Z.updateShardMapping(J,$)}async function F7(){let J=R();if(J.coordinator)try{let $=J.coordinator.idFromName("default"),Y=await J.coordinator.get($).fetch("http://coordinator/shards");if(Y.ok)return await Y.json()}catch($){console.warn("Failed to get shards from coordinator:",$)}try{let X=await q(J).getKnownShards(),Y=new Set([...Object.keys(J.shards),...X]);return Array.from(Y)}catch{return Object.keys(J.shards)}}async function W7(){let J=R();if(J.coordinator)try{let Z=J.coordinator.idFromName("default"),H=await J.coordinator.get(Z).fetch("http://coordinator/stats");if(H.ok)return await H.json()}catch(Z){console.warn("Failed to get stats from coordinator:",Z)}let $=q(J),X=await $.getShardKeyCounts(),Y=Object.keys(J.shards);try{let Z=await $.getKnownShards();Y=Array.from(new Set([...Y,...Z]))}catch{}return Y.map((Z)=>({binding:Z,count:X[Z]||0}))}async function wJ(J,$,X=[]){let Z=R().shards[J];if(!Z)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");let G=await Z.prepare($).bind(...X).run();if(!G.success)throw new j(`Query failed: ${G.error||"Unknown error"}`,"QUERY_FAILED");return G}async function QJ(J,$,X=[]){let Z=R().shards[J];if(!Z)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");return await Z.prepare($).bind(...X).all()}async function vJ(J,$,X=[]){let Z=R().shards[J];if(!Z)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");return await Z.prepare($).bind(...X).first()}async function P6(J,$=[],X=50){let Y=R(),Z=[];for(let[H,U]of Object.entries(Y.shards)){if(!H||!U){console.error(`Shard ${H??"<null>"} not found, skipping`);continue}Z.push(()=>U.prepare(J).bind(...$).run().catch((_)=>{return console.error(`Error executing query on shard ${H}:`,_),{success:!1,results:[],error:_ instanceof Error?_.message:String(_),meta:{duration:0}}}))}let G=[];for(let H=0;H<Z.length;H+=X){let U=Z.slice(H,H+X).map((_)=>_());G.push(...await Promise.all(U))}return G}async function VJ(J,$=[],X=50){let Y=R(),Z=[];for(let[H,U]of Object.entries(Y.shards)){if(!H||!U){console.error(`Shard ${H??"<null>"} not found, skipping`);continue}Z.push(()=>U.prepare(J).bind(...$).all().catch((_)=>{return console.error(`Error executing query on shard ${H}:`,_),{success:!1,results:[],error:_ instanceof Error?_.message:String(_),meta:{duration:0}}}))}let G=[];for(let H=0;H<Z.length;H+=X){let U=Z.slice(H,H+X).map((_)=>_());G.push(...await Promise.all(U))}return G}function YJ(J,$=50){if(!Number.isFinite(J??$))return $;return Math.max(1,Math.floor(J??$))}function O7(J){if(!Number.isFinite(J??0))return 0;return Math.max(0,Math.floor(J??0))}function A7(J){if(J===void 0)return;if(!Number.isFinite(J))return;return Math.max(0,Math.floor(J))}function U6(J,$){if(typeof $==="function")return $(J);if(!$||typeof J!=="object"||J===null)return;return J[String($)]}function j7(J,$){if(J===$)return 0;if(J===null||J===void 0)return 1;if($===null||$===void 0)return-1;if(typeof J==="number"&&typeof $==="number")return J-$;if(typeof J==="bigint"&&typeof $==="bigint")return J<$?-1:1;if(J instanceof Date&&$ instanceof Date)return J.getTime()-$.getTime();if(typeof J==="boolean"&&typeof $==="boolean")return Number(J)-Number($);return String(J).localeCompare(String($),void 0,{numeric:!0,sensitivity:"base"})}function T6(J){let $=J.flatMap((G)=>G.results||[]),X=J.filter((G)=>!G.success),Y=J.reduce((G,H)=>G+(H.meta?.duration||0),0);if(X.length===0)return{success:!0,results:$,meta:{duration:Y}};let Z=X.map((G)=>G.error||"Unknown shard query error").filter(Boolean).join("; ");return{success:!1,results:$,error:Z||"One or more shard queries failed",meta:{duration:Y}}}async function D6(J,$=[],X={}){let Y=YJ(X.batchSize),Z=O7(X.offset),G=A7(X.limit),H=T6(await VJ(J,$,Y)),U=H.results;if(X.filter)U=U.filter((W)=>X.filter?.(W));if(X.comparator)U=[...U].sort(X.comparator);else if(X.sortBy){let W=X.sortDirection==="desc"?-1:1;U=[...U].sort((O,A)=>{let Q=U6(O,X.sortBy),z=U6(A,X.sortBy);return j7(Q,z)*W})}let _=G===void 0?void 0:Z+G,F=U.slice(Z,_);return{...H,results:F}}async function z6(J,$=[],X=50){let Y=R(),Z=[];for(let[H,U]of Object.entries(Y.shards)){if(!H||!U){console.error(`Shard ${H??"<null>"} not found, skipping`);continue}Z.push(()=>U.prepare(J).bind(...$).first().catch((_)=>{return console.error(`Error executing query on shard ${H}:`,_),null}))}let G=[];for(let H=0;H<Z.length;H+=X){let U=Z.slice(H,H+X).map((_)=>_());G.push(...await Promise.all(U))}return G}async function L7(J,$=[],X={}){return(await D6(J,$,{...X,limit:1})).results[0]??null}async function Q7(){let J=R();if(await q(J).clearAllMappings(),s.clear(),J.coordinator)try{let X=J.coordinator.idFromName("default");await J.coordinator.get(X).fetch("http://coordinator/flush",{method:"POST"})}catch(X){console.warn("Failed to flush coordinator:",X)}}async function V7(J){let X=R().shards[J];if(!X)throw new j(`Shard ${J} not found`,"SHARD_NOT_FOUND");return await jJ(X)}var E7=/^[A-Za-z_][A-Za-z0-9_]*$/;function p(J){let $=J.trim();if(!$)throw new j("Identifier cannot be empty","INVALID_IDENTIFIER");let X=$.split(".").map((Y)=>Y.trim());if(X.some((Y)=>!Y||!E7.test(Y)))throw new j(`Invalid SQL identifier: ${J}`,"INVALID_IDENTIFIER");return X.map((Y)=>`"${Y}"`).join(".")}function _6(J){return J.toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"")}function P7(J){if(typeof J==="string")return[{name:J}];if(!Array.isArray(J)||J.length===0)throw new j("At least one index column is required","INVALID_INDEX_COLUMNS");return J.map(($)=>{if(typeof $==="string")return{name:$};if(!$?.name)throw new j("Index column name is required","INVALID_INDEX_COLUMNS");return{name:$.name,order:$.order,collate:$.collate}})}function kJ(J,$,X={}){let Y=P7($),Z=p(J),G=X.indexName?X.indexName:["idx",_6(J),...Y.map((O)=>_6(O.name))].filter(Boolean).join("_").slice(0,120),H=p(G||"idx_auto"),U=Y.map((O)=>{let A=p(O.name),Q=O.order?` ${O.order}`:"",z=O.collate?` COLLATE ${p(O.collate).replace(/"/g,"")}`:"";return`${A}${z}${Q}`}).join(", "),_=X.ifNotExists===!1?"":" IF NOT EXISTS",F=X.unique?"UNIQUE ":"",W=X.where?.trim()?` WHERE ${X.where.trim()}`:"";return`CREATE ${F}INDEX${_} ${H} ON ${Z} (${U})${W}`}async function T7(J,$,X,Y={}){let Z=kJ($,X,Y);return L6(J,Z)}async function D7(J,$,X,Y={}){let Z=kJ($,X,Y);return wJ(J,Z)}async function z7(J,$,X={}){let Y=kJ(J,$,X);return P6(Y,[],YJ(X.batchSize))}function xJ(J,$="query-plan"){switch($){case"raw":return`EXPLAIN ${J}`;case"analyze":return`EXPLAIN ANALYZE ${J}`;case"query-plan":default:return`EXPLAIN QUERY PLAN ${J}`}}async function M7(J,$,X=[],Y={}){return V6(J,xJ($,Y.mode),X)}async function I7(J,$,X=[],Y={}){return QJ(J,xJ($,Y.mode),X)}async function B7(J,$=[],X={}){return VJ(xJ(J,X.mode),$,YJ(X.batchSize))}async function R7(J,$){let X=p($),Y=await E6(J,`SELECT COUNT(*) AS row_count FROM ${X}`);if(!Y||Y.row_count===void 0||Y.row_count===null)return 0;return Number(Y.row_count)||0}async function N7(J,$){let X=p($),Y=await vJ(J,`SELECT COUNT(*) AS row_count FROM ${X}`);if(!Y||Y.row_count===void 0||Y.row_count===null)return 0;return Number(Y.row_count)||0}async function C7(J,$=50){let X=R(),Y=YJ($),G=`SELECT COUNT(*) AS row_count FROM ${p(J)}`,H=[];for(let[F,W]of Object.entries(X.shards)){if(!F||!W)continue;H.push(async()=>{try{let O=await W.prepare(G).first(),A=Number(O?.row_count??0);return{shard:F,count:Number.isFinite(A)?A:0,success:!0}}catch(O){return{shard:F,count:null,success:!1,error:O instanceof Error?O.message:String(O)}}})}let U=[];for(let F=0;F<H.length;F+=Y){let W=H.slice(F,F+Y).map((O)=>O());U.push(...await Promise.all(W))}return{total:U.reduce((F,W)=>F+(W.count??0),0),shards:U}}async function w7(J){let $=R(),X=await j6(J,"read"),Y=$.shards[X];if(!Y)throw new j(`Shard ${X} not found in configuration`,"SHARD_NOT_FOUND");return jJ(Y)}async function M6(J=50){let $=R(),X=YJ(J),Y=[];for(let[G,H]of Object.entries($.shards)){if(!G||!H)continue;Y.push(async()=>{try{return{shard:G,size:await jJ(H),success:!0}}catch(U){return{shard:G,size:null,success:!1,error:U instanceof Error?U.message:String(U)}}})}let Z=[];for(let G=0;G<Y.length;G+=X){let H=Y.slice(G,G+X).map((U)=>U());Z.push(...await Promise.all(H))}return Z}async function v7(J=50){return(await M6(J)).reduce((X,Y)=>X+(Y.size??0),0)}b();class I6{state;constructor(J){this.state=J}async getState(){return await this.state.storage.get("coordinator_state")||{knownShards:[],shardStats:{},strategy:"round-robin",roundRobinIndex:0}}async saveState(J){await this.state.storage.put("coordinator_state",J)}async fetch(J){let X=new URL(J.url).pathname,Y=J.method;try{switch(`${Y} ${X}`){case"GET /shards":return this.handleListShards();case"POST /shards":return this.handleAddShard(J);case"DELETE /shards":return this.handleRemoveShard(J);case"GET /stats":return this.handleGetStats();case"POST /stats":return this.handleUpdateStats(J);case"POST /allocate":return this.handleAllocateShard(J);case"POST /flush":return this.handleFlush();case"GET /health":return new Response("OK",{status:200});default:return new Response("Not Found",{status:404})}}catch(Z){return console.error("ShardCoordinator error:",Z),new Response("Internal Server Error",{status:500})}}async handleListShards(){let J=await this.getState();return new Response(JSON.stringify(J.knownShards),{headers:{"Content-Type":"application/json"}})}async handleAddShard(J){let{shard:$}=await J.json();if(!$||typeof $!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let X=await this.getState();if(!X.knownShards.includes($))X.knownShards.push($),X.shardStats[$]={binding:$,count:0,lastUpdated:Date.now()},await this.saveState(X);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleRemoveShard(J){let{shard:$}=await J.json();if(!$||typeof $!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let X=await this.getState(),Y=X.knownShards.indexOf($);if(Y>-1){if(X.knownShards.splice(Y,1),delete X.shardStats[$],X.roundRobinIndex>=X.knownShards.length)X.roundRobinIndex=0;await this.saveState(X)}return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleGetStats(){let J=await this.getState(),$=Object.values(J.shardStats);return new Response(JSON.stringify($),{headers:{"Content-Type":"application/json"}})}async handleUpdateStats(J){let{shard:$,count:X}=await J.json();if(!$||typeof $!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});if(X===void 0||typeof X!=="number")return new Response(JSON.stringify({error:"Missing or invalid count parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Y=await this.getState();if(Y.shardStats[$])Y.shardStats[$].count=X,Y.shardStats[$].lastUpdated=Date.now(),await this.saveState(Y);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleAllocateShard(J){let{primaryKey:$,strategy:X,operationType:Y,availableShards:Z}=await J.json();if(!$||typeof $!=="string")return new Response(JSON.stringify({error:"Missing or invalid primaryKey parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let G=await this.getState(),H=Z||G.knownShards;if(H.length===0)return new Response(JSON.stringify({error:"No shards available"}),{status:400,headers:{"Content-Type":"application/json"}});let U=this.resolveStrategy(G.strategy,X,Y||"write"),_=this.selectShard($,G,U,H);if(U==="round-robin")G.roundRobinIndex=(G.roundRobinIndex+1)%H.length,await this.saveState(G);return new Response(JSON.stringify({shard:_}),{headers:{"Content-Type":"application/json"}})}async handleFlush(){return await this.state.storage.deleteAll(),new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}resolveStrategy(J,$,X="write"){if($)return $;if(typeof J==="string")return J;return J[X]}selectShard(J,$,X,Y){let Z=Y||$.knownShards;if(Z.length===0)throw new j("No shards available","NO_SHARDS");switch(X){case"round-robin":return Z[$.roundRobinIndex]??Z[0];case"random":return Z[Math.floor(Math.random()*Z.length)];case"hash":{let G=0;for(let U=0;U<J.length;U++){let _=J.charCodeAt(U);G=(G<<5)-G+_,G=G&G}let H=Math.abs(G)%Z.length;return Z[H]}case"location":{let G=$.targetRegion,H=$.shardLocations||{},U=Z.filter((E)=>H[E]);if(!G||U.length===0){let E=0;for(let M=0;M<J.length;M++){let D=J.charCodeAt(M);E=(E<<5)-E+D,E=E&E}let P=Math.abs(E)%Z.length;return Z[P]}let _={wnam:{lat:37.7749,lon:-122.4194},enam:{lat:40.7357,lon:-74.1724},weur:{lat:51.5074,lon:-0.1278},eeur:{lat:52.2297,lon:21.0122},apac:{lat:35.6762,lon:139.6503},oc:{lat:-33.8688,lon:151.2093},me:{lat:25.2048,lon:55.2708},af:{lat:-26.2041,lon:28.0473}},F=(E,P)=>(P in E),W=(E)=>F(_,E)?E:"wnam",O=(E,P)=>{let M=_[W(E)],D=_[W(P)],V=M.lat-D.lat,L=M.lon-D.lon;return Math.sqrt(V*V+L*L)},A=U.map((E)=>{let P=H[E],M=O(G,P.region),D=P.priority||1;return{shard:E,score:M-D*0.1}});A.sort((E,P)=>E.score-P.score);let Q=A[0].score,z=A.filter((E)=>Math.abs(E.score-Q)<0.01);if(z.length===1)return z[0].shard;let T=0;for(let E=0;E<J.length;E++){let P=J.charCodeAt(E);T=(T<<5)-T+P,T=T&T}let B=Math.abs(T)%z.length;return z[B].shard}default:return Z[0]}}async incrementShardCount(J){let $=await this.getState();if($.shardStats[J])$.shardStats[J].count++,$.shardStats[J].lastUpdated=Date.now(),await this.saveState($)}async decrementShardCount(J){let $=await this.getState();if($.shardStats[J]&&$.shardStats[J].count>0)$.shardStats[J].count--,$.shardStats[J].lastUpdated=Date.now(),await this.saveState($)}}b();JJ();b();var k7=500;function N6(J,$={}){let X=$.scanCount??k7;return{async get(Y,Z="text"){let G=await J.get(Y);if(G===null)return null;if(Z!=="json")return G;try{return JSON.parse(G)}catch(H){throw new j(`Failed to parse JSON from Redis for key ${Y}: ${H instanceof Error?H.message:String(H)}`,"KV_JSON_PARSE_FAILED")}},async put(Y,Z){await J.set(Y,Z)},async delete(Y){await J.del(Y)},async list(Y){let Z=Y?.prefix??"",G=`${Z}*`,H=Y?.cursor??"0",U=Y?.limit,_=[];do{let F=await y7(J,H,G,X);H=F.cursor;for(let W of F.keys){if(!Z||W.startsWith(Z))_.push(W);if(U&&_.length>=U)break}if(U&&_.length>=U)break}while(H!=="0");return{keys:_.map((F)=>({name:F})),cursor:H,list_complete:H==="0"}}}}function x7(J,$={}){return N6(J,$)}function C6(J,$){if($)return PJ(J,$);return{prepare(X){return new hJ(J,X)}}}function w6(J,$){if($)return PJ(J,$);return{prepare(X){return new yJ(J,X)}}}function K7(J,$){if($)return PJ(J,$);return{prepare(X){return new gJ(J,X)}}}function PJ(J,$){return{prepare(X){return new pJ(J,$,X)}}}function S7(J){return{async get($,X="text"){let Y=await u7(J,$);if(Y===null||Y===void 0)return null;if(X==="json"){if(typeof Y==="string")try{return JSON.parse(Y)}catch(Z){throw new j(`Failed to parse JSON from NuxtHub KV for key ${$}: ${Z instanceof Error?Z.message:String(Z)}`,"KV_JSON_PARSE_FAILED")}return Y}return typeof Y==="string"?Y:JSON.stringify(Y)},async put($,X){await c7(J,$,X)},async delete($){await d7(J,$)},async list($){let X=$?.prefix??"",Y=await l7(J,X);return{keys:(typeof $?.limit==="number"?Y.slice(0,$.limit):Y).map((G)=>({name:G})),list_complete:!0}}}}function q7(J,$){return C6({query:async(Y,Z=[])=>{let G=$(J.connectionString);if(typeof G.connect==="function")await G.connect();try{return await G.query(Y,Z)}finally{if(typeof G.release==="function")G.release();else if(typeof G.end==="function")await G.end()}}})}function f7(J,$){return w6({execute:async(Y,Z=[])=>{let G=$(J.connectionString);try{if(typeof G.execute==="function")return await G.execute(Y,Z);if(typeof G.query==="function")return await G.query(Y,Z);throw new j("Hyperdrive MySQL client is missing execute/query methods","MYSQL_CLIENT_INVALID")}finally{if(typeof G.end==="function")await G.end();else if(typeof G.close==="function")await G.close();else if(typeof G.destroy==="function")G.destroy()}}})}function b7(J){if(!J||typeof J!=="object")return!1;return typeof J.prepare==="function"}function h7(J){if(!J||typeof J!=="object")return!1;let $=J;return typeof $.get==="function"&&typeof $.put==="function"&&typeof $.delete==="function"&&typeof $.list==="function"}class hJ{client;sql;bindings;constructor(J,$,X=[]){this.client=J,this.sql=$,this.bindings=X}bind(...J){return new hJ(this.client,this.sql,J)}async run(){let J=Date.now(),$=bJ(this.sql),X=await this.client.query($,this.bindings);return{success:!0,results:X.rows??[],meta:K(J,{changes:typeof X.rowCount==="number"?X.rowCount:void 0,command:X.command})}}async all(){let J=Date.now(),$=bJ(this.sql),X=await this.client.query($,this.bindings);return{success:!0,results:X.rows??[],meta:K(J,{changes:typeof X.rowCount==="number"?X.rowCount:void 0,command:X.command})}}async first(){let J=bJ(this.sql);return(await this.client.query(J,this.bindings)).rows?.[0]??null}}class yJ{client;sql;bindings;constructor(J,$,X=[]){this.client=J,this.sql=$,this.bindings=X}bind(...J){return new yJ(this.client,this.sql,J)}async run(){let J=Date.now(),$=await KJ(this.client,this.sql,this.bindings);if(Array.isArray($))return{success:!0,results:$,meta:K(J)};let X=$;return{success:!0,results:[],meta:K(J,{changes:X.affectedRows,last_row_id:X.insertId,warningStatus:X.warningStatus})}}async all(){let J=Date.now(),$=await KJ(this.client,this.sql,this.bindings);return{success:!0,results:Array.isArray($)?$:[],meta:K(J,{changes:!Array.isArray($)?$.affectedRows:void 0})}}async first(){let J=await KJ(this.client,this.sql,this.bindings);if(!Array.isArray(J)||J.length===0)return null;return J[0]}}class gJ{client;sql;bindings;constructor(J,$,X=[]){this.client=J,this.sql=$,this.bindings=X}bind(...J){return new gJ(this.client,this.sql,J)}async run(){let J=Date.now();if(typeof this.client.execute==="function"){let Z=await this.client.execute(this.sql,this.bindings);return{success:!0,results:fJ(Z),meta:K(J)}}let $=this.client.prepare?.(this.sql);if(!$||typeof $.run!=="function")throw new j("SQLite client must expose execute() or prepare().run()","SQLITE_CLIENT_INVALID");let Y=await $.run(...this.bindings)??{};return{success:!0,results:[],meta:K(J,{changes:EJ(Y.changes),last_row_id:Y.lastInsertRowid??Y.lastID})}}async all(){let J=Date.now();if(typeof this.client.execute==="function"){let Y=await this.client.execute(this.sql,this.bindings);return{success:!0,results:fJ(Y),meta:K(J)}}let $=this.client.prepare?.(this.sql);if(!$||typeof $.all!=="function")throw new j("SQLite client must expose execute() or prepare().all()","SQLITE_CLIENT_INVALID");let X=await $.all(...this.bindings);return{success:!0,results:Array.isArray(X)?X:[],meta:K(J)}}async first(){if(typeof this.client.execute==="function"){let $=await this.client.execute(this.sql,this.bindings);return fJ($)[0]??null}let J=this.client.prepare?.(this.sql);if(!J)throw new j("SQLite client must expose execute() or prepare().get()","SQLITE_CLIENT_INVALID");if(typeof J.get==="function"){let $=await J.get(...this.bindings);return $===void 0||$===null?null:$}if(typeof J.all==="function"){let $=await J.all(...this.bindings);if(!Array.isArray($)||$.length===0)return null;let X=$[0];return X===void 0||X===null?null:X}throw new j("SQLite prepare() result must expose get() or all()","SQLITE_CLIENT_INVALID")}}class pJ{client;sqlTag;sqlText;bindings;constructor(J,$,X,Y=[]){this.client=J,this.sqlTag=$,this.sqlText=X,this.bindings=Y}bind(...J){return new pJ(this.client,this.sqlTag,this.sqlText,J)}async run(){let J=Date.now(),$=SJ(this.sqlTag,this.sqlText,this.bindings),X=await g7(this.client,$);return{success:!0,results:qJ(X),meta:K(J,R6(X))}}async all(){let J=Date.now(),$=SJ(this.sqlTag,this.sqlText,this.bindings),X=await v6(this.client,$);return{success:!0,results:qJ(X),meta:K(J,R6(X))}}async first(){let J=SJ(this.sqlTag,this.sqlText,this.bindings),$=await p7(this.client,J),X=qJ($);if(X.length>0)return X[0]??null;if($&&typeof $==="object"&&"row"in $){let Y=$.row;return Y===void 0||Y===null?null:Y}if($&&typeof $==="object"&&!Array.isArray($)&&!("rows"in $)&&!("results"in $)&&!("data"in $))return $;return null}}async function y7(J,$,X,Y){try{let Z=await J.scan($,{MATCH:X,COUNT:Y});return B6(Z)}catch{let Z=await J.scan($,"MATCH",X,"COUNT",String(Y));return B6(Z)}}function B6(J){if(Array.isArray(J))return{cursor:String(J[0]??"0"),keys:Array.isArray(J[1])?J[1]:[]};return{cursor:String(J.cursor??"0"),keys:Array.isArray(J.keys)?J.keys:[]}}async function KJ(J,$,X){if(typeof J.execute==="function"){let Y=await J.execute($,X);if(Array.isArray(Y))return Y[0];return Y}if(typeof J.query==="function"){let Y=await J.query($,X);if(Array.isArray(Y))return Y[0];return Y}throw new j("MySQL client must expose execute() or query()","MYSQL_CLIENT_INVALID")}async function g7(J,$){if(typeof J.run==="function")return await J.run($);if(typeof J.execute==="function")return await J.execute($);if(typeof J.all==="function")return await J.all($);throw new j("Drizzle client must expose run(), execute(), or all()","DRIZZLE_CLIENT_INVALID")}async function v6(J,$){if(typeof J.all==="function")return await J.all($);if(typeof J.execute==="function")return await J.execute($);if(typeof J.run==="function")return await J.run($);throw new j("Drizzle client must expose all(), execute(), or run()","DRIZZLE_CLIENT_INVALID")}async function p7(J,$){if(typeof J.get==="function")return await J.get($);return await v6(J,$)}function SJ(J,$,X){let Y=m7($),Z=Y.length-1;if(Z!==X.length)throw new j(`Drizzle binding mismatch: expected ${Z} bindings, received ${X.length}`,"DRIZZLE_BINDINGS_MISMATCH");if(Z===0)return J.raw($);let G=typeof J.empty==="function"?J.empty():J.raw("");for(let H=0;H<Y.length;H++){let U=Y[H];if(U)G.append(J.raw(U));if(H<Z)G.append(J`${X[H]}`)}return G}function m7(J){let $=[],X=0,Y=!1,Z=!1,G=!1,H=!1;for(let U=0;U<J.length;U++){let _=J[U],F=U+1<J.length?J[U+1]:"";if(G){if(_===`
|
|
17
|
+
`)G=!1;continue}if(H){if(_==="*"&&F==="/")U++,H=!1;continue}if(!Y&&!Z){if(_==="-"&&F==="-"){U++,G=!0;continue}if(_==="/"&&F==="*"){U++,H=!0;continue}}if(_==="'"&&!Z){if(Y&&F==="'"){U++;continue}Y=!Y;continue}if(_==='"'&&!Y){if(Z&&F==='"'){U++;continue}Z=!Z;continue}if(_==="?"&&!Y&&!Z)$.push(J.slice(X,U)),X=U+1}return $.push(J.slice(X)),$}function qJ(J){let $=(Y)=>{if(!Y||typeof Y!=="object"||Array.isArray(Y))return;let Z=Y;if(Array.isArray(Z.rows))return Z.rows;if(Array.isArray(Z.results))return Z.results;if(Array.isArray(Z.data))return Z.data;return},X=(Y)=>{if(!Y||typeof Y!=="object"||Array.isArray(Y))return!1;return Object.keys(Y).length>0};if(Array.isArray(J)){if(J.length===2){let Y=$(J[0]);if(Y)return Y;let Z=$(J[1]);if(Z)return Z;if(!Array.isArray(J[0])&&!Array.isArray(J[1])){if(X(J[0]))return[J[0]];if(X(J[1]))return[J[1]]}if(Array.isArray(J[0]))return J[0];if(Array.isArray(J[1]))return J[1]}return J}if(J&&typeof J==="object"){let Y=$(J);if(Y)return Y}return[]}function R6(J){if(!J)return{};let $;if(Array.isArray(J)){if(J.length===2){if(J[0]&&typeof J[0]==="object"&&!Array.isArray(J[0]))$=J[0];else if(J[1]&&typeof J[1]==="object"&&!Array.isArray(J[1]))$=J[1]}}else if(typeof J==="object"&&!Array.isArray(J))$=J;if(!$)return{};let X={},Y=EJ($.rowCount)??EJ($.changes)??EJ($.affectedRows);if(Y!==void 0)X.changes=Y;let Z=$.lastInsertRowid??$.lastInsertId??$.lastID??$.lastRowID??$.insertId??$.insertID;if(typeof Z==="number"||typeof Z==="string")X.last_row_id=Z;if($.meta&&typeof $.meta==="object")Object.assign(X,$.meta);return X}async function u7(J,$){if(typeof J.get==="function")return await J.get($);if(typeof J.getItem==="function")return await J.getItem($);throw new j("NuxtHub KV client must expose get() or getItem()","NUXTHUB_KV_CLIENT_INVALID")}async function c7(J,$,X){if(typeof J.set==="function"){await J.set($,X);return}if(typeof J.setItem==="function"){await J.setItem($,X);return}throw new j("NuxtHub KV client must expose set() or setItem()","NUXTHUB_KV_CLIENT_INVALID")}async function d7(J,$){if(typeof J.del==="function"){await J.del($);return}if(typeof J.removeItem==="function"){await J.removeItem($);return}throw new j("NuxtHub KV client must expose del() or removeItem()","NUXTHUB_KV_CLIENT_INVALID")}async function l7(J,$){let X;if(typeof J.keys==="function")X=await J.keys($);else if(typeof J.getKeys==="function")X=await J.getKeys($);else throw new j("NuxtHub KV client must expose keys() or getKeys()","NUXTHUB_KV_CLIENT_INVALID");if(!Array.isArray(X))return[];if(!$)return[...X];return X.filter((Y)=>Y.startsWith($))}function fJ(J){if(Array.isArray(J))return J;if(J&&typeof J==="object"){let $=J;if(Array.isArray($.rows))return $.rows;if(Array.isArray($.results))return $.results}return[]}function K(J,$={}){return{duration:Date.now()-J,...$}}function EJ(J){if(typeof J==="number"&&Number.isFinite(J))return J;return}var ZJ=new Map;function bJ(J){let $=ZJ.get(J);if($)return $;let X="",Y=0,Z=!1,G=!1,H=!1,U=!1;for(let _=0;_<J.length;_++){let F=J[_],W=_+1<J.length?J[_+1]:"";if(H){if(X+=F,F===`
|
|
18
|
+
`)H=!1;continue}if(U){if(X+=F,F==="*"&&W==="/")X+="/",_++,U=!1;continue}if(!Z&&!G){if(F==="-"&&W==="-"){X+="--",_++,H=!0;continue}if(F==="/"&&W==="*"){X+="/*",_++,U=!0;continue}}if(F==="'"&&!G){Z=!Z,X+=F;continue}if(F==='"'&&!Z){G=!G,X+=F;continue}if(F==="?"&&!Z&&!G){Y++,X+=`$${Y}`;continue}X+=F}if(ZJ.set(J,X),ZJ.size>5000){let _=ZJ.keys().next().value;if(_)ZJ.delete(_)}return X}b();var o7={casing:{getColumnCasing(J){return J?.name??""}},escapeName(J){return J},escapeParam(){return"?"},escapeString(J){return J.replace(/'/g,"''")}},f6=["<=",">=","!=","<>","=","<",">"],n7=new Set(["COUNT","MAX","MIN","SUM","AVG"]),s7=new Set(["COALESCE","IFNULL","LOWER","UPPER","LENGTH","ABS"]);function N(J){return J.trim().replace(/^[`"\[]+|[`"\]]+$/g,"").split(".").pop()?.trim()??J.trim()}function i7(J){return J.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function a(J){if(typeof J==="number"&&Number.isFinite(J))return J;if(typeof J==="bigint")return Number(J);if(typeof J==="string"){let $=J.trim();if($==="")return;let X=Number($);return Number.isFinite(X)?X:void 0}return}function r(J,$=","){let X=[],Y=0,Z="",G=!1,H=!1;for(let _=0;_<J.length;_++){let F=J[_];if(F==="'"&&!H){G=!G,Z+=F;continue}if(F==='"'&&!G){H=!H,Z+=F;continue}if(!G&&!H){if(F==="(")Y++;else if(F===")")Y=Math.max(0,Y-1);else if(Y===0&&F===$){X.push(Z.trim()),Z="";continue}}Z+=F}let U=Z.trim();if(U.length>0)X.push(U);return X}function MJ(J,$){let X=0,Y=!1,Z=!1;for(let G=$;G<J.length;G++){let H=J[G];if(H==="'"&&!Z){Y=!Y;continue}if(H==='"'&&!Y){Z=!Z;continue}if(Y||Z)continue;if(H==="(")X++;else if(H===")"){if(X--,X===0)return G}}return-1}function UJ(J){let $=J.trim();if($.length===0)return{value:null,consumed:!1};if($==="?")return{value:null,consumed:!1};if(/^null$/i.test($))return{value:null,consumed:!0};if(/^true$/i.test($))return{value:1,consumed:!0};if(/^false$/i.test($))return{value:0,consumed:!0};if($.startsWith("'")&&$.endsWith("'")||$.startsWith('"')&&$.endsWith('"'))return{value:$.slice(1,-1).replace(/''/g,"'").replace(/""/g,'"'),consumed:!0};let X=Number($);if(Number.isFinite(X)&&/^-?\d+(\.\d+)?$/.test($))return{value:X,consumed:!0};return{value:void 0,consumed:!1}}function TJ(J){let $=J.toUpperCase(),X=x($,J,"WHERE");if(X===-1){let H=x($,J,"FROM");return{whereClause:null,afterWhere:H===-1?"":J.slice(H+4)}}let Y=X+5,Z=["ORDER BY","GROUP BY","HAVING","LIMIT","OFFSET","RETURNING",";"],G=J.length;for(let H of Z){let U=x($,J,H,Y);if(U!==-1&&U<G)G=U}return{whereClause:J.slice(Y,G).trim(),afterWhere:J.slice(G)}}function x(J,$,X,Y=0){let Z=Y,G=!1,H=!1;while(Z<=J.length-X.length){let U=$[Z];if(U==="'"&&!H){G=!G,Z++;continue}if(U==='"'&&!G){H=!H,Z++;continue}if(!G&&!H){if(J.startsWith(X,Z)){let _=Z===0?" ":J[Z-1],F=J[Z+X.length]??" ",W=/[A-Z0-9_]/.test(_)===!1,O=/[A-Z0-9_]/.test(F)===!1;if(W&&O)return Z}}Z++}return-1}function k6(J){let $=J.toUpperCase(),X={},Y=x($,J,"LIMIT");if(Y!==-1){let H=J.slice(Y+5).trim().match(/^(\d+)(?:\s*,\s*(\d+))?/);if(H){let U=Number(H[1]),_=H[2]!==void 0?Number(H[2]):void 0;if(_!==void 0)X.offset=U,X.limit=_;else X.limit=U}}let Z=x($,J,"OFFSET");if(Z!==-1){let H=J.slice(Z+6).trim().match(/^(\d+)/);if(H)X.offset=Number(H[1])}return X}function t7(J){let $=[];for(let X of r(J,",")){let Y=X.indexOf("=");if(Y===-1)continue;let Z=N(X.slice(0,Y)),G=X.slice(Y+1).trim();if(Z.length===0)continue;$.push({column:Z,expression:G})}return $}function DJ(J){let $=[],X=0;while(X<J.length){let Y=J[X];if(/\s/.test(Y)){X++;continue}if(Y==="("||Y===")"){$.push(Y),X++;continue}if(Y==="?"){$.push("?"),X++;continue}if(Y==="'"||Y==='"'){let H=Y,U=X+1;while(U<J.length){if(J[U]===H){if(J[U+1]===H){U+=2;continue}U++;break}U++}$.push(J.slice(X,U)),X=U;continue}let Z=null;for(let H of f6)if(J.startsWith(H,X)){Z=H;break}if(Z){$.push(Z),X+=Z.length;continue}let G=X;while(G<J.length&&/[A-Za-z0-9_.$]/.test(J[G]))G++;if(G===X)$.push(Y),X++;else $.push(J.slice(X,G)),X=G}return $}class GJ{tokens;position=0;constructor(J){this.tokens=J}parse(){if(this.tokens.length===0)return{type:"always-true"};return this.parseOr()}peek(){return this.tokens[this.position]}take(){return this.tokens[this.position++]}isKeyword(J,$){return typeof J==="string"&&J.toUpperCase()===$}parseOr(){let J=this.parseAnd();while(this.isKeyword(this.peek(),"OR")){this.take();let $=this.parseAnd();J=J.type==="or"?{type:"or",children:[...J.children,$]}:{type:"or",children:[J,$]}}return J}parseAnd(){let J=this.parseTerm();while(this.isKeyword(this.peek(),"AND")){this.take();let $=this.parseTerm();J=J.type==="and"?{type:"and",children:[...J.children,$]}:{type:"and",children:[J,$]}}return J}parseTerm(){if(this.peek()==="("){this.take();let $=this.parseOr();if(this.peek()===")")this.take();return $}return this.parseComparison()}parseComparison(){let J=this.take();if(J===void 0)return{type:"always-true"};let $=N(J),X=this.take();if(X===void 0)return{type:"always-true"};let Y=X.toUpperCase();if(Y==="IS"){let U=this.peek();if(this.isKeyword(U,"NOT")){this.take();let F=this.take();if(this.isKeyword(F,"NULL"))return{type:"null-check",column:$,operator:"IS NOT NULL"}}let _=this.take();if(this.isKeyword(_,"NULL"))return{type:"null-check",column:$,operator:"IS NULL"};return{type:"always-true"}}let Z=null;if(Y==="LIKE")Z="LIKE";else if(Y==="NOT"){let U=this.take();if(this.isKeyword(U,"LIKE"))Z="NOT LIKE";else return{type:"always-true"}}else if(f6.includes(Y))Z=Y;if(!Z)return{type:"always-true"};let G=this.take();if(G==="?")return{type:"compare",column:$,operator:Z,value:{kind:"param"}};let H=UJ(G??"");return{type:"compare",column:$,operator:Z,value:{kind:"literal",value:H.consumed?H.value:G??null}}}}function t(J,$,X,Y){switch(J.type){case"always-true":return!0;case"and":return J.children.every((Z)=>t(Z,$,X,Y));case"or":{let Z=!1;for(let G of J.children)if(t(G,$,X,Y))Z=!0;return Z}case"null-check":{let Z=$[J.column],G=Z===null||Z===void 0;return J.operator==="IS NULL"?G:!G}case"compare":{let Z;if(J.value.kind==="param")Z=X[Y.value++];else Z=J.value.value;let G=$[J.column];if(J.operator==="LIKE"||J.operator==="NOT LIKE"){let F=String(Z??""),O=new RegExp(`^${i7(F).replace(/%/g,".*").replace(/_/g,".")}$`,"i").test(String(G??""));return J.operator==="LIKE"?O:!O}let H=a(G),U=a(Z),_;if(H!==void 0&&U!==void 0)_=H===U?0:H<U?-1:1;else if(G===null||G===void 0)if(Z===null||Z===void 0)_=0;else _=-1;else if(Z===null||Z===void 0)_=1;else{let F=String(G),W=String(Z);_=F===W?0:F<W?-1:1}switch(J.operator){case"=":return _===0;case"!=":case"<>":return _!==0;case"<":return _<0;case"<=":return _<=0;case">":return _>0;case">=":return _>=0;default:return!1}}}}function x6(J){let $=0,X=!1,Y=!1;for(let Z=0;Z<J.length;Z++){let G=J[Z];if(G==="'"&&!Y){X=!X;continue}if(G==='"'&&!X){Y=!Y;continue}if(!X&&!Y&&G==="?")$++}return $}function K6(J){let $=J.trim().toUpperCase();if($.startsWith("SELECT")||$.startsWith("WITH")){if($.includes("SQLITE_MASTER"))return"sqlite-master-select";return"select"}if($.startsWith("INSERT"))return"insert";if($.startsWith("UPDATE"))return"update";if($.startsWith("DELETE"))return"delete";if($.startsWith("CREATE TABLE"))return"create-table";if($.startsWith("DROP TABLE"))return"drop-table";if($.startsWith("PRAGMA"))return"pragma";return"other"}function i(J){let $=J.toUpperCase(),X=J.match(/create\s+table\s+(?:if\s+not\s+exists\s+)?([`"\[]?[\w.]+[`"\]]?)/i);if(X)return N(X[1]??"");let Y=J.match(/drop\s+table\s+(?:if\s+exists\s+)?([`"\[]?[\w.]+[`"\]]?)/i);if(Y)return N(Y[1]??"");let Z=J.match(/insert\s+(?:or\s+\w+\s+)?into\s+([`"\[]?[\w.]+[`"\]]?)/i);if(Z)return N(Z[1]??"");let G=J.match(/update\s+(?:or\s+\w+\s+)?([`"\[]?[\w.]+[`"\]]?)\s+set/i);if(G)return N(G[1]??"");let H=J.match(/delete\s+from\s+([`"\[]?[\w.]+[`"\]]?)/i);if(H)return N(H[1]??"");let U=x($,J,"FROM");if(U!==-1){let F=J.slice(U+4).trim().match(/^([`"\[]?[\w.]+[`"\]]?)/);if(F)return N(F[1]??"")}return null}function a7(J,$=[]){if(typeof J==="string")return{sql:J,bindings:$};if(!J||typeof J!=="object")throw new j("Unsupported query input","INVALID_QUERY_INPUT");if(typeof J.toQuery==="function"){let X=J.toQuery(o7);if(X&&typeof X.sql==="string")return{sql:X.sql,bindings:Array.isArray(X.params)?[...X.params]:$}}if(typeof J.sql==="string")return{sql:J.sql,bindings:Array.isArray(J.params)?[...J.params]:$};if(typeof J.text==="string")return{sql:J.text,bindings:Array.isArray(J.params)?[...J.params]:$};throw new j("Unsupported Drizzle-style query object","INVALID_QUERY_INPUT")}function cJ(J){return r(J,",").map((X)=>{let Y=X.match(/\s+as\s+([`"\[]?[\w.]+[`"\]]?)\s*$/i),Z=Y?X.slice(0,Y.index).trim():X.trim(),G=Y?N(Y[1]??""):r7(Z);if(Z==="*")return{expression:Z,alias:"*",kind:"star"};let H=Z.toUpperCase(),U=Z.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*\(/);if(U){let _=(U[1]??"").toUpperCase();if(n7.has(_)||/\b(?:COUNT|MAX|MIN|SUM|AVG)\s*\(/i.test(H))return{expression:Z,alias:G,kind:"aggregate"};if(s7.has(_))return{expression:Z,alias:G,kind:"scalar"}}if(/[+\-*/()]/.test(Z)||/\bCOUNT\s*\(/i.test(Z)||/\bMAX\s*\(/i.test(Z))return{expression:Z,alias:G,kind:"expression"};return{expression:Z,alias:G,kind:"column"}})}function r7(J){let $=J.trim();if($==="*")return"*";if($.match(/^([`"\[]?[\w.]+[`"\]]?)$/))return N($);return $}function b6(J,$,X){let Y="",Z=!1,G=!1,H=0,U=X;while(H<J.length){let _=J[H];if(_==="'"&&!G){Z=!Z,Y+=_,H++;continue}if(_==='"'&&!Z){G=!G,Y+=_,H++;continue}if(!Z&&!G&&_==="?"){let F=$[U++];Y+=dJ(F),H++;continue}Y+=_,H++}return{expression:Y,cursor:U}}function dJ(J){if(J===null||J===void 0)return"NULL";if(typeof J==="number"||typeof J==="bigint")return String(J);if(typeof J==="boolean")return J?"1":"0";return`'${String(J).replace(/'/g,"''")}'`}function zJ(J,$,X,Y){if(J.kind==="star")return;if(J.kind==="column"){let H=$[0];return H?H[J.expression]:null}let Z=b6(J.expression,X,Y).expression;if(J.kind==="aggregate"||/\b(?:COUNT|MAX|MIN|SUM|AVG)\s*\(/i.test(Z))return e7(Z,$);if(J.kind==="scalar"){let H=$[0]??{};return HJ(Z,H)}let G=$[0]??{};return HJ(Z,G)}function e7(J,$){let X=J,Y=/(COUNT|MAX|MIN|SUM|AVG)\s*\(/i,Z=0;while(Y.test(X)&&Z<25){Z++;let G=X.match(Y);if(!G||G.index===void 0)break;let H=X.indexOf("(",G.index);if(H===-1)break;let U=MJ(X,H);if(U===-1)break;let _=(G[1]??"").toUpperCase(),F=X.slice(H+1,U).trim(),W=J9(_,F,$),O=dJ(W);X=X.slice(0,G.index)+O+X.slice(U+1)}return HJ(X,$[0]??{})}function J9(J,$,X){if(J==="COUNT"){if($==="*")return X.length;let G=/^distinct\s+/i.test($),H=N($.replace(/^distinct\s+/i,"")),U=X.map((_)=>_[H]).filter((_)=>_!==null&&_!==void 0);if(G)return new Set(U.map((_)=>String(_))).size;return U.length}let Y=N($),Z=X.map((G)=>a(G[Y])).filter((G)=>G!==void 0);if(Z.length===0)return null;switch(J){case"MAX":return Math.max(...Z);case"MIN":return Math.min(...Z);case"SUM":return Z.reduce((G,H)=>G+H,0);case"AVG":return Z.reduce((G,H)=>G+H,0)/Z.length;default:return null}}function HJ(J,$){let X=J.trim();if(X.length===0)return null;let Y=UJ(X);if(Y.consumed)return Y.value;let Z=X.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*\(/);if(Z){let H=(Z[1]??"").toUpperCase(),U=X.indexOf("(",Z.index),_=MJ(X,U);if(_!==-1){let F=X.slice(U+1,_),W=r(F,",").map((Q)=>HJ(Q,$)),O=X.slice(_+1).trim(),A=$9(H,W);if(O.length===0)return A;return S6(`${dJ(A)} ${O}`,$)}}if(X.match(/^([`"\[]?[\w.]+[`"\]]?)$/))return $[N(X)]??null;return S6(X,$)}function $9(J,$){switch(J){case"COALESCE":case"IFNULL":{for(let X of $)if(X!==null&&X!==void 0)return X;return null}case"LOWER":return $[0]===null||$[0]===void 0?null:String($[0]).toLowerCase();case"UPPER":return $[0]===null||$[0]===void 0?null:String($[0]).toUpperCase();case"LENGTH":return $[0]===null||$[0]===void 0?null:String($[0]).length;case"ABS":{let X=a($[0]);return X===void 0?null:Math.abs(X)}default:return null}}function S6(J,$){let X=J.trim();if(X.length===0)return null;let Y=UJ(X);if(Y.consumed)return Y.value;if(!/^[\d+\-*/().\s]+$/.test(X)){let G=X.split(/(\s|[+\-*/()])/).filter((H)=>H.trim().length>0).map((H)=>{if(/^[+\-*/()]$/.test(H))return H;let U=Number(H);if(Number.isFinite(U))return H;if(H.toLowerCase()==="null")return"null";let _=$[N(H)];if(_===null||_===void 0)return"null";if(typeof _==="number")return String(_);return JSON.stringify(_)}).join(" ");if(!/^[\d+\-*/().\s]+$/.test(G.replace(/null/g,"0")))return X;try{return Function(`return (${G.replace(/null/g,"0")});`)()}catch{return X}}try{return Function(`return (${X});`)()}catch{return X}}class lJ{tables=new Map;schemas=new Map;autoIncrementCounters=new Map;lastInsertRowId=null;prepare(J){return new h6(this,J)}async execute(J,$=[]){return await this.executeClientQuery(J,$)}async run(J,$=[]){return await this.executeClientQuery(J,$)}async all(J,$=[]){return await this.executeClientQuery(J,$)}async get(J,$=[]){return await this.executeClientQuery(J,$)}async executeClientQuery(J,$){let X=a7(J,$);return await this.executeStatement(X.sql,X.bindings)}async executeStatement(J,$){let X=Date.now();try{switch(K6(J)){case"create-table":return await this.handleCreateTable(J);case"drop-table":return await this.handleDropTable(J);case"insert":return await this.handleInsert(J,$);case"update":return await this.handleUpdate(J,$);case"delete":return await this.handleDelete(J,$);case"select":return await this.handleSelect(J,$);case"sqlite-master-select":return await this.handleSqliteMasterSelect(J,$);case"pragma":return await this.handlePragma(J);case"other":default:return{success:!0,results:[],meta:{duration:Date.now()-X}}}}catch(Y){let Z=Y instanceof Error?Y.message:String(Y);return{success:!1,results:[],meta:{duration:Date.now()-X},error:Z}}}async executeQuery(J,$){let X=Date.now(),Y=K6(J);if(Y==="select"||Y==="sqlite-master-select"||Y==="pragma")return await this.executeStatement(J,$);return{success:!1,results:[],meta:{duration:Date.now()-X},error:"Use executeStatement for non-SELECT queries"}}async handleCreateTable(J){let $=Date.now(),X=i(J);if(!X)return{success:!1,results:[],meta:{duration:Date.now()-$},error:"Could not extract table name"};let Y=new Map,Z=J.indexOf("("),G=Z===-1?-1:MJ(J,Z);if(Z!==-1&&G!==-1){let H=J.slice(Z+1,G);for(let U of r(H,",")){let _=U.trim().split(/\s+/);if(_.length===0)continue;let F=_[0]?.toUpperCase()??"";if(["PRIMARY","FOREIGN","UNIQUE","CHECK","CONSTRAINT"].includes(F))continue;let W=N(_[0]??"");if(W.length===0)continue;let O=(_[1]??"").toUpperCase(),A=_.slice(2).join(" ").toUpperCase();Y.set(W,{name:W,type:O,isPrimaryKey:A.includes("PRIMARY KEY"),isAutoIncrement:A.includes("AUTOINCREMENT")||A.includes("AUTO_INCREMENT")||A.includes("GENERATED BY DEFAULT AS IDENTITY"),defaultValue:_9(_.slice(2).join(" ")),notNull:A.includes("NOT NULL")})}}this.tables.set(X,new Map),this.schemas.set(X,Y);for(let H of Y.values())if(H.isAutoIncrement){this.autoIncrementCounters.set(X,this.autoIncrementCounters.get(X)??0);break}return{success:!0,results:[],meta:{duration:Date.now()-$}}}async handleDropTable(J){let $=Date.now(),X=i(J);if(!X)return{success:!1,results:[],meta:{duration:Date.now()-$},error:"Could not extract table name"};return this.tables.delete(X),this.schemas.delete(X),this.autoIncrementCounters.delete(X),{success:!0,results:[],meta:{duration:Date.now()-$}}}async handleInsert(J,$){let X=Date.now(),Y=i(J);if(!Y)return{success:!1,results:[],meta:{duration:Date.now()-X},error:"Could not extract table name"};if(!this.tables.has(Y))this.tables.set(Y,new Map);let Z=this.tables.get(Y),G=this.schemas.get(Y),H=G?Array.from(G.values()):[],U=H.find((M)=>M.isPrimaryKey),_=H.find((M)=>M.isAutoIncrement),F=U9(J),W=/\binsert\s+or\s+replace\b/i.test(J),O=/\binsert\s+or\s+(?:ignore|abort|fail|rollback)\b/i.test(J),A=H9(J),Q=[],z=A.length>0?A:[null],T=0;for(let M of z){let D={};if(F&&F.length>0){let I=M?r(M,",").map((e)=>e.trim()):F.map(()=>"?");F.forEach((e,IJ)=>{let m=I[IJ];if(m===void 0)return;if(m==="?")D[e]=$[T++];else{let S=UJ(m);D[e]=S.consumed?S.value:m}})}else if(G){for(let I of G.keys())if(T<$.length)D[I]=$[T++]}else for(let I of $.slice(T))D[Object.keys(D).length===0?"id":`column_${Object.keys(D).length}`]=I,T++;if(G){for(let I of G.values())if(D[I.name]===void 0&&I.defaultValue!==void 0)D[I.name]=I.defaultValue}let V=U?.name??"id",L=D[V];if((L===void 0||L===null||L==="")&&_){let I=(this.autoIncrementCounters.get(Y)??0)+1;if(this.autoIncrementCounters.set(Y,I),D[_.name]=I,V!==_.name)D[V]=I;L=I}if(L===void 0||L===null||L===""){let I=(this.autoIncrementCounters.get(Y)??0)+1;this.autoIncrementCounters.set(Y,I),L=I,D[V]=I}if(_){let I=typeof L==="number"?L:Number(L);if(Number.isFinite(I))this.autoIncrementCounters.set(Y,Math.max(this.autoIncrementCounters.get(Y)??0,I))}let C=String(L);if(Z.has(C)&&!W){if(O)continue;return{success:!1,results:[],meta:{duration:Date.now()-X},error:`UNIQUE constraint failed: ${Y}.${V}`}}Z.set(C,D),this.lastInsertRowId=typeof L==="number"||typeof L==="string"?L:String(L),Q.push(D)}let B=/\breturning\b/i.test(J),E=B?mJ(J):null;return{success:!0,results:B?Q.map((M)=>uJ(M,E??["*"])):[],meta:{duration:Date.now()-X,last_row_id:this.lastInsertRowId??void 0,changes:Q.length}}}async handleUpdate(J,$){let X=Date.now(),Y=i(J);if(!Y)return{success:!1,results:[],meta:{duration:Date.now()-X},error:"Could not extract table name"};if(!this.tables.has(Y))return{success:!1,results:[],meta:{duration:Date.now()-X},error:`Table ${Y} not found`};let Z=Y9(J);if(!Z)return{success:!1,results:[],meta:{duration:Date.now()-X},error:"UPDATE missing SET clause"};let G=t7(Z),H=this.tables.get(Y),U=Array.from(H.values()),_=x6(Z),F=$.slice(_),W=$.slice(0,_),{whereClause:O}=TJ(J),A=O?new GJ(DJ(O)).parse():{type:"always-true"},Q=[];for(let P of U)if(t(A,P,F,{value:0}))Q.push(P);let z=0;for(let P of Q){let M={value:0};for(let{column:D,expression:V}of G){let L=x6(V),C=W.slice(M.value,M.value+L);M.value+=L,P[D]=X9(V,C,P)}z++}let T=/\breturning\b/i.test(J),B=T?mJ(J):null;return{success:!0,results:T?Q.map((P)=>uJ(P,B??["*"])):[],meta:{duration:Date.now()-X,changes:z}}}async handleDelete(J,$){let X=Date.now(),Y=i(J);if(!Y)return{success:!1,results:[],meta:{duration:Date.now()-X},error:"Could not extract table name"};if(!this.tables.has(Y))return{success:!0,results:[],meta:{duration:Date.now()-X,changes:0}};let Z=this.tables.get(Y),{whereClause:G}=TJ(J);if(!G){let O=Z.size;return Z.clear(),{success:!0,results:[],meta:{duration:Date.now()-X,changes:O}}}let H=new GJ(DJ(G)).parse(),U=[];for(let[O,A]of Array.from(Z.entries()))if(t(H,A,$,{value:0}))Z.delete(O),U.push(A);let _=/\breturning\b/i.test(J),F=_?mJ(J):null;return{success:!0,results:_?U.map((O)=>uJ(O,F??["*"])):[],meta:{duration:Date.now()-X,changes:U.length}}}async handleSelect(J,$){let X=Date.now(),Y=i(J);if(!Y)return{success:!1,results:[],meta:{duration:Date.now()-X},error:"Could not extract table name"};if(!this.tables.has(Y))return{success:!0,results:[],meta:{duration:Date.now()-X}};let Z=this.tables.get(Y),G=Array.from(Z.values()),{whereClause:H,afterWhere:U}=TJ(J),_=H?new GJ(DJ(H)).parse():{type:"always-true"},F=q6(J),W=cJ(F),O=[];for(let V of G)if(t(_,V,$,{value:0}))O.push(V);let A=Z9(U||J),Q=O;if(A)Q=[...O].sort((V,L)=>G9(V,L,A));let z=W.some((V)=>V.kind==="aggregate"),T;if(z){let V={};for(let L of W)V[L.alias]=zJ(L,Q,$,0);T=[V]}else if(W.length===1&&W[0]?.kind==="star")T=Q.map((V)=>({...V}));else T=Q.map((V)=>{let L={};for(let C of W)if(C.kind==="star")Object.assign(L,V);else if(C.kind==="column")L[C.alias]=V[C.expression]??null;else L[C.alias]=zJ(C,[V],$,0);return L});let{limit:B,offset:E}=k6(U),P=E??0,M=B===void 0?T.length:P+B;return{success:!0,results:T.slice(P,M),meta:{duration:Date.now()-X}}}async handleSqliteMasterSelect(J,$){let X=Date.now(),Y=[];for(let T of this.tables.keys())Y.push({name:T,type:"table",tbl_name:T,sql:`CREATE TABLE ${T} (...)`});let{whereClause:Z,afterWhere:G}=TJ(J),H=Z?new GJ(DJ(Z)).parse():{type:"always-true"},U=Y.filter((T)=>{return t(H,T,$,{value:0})}),_=q6(J),F=cJ(_),W=U.map((T)=>{if(F.length===1&&F[0]?.kind==="star")return{...T};let B={};for(let E of F)if(E.kind==="star")Object.assign(B,T);else if(E.kind==="column")B[E.alias]=T[E.expression]??null;else B[E.alias]=zJ(E,[T],$,0);return B}),{limit:O,offset:A}=k6(G),Q=A??0,z=O===void 0?W.length:Q+O;return{success:!0,results:W.slice(Q,z),meta:{duration:Date.now()-X}}}async handlePragma(J){let $=Date.now(),X=J.trim().toLowerCase();if(X.startsWith("pragma page_count")){let Y=0;for(let Z of this.tables.values())Y+=Z.size;return{success:!0,results:[{page_count:Math.max(1,Y)}],meta:{duration:Date.now()-$}}}if(X.startsWith("pragma page_size"))return{success:!0,results:[{page_size:4096}],meta:{duration:Date.now()-$}};if(X.startsWith("pragma table_info")){let Y=X.match(/pragma\s+table_info\s*\(\s*([`"\[]?[\w.]+[`"\]]?)\s*\)/);if(Y){let Z=N(Y[1]??""),G=this.schemas.get(Z);if(G)return{success:!0,results:Array.from(G.values()).map((U,_)=>({cid:_,name:U.name,type:U.type,notnull:U.notNull?1:0,dflt_value:U.defaultValue??null,pk:U.isPrimaryKey?1:0})),meta:{duration:Date.now()-$}}}}return{success:!0,results:[],meta:{duration:Date.now()-$}}}}function X9(J,$,X){if(J==="?")return $[0];let Y=b6(J,$,0).expression;return HJ(Y,X)}function q6(J){let $=J.toUpperCase(),X=x($,J,"SELECT");if(X===-1)return"*";let Y=x($,J,"FROM",X+6);if(Y===-1)return J.slice(X+6).trim();return J.slice(X+6,Y).trim().replace(/^distinct\s+/i,"")}function Y9(J){let $=J.toUpperCase(),X=x($,J,"SET");if(X===-1)return null;let Y=X+3,Z=["WHERE","RETURNING","ORDER BY","LIMIT"],G=J.length;for(let H of Z){let U=x($,J,H,Y);if(U!==-1&&U<G)G=U}return J.slice(Y,G).trim()}function Z9(J){let $=J.toUpperCase(),X=x($,J,"ORDER BY");if(X===-1)return null;let Z=J.slice(X+8).trim().match(/^([`"\[]?[\w.]+[`"\]]?)(?:\s+(asc|desc))?/i);if(!Z)return null;return{column:N(Z[1]??""),direction:(Z[2]??"asc").toLowerCase()==="desc"?"desc":"asc"}}function G9(J,$,X){let Y=J[X.column],Z=$[X.column];if(Y===Z)return 0;if(Y===void 0||Y===null)return X.direction==="desc"?1:-1;if(Z===void 0||Z===null)return X.direction==="desc"?-1:1;let G=a(Y),H=a(Z),U;if(G!==void 0&&H!==void 0)U=G===H?0:G<H?-1:1;else U=String(Y).localeCompare(String(Z));return X.direction==="desc"?-U:U}function H9(J){let $=J.toUpperCase(),X=x($,J,"VALUES");if(X===-1)return[];let Y=[],Z=X+6;while(Z<J.length){while(Z<J.length&&/[\s,]/.test(J[Z]))Z++;if(J[Z]!=="(")break;let G=MJ(J,Z);if(G===-1)break;Y.push(J.slice(Z+1,G).trim()),Z=G+1}return Y}function U9(J){let $=J.match(/insert\s+(?:or\s+\w+\s+)?into\s+[^()]+\(([^)]+)\)/i);if(!$||!$[1]||$.index===void 0)return null;let Y=J.slice(0,$.index+$[0].length).toUpperCase();if(Y.includes("VALUES")||Y.includes("SELECT"))return null;return $[1].split(",").map((Z)=>N(Z)).filter((Z)=>Z.length>0)}function mJ(J){let $=J.match(/\breturning\b\s+([^;]+)/i);if(!$||!$[1])return null;return r($[1],",").map((X)=>X.trim())}function uJ(J,$){if($.length===1&&$[0]==="*")return{...J};let X=cJ($.join(", ")),Y={};for(let Z of X)if(Z.kind==="star")Object.assign(Y,J);else if(Z.kind==="column")Y[Z.alias]=J[Z.expression]??null;else Y[Z.alias]=zJ(Z,[J],[],0);return Y}function _9(J){let $=J.match(/default\s+('([^']*)'|"([^"]*)"|[\w.-]+)/i);if(!$)return;let X=$[1]??"",Y=UJ(X);return Y.consumed?Y.value:X}class h6{database;sql;bindings=[];constructor(J,$){this.database=J;this.sql=$}bind(...J){return this.bindings=J,this}async run(){return await this.database.executeStatement(this.sql,this.bindings)}async all(){return await this.database.executeStatement(this.sql,this.bindings)}async first(){return(await this.database.executeStatement(this.sql,this.bindings)).results[0]??null}}class oJ{store=new Map;expirations=new Map;pruneExpired(){if(this.expirations.size===0)return;let J=Date.now();for(let[$,X]of this.expirations)if(X<J)this.store.delete($),this.expirations.delete($)}normalizeValue(J){return typeof J==="string"?J:JSON.stringify(J)??String(J)}async get(J,$="text"){let X=this.expirations.get(J);if(X!==void 0&&X<Date.now())return this.store.delete(J),this.expirations.delete(J),null;let Y=this.store.get(J);if(Y===void 0)return null;if($==="json")try{return JSON.parse(Y)}catch(Z){throw new j(`Failed to parse JSON from KV for key ${J}: ${Z instanceof Error?Z.message:String(Z)}`,"KV_JSON_PARSE_FAILED")}return Y}async put(J,$,X){if(this.store.set(J,$),X?.expirationTtl)this.expirations.set(J,Date.now()+X.expirationTtl*1000);else this.expirations.delete(J)}async set(J,$,X){if(this.store.set(J,this.normalizeValue($)),X?.ttl)this.expirations.set(J,Date.now()+X.ttl*1000);else this.expirations.delete(J)}async del(J){await this.delete(J)}async keys(J=""){return(await this.list({prefix:J})).keys.map((X)=>X.name)}async getItem(J){return await this.get(J,"text")??null}async setItem(J,$){await this.set(J,$)}async removeItem(J){await this.delete(J)}async getKeys(J=""){return await this.keys(J)}async delete(J){this.store.delete(J),this.expirations.delete(J)}async list(J){this.pruneExpired();let $=J?.prefix??"",X=J?.limit??1000,Y=J?.cursor?Number.parseInt(J.cursor,10):0,Z=Number.isFinite(Y)&&Y>=0?Y:0,G=[];for(let F of this.store.keys())if(F.startsWith($))G.push(F);let H=G.slice(Z,Z+X).map((F)=>({name:F})),U=Z+X,_=U>=G.length;return{keys:H,cursor:_?void 0:String(U),list_complete:_}}clear(){this.store.clear(),this.expirations.clear()}size(){return this.pruneExpired(),this.store.size}}function F9(){return new lJ}function W9(){return new oJ}$J();export{OJ as validateTableForSharding,rJ as schemaExists,wJ as runShard,P6 as runAllShards,L6 as run,o6 as resetConfig,_7 as reassignShard,LJ as prepare,J6 as migrateRecord,d as listTables,F7 as listKnownShards,b7 as isSQLDatabase,h7 as isKVStorage,X6 as integrateExistingDatabase,G7 as insertShard,Z7 as insert,F6 as initializeAsync,d6 as initialize,D7 as indexShard,z7 as indexAllShards,T7 as index,v7 as getTotalDatabaseSize,W7 as getShardStats,M6 as getDatabaseSizesAllShards,V7 as getDatabaseSizeForShard,w7 as getDatabaseSizeForKey,i6 as getClosestRegionFromIP,Q7 as flush,vJ as firstShard,U7 as firstByLookupKey,L7 as firstAllShardsGlobal,z6 as firstAllShards,E6 as first,I7 as explainShard,B7 as explainAllShards,M7 as explain,eJ as dropSchema,WJ as discoverExistingRecordsWithColumns,FJ as discoverExistingPrimaryKeys,x7 as createValkeyKVProvider,aJ as createSchemaAcrossShards,J7 as createSchema,K7 as createSQLiteProvider,N6 as createRedisKVProvider,C6 as createPostgreSQLProvider,S7 as createNuxtHubKVProvider,w6 as createMySQLProvider,$6 as createMappingsForExistingKeys,F9 as createInMemorySQLProvider,W9 as createInMemoryKVProvider,q7 as createHyperdrivePostgresProvider,f7 as createHyperdriveMySQLProvider,PJ as createDrizzleSQLProvider,N7 as countShard,C7 as countAllShards,R7 as count,l6 as collegedb,H6 as clearShardMigrationCache,G6 as clearMigrationCache,Z6 as checkMigrationNeeded,Y6 as autoDetectAndMigrate,QJ as allShard,H7 as allByLookupKey,D6 as allAllShardsGlobal,VJ as allAllShards,V6 as all,I6 as ShardCoordinator,y as KVShardMapper,lJ as InMemorySQLDatabase,oJ as InMemoryKVStorage,j as CollegeDBError};
|
|
19
19
|
|
|
20
|
-
//# debugId=
|
|
20
|
+
//# debugId=95D2376A53E89F0B64756E2164756E21
|
|
21
21
|
//# sourceMappingURL=index.js.map
|