@earth-app/collegedb 1.1.3 → 1.1.4
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 +114 -48
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +6 -6
- package/dist/router.d.ts +73 -0
- package/dist/router.d.ts.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -71,6 +71,7 @@ This allows you to:
|
|
|
71
71
|
- Automatic query routing (primary key to shard mapping)
|
|
72
72
|
- Provider adapters for Redis/Valkey/NuxtHub KV plus PostgreSQL/MySQL/SQLite SQL
|
|
73
73
|
- Drizzle interop through existing SQL providers (`createPostgreSQLProvider`, `createMySQLProvider`, `createSQLiteProvider`)
|
|
74
|
+
- Auto-allocated generated-id inserts via `insert()` and direct-shard inserts via `insertShard()` for AUTOINCREMENT / RETURNING workflows
|
|
74
75
|
- Hyperdrive helpers for PostgreSQL and MySQL
|
|
75
76
|
- Multiple allocation strategies: round-robin, random, hash, location-aware, and mixed read/write strategies
|
|
76
77
|
- Durable Object shard coordination and shard statistics
|
|
@@ -193,18 +194,19 @@ CollegeDB includes a benchmark runner that executes each SQL+KV combination acro
|
|
|
193
194
|
|
|
194
195
|
### Scenario Catalog
|
|
195
196
|
|
|
196
|
-
| Scenario Key | Scenario | What Happens
|
|
197
|
-
| ----------------- | -------------------------------- |
|
|
198
|
-
| basic_crud | Basic CRUD round-trip | Insert, read, update, and delete a user via routed queries.
|
|
199
|
-
| advanced_usage | Advanced lookup workflow | Writes user+post, adds lookup aliases, then validates join and alias-based lookup.
|
|
200
|
-
| migration_mapping | Migration-style mapping creation | Inserts legacy records on a fixed shard, then builds shard mappings in batch and validates routing.
|
|
201
|
-
| bulk_crud | Bulk CRUD pressure | Performs bulk inserts, half updates, and full delete sweep, then validates shard-wide totals.
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
|
207
|
-
|
|
|
197
|
+
| Scenario Key | Scenario | What Happens | Workload Per Run |
|
|
198
|
+
| ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
199
|
+
| basic_crud | Basic CRUD round-trip | Insert, read, update, and delete a user via routed queries. | 20 iterations; 4 routed SQL ops per iteration |
|
|
200
|
+
| advanced_usage | Advanced lookup workflow | Writes user+post, adds lookup aliases, then validates join and alias-based lookup. | 15 iterations; ~5 routed SQL ops + KV lookup-key updates per iteration |
|
|
201
|
+
| migration_mapping | Migration-style mapping creation | Inserts legacy records on a fixed shard, then builds shard mappings in batch and validates routing. | 10 iterations; 20 legacy records mapped per iteration |
|
|
202
|
+
| bulk_crud | Bulk CRUD pressure | Performs bulk inserts, half updates, and full delete sweep, then validates shard-wide totals. | 7 iterations; 160 inserts + 80 updates + 160 deletes per iteration |
|
|
203
|
+
| auto_increment | Auto-generated primary keys | Inserts rows with generated ids on an automatically selected shard, captures the generated key, then validates routed readback. | 6 iterations; insert + generated-id readback per iteration |
|
|
204
|
+
| indexing | Indexed query scan | Creates an index on posts(user_id) and repeatedly queries the indexed path. | 15 iterations after warmup dataset build |
|
|
205
|
+
| metadata_fetch | Metadata inspection | Reads table metadata/introspection rows from one shard. | 14 iterations; 1 metadata query per iteration |
|
|
206
|
+
| pragma_or_info | PRAGMA / server info | Runs provider-specific PRAGMA/info query to sample low-level metadata latency. | 14 iterations; 1 pragma/info query per iteration |
|
|
207
|
+
| counting | Cross-shard counting | Counts users across all shards to measure fanout aggregation overhead. | 14 iterations; all-shard count aggregation per iteration |
|
|
208
|
+
| shard_fanout | Shard fanout query | Runs query fanout to all shards and aggregates shard-level responses. | 14 iterations; 1 all-shards query per iteration |
|
|
209
|
+
| reassignment | Shard reassignment flow | Creates a record, reassigns it to another shard, and verifies routed reads still succeed. | 10 iterations; insert + reassignment + verification per iteration |
|
|
208
210
|
|
|
209
211
|
### Report Matrices
|
|
210
212
|
|
|
@@ -439,6 +441,7 @@ Benchmark coverage includes:
|
|
|
439
441
|
- advanced lookup/routing workflows
|
|
440
442
|
- migration-style mapping creation
|
|
441
443
|
- bulk CRUD
|
|
444
|
+
- auto-generated primary key inserts and readback
|
|
442
445
|
- indexing queries
|
|
443
446
|
- metadata fetch
|
|
444
447
|
- pragma/info queries (provider-specific)
|
|
@@ -572,6 +575,67 @@ This approach provides:
|
|
|
572
575
|
- **Optimal read performance**: Queries use `hash` strategy for consistent, high-performance routing
|
|
573
576
|
- **Flexibility**: Each operation type can use the most appropriate routing strategy
|
|
574
577
|
|
|
578
|
+
### Auto-Generated Primary Keys
|
|
579
|
+
|
|
580
|
+
When your table assigns the primary key during insert, use `insert()` for the automatic shard-allocation path or `insertShard()` when you already know the target shard. Both helpers capture the generated id from provider metadata or `RETURNING` rows, then store the generated-id mapping so the normal routed `first()` / `all()` helpers can read the row back.
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
import { first, insert, insertShard } from '@earth-app/collegedb';
|
|
584
|
+
|
|
585
|
+
// SQLite / D1
|
|
586
|
+
await createSchema(
|
|
587
|
+
env['db-east'],
|
|
588
|
+
`
|
|
589
|
+
CREATE TABLE IF NOT EXISTS auto_users (
|
|
590
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
591
|
+
name TEXT NOT NULL,
|
|
592
|
+
email TEXT UNIQUE,
|
|
593
|
+
created_at INTEGER
|
|
594
|
+
)
|
|
595
|
+
`
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
const created = await insert('INSERT INTO auto_users (name, email, created_at) VALUES (?, ?, ?)', ['Ada', 'ada@example.com', Date.now()]);
|
|
599
|
+
|
|
600
|
+
const row = await first(String(created.generatedId), 'SELECT * FROM auto_users WHERE id = ?', [created.generatedId]);
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
// Direct shard insert when you want to pin the write to a specific shard
|
|
605
|
+
const directCreated = await insertShard('db-east', 'INSERT INTO auto_users (name, email, created_at) VALUES (?, ?, ?)', [
|
|
606
|
+
'Ada',
|
|
607
|
+
'ada@example.com',
|
|
608
|
+
Date.now()
|
|
609
|
+
]);
|
|
610
|
+
|
|
611
|
+
console.log(directCreated.generatedId);
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
// PostgreSQL / MySQL 8.0.19+ RETURNING path
|
|
616
|
+
await createSchema(
|
|
617
|
+
env['db-east'],
|
|
618
|
+
`
|
|
619
|
+
CREATE TABLE IF NOT EXISTS auto_users (
|
|
620
|
+
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
621
|
+
name VARCHAR(255) NOT NULL,
|
|
622
|
+
email VARCHAR(255) UNIQUE,
|
|
623
|
+
created_at BIGINT
|
|
624
|
+
)
|
|
625
|
+
`
|
|
626
|
+
);
|
|
627
|
+
|
|
628
|
+
const created = await insert('INSERT INTO auto_users (name, email, created_at) VALUES (?, ?, ?) RETURNING id', [
|
|
629
|
+
'Ada',
|
|
630
|
+
'ada@example.com',
|
|
631
|
+
Date.now()
|
|
632
|
+
]);
|
|
633
|
+
|
|
634
|
+
const row = await first(String(created.generatedId), 'SELECT * FROM auto_users WHERE id = ?', [created.generatedId]);
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
If your SQL dialect uses `RETURNING`, include it in the insert statement. The helper will use the returned row instead of provider metadata when present.
|
|
638
|
+
|
|
575
639
|
## Multi-Key Shard Mappings
|
|
576
640
|
|
|
577
641
|
CollegeDB supports **multiple lookup keys** for the same record, allowing you to query by username, email, ID, or any unique identifier. Keys are automatically hashed with SHA-256 for security and privacy.
|
|
@@ -1022,42 +1086,44 @@ await first('user-123', 'SELECT * FROM users WHERE email = ?', [email]);
|
|
|
1022
1086
|
|
|
1023
1087
|
## API Reference
|
|
1024
1088
|
|
|
1025
|
-
| Function | Description
|
|
1026
|
-
| ------------------------------------------------- |
|
|
1027
|
-
| `collegedb(config, callback)` | Initialize CollegeDB, then run a callback
|
|
1028
|
-
| `initialize(config)` | Initialize CollegeDB with configuration
|
|
1029
|
-
| `createSchema(db, schema)` | Create schema on a shard database
|
|
1030
|
-
| `prepare(key, sql)` | Prepare a SQL statement for execution
|
|
1031
|
-
| `run(key, sql, bindings)` | Execute a SQL query with primary key routing
|
|
1032
|
-
| `
|
|
1033
|
-
| `
|
|
1034
|
-
| `
|
|
1035
|
-
| `
|
|
1036
|
-
| `
|
|
1037
|
-
| `
|
|
1038
|
-
| `
|
|
1039
|
-
| `
|
|
1040
|
-
| `
|
|
1041
|
-
| `
|
|
1042
|
-
| `
|
|
1043
|
-
| `
|
|
1044
|
-
| `
|
|
1045
|
-
| `
|
|
1046
|
-
| `
|
|
1047
|
-
| `
|
|
1048
|
-
| `
|
|
1049
|
-
| `
|
|
1050
|
-
| `
|
|
1051
|
-
| `
|
|
1052
|
-
| `
|
|
1053
|
-
| `
|
|
1054
|
-
| `
|
|
1055
|
-
| `
|
|
1056
|
-
| `
|
|
1057
|
-
| `
|
|
1058
|
-
| `
|
|
1059
|
-
| `
|
|
1060
|
-
| `
|
|
1089
|
+
| Function | Description | Parameters |
|
|
1090
|
+
| ------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
1091
|
+
| `collegedb(config, callback)` | Initialize CollegeDB, then run a callback | `CollegeDBConfig, () => T` |
|
|
1092
|
+
| `initialize(config)` | Initialize CollegeDB with configuration | `CollegeDBConfig` |
|
|
1093
|
+
| `createSchema(db, schema)` | Create schema on a shard database | `SQLDatabase, string` |
|
|
1094
|
+
| `prepare(key, sql)` | Prepare a SQL statement for execution | `string, string` |
|
|
1095
|
+
| `run(key, sql, bindings)` | Execute a SQL query with primary key routing | `string, string, any[]` |
|
|
1096
|
+
| `insert(sql, bindings)` | Insert on an automatically selected shard and capture the generated id | `string, any[]` |
|
|
1097
|
+
| `insertShard(shard, sql, bindings)` | Insert directly on a specific shard and capture the generated id | `string, string, any[]` |
|
|
1098
|
+
| `first(key, sql, bindings)` | Execute a SQL query and return first result | `string, string, any[]` |
|
|
1099
|
+
| `all(key, sql, bindings)` | Execute a SQL query and return all results | `string, string, any[]` |
|
|
1100
|
+
| `index(key, table, columns, options)` | Create an index on routed shard | `string, string, string or index-column array, CreateIndexOptions` |
|
|
1101
|
+
| `indexShard(shard, table, columns, options)` | Create an index on one shard | `string, string, string or index-column array, CreateIndexOptions` |
|
|
1102
|
+
| `indexAllShards(table, columns, options)` | Create an index on all shards | `string, string or index-column array, CreateIndexOptions` |
|
|
1103
|
+
| `firstByLookupKey(key, sql, bindings, batchSize)` | Resolve secondary-key mapping, fallback to fanout | `string, string, any[], number` |
|
|
1104
|
+
| `allByLookupKey(key, sql, bindings, batchSize)` | Resolve secondary-key mapping, fallback to fanout | `string, string, any[], number` |
|
|
1105
|
+
| `runShard(shard, sql, bindings)` | Execute a query directly on a specific shard | `string, string, any[]` |
|
|
1106
|
+
| `allShard(shard, sql, bindings)` | Execute a query on specific shard, return all results | `string, string, any[]` |
|
|
1107
|
+
| `firstShard(shard, sql, bindings)` | Execute a query on specific shard, return first result | `string, string, any[]` |
|
|
1108
|
+
| `explain(key, sql, bindings, options)` | Inspect query plan on routed shard | `string, string, any[], ExplainOptions` |
|
|
1109
|
+
| `explainShard(shard, sql, bindings, options)` | Inspect query plan on one shard | `string, string, any[], ExplainOptions` |
|
|
1110
|
+
| `explainAllShards(sql, bindings, options)` | Inspect query plan on all shards | `string, any[], ExplainOptions` |
|
|
1111
|
+
| `count(key, table)` | Count rows on routed shard | `string, string` |
|
|
1112
|
+
| `countShard(shard, table)` | Count rows on a specific shard | `string, string` |
|
|
1113
|
+
| `countAllShards(table, batchSize)` | Count rows per shard and global total | `string, number` |
|
|
1114
|
+
| `runAllShards(sql, bindings, batchSize)` | Execute query on all shards | `string, any[], number` |
|
|
1115
|
+
| `allAllShards(sql, bindings, batchSize)` | Execute query on all shards (SQL pagination applies per shard) | `string, any[], number` |
|
|
1116
|
+
| `firstAllShards(sql, bindings, batchSize)` | Execute query on all shards, return first row per shard | `string, any[], number` |
|
|
1117
|
+
| `allAllShardsGlobal(sql, bindings, options)` | Execute query on all shards, then globally merge/sort/paginate | `string, any[], GlobalAllShardsOptions` |
|
|
1118
|
+
| `firstAllShardsGlobal(sql, bindings, options)` | Return first row after global merge/sort/paginate | `string, any[], GlobalAllShardsOptions` |
|
|
1119
|
+
| `reassignShard(key, newShard)` | Move primary key to different shard | `string, string` |
|
|
1120
|
+
| `listKnownShards()` | Get list of available shards | `void` |
|
|
1121
|
+
| `getShardStats()` | Get statistics for all shards | `void` |
|
|
1122
|
+
| `getDatabaseSizeForKey(key)` | Get size of key-routed shard in bytes | `string` |
|
|
1123
|
+
| `getDatabaseSizeForShard(shard)` | Get size of a specific shard in bytes | `string` |
|
|
1124
|
+
| `getDatabaseSizesAllShards(batchSize)` | Get per-shard size data | `number` |
|
|
1125
|
+
| `getTotalDatabaseSize(batchSize)` | Get total size across all shards | `number` |
|
|
1126
|
+
| `flush()` | Clear all shard mappings (development only) | `void` |
|
|
1061
1127
|
|
|
1062
1128
|
### Provider Adapter Functions
|
|
1063
1129
|
|
package/dist/index.d.ts
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* @author Gregory Mitchell
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
export { all, allAllShards, allAllShardsGlobal, allByLookupKey, allShard, collegedb, count, countAllShards, countShard, createSchema, explain, explainAllShards, explainShard, first, firstAllShards, firstAllShardsGlobal, firstByLookupKey, firstShard, flush, getClosestRegionFromIP, getDatabaseSizeForKey, getDatabaseSizeForShard, getDatabaseSizesAllShards, getShardStats, getTotalDatabaseSize, index, indexAllShards, indexShard, initialize, initializeAsync, listKnownShards, prepare, reassignShard, resetConfig, run, runAllShards, runShard } from './router';
|
|
12
|
-
export type { CreateIndexOptions, ExplainOptions, GlobalAllShardsOptions, IndexColumnDefinition, ShardSizeResult, ShardTableCount } from './router';
|
|
11
|
+
export { all, allAllShards, allAllShardsGlobal, allByLookupKey, allShard, collegedb, count, countAllShards, countShard, createSchema, explain, explainAllShards, explainShard, first, firstAllShards, firstAllShardsGlobal, firstByLookupKey, firstShard, flush, getClosestRegionFromIP, getDatabaseSizeForKey, getDatabaseSizeForShard, getDatabaseSizesAllShards, getShardStats, getTotalDatabaseSize, index, indexAllShards, indexShard, initialize, initializeAsync, insert, insertShard, listKnownShards, prepare, reassignShard, resetConfig, run, runAllShards, runShard } from './router';
|
|
12
|
+
export type { CreateIndexOptions, ExplainOptions, GlobalAllShardsOptions, IndexColumnDefinition, InsertResult, ShardSizeResult, ShardTableCount } from './router';
|
|
13
13
|
export { ShardCoordinator } from './durable';
|
|
14
14
|
export { CollegeDBError } from './errors';
|
|
15
15
|
export { KVShardMapper } from './kvmap';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACN,GAAG,EACH,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,KAAK,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,KAAK,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,OAAO,EACP,aAAa,EACb,WAAW,EACX,GAAG,EACH,YAAY,EACZ,QAAQ,EACR,MAAM,UAAU,CAAC;AAElB,YAAY,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACN,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,EAC7B,wBAAwB,EACxB,2BAA2B,EAC3B,kCAAkC,EAClC,UAAU,EACV,yBAAyB,EACzB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACX,eAAe,EACf,QAAQ,EACR,GAAG,EACH,YAAY,EACZ,SAAS,EACT,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACN,GAAG,EACH,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,SAAS,EACT,KAAK,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,KAAK,EACL,sBAAsB,EACtB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,eAAe,EACf,MAAM,EACN,WAAW,EACX,eAAe,EACf,OAAO,EACP,aAAa,EACb,WAAW,EACX,GAAG,EACH,YAAY,EACZ,QAAQ,EACR,MAAM,UAAU,CAAC;AAElB,YAAY,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EACN,wBAAwB,EACxB,6BAA6B,EAC7B,gCAAgC,EAChC,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,EAC7B,wBAAwB,EACxB,2BAA2B,EAC3B,kCAAkC,EAClC,UAAU,EACV,yBAAyB,EACzB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACX,eAAe,EACf,QAAQ,EACR,GAAG,EACH,YAAY,EACZ,SAAS,EACT,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
var $J=Object.defineProperty;var XJ=(G)=>G;function WJ(G,J){this[G]=XJ.bind(null,J)}var vG=(G,J)=>{for(var Y in J)$J(G,Y,{get:J[Y],enumerable:!0,configurable:!0,set:WJ.bind(J,Y)})};var $G=(G,J)=>()=>(G&&(J=G(G=0)),J);var F;var q=$G(()=>{F=class F extends Error{code;constructor(G,J){super(G);if(this.name="CollegeDBError",this.code=J,Error.captureStackTrace)Error.captureStackTrace(this,F)}}});var XG={};vG(XG,{KVShardMapper:()=>S});class S{kv;hashKeys;hashCache=new Map;mappingCache=new Map;knownShardsCache={shards:null,expiresAt:0};mappingCacheTtlMs;knownShardsCacheTtlMs;constructor(G,J={}){this.kv=G,this.hashKeys=J.hashShardMappings??!0,this.mappingCacheTtlMs=J.mappingCacheTtlMs??HJ,this.knownShardsCacheTtlMs=J.knownShardsCacheTtlMs??OJ}getCachedMapping(G){let J=this.mappingCache.get(G);if(!J)return;if(J.expiresAt<Date.now()){this.mappingCache.delete(G);return}return J.mapping}setCachedMapping(G,J){if(this.mappingCache.size>50000){let Y=this.mappingCache.keys().next().value;if(Y)this.mappingCache.delete(Y)}this.mappingCache.set(G,{mapping:J,expiresAt:Date.now()+this.mappingCacheTtlMs})}async cacheMappingForKeys(G,J){let Y=await Promise.all(G.map((Z)=>this.hashKey(Z)));for(let Z of Y)this.setCachedMapping(Z,J)}getCachedKnownShards(){if(this.knownShardsCache.shards&&this.knownShardsCache.expiresAt>=Date.now())return[...this.knownShardsCache.shards];return null}setCachedKnownShards(G){this.knownShardsCache.shards=[...G],this.knownShardsCache.expiresAt=Date.now()+this.knownShardsCacheTtlMs}async hashKey(G){if(!this.hashKeys)return G;let J=this.hashCache.get(G);if(J)return J;let Z=new TextEncoder().encode(G),$=await crypto.subtle.digest("SHA-256",Z),X=new Uint8Array($),W=Array.from(X).map((H)=>H.toString(16).padStart(2,"0")).join("");if(this.hashCache.size<1e4)this.hashCache.set(G,W);return W}async getShardMapping(G){let J=await this.hashKey(G),Y=this.getCachedMapping(J);if(Y!==void 0)return Y;let Z=`${M}${J}`,$=await this.kv.get(Z,"json");if($)return this.setCachedMapping(J,$),$;let X=await this.kv.get(`${N}${J}`,"json");if(X){let W={shard:X.shard,createdAt:X.createdAt,updatedAt:X.updatedAt,originalKey:this.hashKeys?void 0:G};if(this.setCachedMapping(J,W),this.hashKeys)for(let H of X.keys)this.setCachedMapping(H,W);return W}return this.setCachedMapping(J,null),null}async setShardMapping(G,J,Y=[]){let Z=[G,...Y],$=Date.now(),X={shard:J,createdAt:$,updatedAt:$,originalKey:this.hashKeys?void 0:G};if(Z.length===1){let W=await this.hashKey(G),H=`${M}${W}`;await this.kv.put(H,JSON.stringify(X)),this.setCachedMapping(W,X)}else{let W=await this.hashKey(G),H=`${N}${W}`,O=this.hashKeys?await Promise.all(Z.map((V)=>this.hashKey(V))):Z,U={shard:J,createdAt:$,updatedAt:$,keys:O};await this.kv.put(H,JSON.stringify(U));let _=Z.map(async(V)=>{let L=await this.hashKey(V),I=`${M}${L}`,P={shard:J,createdAt:$,updatedAt:$,originalKey:this.hashKeys?void 0:V};return this.kv.put(I,JSON.stringify(P))});await Promise.all(_),await this.cacheMappingForKeys(Z,X)}}async updateShardMapping(G,J){let Y=await this.getShardMapping(G);if(!Y)throw new F(`No existing mapping found for primary key: ${G}`,"MAPPING_NOT_FOUND");let Z=await this.hashKey(G),$=`${M}${Z}`,X=`${N}${Z}`,W=await this.kv.get(X,"json");if(W){let H=Date.now(),O={...W,shard:J,updatedAt:H};await this.kv.put(X,JSON.stringify(O));let U=W.keys.length>0?this.hashKeys?W.keys:W.keys:[await this.hashKey(G)],_=U.map(async(L)=>{let I=`${M}${L}`,P={...Y,shard:J,updatedAt:H};return this.kv.put(I,JSON.stringify(P))});await Promise.all(_);let V={...Y,shard:J,updatedAt:H};if(this.hashKeys)for(let L of U)this.setCachedMapping(L,V);this.setCachedMapping(Z,V)}else{let H={...Y,shard:J,updatedAt:Date.now()};await this.kv.put($,JSON.stringify(H)),this.setCachedMapping(Z,H)}}async deleteShardMapping(G){let J=await this.hashKey(G),Y=`${M}${J}`,Z=`${N}${J}`,$=await this.kv.get(Z,"json");if($){await this.kv.delete(Z);let X=$.keys.length>0?this.hashKeys?$.keys:$.keys:[await this.hashKey(G)],W=X.map(async(H)=>{let O=`${M}${H}`;return this.kv.delete(O)});if(await Promise.all(W),this.hashKeys)for(let H of X)this.setCachedMapping(H,null);this.setCachedMapping(J,null)}else await this.kv.delete(Y),this.setCachedMapping(J,null)}async getKnownShards(){let G=this.getCachedKnownShards();if(G)return G;let Y=await this.kv.get(zG,"json")||[];return this.setCachedKnownShards(Y),Y}async setKnownShards(G){if(!G||G.length===0)return;let J=[...new Set(G.filter(Boolean))];if(J.length===0)return;await this.kv.put(zG,JSON.stringify(J)),this.setCachedKnownShards(J)}async addKnownShard(G){if(!G)return;let J=await this.getKnownShards();if(!J.includes(G))J.push(G),await this.setKnownShards(J)}async getKeysForShard(G){let J=[],Y=await this.kv.list({prefix:M});for(let $ of Y.keys){let X=await this.kv.get($.name,"json");if(X?.shard===G){let W=$.name.replace(M,"");if(X.originalKey)J.push(X.originalKey);else if(!this.hashKeys)J.push(W)}}let Z=await this.kv.list({prefix:N});for(let $ of Z.keys){let X=await this.kv.get($.name,"json");if(X?.shard===G)J.push(...X.keys)}return[...new Set(J)]}async getShardKeyCounts(){let G={},J=await this.kv.list({prefix:M});for(let Z of J.keys){let $=await this.kv.get(Z.name,"json");if($)G[$.shard]=(G[$.shard]||0)+1}let Y=await this.kv.list({prefix:N});for(let Z of Y.keys){let $=await this.kv.get(Z.name,"json");if($)G[$.shard]=(G[$.shard]||0)+$.keys.length}return G}async clearAllMappings(){let J=(await this.kv.list({prefix:M})).keys.map(($)=>this.kv.delete($.name)),Z=(await this.kv.list({prefix:N})).keys.map(($)=>this.kv.delete($.name));await Promise.all([...J,...Z]),this.mappingCache.clear()}async addLookupKeys(G,J){let Y=await this.getShardMapping(G);if(!Y)throw new F(`No existing mapping found for primary key: ${G}`,"MAPPING_NOT_FOUND");let Z=await this.hashKey(G),$=`${N}${Z}`,X=await this.kv.get($,"json"),W=[G,...J],H=Date.now();if(!X){let _=this.hashKeys?await Promise.all(W.map((V)=>this.hashKey(V))):W;X={shard:Y.shard,createdAt:Y.createdAt,updatedAt:H,keys:_}}else{let _=this.hashKeys?await Promise.all(W.map((V)=>this.hashKey(V))):W;X={...X,updatedAt:H,keys:[...new Set([...X.keys,..._])]}}await this.kv.put($,JSON.stringify(X));let O=J.map(async(_)=>{let V=await this.hashKey(_),L=`${M}${V}`,I={shard:Y.shard,createdAt:Y.createdAt,updatedAt:H,originalKey:this.hashKeys?void 0:_};return this.kv.put(L,JSON.stringify(I))});await Promise.all(O);let U={shard:Y.shard,createdAt:Y.createdAt,updatedAt:H,originalKey:Y.originalKey};await this.cacheMappingForKeys([G,...J],U)}async setShardMappingsBatch(G,J={}){if(G.length===0)return;let Y=Math.max(1,J.concurrency??25),Z=0,$=Array(Math.min(Y,G.length)).fill(null).map(async()=>{while(Z<G.length){let X=Z++,W=G[X];if(!W)continue;await this.setShardMapping(W.primaryKey,W.shard,W.additionalKeys||[])}});await Promise.all($)}async getAllLookupKeys(G){let J=await this.hashKey(G),Y=`${N}${J}`,Z=await this.kv.get(Y,"json");if(Z)return Z.keys;let $=await this.getShardMapping(G);if($)return $.originalKey?[$.originalKey]:[G];throw new F(`No mapping found for key: ${G}`,"MAPPING_NOT_FOUND")}}var M="shard:",N="multikey:",zG="known_shards",HJ=30000,OJ=1e4;var u=$G(()=>{q()});var t={};vG(t,{validateTableForSharding:()=>s,schemaExists:()=>OG,migrateRecord:()=>NG,listTables:()=>h,integrateExistingDatabase:()=>kG,dropSchema:()=>wG,discoverExistingRecordsWithColumns:()=>i,discoverExistingPrimaryKeys:()=>l,createSchemaAcrossShards:()=>BG,createSchema:()=>HG,createMappingsForExistingKeys:()=>CG,clearShardMigrationCache:()=>fG,clearMigrationCache:()=>KG,checkMigrationNeeded:()=>SG,autoDetectAndMigrate:()=>qG});async function MG(G,J,Y){if(G.length===0)return;let Z=Math.max(1,Math.min(J,G.length)),$=0,X=Array(Z).fill(null).map(async()=>{while($<G.length){let W=$++,H=G[W];if(H===void 0)continue;await Y(H,W)}});await Promise.all(X)}function UJ(G,J,Y,Z){let $=Y.length;switch(Z){case"hash":{let X=0;for(let H=0;H<G.length;H++){let O=G.charCodeAt(H);X=(X<<5)-X+O,X=X&X}let W=Math.abs(X)%$;return Y[W]}case"random":return Y[Math.floor(Math.random()*$)];default:return Y[J%$]}}async function HG(G,J){let Y=J.split(";").map((Z)=>Z.trim()).filter((Z)=>Z.length>0&&!Z.startsWith("--"));for(let Z of Y)try{await G.prepare(Z).run()}catch($){throw console.error("Failed to execute schema statement:",Z,$),new F(`Schema migration failed: ${$}`,"SCHEMA_MIGRATION_FAILED")}}async function BG(G,J){let Y=Object.entries(G).map(([Z,$])=>{return HG($,J).catch((X)=>{throw new F(`Failed to create schema on shard ${Z}: ${X.message}`,"SCHEMA_CREATION_FAILED")})});await Promise.all(Y)}async function OG(G,J){try{return await G.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind(J).first()!==null}catch{return!1}}async function wG(G,...J){for(let Y of J)try{await G.prepare(`DROP TABLE IF EXISTS ${Y}`).run()}catch(Z){console.error(`Failed to drop table ${Y}:`,Z)}}async function h(G){try{return(await G.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all()).results.map((Y)=>Y.name)}catch{return[]}}async function NG(G,J,Y,Z){let $=await G.prepare(`SELECT * FROM ${Z} WHERE id = ?`).bind(Y).first();if(!$)throw new F(`Record with primary key ${Y} not found in source database`,"RECORD_NOT_FOUND");if(!await OG(J,Z))await HG(J,Z);let X=Object.keys($),W=X.map(()=>"?").join(", "),H=X.map((U)=>$[U]),O=`INSERT OR REPLACE INTO ${Z} (${X.join(", ")}) VALUES (${W})`;await J.prepare(O).bind(...H).run(),await G.prepare(`DELETE FROM ${Z} WHERE id = ?`).bind(Y).run()}async function l(G,J,Y="id"){try{return(await G.prepare(`SELECT ${Y} FROM ${J}`).all()).results.map(($)=>String($[Y]))}catch(Z){throw new F(`Failed to discover primary keys in table ${J}: ${Z}`,"DISCOVERY_FAILED")}}async function i(G,J,Y="id"){try{let Z=`${J}_columns`,$;if(WG.has(Z))$=WG.get(Z).map((O)=>O.name);else{let U=(await G.prepare(`PRAGMA table_info(${J})`).all()).results.map((_)=>({name:_.name,type:_.type}));WG.set(Z,U),$=U.map((_)=>_.name)}let X=[Y];if($.includes("username"))X.push("username");if($.includes("email"))X.push("email");if($.includes("name"))X.push("name");let W=`SELECT ${X.join(", ")} FROM ${J}`;return(await G.prepare(W).all()).results}catch(Z){throw new F(`Failed to discover records with columns in table ${J}: ${Z}`,"DISCOVERY_FAILED")}}async function CG(G,J,Y,Z,$={}){if(G.length===0||J.length===0)return;let X=Math.max(1,$.concurrency??25),W=G.map((H,O)=>({primaryKey:H,shard:UJ(H,O,J,Y)}));await Z.setShardMappingsBatch(W,{concurrency:X})}async function s(G,J,Y){let Z=[],$=0;try{if(!await G.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind(J).first())return Z.push(`Table '${J}' does not exist`),{isValid:!1,tableName:J,primaryKeyColumn:Y,recordCount:0,issues:Z};if(!(await G.prepare(`PRAGMA table_info(${J})`).all()).results.some((U)=>U.name===Y&&U.pk===1))Z.push(`Primary key column '${Y}' not found or not set as primary key`);if($=(await G.prepare(`SELECT COUNT(*) as count FROM ${J}`).first())?.count||0,$===0)Z.push(`Table '${J}' is empty`)}catch(X){Z.push(`Database validation error: ${X}`)}return{isValid:Z.length===0,tableName:J,primaryKeyColumn:Y,recordCount:$,issues:Z}}async function kG(G,J,Y,Z={}){let{tables:$,primaryKeyColumn:X="id",strategy:W="hash",addShardMappingsTable:H=!0,dryRun:O=!1,migrateOtherColumns:U=!1,concurrency:_=25}=Z,V=Math.max(1,_),L=[],I=0,P=0,x=0;try{let A=($||await h(G)).filter((j)=>j!=="shard_mappings");for(let j of A)try{let R=await s(G,j,X);if(!R.isValid){L.push(`Table ${j}: ${R.issues.join(", ")}`);continue}if(U){let D=await i(G,j,X);if(D.length===0){L.push(`Table ${j} has no records to process`);continue}if(!O){let E=D.map((Q)=>{let YG=String(Q[X]),b=[];if(Q.username&&typeof Q.username==="string")b.push(`username:${Q.username}`);if(Q.email&&typeof Q.email==="string")b.push(`email:${Q.email}`);if(Q.name&&typeof Q.name==="string")b.push(`name:${Q.name}`);return{primaryKey:YG,shard:J,additionalKeys:b}});await Y.setShardMappingsBatch(E,{concurrency:V}),x+=E.length}P+=D.length}else{let D=await l(G,j,X);if(D.length===0){L.push(`Table ${j} has no records to process`);continue}if(!O){let E=D.map((Q)=>({primaryKey:Q,shard:J}));await Y.setShardMappingsBatch(E,{concurrency:V}),x+=E.length}P+=D.length}I++}catch(R){L.push(`Failed to process table ${j}: ${R}`)}if(H&&!O){if(!(await h(G)).includes("shard_mappings"))await G.prepare(`
|
|
1
|
+
var UJ=Object.defineProperty;var _J=(G)=>G;function OJ(G,J){this[G]=_J.bind(null,J)}var zG=(G,J)=>{for(var Y in J)UJ(G,Y,{get:J[Y],enumerable:!0,configurable:!0,set:OJ.bind(J,Y)})};var WG=(G,J)=>()=>(G&&(J=G(G=0)),J);var F;var q=WG(()=>{F=class F extends Error{code;constructor(G,J){super(G);if(this.name="CollegeDBError",this.code=J,Error.captureStackTrace)Error.captureStackTrace(this,F)}}});var HG={};zG(HG,{KVShardMapper:()=>S});class S{kv;hashKeys;hashCache=new Map;mappingCache=new Map;knownShardsCache={shards:null,expiresAt:0};mappingCacheTtlMs;knownShardsCacheTtlMs;constructor(G,J={}){this.kv=G,this.hashKeys=J.hashShardMappings??!0,this.mappingCacheTtlMs=J.mappingCacheTtlMs??FJ,this.knownShardsCacheTtlMs=J.knownShardsCacheTtlMs??VJ}getCachedMapping(G){let J=this.mappingCache.get(G);if(!J)return;if(J.expiresAt<Date.now()){this.mappingCache.delete(G);return}return J.mapping}setCachedMapping(G,J){if(this.mappingCache.size>50000){let Y=this.mappingCache.keys().next().value;if(Y)this.mappingCache.delete(Y)}this.mappingCache.set(G,{mapping:J,expiresAt:Date.now()+this.mappingCacheTtlMs})}async cacheMappingForKeys(G,J){let Y=await Promise.all(G.map((Z)=>this.hashKey(Z)));for(let Z of Y)this.setCachedMapping(Z,J)}getCachedKnownShards(){if(this.knownShardsCache.shards&&this.knownShardsCache.expiresAt>=Date.now())return[...this.knownShardsCache.shards];return null}setCachedKnownShards(G){this.knownShardsCache.shards=[...G],this.knownShardsCache.expiresAt=Date.now()+this.knownShardsCacheTtlMs}async hashKey(G){if(!this.hashKeys)return G;let J=this.hashCache.get(G);if(J)return J;let Z=new TextEncoder().encode(G),$=await crypto.subtle.digest("SHA-256",Z),X=new Uint8Array($),W=Array.from(X).map((H)=>H.toString(16).padStart(2,"0")).join("");if(this.hashCache.size<1e4)this.hashCache.set(G,W);return W}async getShardMapping(G){let J=await this.hashKey(G),Y=this.getCachedMapping(J);if(Y!==void 0)return Y;let Z=`${N}${J}`,$=await this.kv.get(Z,"json");if($)return this.setCachedMapping(J,$),$;let X=await this.kv.get(`${C}${J}`,"json");if(X){let W={shard:X.shard,createdAt:X.createdAt,updatedAt:X.updatedAt,originalKey:this.hashKeys?void 0:G};if(this.setCachedMapping(J,W),this.hashKeys)for(let H of X.keys)this.setCachedMapping(H,W);return W}return this.setCachedMapping(J,null),null}async setShardMapping(G,J,Y=[]){let Z=[G,...Y],$=Date.now(),X={shard:J,createdAt:$,updatedAt:$,originalKey:this.hashKeys?void 0:G};if(Z.length===1){let W=await this.hashKey(G),H=`${N}${W}`;await this.kv.put(H,JSON.stringify(X)),this.setCachedMapping(W,X)}else{let W=await this.hashKey(G),H=`${C}${W}`,U=this.hashKeys?await Promise.all(Z.map((V)=>this.hashKey(V))):Z,_={shard:J,createdAt:$,updatedAt:$,keys:U};await this.kv.put(H,JSON.stringify(_));let O=Z.map(async(V)=>{let A=await this.hashKey(V),P=`${N}${A}`,Q={shard:J,createdAt:$,updatedAt:$,originalKey:this.hashKeys?void 0:V};return this.kv.put(P,JSON.stringify(Q))});await Promise.all(O),await this.cacheMappingForKeys(Z,X)}}async updateShardMapping(G,J){let Y=await this.getShardMapping(G);if(!Y)throw new F(`No existing mapping found for primary key: ${G}`,"MAPPING_NOT_FOUND");let Z=await this.hashKey(G),$=`${N}${Z}`,X=`${C}${Z}`,W=await this.kv.get(X,"json");if(W){let H=Date.now(),U={...W,shard:J,updatedAt:H};await this.kv.put(X,JSON.stringify(U));let _=W.keys.length>0?this.hashKeys?W.keys:W.keys:[await this.hashKey(G)],O=_.map(async(A)=>{let P=`${N}${A}`,Q={...Y,shard:J,updatedAt:H};return this.kv.put(P,JSON.stringify(Q))});await Promise.all(O);let V={...Y,shard:J,updatedAt:H};if(this.hashKeys)for(let A of _)this.setCachedMapping(A,V);this.setCachedMapping(Z,V)}else{let H={...Y,shard:J,updatedAt:Date.now()};await this.kv.put($,JSON.stringify(H)),this.setCachedMapping(Z,H)}}async deleteShardMapping(G){let J=await this.hashKey(G),Y=`${N}${J}`,Z=`${C}${J}`,$=await this.kv.get(Z,"json");if($){await this.kv.delete(Z);let X=$.keys.length>0?this.hashKeys?$.keys:$.keys:[await this.hashKey(G)],W=X.map(async(H)=>{let U=`${N}${H}`;return this.kv.delete(U)});if(await Promise.all(W),this.hashKeys)for(let H of X)this.setCachedMapping(H,null);this.setCachedMapping(J,null)}else await this.kv.delete(Y),this.setCachedMapping(J,null)}async getKnownShards(){let G=this.getCachedKnownShards();if(G)return G;let Y=await this.kv.get(NG,"json")||[];return this.setCachedKnownShards(Y),Y}async setKnownShards(G){if(!G||G.length===0)return;let J=[...new Set(G.filter(Boolean))];if(J.length===0)return;await this.kv.put(NG,JSON.stringify(J)),this.setCachedKnownShards(J)}async addKnownShard(G){if(!G)return;let J=await this.getKnownShards();if(!J.includes(G))J.push(G),await this.setKnownShards(J)}async getKeysForShard(G){let J=[],Y=await this.kv.list({prefix:N});for(let $ of Y.keys){let X=await this.kv.get($.name,"json");if(X?.shard===G){let W=$.name.replace(N,"");if(X.originalKey)J.push(X.originalKey);else if(!this.hashKeys)J.push(W)}}let Z=await this.kv.list({prefix:C});for(let $ of Z.keys){let X=await this.kv.get($.name,"json");if(X?.shard===G)J.push(...X.keys)}return[...new Set(J)]}async getShardKeyCounts(){let G={},J=await this.kv.list({prefix:N});for(let Z of J.keys){let $=await this.kv.get(Z.name,"json");if($)G[$.shard]=(G[$.shard]||0)+1}let Y=await this.kv.list({prefix:C});for(let Z of Y.keys){let $=await this.kv.get(Z.name,"json");if($)G[$.shard]=(G[$.shard]||0)+$.keys.length}return G}async clearAllMappings(){let J=(await this.kv.list({prefix:N})).keys.map(($)=>this.kv.delete($.name)),Z=(await this.kv.list({prefix:C})).keys.map(($)=>this.kv.delete($.name));await Promise.all([...J,...Z]),this.mappingCache.clear()}async addLookupKeys(G,J){let Y=await this.getShardMapping(G);if(!Y)throw new F(`No existing mapping found for primary key: ${G}`,"MAPPING_NOT_FOUND");let Z=await this.hashKey(G),$=`${C}${Z}`,X=await this.kv.get($,"json"),W=[G,...J],H=Date.now();if(!X){let O=this.hashKeys?await Promise.all(W.map((V)=>this.hashKey(V))):W;X={shard:Y.shard,createdAt:Y.createdAt,updatedAt:H,keys:O}}else{let O=this.hashKeys?await Promise.all(W.map((V)=>this.hashKey(V))):W;X={...X,updatedAt:H,keys:[...new Set([...X.keys,...O])]}}await this.kv.put($,JSON.stringify(X));let U=J.map(async(O)=>{let V=await this.hashKey(O),A=`${N}${V}`,P={shard:Y.shard,createdAt:Y.createdAt,updatedAt:H,originalKey:this.hashKeys?void 0:O};return this.kv.put(A,JSON.stringify(P))});await Promise.all(U);let _={shard:Y.shard,createdAt:Y.createdAt,updatedAt:H,originalKey:Y.originalKey};await this.cacheMappingForKeys([G,...J],_)}async setShardMappingsBatch(G,J={}){if(G.length===0)return;let Y=Math.max(1,J.concurrency??25),Z=0,$=Array(Math.min(Y,G.length)).fill(null).map(async()=>{while(Z<G.length){let X=Z++,W=G[X];if(!W)continue;await this.setShardMapping(W.primaryKey,W.shard,W.additionalKeys||[])}});await Promise.all($)}async getAllLookupKeys(G){let J=await this.hashKey(G),Y=`${C}${J}`,Z=await this.kv.get(Y,"json");if(Z)return Z.keys;let $=await this.getShardMapping(G);if($)return $.originalKey?[$.originalKey]:[G];throw new F(`No mapping found for key: ${G}`,"MAPPING_NOT_FOUND")}}var N="shard:",C="multikey:",NG="known_shards",FJ=30000,VJ=1e4;var g=WG(()=>{q()});var a={};zG(a,{validateTableForSharding:()=>t,schemaExists:()=>OG,migrateRecord:()=>CG,listTables:()=>h,integrateExistingDatabase:()=>qG,dropSchema:()=>wG,discoverExistingRecordsWithColumns:()=>i,discoverExistingPrimaryKeys:()=>s,createSchemaAcrossShards:()=>vG,createSchema:()=>_G,createMappingsForExistingKeys:()=>kG,clearShardMigrationCache:()=>bG,clearMigrationCache:()=>fG,checkMigrationNeeded:()=>KG,autoDetectAndMigrate:()=>SG});async function BG(G,J,Y){if(G.length===0)return;let Z=Math.max(1,Math.min(J,G.length)),$=0,X=Array(Z).fill(null).map(async()=>{while($<G.length){let W=$++,H=G[W];if(H===void 0)continue;await Y(H,W)}});await Promise.all(X)}function AJ(G,J,Y,Z){let $=Y.length;switch(Z){case"hash":{let X=0;for(let H=0;H<G.length;H++){let U=G.charCodeAt(H);X=(X<<5)-X+U,X=X&X}let W=Math.abs(X)%$;return Y[W]}case"random":return Y[Math.floor(Math.random()*$)];default:return Y[J%$]}}async function _G(G,J){let Y=J.split(";").map((Z)=>Z.trim()).filter((Z)=>Z.length>0&&!Z.startsWith("--"));for(let Z of Y)try{await G.prepare(Z).run()}catch($){throw console.error("Failed to execute schema statement:",Z,$),new F(`Schema migration failed: ${$}`,"SCHEMA_MIGRATION_FAILED")}}async function vG(G,J){let Y=Object.entries(G).map(([Z,$])=>{return _G($,J).catch((X)=>{throw new F(`Failed to create schema on shard ${Z}: ${X.message}`,"SCHEMA_CREATION_FAILED")})});await Promise.all(Y)}async function OG(G,J){try{return await G.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind(J).first()!==null}catch{return!1}}async function wG(G,...J){for(let Y of J)try{await G.prepare(`DROP TABLE IF EXISTS ${Y}`).run()}catch(Z){console.error(`Failed to drop table ${Y}:`,Z)}}async function h(G){try{return(await G.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all()).results.map((Y)=>Y.name)}catch{return[]}}async function CG(G,J,Y,Z){let $=await G.prepare(`SELECT * FROM ${Z} WHERE id = ?`).bind(Y).first();if(!$)throw new F(`Record with primary key ${Y} not found in source database`,"RECORD_NOT_FOUND");if(!await OG(J,Z))await _G(J,Z);let X=Object.keys($),W=X.map(()=>"?").join(", "),H=X.map((_)=>$[_]),U=`INSERT OR REPLACE INTO ${Z} (${X.join(", ")}) VALUES (${W})`;await J.prepare(U).bind(...H).run(),await G.prepare(`DELETE FROM ${Z} WHERE id = ?`).bind(Y).run()}async function s(G,J,Y="id"){try{return(await G.prepare(`SELECT ${Y} FROM ${J}`).all()).results.map(($)=>String($[Y]))}catch(Z){throw new F(`Failed to discover primary keys in table ${J}: ${Z}`,"DISCOVERY_FAILED")}}async function i(G,J,Y="id"){try{let Z=`${J}_columns`,$;if(UG.has(Z))$=UG.get(Z).map((U)=>U.name);else{let _=(await G.prepare(`PRAGMA table_info(${J})`).all()).results.map((O)=>({name:O.name,type:O.type}));UG.set(Z,_),$=_.map((O)=>O.name)}let X=[Y];if($.includes("username"))X.push("username");if($.includes("email"))X.push("email");if($.includes("name"))X.push("name");let W=`SELECT ${X.join(", ")} FROM ${J}`;return(await G.prepare(W).all()).results}catch(Z){throw new F(`Failed to discover records with columns in table ${J}: ${Z}`,"DISCOVERY_FAILED")}}async function kG(G,J,Y,Z,$={}){if(G.length===0||J.length===0)return;let X=Math.max(1,$.concurrency??25),W=G.map((H,U)=>({primaryKey:H,shard:AJ(H,U,J,Y)}));await Z.setShardMappingsBatch(W,{concurrency:X})}async function t(G,J,Y){let Z=[],$=0;try{if(!await G.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name=?").bind(J).first())return Z.push(`Table '${J}' does not exist`),{isValid:!1,tableName:J,primaryKeyColumn:Y,recordCount:0,issues:Z};if(!(await G.prepare(`PRAGMA table_info(${J})`).all()).results.some((_)=>_.name===Y&&_.pk===1))Z.push(`Primary key column '${Y}' not found or not set as primary key`);if($=(await G.prepare(`SELECT COUNT(*) as count FROM ${J}`).first())?.count||0,$===0)Z.push(`Table '${J}' is empty`)}catch(X){Z.push(`Database validation error: ${X}`)}return{isValid:Z.length===0,tableName:J,primaryKeyColumn:Y,recordCount:$,issues:Z}}async function qG(G,J,Y,Z={}){let{tables:$,primaryKeyColumn:X="id",strategy:W="hash",addShardMappingsTable:H=!0,dryRun:U=!1,migrateOtherColumns:_=!1,concurrency:O=25}=Z,V=Math.max(1,O),A=[],P=0,Q=0,x=0;try{let L=($||await h(G)).filter((j)=>j!=="shard_mappings");for(let j of L)try{let R=await t(G,j,X);if(!R.isValid){A.push(`Table ${j}: ${R.issues.join(", ")}`);continue}if(_){let D=await i(G,j,X);if(D.length===0){A.push(`Table ${j} has no records to process`);continue}if(!U){let E=D.map((I)=>{let $G=String(I[X]),b=[];if(I.username&&typeof I.username==="string")b.push(`username:${I.username}`);if(I.email&&typeof I.email==="string")b.push(`email:${I.email}`);if(I.name&&typeof I.name==="string")b.push(`name:${I.name}`);return{primaryKey:$G,shard:J,additionalKeys:b}});await Y.setShardMappingsBatch(E,{concurrency:V}),x+=E.length}Q+=D.length}else{let D=await s(G,j,X);if(D.length===0){A.push(`Table ${j} has no records to process`);continue}if(!U){let E=D.map((I)=>({primaryKey:I,shard:J}));await Y.setShardMappingsBatch(E,{concurrency:V}),x+=E.length}Q+=D.length}P++}catch(R){A.push(`Failed to process table ${j}: ${R}`)}if(H&&!U){if(!(await h(G)).includes("shard_mappings"))await G.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(!
|
|
7
|
+
);`.trim()).run()}if(!U)await Y.addKnownShard(J)}catch(w){A.push(`Integration failed: ${w}`)}return{success:A.length===0||A.length>0&&P>0,shardName:J,tablesProcessed:P,totalRecords:Q,mappingsCreated:x,issues:A}}async function SG(G,J,Y,Z={}){let{primaryKeyColumn:$="id",tablesToCheck:X,skipCache:W=!1,maxRecordsToCheck:H=1000,migrateOtherColumns:U=!1,concurrency:_=Y.migrationConcurrency??25}=Z,O=Math.max(1,_),V=`${J}_migration_check`;if(!W&&K.has(V))return{migrationNeeded:!1,migrationPerformed:!1,recordsMigrated:0,tablesProcessed:0,issues:[]};let A=[],P=0,Q=0,x=!1,w=!1;try{let{KVShardMapper:L}=await Promise.resolve().then(() => (g(),HG)),j=new L(Y.kv,{hashShardMappings:Y.hashShardMappings,mappingCacheTtlMs:Y.mappingCacheTtlMs,knownShardsCacheTtlMs:Y.knownShardsCacheTtlMs}),R=await h(G),D=X||R.filter((E)=>E!=="shard_mappings"&&!E.startsWith("sqlite_")&&E!=="sqlite_sequence");if(D.length===0)return K.set(V,!0),{migrationNeeded:!1,migrationPerformed:!1,recordsMigrated:0,tablesProcessed:0,issues:[]};for(let E of D)try{let I=await t(G,E,$);if(!I.isValid||I.recordCount===0)continue;let $G=Math.min(H,I.recordCount),b=await G.prepare(`
|
|
8
8
|
SELECT ${$} FROM ${E}
|
|
9
9
|
ORDER BY ${$}
|
|
10
|
-
LIMIT ?`.trim()).bind(
|
|
10
|
+
LIMIT ?`.trim()).bind($G).all(),MG=0,WJ=b.results.slice(0,10).map(async(k)=>{let z=String(k[$]);return{key:z,mapping:await j.getShardMapping(z)}}),HJ=await Promise.all(WJ);for(let k of HJ)if(!k.mapping)MG++,x=!0;if(MG>0){if(Y.debug)console.log(`Auto-migrating table ${E} in shard ${J} (${I.recordCount} records)`);if(U){let k=await i(G,E,$),z=[];if(await BG(k,O,async(M)=>{let XG=String(M[$]);if(await j.getShardMapping(XG))return;let l=[];if(M.username&&typeof M.username==="string")l.push(`username:${M.username}`);if(M.email&&typeof M.email==="string")l.push(`email:${M.email}`);if(M.name&&typeof M.name==="string")l.push(`name:${M.name}`);z.push({primaryKey:XG,shard:J,additionalKeys:l})}),z.length>0)await j.setShardMappingsBatch(z,{concurrency:O});P+=z.length}else{let k=await s(G,E,$),z=[];if(await BG(k,O,async(M)=>{if(!await j.getShardMapping(M))z.push({primaryKey:M,shard:J})}),z.length>0)await j.setShardMappingsBatch(z,{concurrency:O});P+=z.length}if(Q++,w=!0,Y.debug)console.log(`Auto-migrated ${P} records from table ${E}`)}}catch(I){A.push(`Auto-migration failed for table ${E}: ${I}`)}if(w){if(await j.addKnownShard(J),!R.includes("shard_mappings"))await G.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(K.set(V,!0),w&&Y.debug)console.log(`Auto-migration completed for shard ${J}: ${I} records from ${P} tables`)}catch(A){L.push(`Auto-migration error: ${A}`)}return{migrationNeeded:x,migrationPerformed:w,recordsMigrated:I,tablesProcessed:P,issues:L}}async function SG(G,J,Y){let Z=`${J}_migration_check`;if(K.has(Z))return!1;try{let $=await h(G);if($.includes("shard_mappings"))return K.set(Z,!0),!1;let{KVShardMapper:W}=await Promise.resolve().then(() => (u(),XG)),H=new W(Y.kv,{hashShardMappings:Y.hashShardMappings,mappingCacheTtlMs:Y.mappingCacheTtlMs,knownShardsCacheTtlMs:Y.knownShardsCacheTtlMs}),O=$.filter((U)=>U!=="shard_mappings"&&!U.startsWith("sqlite_")&&U!=="sqlite_sequence");for(let U of O.slice(0,3))try{if(((await G.prepare(`SELECT COUNT(*) as count FROM ${U} LIMIT 1`).first())?.count||0)>0){let L=await G.prepare(`SELECT id FROM ${U} LIMIT 1`).first();if(L){let I=String(L.id);if(!await H.getShardMapping(I))return!0}}}catch{continue}return!1}catch{return!1}}function KG(){K.clear()}function fG(G){let J=`${G}_migration_check`;K.delete(J)}var K,WG;var g=$G(()=>{q();K=new Map,WG=new Map});q();u();var c=null,p=null,y=new Map;function C(G){if(!p)p=new S(G.kv,{hashShardMappings:G.hashShardMappings,mappingCacheTtlMs:G.mappingCacheTtlMs,knownShardsCacheTtlMs:G.knownShardsCacheTtlMs});return p}function _J(G){c=G,p=new S(G.kv,{hashShardMappings:G.hashShardMappings,mappingCacheTtlMs:G.mappingCacheTtlMs,knownShardsCacheTtlMs:G.knownShardsCacheTtlMs}),y.clear();try{let J=C(G);Promise.resolve().then(async()=>{let Y=await J.getKnownShards(),Z=Array.from(new Set([...Y,...Object.keys(G.shards)]));await J.setKnownShards(Z)}).catch(()=>{return})}catch{}if(G.shards&&Object.keys(G.shards).length>0&&!G.disableAutoMigration)yG(G).catch((J)=>{console.warn("Background auto-migration failed:",J)})}async function pG(G){c=G,p=new S(G.kv,{hashShardMappings:G.hashShardMappings,mappingCacheTtlMs:G.mappingCacheTtlMs,knownShardsCacheTtlMs:G.knownShardsCacheTtlMs}),y.clear();try{let J=C(G),Y=await J.getKnownShards(),Z=Array.from(new Set([...Y,...Object.keys(G.shards)]));await J.setKnownShards(Z)}catch{}if(G.shards&&Object.keys(G.shards).length>0&&!G.disableAutoMigration)try{await yG(G)}catch(J){console.warn("Auto migration failed:",J)}}async function VJ(G,J){return await pG(G),await J()}async function yG(G){try{let{autoDetectAndMigrate:J}=await Promise.resolve().then(() => (g(),t)),Y=Object.keys(G.shards);if(G.debug)console.log(`\uD83D\uDD0D Checking ${Y.length} shards for existing data...`);let Z=Y.map(async(W)=>{let H=G.shards[W];if(!H)return null;try{let O=await J(H,W,G,{maxRecordsToCheck:1000});return{shardName:W,...O}}catch(O){return console.warn(`Auto-migration failed for shard ${W}:`,O),null}}),X=(await Promise.all(Z)).filter((W)=>W?.migrationPerformed);if(G.debug)if(X.length>0){let W=X.reduce((H,O)=>H+(O?.recordsMigrated||0),0);console.log(`\uD83C\uDF89 Auto-migration completed! Migrated ${W} records across ${X.length} shards`),X.forEach((H)=>{if(H)console.log(` ✅ ${H.shardName}: ${H.recordsMigrated} records from ${H.tablesProcessed} tables`)})}else console.log("✅ All shards ready - no migration needed")}catch(J){console.warn("Background auto-migration setup failed:",J)}}function FJ(){c=null,p=null,y.clear()}function T(){if(!c)throw new F("CollegeDB not initialized. Call initialize() first.","NOT_INITIALIZED");return c}function LJ(G){let J=G.trim().toUpperCase();if(J.startsWith("SELECT")||J.startsWith("VALUES")||J.startsWith("TABLE")||J.startsWith("PRAGMA")||J.startsWith("EXPLAIN")||J.startsWith("WITH")||J.startsWith("SHOW"))return"read";return"write"}function AJ(G,J){let Y=G.strategy||"hash";if(typeof Y==="string")return Y;let Z=Y;return Z[J]||Z.write||Z.read||"hash"}function jJ(G,J){if(G===J)return 0;let Y={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=Y[G],$=Y[J],X=Z.lat-$.lat,W=Z.lon-$.lon;return Math.sqrt(X*X+W*W)}function IJ(G){let J=G.cf;if(!J||!J.country)return"wnam";let{country:Y,continent:Z}=J;if(["US","CA","MX"].includes(Y)){let $=J.region||J.regionCode||"",X=J.timezone||"";if($.includes("CA")||$.includes("WA")||$.includes("OR")||$.includes("NV")||$.includes("AZ")||$.includes("UT")||X.includes("Pacific")||X.includes("America/Los_Angeles"))return"wnam";return"enam"}if(["GL","PM","BM"].includes(Y))return"enam";if(["GB","IE","FR","ES","PT","NL","BE","LU","CH","AT","IT"].includes(Y))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(Y))return"eeur";if(Y==="RU")return"eeur";if(["JP","KR","CN","HK","TW","MO","MN","KP"].includes(Y))return"apac";if(["TH","VN","SG","MY","ID","PH","BN","KH","LA","MM","TL","IN","PK","BD","LK","NP","BT","MV","AF"].includes(Y))return"apac";if(["AU","NZ","PG","FJ","NC","VU","SB","WS","TO","KI","NR","PW","FM","MH","TV"].includes(Y))return"oc";if(["AE","SA","QA","KW","BH","OM","YE","IQ","IR","SY","LB","JO","IL","PS","TR","CY"].includes(Y))return"me";if(Z==="AF"||["EG","LY","TN","DZ","MA","SD","SS","ET","ER","DJ","SO"].includes(Y))return"af";if(["KZ","UZ","TM","TJ","KG"].includes(Y))return"eeur";if(Z==="SA"||["BR","AR","CL","PE","CO","VE","EC","BO","PY","UY","GY","SR","GF"].includes(Y))return"enam";if(["GT","BZ","SV","HN","NI","CR","PA","CU","JM","HT","DO","PR","TT","BB","GD","VC","LC","DM","AG","KN"].includes(Y))return"enam";return"wnam"}function PJ(G){if(typeof G==="string")return G;return G.region||"wnam"}async function a(G){try{let[J,Y]=await Promise.all([G.prepare("PRAGMA page_count").first(),G.prepare("PRAGMA page_size").first()]);if(!J?.page_count||!Y?.page_size)throw new F("Failed to retrieve database size information","SIZE_QUERY_FAILED");return J.page_count*Y.page_size}catch(J){throw new F(`Failed to get database size: ${J instanceof Error?J.message:"Unknown error"}`,"SIZE_QUERY_FAILED")}}async function QJ(G,J){let Y=Math.max(0,J.sizeCacheTtlMs??30000),Z=y.get(G);if(Z&&Z.expiresAt>=Date.now())return Z.size;let $=J.shards[G];if(!$)throw new F(`Shard ${G} not found in configuration`,"SHARD_NOT_FOUND");let X=await a($);if(Y>0)y.set(G,{size:X,expiresAt:Date.now()+Y});return X}async function EJ(G,J){if(typeof J.maxDatabaseSize!=="number"||!Number.isFinite(J.maxDatabaseSize)||J.maxDatabaseSize<=0)return G;let Y=J.maxDatabaseSize,$=(await Promise.allSettled(G.map(async(X)=>{let W=await QJ(X,J);return{shard:X,size:W,withinLimit:W<Y}}))).filter((X)=>X.status==="fulfilled"&&X.value.withinLimit).map((X)=>X.value.shard);if($.length===0){if(J.debug)console.warn("All shards exceed maxDatabaseSize limit. Allowing allocation to prevent failure.");return G}if(J.debug&&$.length<G.length){let X=G.filter((W)=>!$.includes(W));console.log(`Excluded ${X.length} shards due to size limits: ${X.join(", ")}`)}return $}function TJ(G,J,Y,Z){let $=J.filter((_)=>Y[_]);if($.length===0){let _=0;for(let L=0;L<Z.length;L++){let I=Z.charCodeAt(L);_=(_<<5)-_+I,_=_&_}let V=Math.abs(_)%J.length;return J[V]}let X=$.map((_)=>{let V=Y[_],L=jJ(G,PJ(V)),I=typeof V==="object"?V.priority||1:1,P=L-I*0.1;return{shard:_,score:P,distance:L,priority:I}});X.sort((_,V)=>_.score-V.score);let W=X[0].score,H=X.filter((_)=>Math.abs(_.score-W)<0.01);if(H.length===1)return H[0].shard;let O=0;for(let _=0;_<Z.length;_++){let V=Z.charCodeAt(_);O=(O<<5)-O+V,O=O&O}let U=Math.abs(O)%H.length;return H[U].shard}function m(G,J,Y,Z){switch(G){case"hash":{let $=0;for(let W=0;W<J.length;W++){let H=J.charCodeAt(W);$=($<<5)-$+H,$=$&$}let X=Math.abs($)%Y.length;return Y[X]||Y[0]}case"location":{if(!Z.targetRegion)return m("hash",J,Y,Z);return TJ(Z.targetRegion,Y,Z.shardLocations||{},J)}case"random":return Y[Math.floor(Math.random()*Y.length)]||Y[0];default:return m("hash",J,Y,Z)}}async function uG(G,J="write"){let Y=T(),Z=C(Y),$=await Z.getShardMapping(G);if($)return $.shard;let X=Object.keys(Y.shards);if(X.length===0)throw new F("No shards configured","NO_SHARDS");let W=await EJ(X,Y),H,O=AJ(Y,J);if(Y.coordinator)try{let U=Y.coordinator.idFromName("default"),V=await Y.coordinator.get(U).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:G,strategy:O,operationType:J,targetRegion:Y.targetRegion,shardLocations:Y.shardLocations,availableShards:W})});if(V.ok)H=(await V.json()).shard;else H=m(O,G,W,Y)}catch(U){console.warn("Coordinator allocation failed, falling back to local strategy:",U),H=m(O,G,W,Y)}else H=m(O,G,W,Y);return await Z.setShardMapping(G,H),H}async function DJ(G,J="write"){let Y=T(),Z=await uG(G,J),$=Y.shards[Z];if(!$)throw new F(`Shard ${Z} not found in configuration`,"SHARD_NOT_FOUND");return $}async function RJ(G,J){let{createSchema:Y}=await Promise.resolve().then(() => (g(),t));await Y(G,J)}async function r(G,J){let Y=LJ(J);return(await DJ(G,Y)).prepare(J)}async function gG(G,J,Y=[]){let $=await(await r(G,J)).bind(...Y).run();if(!$.success)throw new F(`Query failed: ${$.error||"Unknown error"}`,"QUERY_FAILED");return $}async function mG(G,J,Y=[]){let $=await(await r(G,J)).bind(...Y).all();if(!$.success)throw new F(`Query failed: ${$.error||"Unknown error"}`,"QUERY_FAILED");return $}async function cG(G,J,Y=[]){return await(await r(G,J)).bind(...Y).first()}async function xJ(G,J,Y=[],Z=50){let $=T(),W=await C($).getShardMapping(G);if(W){if($.shards[W.shard]){let U=await UG(W.shard,J,Y);if(U.success&&U.results.length>0)return U}}let H=await e(J,Y,Z);return oG(H)}async function vJ(G,J,Y=[],Z=50){let $=T(),W=await C($).getShardMapping(G);if(W){if($.shards[W.shard]){let U=await _G(W.shard,J,Y);if(U!==null)return U}}return(await iG(J,Y,Z)).find((O)=>O!==null)??null}async function zJ(G,J,Y){let Z=T();if(!Z.shards[J])throw new F(`Shard ${J} not found in configuration`,"SHARD_NOT_FOUND");let $=C(Z),X=await $.getShardMapping(G);if(!X)throw new F(`No existing mapping found for primary key: ${G}`,"MAPPING_NOT_FOUND");if(X.shard!==J){let{migrateRecord:W}=await Promise.resolve().then(() => (g(),t)),H=Z.shards[X.shard],O=Z.shards[J];if(!H||!O)throw new F("Source or target shard not available","SHARD_UNAVAILABLE");await W(H,O,G,Y)}await $.updateShardMapping(G,J)}async function MJ(){let G=T();if(G.coordinator)try{let J=G.coordinator.idFromName("default"),Z=await G.coordinator.get(J).fetch("http://coordinator/shards");if(Z.ok)return await Z.json()}catch(J){console.warn("Failed to get shards from coordinator:",J)}try{let Y=await C(G).getKnownShards(),Z=new Set([...Object.keys(G.shards),...Y]);return Array.from(Z)}catch{return Object.keys(G.shards)}}async function BJ(){let G=T();if(G.coordinator)try{let $=G.coordinator.idFromName("default"),W=await G.coordinator.get($).fetch("http://coordinator/stats");if(W.ok)return await W.json()}catch($){console.warn("Failed to get stats from coordinator:",$)}let J=C(G),Y=await J.getShardKeyCounts(),Z=Object.keys(G.shards);try{let $=await J.getKnownShards();Z=Array.from(new Set([...Z,...$]))}catch{}return Z.map(($)=>({binding:$,count:Y[$]||0}))}async function dG(G,J,Y=[]){let $=T().shards[G];if(!$)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");let X=await $.prepare(J).bind(...Y).run();if(!X.success)throw new F(`Query failed: ${X.error||"Unknown error"}`,"QUERY_FAILED");return X}async function UG(G,J,Y=[]){let $=T().shards[G];if(!$)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");return await $.prepare(J).bind(...Y).all()}async function _G(G,J,Y=[]){let $=T().shards[G];if(!$)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");return await $.prepare(J).bind(...Y).first()}async function nG(G,J=[],Y=50){let Z=T(),$=[];for(let[W,H]of Object.entries(Z.shards)){if(!W||!H){console.error(`Shard ${W??"<null>"} not found, skipping`);continue}$.push(()=>H.prepare(G).bind(...J).run().catch((O)=>{return console.error(`Error executing query on shard ${W}:`,O),{success:!1,results:[],error:O instanceof Error?O.message:String(O),meta:{duration:0}}}))}let X=[];for(let W=0;W<$.length;W+=Y){let H=$.slice(W,W+Y).map((O)=>O());X.push(...await Promise.all(H))}return X}async function e(G,J=[],Y=50){let Z=T(),$=[];for(let[W,H]of Object.entries(Z.shards)){if(!W||!H){console.error(`Shard ${W??"<null>"} not found, skipping`);continue}$.push(()=>H.prepare(G).bind(...J).all().catch((O)=>{return console.error(`Error executing query on shard ${W}:`,O),{success:!1,results:[],error:O instanceof Error?O.message:String(O),meta:{duration:0}}}))}let X=[];for(let W=0;W<$.length;W+=Y){let H=$.slice(W,W+Y).map((O)=>O());X.push(...await Promise.all(H))}return X}function d(G,J=50){if(!Number.isFinite(G??J))return J;return Math.max(1,Math.floor(G??J))}function wJ(G){if(!Number.isFinite(G??0))return 0;return Math.max(0,Math.floor(G??0))}function NJ(G){if(G===void 0)return;if(!Number.isFinite(G))return;return Math.max(0,Math.floor(G))}function bG(G,J){if(typeof J==="function")return J(G);if(!J||typeof G!=="object"||G===null)return;return G[String(J)]}function CJ(G,J){if(G===J)return 0;if(G===null||G===void 0)return 1;if(J===null||J===void 0)return-1;if(typeof G==="number"&&typeof J==="number")return G-J;if(typeof G==="bigint"&&typeof J==="bigint")return G<J?-1:1;if(G instanceof Date&&J instanceof Date)return G.getTime()-J.getTime();if(typeof G==="boolean"&&typeof J==="boolean")return Number(G)-Number(J);return String(G).localeCompare(String(J),void 0,{numeric:!0,sensitivity:"base"})}function oG(G){let J=G.flatMap((X)=>X.results||[]),Y=G.filter((X)=>!X.success),Z=G.reduce((X,W)=>X+(W.meta?.duration||0),0);if(Y.length===0)return{success:!0,results:J,meta:{duration:Z}};let $=Y.map((X)=>X.error||"Unknown shard query error").filter(Boolean).join("; ");return{success:!1,results:J,error:$||"One or more shard queries failed",meta:{duration:Z}}}async function lG(G,J=[],Y={}){let Z=d(Y.batchSize),$=wJ(Y.offset),X=NJ(Y.limit),W=oG(await e(G,J,Z)),H=W.results;if(Y.filter)H=H.filter((_)=>Y.filter?.(_));if(Y.comparator)H=[...H].sort(Y.comparator);else if(Y.sortBy){let _=Y.sortDirection==="desc"?-1:1;H=[...H].sort((V,L)=>{let I=bG(V,Y.sortBy),P=bG(L,Y.sortBy);return CJ(I,P)*_})}let O=X===void 0?void 0:$+X,U=H.slice($,O);return{...W,results:U}}async function iG(G,J=[],Y=50){let Z=T(),$=[];for(let[W,H]of Object.entries(Z.shards)){if(!W||!H){console.error(`Shard ${W??"<null>"} not found, skipping`);continue}$.push(()=>H.prepare(G).bind(...J).first().catch((O)=>{return console.error(`Error executing query on shard ${W}:`,O),null}))}let X=[];for(let W=0;W<$.length;W+=Y){let H=$.slice(W,W+Y).map((O)=>O());X.push(...await Promise.all(H))}return X}async function kJ(G,J=[],Y={}){return(await lG(G,J,{...Y,limit:1})).results[0]??null}async function qJ(){let G=T();if(await C(G).clearAllMappings(),y.clear(),G.coordinator)try{let Y=G.coordinator.idFromName("default");await G.coordinator.get(Y).fetch("http://coordinator/flush",{method:"POST"})}catch(Y){console.warn("Failed to flush coordinator:",Y)}}async function SJ(G){let Y=T().shards[G];if(!Y)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");return await a(Y)}var KJ=/^[A-Za-z_][A-Za-z0-9_]*$/;function f(G){let J=G.trim();if(!J)throw new F("Identifier cannot be empty","INVALID_IDENTIFIER");let Y=J.split(".").map((Z)=>Z.trim());if(Y.some((Z)=>!Z||!KJ.test(Z)))throw new F(`Invalid SQL identifier: ${G}`,"INVALID_IDENTIFIER");return Y.map((Z)=>`"${Z}"`).join(".")}function hG(G){return G.toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"")}function fJ(G){if(typeof G==="string")return[{name:G}];if(!Array.isArray(G)||G.length===0)throw new F("At least one index column is required","INVALID_INDEX_COLUMNS");return G.map((J)=>{if(typeof J==="string")return{name:J};if(!J?.name)throw new F("Index column name is required","INVALID_INDEX_COLUMNS");return{name:J.name,order:J.order,collate:J.collate}})}function VG(G,J,Y={}){let Z=fJ(J),$=f(G),X=Y.indexName?Y.indexName:["idx",hG(G),...Z.map((V)=>hG(V.name))].filter(Boolean).join("_").slice(0,120),W=f(X||"idx_auto"),H=Z.map((V)=>{let L=f(V.name),I=V.order?` ${V.order}`:"",P=V.collate?` COLLATE ${f(V.collate).replace(/"/g,"")}`:"";return`${L}${P}${I}`}).join(", "),O=Y.ifNotExists===!1?"":" IF NOT EXISTS",U=Y.unique?"UNIQUE ":"",_=Y.where?.trim()?` WHERE ${Y.where.trim()}`:"";return`CREATE ${U}INDEX${O} ${W} ON ${$} (${H})${_}`}async function bJ(G,J,Y,Z={}){let $=VG(J,Y,Z);return gG(G,$)}async function hJ(G,J,Y,Z={}){let $=VG(J,Y,Z);return dG(G,$)}async function pJ(G,J,Y={}){let Z=VG(G,J,Y);return nG(Z,[],d(Y.batchSize))}function FG(G,J="query-plan"){switch(J){case"raw":return`EXPLAIN ${G}`;case"analyze":return`EXPLAIN ANALYZE ${G}`;case"query-plan":default:return`EXPLAIN QUERY PLAN ${G}`}}async function yJ(G,J,Y=[],Z={}){return mG(G,FG(J,Z.mode),Y)}async function uJ(G,J,Y=[],Z={}){return UG(G,FG(J,Z.mode),Y)}async function gJ(G,J=[],Y={}){return e(FG(G,Y.mode),J,d(Y.batchSize))}async function mJ(G,J){let Y=f(J),Z=await cG(G,`SELECT COUNT(*) AS row_count FROM ${Y}`);if(!Z||Z.row_count===void 0||Z.row_count===null)return 0;return Number(Z.row_count)||0}async function cJ(G,J){let Y=f(J),Z=await _G(G,`SELECT COUNT(*) AS row_count FROM ${Y}`);if(!Z||Z.row_count===void 0||Z.row_count===null)return 0;return Number(Z.row_count)||0}async function dJ(G,J=50){let Y=T(),Z=d(J),X=`SELECT COUNT(*) AS row_count FROM ${f(G)}`,W=[];for(let[U,_]of Object.entries(Y.shards)){if(!U||!_)continue;W.push(async()=>{try{let V=await _.prepare(X).first(),L=Number(V?.row_count??0);return{shard:U,count:Number.isFinite(L)?L:0,success:!0}}catch(V){return{shard:U,count:null,success:!1,error:V instanceof Error?V.message:String(V)}}})}let H=[];for(let U=0;U<W.length;U+=Z){let _=W.slice(U,U+Z).map((V)=>V());H.push(...await Promise.all(_))}return{total:H.reduce((U,_)=>U+(_.count??0),0),shards:H}}async function nJ(G){let J=T(),Y=await uG(G,"read"),Z=J.shards[Y];if(!Z)throw new F(`Shard ${Y} not found in configuration`,"SHARD_NOT_FOUND");return a(Z)}async function sG(G=50){let J=T(),Y=d(G),Z=[];for(let[X,W]of Object.entries(J.shards)){if(!X||!W)continue;Z.push(async()=>{try{return{shard:X,size:await a(W),success:!0}}catch(H){return{shard:X,size:null,success:!1,error:H instanceof Error?H.message:String(H)}}})}let $=[];for(let X=0;X<Z.length;X+=Y){let W=Z.slice(X,X+Y).map((H)=>H());$.push(...await Promise.all(W))}return $}async function oJ(G=50){return(await sG(G)).reduce((Y,Z)=>Y+(Z.size??0),0)}q();class LG{state;constructor(G){this.state=G}async getState(){return await this.state.storage.get("coordinator_state")||{knownShards:[],shardStats:{},strategy:"round-robin",roundRobinIndex:0}}async saveState(G){await this.state.storage.put("coordinator_state",G)}async fetch(G){let Y=new URL(G.url).pathname,Z=G.method;try{switch(`${Z} ${Y}`){case"GET /shards":return this.handleListShards();case"POST /shards":return this.handleAddShard(G);case"DELETE /shards":return this.handleRemoveShard(G);case"GET /stats":return this.handleGetStats();case"POST /stats":return this.handleUpdateStats(G);case"POST /allocate":return this.handleAllocateShard(G);case"POST /flush":return this.handleFlush();case"GET /health":return new Response("OK",{status:200});default:return new Response("Not Found",{status:404})}}catch($){return console.error("ShardCoordinator error:",$),new Response("Internal Server Error",{status:500})}}async handleListShards(){let G=await this.getState();return new Response(JSON.stringify(G.knownShards),{headers:{"Content-Type":"application/json"}})}async handleAddShard(G){let{shard:J}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Y=await this.getState();if(!Y.knownShards.includes(J))Y.knownShards.push(J),Y.shardStats[J]={binding:J,count:0,lastUpdated:Date.now()},await this.saveState(Y);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleRemoveShard(G){let{shard:J}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Y=await this.getState(),Z=Y.knownShards.indexOf(J);if(Z>-1){if(Y.knownShards.splice(Z,1),delete Y.shardStats[J],Y.roundRobinIndex>=Y.knownShards.length)Y.roundRobinIndex=0;await this.saveState(Y)}return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleGetStats(){let G=await this.getState(),J=Object.values(G.shardStats);return new Response(JSON.stringify(J),{headers:{"Content-Type":"application/json"}})}async handleUpdateStats(G){let{shard:J,count:Y}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});if(Y===void 0||typeof Y!=="number")return new Response(JSON.stringify({error:"Missing or invalid count parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Z=await this.getState();if(Z.shardStats[J])Z.shardStats[J].count=Y,Z.shardStats[J].lastUpdated=Date.now(),await this.saveState(Z);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleAllocateShard(G){let{primaryKey:J,strategy:Y,operationType:Z,availableShards:$}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid primaryKey parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let X=await this.getState(),W=$||X.knownShards;if(W.length===0)return new Response(JSON.stringify({error:"No shards available"}),{status:400,headers:{"Content-Type":"application/json"}});let H=this.resolveStrategy(X.strategy,Y,Z||"write"),O=this.selectShard(J,X,H,W);if(H==="round-robin")X.roundRobinIndex=(X.roundRobinIndex+1)%W.length,await this.saveState(X);return new Response(JSON.stringify({shard:O}),{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(G,J,Y="write"){if(J)return J;if(typeof G==="string")return G;return G[Y]}selectShard(G,J,Y,Z){let $=Z||J.knownShards;if($.length===0)throw new F("No shards available","NO_SHARDS");switch(Y){case"round-robin":return $[J.roundRobinIndex]??$[0];case"random":return $[Math.floor(Math.random()*$.length)];case"hash":{let X=0;for(let H=0;H<G.length;H++){let O=G.charCodeAt(H);X=(X<<5)-X+O,X=X&X}let W=Math.abs(X)%$.length;return $[W]}case"location":{let X=J.targetRegion,W=J.shardLocations||{},H=$.filter((A)=>W[A]);if(!X||H.length===0){let A=0;for(let R=0;R<G.length;R++){let D=G.charCodeAt(R);A=(A<<5)-A+D,A=A&A}let j=Math.abs(A)%$.length;return $[j]}let O={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}},U=(A,j)=>(j in A),_=(A)=>U(O,A)?A:"wnam",V=(A,j)=>{let R=O[_(A)],D=O[_(j)],E=R.lat-D.lat,Q=R.lon-D.lon;return Math.sqrt(E*E+Q*Q)},L=H.map((A)=>{let j=W[A],R=V(X,j.region),D=j.priority||1;return{shard:A,score:R-D*0.1}});L.sort((A,j)=>A.score-j.score);let I=L[0].score,P=L.filter((A)=>Math.abs(A.score-I)<0.01);if(P.length===1)return P[0].shard;let x=0;for(let A=0;A<G.length;A++){let j=G.charCodeAt(A);x=(x<<5)-x+j,x=x&x}let w=Math.abs(x)%P.length;return P[w].shard}default:return $[0]}}async incrementShardCount(G){let J=await this.getState();if(J.shardStats[G])J.shardStats[G].count++,J.shardStats[G].lastUpdated=Date.now(),await this.saveState(J)}async decrementShardCount(G){let J=await this.getState();if(J.shardStats[G]&&J.shardStats[G].count>0)J.shardStats[G].count--,J.shardStats[G].lastUpdated=Date.now(),await this.saveState(J)}}if(typeof global<"u"){class G{data=new Map;async get(Z){return this.data.get(Z)}async put(Z,$){this.data.set(Z,$)}async delete(Z){return this.data.delete(Z)}async deleteAll(){this.data.clear()}async list(Z){if(!Z?.prefix)return new Map(this.data);let $=new Map;for(let[X,W]of this.data.entries())if(X.startsWith(Z.prefix))$.set(X,W);return $}}class J{storage;constructor(){this.storage=new G}}class Y{coordinator;mockState;constructor(){this.mockState=new J,this.coordinator=new LG(this.mockState)}async testShardAllocation(){await this.coordinator.fetch(new Request("http://test/shards",{method:"POST",body:JSON.stringify({shard:"db-east"})})),await this.coordinator.fetch(new Request("http://test/shards",{method:"POST",body:JSON.stringify({shard:"db-west"})}));let $=await(await this.coordinator.fetch(new Request("http://test/allocate",{method:"POST",body:JSON.stringify({primaryKey:"user-1",strategy:"round-robin"})}))).json(),W=await(await this.coordinator.fetch(new Request("http://test/allocate",{method:"POST",body:JSON.stringify({primaryKey:"user-2",strategy:"round-robin"})}))).json();console.assert($.shard!==W.shard,"Round-robin should alternate shards");let O=await(await this.coordinator.fetch(new Request("http://test/allocate",{method:"POST",body:JSON.stringify({primaryKey:"consistent-key",strategy:"hash"})}))).json(),_=await(await this.coordinator.fetch(new Request("http://test/allocate",{method:"POST",body:JSON.stringify({primaryKey:"consistent-key",strategy:"hash"})}))).json();console.assert(O.shard===_.shard,"Hash allocation should be consistent"),console.log("✅ Shard allocation tests passed")}async testShardStats(){await this.coordinator.fetch(new Request("http://test/flush",{method:"POST"})),await this.coordinator.fetch(new Request("http://test/shards",{method:"POST",body:JSON.stringify({shard:"db-stats-test"})})),await this.coordinator.fetch(new Request("http://test/stats",{method:"POST",body:JSON.stringify({shard:"db-stats-test",count:42})}));let $=await(await this.coordinator.fetch(new Request("http://test/stats",{method:"GET"}))).json();console.assert($.length===1,"Should have one shard stat"),console.assert($[0]?.binding==="db-stats-test","Should have correct binding name"),console.assert($[0]?.count===42,"Should have correct count"),console.log("✅ Shard stats tests passed")}async testErrorHandling(){await this.coordinator.fetch(new Request("http://test/flush",{method:"POST"}));let Z=await this.coordinator.fetch(new Request("http://test/allocate",{method:"POST",body:JSON.stringify({primaryKey:"test-key"})}));console.assert(Z.status===400,"Should return 400 for no shards available");let $=await this.coordinator.fetch(new Request("http://test/invalid",{method:"GET"}));console.assert($.status===404,"Should return 404 for invalid endpoint"),console.log("✅ Error handling tests passed")}async testCountManagement(){await this.coordinator.fetch(new Request("http://test/shards",{method:"POST",body:JSON.stringify({shard:"db-count-test"})})),await this.coordinator.incrementShardCount("db-count-test"),await this.coordinator.incrementShardCount("db-count-test");let Z=await this.coordinator.fetch(new Request("http://test/stats",{method:"GET"})),$=await Z.json(),X=$.find((H)=>H.binding==="db-count-test");console.assert(X?.count===2,"Count should be 2 after two increments"),await this.coordinator.decrementShardCount("db-count-test"),Z=await this.coordinator.fetch(new Request("http://test/stats",{method:"GET"})),$=await Z.json();let W=$.find((H)=>H.binding==="db-count-test");console.assert(W?.count===1,"Count should be 1 after decrement"),console.log("✅ Count management tests passed")}async runAllTests(){console.log("\uD83E\uDDEA Running ShardCoordinator tests...");try{return await this.testShardAllocation(),await this.testShardStats(),await this.testErrorHandling(),await this.testCountManagement(),console.log("\uD83C\uDF89 All ShardCoordinator tests passed!"),!0}catch(Z){return console.error("❌ ShardCoordinator tests failed:",Z),!1}}}globalThis.testShardCoordinator=()=>new Y}q();u();q();var lJ=500;function rG(G,J={}){let Y=J.scanCount??lJ;return{async get(Z,$="text"){let X=await G.get(Z);if(X===null)return null;if($!=="json")return X;try{return JSON.parse(X)}catch(W){throw new F(`Failed to parse JSON from Redis for key ${Z}: ${W instanceof Error?W.message:String(W)}`,"KV_JSON_PARSE_FAILED")}},async put(Z,$){await G.set(Z,$)},async delete(Z){await G.del(Z)},async list(Z){let $=Z?.prefix??"",X=`${$}*`,W=Z?.cursor??"0",H=Z?.limit,O=[];do{let U=await JY(G,W,X,Y);W=U.cursor;for(let _ of U.keys){if(!$||_.startsWith($))O.push(_);if(H&&O.length>=H)break}if(H&&O.length>=H)break}while(W!=="0");return{keys:O.map((U)=>({name:U})),cursor:W,list_complete:W==="0"}}}}function iJ(G,J={}){return rG(G,J)}function eG(G,J){if(J)return JG(G,J);return{prepare(Y){return new EG(G,Y)}}}function GJ(G,J){if(J)return JG(G,J);return{prepare(Y){return new TG(G,Y)}}}function sJ(G,J){if(J)return JG(G,J);return{prepare(Y){return new DG(G,Y)}}}function JG(G,J){return{prepare(Y){return new RG(G,J,Y)}}}function tJ(G){return{async get(J,Y="text"){let Z=await XY(G,J);if(Z===null||Z===void 0)return null;if(Y==="json"){if(typeof Z==="string")try{return JSON.parse(Z)}catch($){throw new F(`Failed to parse JSON from NuxtHub KV for key ${J}: ${$ instanceof Error?$.message:String($)}`,"KV_JSON_PARSE_FAILED")}return Z}return typeof Z==="string"?Z:JSON.stringify(Z)},async put(J,Y){await WY(G,J,Y)},async delete(J){await HY(G,J)},async list(J){let Y=J?.prefix??"",Z=await OY(G,Y);return{keys:(typeof J?.limit==="number"?Z.slice(0,J.limit):Z).map((X)=>({name:X})),list_complete:!0}}}}function aJ(G,J){return eG({query:async(Z,$=[])=>{let X=J(G.connectionString);if(typeof X.connect==="function")await X.connect();try{return await X.query(Z,$)}finally{if(typeof X.release==="function")X.release();else if(typeof X.end==="function")await X.end()}}})}function rJ(G,J){return GJ({execute:async(Z,$=[])=>{let X=J(G.connectionString);try{if(typeof X.execute==="function")return await X.execute(Z,$);if(typeof X.query==="function")return await X.query(Z,$);throw new F("Hyperdrive MySQL client is missing execute/query methods","MYSQL_CLIENT_INVALID")}finally{if(typeof X.end==="function")await X.end();else if(typeof X.close==="function")await X.close();else if(typeof X.destroy==="function")X.destroy()}}})}function eJ(G){if(!G||typeof G!=="object")return!1;return typeof G.prepare==="function"}function GY(G){if(!G||typeof G!=="object")return!1;let J=G;return typeof J.get==="function"&&typeof J.put==="function"&&typeof J.delete==="function"&&typeof J.list==="function"}class EG{client;sql;bindings;constructor(G,J,Y=[]){this.client=G,this.sql=J,this.bindings=Y}bind(...G){return new EG(this.client,this.sql,G)}async run(){let G=Date.now(),J=QG(this.sql),Y=await this.client.query(J,this.bindings);return{success:!0,results:Y.rows??[],meta:B(G,{changes:typeof Y.rowCount==="number"?Y.rowCount:void 0,command:Y.command})}}async all(){let G=Date.now(),J=QG(this.sql),Y=await this.client.query(J,this.bindings);return{success:!0,results:Y.rows??[],meta:B(G,{changes:typeof Y.rowCount==="number"?Y.rowCount:void 0,command:Y.command})}}async first(){let G=QG(this.sql);return(await this.client.query(G,this.bindings)).rows?.[0]??null}}class TG{client;sql;bindings;constructor(G,J,Y=[]){this.client=G,this.sql=J,this.bindings=Y}bind(...G){return new TG(this.client,this.sql,G)}async run(){let G=Date.now(),J=await AG(this.client,this.sql,this.bindings);if(Array.isArray(J))return{success:!0,results:J,meta:B(G)};let Y=J;return{success:!0,results:[],meta:B(G,{changes:Y.affectedRows,last_row_id:Y.insertId,warningStatus:Y.warningStatus})}}async all(){let G=Date.now(),J=await AG(this.client,this.sql,this.bindings);return{success:!0,results:Array.isArray(J)?J:[],meta:B(G,{changes:!Array.isArray(J)?J.affectedRows:void 0})}}async first(){let G=await AG(this.client,this.sql,this.bindings);if(!Array.isArray(G)||G.length===0)return null;return G[0]}}class DG{client;sql;bindings;constructor(G,J,Y=[]){this.client=G,this.sql=J,this.bindings=Y}bind(...G){return new DG(this.client,this.sql,G)}async run(){let G=Date.now();if(typeof this.client.execute==="function"){let $=await this.client.execute(this.sql,this.bindings);return{success:!0,results:PG($),meta:B(G)}}let J=this.client.prepare?.(this.sql);if(!J||typeof J.run!=="function")throw new F("SQLite client must expose execute() or prepare().run()","SQLITE_CLIENT_INVALID");let Z=await J.run(...this.bindings)??{};return{success:!0,results:[],meta:B(G,{changes:GG(Z.changes),last_row_id:Z.lastInsertRowid??Z.lastID})}}async all(){let G=Date.now();if(typeof this.client.execute==="function"){let Z=await this.client.execute(this.sql,this.bindings);return{success:!0,results:PG(Z),meta:B(G)}}let J=this.client.prepare?.(this.sql);if(!J||typeof J.all!=="function")throw new F("SQLite client must expose execute() or prepare().all()","SQLITE_CLIENT_INVALID");let Y=await J.all(...this.bindings);return{success:!0,results:Array.isArray(Y)?Y:[],meta:B(G)}}async first(){if(typeof this.client.execute==="function"){let J=await this.client.execute(this.sql,this.bindings);return PG(J)[0]??null}let G=this.client.prepare?.(this.sql);if(!G)throw new F("SQLite client must expose execute() or prepare().get()","SQLITE_CLIENT_INVALID");if(typeof G.get==="function"){let J=await G.get(...this.bindings);return J===void 0||J===null?null:J}if(typeof G.all==="function"){let J=await G.all(...this.bindings);if(!Array.isArray(J)||J.length===0)return null;let Y=J[0];return Y===void 0||Y===null?null:Y}throw new F("SQLite prepare() result must expose get() or all()","SQLITE_CLIENT_INVALID")}}class RG{client;sqlTag;sqlText;bindings;constructor(G,J,Y,Z=[]){this.client=G,this.sqlTag=J,this.sqlText=Y,this.bindings=Z}bind(...G){return new RG(this.client,this.sqlTag,this.sqlText,G)}async run(){let G=Date.now(),J=jG(this.sqlTag,this.sqlText,this.bindings),Y=await YY(this.client,J);return{success:!0,results:IG(Y),meta:B(G,aG(Y))}}async all(){let G=Date.now(),J=jG(this.sqlTag,this.sqlText,this.bindings),Y=await JJ(this.client,J);return{success:!0,results:IG(Y),meta:B(G,aG(Y))}}async first(){let G=jG(this.sqlTag,this.sqlText,this.bindings),J=await ZY(this.client,G),Y=IG(J);if(Y.length>0)return Y[0]??null;if(J&&typeof J==="object"&&"row"in J){let Z=J.row;return Z===void 0||Z===null?null:Z}if(J&&typeof J==="object"&&!Array.isArray(J)&&!("rows"in J)&&!("results"in J)&&!("data"in J))return J;return null}}async function JY(G,J,Y,Z){try{let $=await G.scan(J,{MATCH:Y,COUNT:Z});return tG($)}catch{let $=await G.scan(J,"MATCH",Y,"COUNT",String(Z));return tG($)}}function tG(G){if(Array.isArray(G))return{cursor:String(G[0]??"0"),keys:Array.isArray(G[1])?G[1]:[]};return{cursor:String(G.cursor??"0"),keys:Array.isArray(G.keys)?G.keys:[]}}async function AG(G,J,Y){if(typeof G.execute==="function"){let Z=await G.execute(J,Y);if(Array.isArray(Z))return Z[0];return Z}if(typeof G.query==="function"){let Z=await G.query(J,Y);if(Array.isArray(Z))return Z[0];return Z}throw new F("MySQL client must expose execute() or query()","MYSQL_CLIENT_INVALID")}async function YY(G,J){if(typeof G.run==="function")return await G.run(J);if(typeof G.execute==="function")return await G.execute(J);if(typeof G.all==="function")return await G.all(J);throw new F("Drizzle client must expose run(), execute(), or all()","DRIZZLE_CLIENT_INVALID")}async function JJ(G,J){if(typeof G.all==="function")return await G.all(J);if(typeof G.execute==="function")return await G.execute(J);if(typeof G.run==="function")return await G.run(J);throw new F("Drizzle client must expose all(), execute(), or run()","DRIZZLE_CLIENT_INVALID")}async function ZY(G,J){if(typeof G.get==="function")return await G.get(J);return await JJ(G,J)}function jG(G,J,Y){let Z=$Y(J),$=Z.length-1;if($!==Y.length)throw new F(`Drizzle binding mismatch: expected ${$} bindings, received ${Y.length}`,"DRIZZLE_BINDINGS_MISMATCH");if($===0)return G.raw(J);let X=typeof G.empty==="function"?G.empty():G.raw("");for(let W=0;W<Z.length;W++){let H=Z[W];if(H)X.append(G.raw(H));if(W<$)X.append(G`${Y[W]}`)}return X}function $Y(G){let J=[],Y=0,Z=!1,$=!1,X=!1,W=!1;for(let H=0;H<G.length;H++){let O=G[H],U=H+1<G.length?G[H+1]:"";if(X){if(O===`
|
|
17
|
-
`)X=!1;continue}if(W){if(
|
|
18
|
-
`)W=!1;continue}if(H){if(Y+=
|
|
16
|
+
`).run()}if(K.set(V,!0),w&&Y.debug)console.log(`Auto-migration completed for shard ${J}: ${P} records from ${Q} tables`)}catch(L){A.push(`Auto-migration error: ${L}`)}return{migrationNeeded:x,migrationPerformed:w,recordsMigrated:P,tablesProcessed:Q,issues:A}}async function KG(G,J,Y){let Z=`${J}_migration_check`;if(K.has(Z))return!1;try{let $=await h(G);if($.includes("shard_mappings"))return K.set(Z,!0),!1;let{KVShardMapper:W}=await Promise.resolve().then(() => (g(),HG)),H=new W(Y.kv,{hashShardMappings:Y.hashShardMappings,mappingCacheTtlMs:Y.mappingCacheTtlMs,knownShardsCacheTtlMs:Y.knownShardsCacheTtlMs}),U=$.filter((_)=>_!=="shard_mappings"&&!_.startsWith("sqlite_")&&_!=="sqlite_sequence");for(let _ of U.slice(0,3))try{if(((await G.prepare(`SELECT COUNT(*) as count FROM ${_} LIMIT 1`).first())?.count||0)>0){let A=await G.prepare(`SELECT id FROM ${_} LIMIT 1`).first();if(A){let P=String(A.id);if(!await H.getShardMapping(P))return!0}}}catch{continue}return!1}catch{return!1}}function fG(){K.clear()}function bG(G){let J=`${G}_migration_check`;K.delete(J)}var K,UG;var c=WG(()=>{q();K=new Map,UG=new Map});q();g();var d=null,p=null,u=new Map,y=0;function v(G){if(!p)p=new S(G.kv,{hashShardMappings:G.hashShardMappings,mappingCacheTtlMs:G.mappingCacheTtlMs,knownShardsCacheTtlMs:G.knownShardsCacheTtlMs});return p}function LJ(G){d=G,p=new S(G.kv,{hashShardMappings:G.hashShardMappings,mappingCacheTtlMs:G.mappingCacheTtlMs,knownShardsCacheTtlMs:G.knownShardsCacheTtlMs}),u.clear(),y=0;try{let J=v(G);Promise.resolve().then(async()=>{let Y=await J.getKnownShards(),Z=Array.from(new Set([...Y,...Object.keys(G.shards)]));await J.setKnownShards(Z)}).catch(()=>{return})}catch{}if(G.shards&&Object.keys(G.shards).length>0&&!G.disableAutoMigration)mG(G).catch((J)=>{console.warn("Background auto-migration failed:",J)})}async function yG(G){d=G,p=new S(G.kv,{hashShardMappings:G.hashShardMappings,mappingCacheTtlMs:G.mappingCacheTtlMs,knownShardsCacheTtlMs:G.knownShardsCacheTtlMs}),u.clear(),y=0;try{let J=v(G),Y=await J.getKnownShards(),Z=Array.from(new Set([...Y,...Object.keys(G.shards)]));await J.setKnownShards(Z)}catch{}if(G.shards&&Object.keys(G.shards).length>0&&!G.disableAutoMigration)try{await mG(G)}catch(J){console.warn("Auto migration failed:",J)}}async function jJ(G,J){return await yG(G),await J()}async function mG(G){try{let{autoDetectAndMigrate:J}=await Promise.resolve().then(() => (c(),a)),Y=Object.keys(G.shards);if(G.debug)console.log(`\uD83D\uDD0D Checking ${Y.length} shards for existing data...`);let Z=Y.map(async(W)=>{let H=G.shards[W];if(!H)return null;try{let U=await J(H,W,G,{maxRecordsToCheck:1000});return{shardName:W,...U}}catch(U){return console.warn(`Auto-migration failed for shard ${W}:`,U),null}}),X=(await Promise.all(Z)).filter((W)=>W?.migrationPerformed);if(G.debug)if(X.length>0){let W=X.reduce((H,U)=>H+(U?.recordsMigrated||0),0);console.log(`\uD83C\uDF89 Auto-migration completed! Migrated ${W} records across ${X.length} shards`),X.forEach((H)=>{if(H)console.log(` ✅ ${H.shardName}: ${H.recordsMigrated} records from ${H.tablesProcessed} tables`)})}else console.log("✅ All shards ready - no migration needed")}catch(J){console.warn("Background auto-migration setup failed:",J)}}function PJ(){d=null,p=null,u.clear(),y=0}function T(){if(!d)throw new F("CollegeDB not initialized. Call initialize() first.","NOT_INITIALIZED");return d}function QJ(G){let J=G.trim().toUpperCase();if(J.startsWith("SELECT")||J.startsWith("VALUES")||J.startsWith("TABLE")||J.startsWith("PRAGMA")||J.startsWith("EXPLAIN")||J.startsWith("WITH")||J.startsWith("SHOW"))return"read";return"write"}function uG(G,J){let Y=G.strategy||"hash";if(typeof Y==="string")return Y;let Z=Y;return Z[J]||Z.write||Z.read||"hash"}function IJ(G,J){if(G===J)return 0;let Y={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=Y[G],$=Y[J],X=Z.lat-$.lat,W=Z.lon-$.lon;return Math.sqrt(X*X+W*W)}function EJ(G){let J=G.cf;if(!J||!J.country)return"wnam";let{country:Y,continent:Z}=J;if(["US","CA","MX"].includes(Y)){let $=J.region||J.regionCode||"",X=J.timezone||"";if($.includes("CA")||$.includes("WA")||$.includes("OR")||$.includes("NV")||$.includes("AZ")||$.includes("UT")||X.includes("Pacific")||X.includes("America/Los_Angeles"))return"wnam";return"enam"}if(["GL","PM","BM"].includes(Y))return"enam";if(["GB","IE","FR","ES","PT","NL","BE","LU","CH","AT","IT"].includes(Y))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(Y))return"eeur";if(Y==="RU")return"eeur";if(["JP","KR","CN","HK","TW","MO","MN","KP"].includes(Y))return"apac";if(["TH","VN","SG","MY","ID","PH","BN","KH","LA","MM","TL","IN","PK","BD","LK","NP","BT","MV","AF"].includes(Y))return"apac";if(["AU","NZ","PG","FJ","NC","VU","SB","WS","TO","KI","NR","PW","FM","MH","TV"].includes(Y))return"oc";if(["AE","SA","QA","KW","BH","OM","YE","IQ","IR","SY","LB","JO","IL","PS","TR","CY"].includes(Y))return"me";if(Z==="AF"||["EG","LY","TN","DZ","MA","SD","SS","ET","ER","DJ","SO"].includes(Y))return"af";if(["KZ","UZ","TM","TJ","KG"].includes(Y))return"eeur";if(Z==="SA"||["BR","AR","CL","PE","CO","VE","EC","BO","PY","UY","GY","SR","GF"].includes(Y))return"enam";if(["GT","BZ","SV","HN","NI","CR","PA","CU","JM","HT","DO","PR","TT","BB","GD","VC","LC","DM","AG","KN"].includes(Y))return"enam";return"wnam"}function TJ(G){if(typeof G==="string")return G;return G.region||"wnam"}async function r(G){try{let[J,Y]=await Promise.all([G.prepare("PRAGMA page_count").first(),G.prepare("PRAGMA page_size").first()]);if(!J?.page_count||!Y?.page_size)throw new F("Failed to retrieve database size information","SIZE_QUERY_FAILED");return J.page_count*Y.page_size}catch(J){throw new F(`Failed to get database size: ${J instanceof Error?J.message:"Unknown error"}`,"SIZE_QUERY_FAILED")}}async function DJ(G,J){let Y=Math.max(0,J.sizeCacheTtlMs??30000),Z=u.get(G);if(Z&&Z.expiresAt>=Date.now())return Z.size;let $=J.shards[G];if(!$)throw new F(`Shard ${G} not found in configuration`,"SHARD_NOT_FOUND");let X=await r($);if(Y>0)u.set(G,{size:X,expiresAt:Date.now()+Y});return X}async function gG(G,J){if(typeof J.maxDatabaseSize!=="number"||!Number.isFinite(J.maxDatabaseSize)||J.maxDatabaseSize<=0)return G;let Y=J.maxDatabaseSize,$=(await Promise.allSettled(G.map(async(X)=>{let W=await DJ(X,J);return{shard:X,size:W,withinLimit:W<Y}}))).filter((X)=>X.status==="fulfilled"&&X.value.withinLimit).map((X)=>X.value.shard);if($.length===0){if(J.debug)console.warn("All shards exceed maxDatabaseSize limit. Allowing allocation to prevent failure.");return G}if(J.debug&&$.length<G.length){let X=G.filter((W)=>!$.includes(W));console.log(`Excluded ${X.length} shards due to size limits: ${X.join(", ")}`)}return $}function RJ(G,J,Y,Z){let $=J.filter((O)=>Y[O]);if($.length===0){let O=0;for(let A=0;A<Z.length;A++){let P=Z.charCodeAt(A);O=(O<<5)-O+P,O=O&O}let V=Math.abs(O)%J.length;return J[V]}let X=$.map((O)=>{let V=Y[O],A=IJ(G,TJ(V)),P=typeof V==="object"?V.priority||1:1,Q=A-P*0.1;return{shard:O,score:Q,distance:A,priority:P}});X.sort((O,V)=>O.score-V.score);let W=X[0].score,H=X.filter((O)=>Math.abs(O.score-W)<0.01);if(H.length===1)return H[0].shard;let U=0;for(let O=0;O<Z.length;O++){let V=Z.charCodeAt(O);U=(U<<5)-U+V,U=U&U}let _=Math.abs(U)%H.length;return H[_].shard}function m(G,J,Y,Z){switch(G){case"hash":{let $=0;for(let W=0;W<J.length;W++){let H=J.charCodeAt(W);$=($<<5)-$+H,$=$&$}let X=Math.abs($)%Y.length;return Y[X]||Y[0]}case"location":{if(!Z.targetRegion)return m("hash",J,Y,Z);return RJ(Z.targetRegion,Y,Z.shardLocations||{},J)}case"random":return Y[Math.floor(Math.random()*Y.length)]||Y[0];default:return m("hash",J,Y,Z)}}async function cG(G,J="write"){let Y=T(),Z=v(Y),$=await Z.getShardMapping(G);if($)return $.shard;let X=Object.keys(Y.shards);if(X.length===0)throw new F("No shards configured","NO_SHARDS");let W=await gG(X,Y),H,U=uG(Y,J);if(Y.coordinator)try{let _=Y.coordinator.idFromName("default"),V=await Y.coordinator.get(_).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:G,strategy:U,operationType:J,targetRegion:Y.targetRegion,shardLocations:Y.shardLocations,availableShards:W})});if(V.ok)H=(await V.json()).shard;else H=m(U,G,W,Y)}catch(_){console.warn("Coordinator allocation failed, falling back to local strategy:",_),H=m(U,G,W,Y)}else H=m(U,G,W,Y);return await Z.setShardMapping(G,H),H}async function xJ(G,J="write"){let Y=T(),Z=await cG(G,J),$=Y.shards[Z];if(!$)throw new F(`Shard ${Z} not found in configuration`,"SHARD_NOT_FOUND");return $}async function MJ(G,J){let{createSchema:Y}=await Promise.resolve().then(() => (c(),a));await Y(G,J)}async function e(G,J){let Y=QJ(J);return(await xJ(G,Y)).prepare(J)}async function dG(G,J,Y=[]){let $=await(await e(G,J)).bind(...Y).run();if(!$.success)throw new F(`Query failed: ${$.error||"Unknown error"}`,"QUERY_FAILED");return $}function zJ(G){let J=G.results[0];if(J&&typeof J==="object"){for(let Z of["id","ID","Id","rowid","ROWID","RowId","last_row_id","lastInsertId","insertId"]){let $=J[Z];if($!==void 0&&$!==null)return $}for(let[Z,$]of Object.entries(J)){let X=Z.toLowerCase();if((X==="id"||X==="rowid")&&(typeof $==="number"||typeof $==="string"))return $}for(let Z of Object.values(J))if(typeof Z==="number"||typeof Z==="string")return Z}let Y=G.meta.last_row_id;if(Y!==void 0&&Y!==null)return Y;return}function NJ(){return`insert:${Date.now()}:${Math.random().toString(36).slice(2)}`}async function BJ(){let G=T(),J=Object.keys(G.shards);if(J.length===0)throw new F("No shards configured","NO_SHARDS");let Y=await gG(J,G);if(Y.length===0)throw new F("No shards available for insert","NO_SHARDS");let Z=uG(G,"write"),$=NJ();if(G.coordinator)try{let X=G.coordinator.idFromName("default"),H=await G.coordinator.get(X).fetch("http://coordinator/allocate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({primaryKey:$,strategy:Z,operationType:"write",targetRegion:G.targetRegion,shardLocations:G.shardLocations,availableShards:Y})});if(H.ok)return(await H.json()).shard}catch(X){console.warn("Coordinator allocation for insert failed, falling back to local strategy:",X)}if(Z==="round-robin"){let X=Y[y%Y.length];return y=(y+1)%Y.length,X}return m(Z,$,Y,G)}async function oG(G,J,Y=[]){let Z=T();if(!Z.shards[G])throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");let X=/\breturning\b/i.test(J)?await GG(G,J,Y):await FG(G,J,Y),W=zJ(X);if(W===void 0)throw new F("Insert did not return a generated primary key","GENERATED_KEY_UNAVAILABLE");return await v(Z).setShardMapping(String(W),G),{...X,generatedId:W}}async function vJ(G,J=[]){let Y=await BJ();return await oG(Y,G,J)}async function wJ(G,J,Y=[]){return await oG(G,J,Y)}async function nG(G,J,Y=[]){let $=await(await e(G,J)).bind(...Y).all();if(!$.success)throw new F(`Query failed: ${$.error||"Unknown error"}`,"QUERY_FAILED");return $}async function lG(G,J,Y=[]){return await(await e(G,J)).bind(...Y).first()}async function CJ(G,J,Y=[],Z=50){let $=T(),W=await v($).getShardMapping(G);if(W){if($.shards[W.shard]){let _=await GG(W.shard,J,Y);if(_.success&&_.results.length>0)return _}}let H=await JG(J,Y,Z);return iG(H)}async function kJ(G,J,Y=[],Z=50){let $=T(),W=await v($).getShardMapping(G);if(W){if($.shards[W.shard]){let _=await VG(W.shard,J,Y);if(_!==null)return _}}return(await aG(J,Y,Z)).find((U)=>U!==null)??null}async function qJ(G,J,Y){let Z=T();if(!Z.shards[J])throw new F(`Shard ${J} not found in configuration`,"SHARD_NOT_FOUND");let $=v(Z),X=await $.getShardMapping(G);if(!X)throw new F(`No existing mapping found for primary key: ${G}`,"MAPPING_NOT_FOUND");if(X.shard!==J){let{migrateRecord:W}=await Promise.resolve().then(() => (c(),a)),H=Z.shards[X.shard],U=Z.shards[J];if(!H||!U)throw new F("Source or target shard not available","SHARD_UNAVAILABLE");await W(H,U,G,Y)}await $.updateShardMapping(G,J)}async function SJ(){let G=T();if(G.coordinator)try{let J=G.coordinator.idFromName("default"),Z=await G.coordinator.get(J).fetch("http://coordinator/shards");if(Z.ok)return await Z.json()}catch(J){console.warn("Failed to get shards from coordinator:",J)}try{let Y=await v(G).getKnownShards(),Z=new Set([...Object.keys(G.shards),...Y]);return Array.from(Z)}catch{return Object.keys(G.shards)}}async function KJ(){let G=T();if(G.coordinator)try{let $=G.coordinator.idFromName("default"),W=await G.coordinator.get($).fetch("http://coordinator/stats");if(W.ok)return await W.json()}catch($){console.warn("Failed to get stats from coordinator:",$)}let J=v(G),Y=await J.getShardKeyCounts(),Z=Object.keys(G.shards);try{let $=await J.getKnownShards();Z=Array.from(new Set([...Z,...$]))}catch{}return Z.map(($)=>({binding:$,count:Y[$]||0}))}async function FG(G,J,Y=[]){let $=T().shards[G];if(!$)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");let X=await $.prepare(J).bind(...Y).run();if(!X.success)throw new F(`Query failed: ${X.error||"Unknown error"}`,"QUERY_FAILED");return X}async function GG(G,J,Y=[]){let $=T().shards[G];if(!$)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");return await $.prepare(J).bind(...Y).all()}async function VG(G,J,Y=[]){let $=T().shards[G];if(!$)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");return await $.prepare(J).bind(...Y).first()}async function sG(G,J=[],Y=50){let Z=T(),$=[];for(let[W,H]of Object.entries(Z.shards)){if(!W||!H){console.error(`Shard ${W??"<null>"} not found, skipping`);continue}$.push(()=>H.prepare(G).bind(...J).run().catch((U)=>{return console.error(`Error executing query on shard ${W}:`,U),{success:!1,results:[],error:U instanceof Error?U.message:String(U),meta:{duration:0}}}))}let X=[];for(let W=0;W<$.length;W+=Y){let H=$.slice(W,W+Y).map((U)=>U());X.push(...await Promise.all(H))}return X}async function JG(G,J=[],Y=50){let Z=T(),$=[];for(let[W,H]of Object.entries(Z.shards)){if(!W||!H){console.error(`Shard ${W??"<null>"} not found, skipping`);continue}$.push(()=>H.prepare(G).bind(...J).all().catch((U)=>{return console.error(`Error executing query on shard ${W}:`,U),{success:!1,results:[],error:U instanceof Error?U.message:String(U),meta:{duration:0}}}))}let X=[];for(let W=0;W<$.length;W+=Y){let H=$.slice(W,W+Y).map((U)=>U());X.push(...await Promise.all(H))}return X}function o(G,J=50){if(!Number.isFinite(G??J))return J;return Math.max(1,Math.floor(G??J))}function fJ(G){if(!Number.isFinite(G??0))return 0;return Math.max(0,Math.floor(G??0))}function bJ(G){if(G===void 0)return;if(!Number.isFinite(G))return;return Math.max(0,Math.floor(G))}function hG(G,J){if(typeof J==="function")return J(G);if(!J||typeof G!=="object"||G===null)return;return G[String(J)]}function hJ(G,J){if(G===J)return 0;if(G===null||G===void 0)return 1;if(J===null||J===void 0)return-1;if(typeof G==="number"&&typeof J==="number")return G-J;if(typeof G==="bigint"&&typeof J==="bigint")return G<J?-1:1;if(G instanceof Date&&J instanceof Date)return G.getTime()-J.getTime();if(typeof G==="boolean"&&typeof J==="boolean")return Number(G)-Number(J);return String(G).localeCompare(String(J),void 0,{numeric:!0,sensitivity:"base"})}function iG(G){let J=G.flatMap((X)=>X.results||[]),Y=G.filter((X)=>!X.success),Z=G.reduce((X,W)=>X+(W.meta?.duration||0),0);if(Y.length===0)return{success:!0,results:J,meta:{duration:Z}};let $=Y.map((X)=>X.error||"Unknown shard query error").filter(Boolean).join("; ");return{success:!1,results:J,error:$||"One or more shard queries failed",meta:{duration:Z}}}async function tG(G,J=[],Y={}){let Z=o(Y.batchSize),$=fJ(Y.offset),X=bJ(Y.limit),W=iG(await JG(G,J,Z)),H=W.results;if(Y.filter)H=H.filter((O)=>Y.filter?.(O));if(Y.comparator)H=[...H].sort(Y.comparator);else if(Y.sortBy){let O=Y.sortDirection==="desc"?-1:1;H=[...H].sort((V,A)=>{let P=hG(V,Y.sortBy),Q=hG(A,Y.sortBy);return hJ(P,Q)*O})}let U=X===void 0?void 0:$+X,_=H.slice($,U);return{...W,results:_}}async function aG(G,J=[],Y=50){let Z=T(),$=[];for(let[W,H]of Object.entries(Z.shards)){if(!W||!H){console.error(`Shard ${W??"<null>"} not found, skipping`);continue}$.push(()=>H.prepare(G).bind(...J).first().catch((U)=>{return console.error(`Error executing query on shard ${W}:`,U),null}))}let X=[];for(let W=0;W<$.length;W+=Y){let H=$.slice(W,W+Y).map((U)=>U());X.push(...await Promise.all(H))}return X}async function pJ(G,J=[],Y={}){return(await tG(G,J,{...Y,limit:1})).results[0]??null}async function yJ(){let G=T();if(await v(G).clearAllMappings(),u.clear(),G.coordinator)try{let Y=G.coordinator.idFromName("default");await G.coordinator.get(Y).fetch("http://coordinator/flush",{method:"POST"})}catch(Y){console.warn("Failed to flush coordinator:",Y)}}async function mJ(G){let Y=T().shards[G];if(!Y)throw new F(`Shard ${G} not found`,"SHARD_NOT_FOUND");return await r(Y)}var uJ=/^[A-Za-z_][A-Za-z0-9_]*$/;function f(G){let J=G.trim();if(!J)throw new F("Identifier cannot be empty","INVALID_IDENTIFIER");let Y=J.split(".").map((Z)=>Z.trim());if(Y.some((Z)=>!Z||!uJ.test(Z)))throw new F(`Invalid SQL identifier: ${G}`,"INVALID_IDENTIFIER");return Y.map((Z)=>`"${Z}"`).join(".")}function pG(G){return G.toLowerCase().replace(/[^a-z0-9_]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"")}function gJ(G){if(typeof G==="string")return[{name:G}];if(!Array.isArray(G)||G.length===0)throw new F("At least one index column is required","INVALID_INDEX_COLUMNS");return G.map((J)=>{if(typeof J==="string")return{name:J};if(!J?.name)throw new F("Index column name is required","INVALID_INDEX_COLUMNS");return{name:J.name,order:J.order,collate:J.collate}})}function AG(G,J,Y={}){let Z=gJ(J),$=f(G),X=Y.indexName?Y.indexName:["idx",pG(G),...Z.map((V)=>pG(V.name))].filter(Boolean).join("_").slice(0,120),W=f(X||"idx_auto"),H=Z.map((V)=>{let A=f(V.name),P=V.order?` ${V.order}`:"",Q=V.collate?` COLLATE ${f(V.collate).replace(/"/g,"")}`:"";return`${A}${Q}${P}`}).join(", "),U=Y.ifNotExists===!1?"":" IF NOT EXISTS",_=Y.unique?"UNIQUE ":"",O=Y.where?.trim()?` WHERE ${Y.where.trim()}`:"";return`CREATE ${_}INDEX${U} ${W} ON ${$} (${H})${O}`}async function cJ(G,J,Y,Z={}){let $=AG(J,Y,Z);return dG(G,$)}async function dJ(G,J,Y,Z={}){let $=AG(J,Y,Z);return FG(G,$)}async function oJ(G,J,Y={}){let Z=AG(G,J,Y);return sG(Z,[],o(Y.batchSize))}function LG(G,J="query-plan"){switch(J){case"raw":return`EXPLAIN ${G}`;case"analyze":return`EXPLAIN ANALYZE ${G}`;case"query-plan":default:return`EXPLAIN QUERY PLAN ${G}`}}async function nJ(G,J,Y=[],Z={}){return nG(G,LG(J,Z.mode),Y)}async function lJ(G,J,Y=[],Z={}){return GG(G,LG(J,Z.mode),Y)}async function sJ(G,J=[],Y={}){return JG(LG(G,Y.mode),J,o(Y.batchSize))}async function iJ(G,J){let Y=f(J),Z=await lG(G,`SELECT COUNT(*) AS row_count FROM ${Y}`);if(!Z||Z.row_count===void 0||Z.row_count===null)return 0;return Number(Z.row_count)||0}async function tJ(G,J){let Y=f(J),Z=await VG(G,`SELECT COUNT(*) AS row_count FROM ${Y}`);if(!Z||Z.row_count===void 0||Z.row_count===null)return 0;return Number(Z.row_count)||0}async function aJ(G,J=50){let Y=T(),Z=o(J),X=`SELECT COUNT(*) AS row_count FROM ${f(G)}`,W=[];for(let[_,O]of Object.entries(Y.shards)){if(!_||!O)continue;W.push(async()=>{try{let V=await O.prepare(X).first(),A=Number(V?.row_count??0);return{shard:_,count:Number.isFinite(A)?A:0,success:!0}}catch(V){return{shard:_,count:null,success:!1,error:V instanceof Error?V.message:String(V)}}})}let H=[];for(let _=0;_<W.length;_+=Z){let O=W.slice(_,_+Z).map((V)=>V());H.push(...await Promise.all(O))}return{total:H.reduce((_,O)=>_+(O.count??0),0),shards:H}}async function rJ(G){let J=T(),Y=await cG(G,"read"),Z=J.shards[Y];if(!Z)throw new F(`Shard ${Y} not found in configuration`,"SHARD_NOT_FOUND");return r(Z)}async function rG(G=50){let J=T(),Y=o(G),Z=[];for(let[X,W]of Object.entries(J.shards)){if(!X||!W)continue;Z.push(async()=>{try{return{shard:X,size:await r(W),success:!0}}catch(H){return{shard:X,size:null,success:!1,error:H instanceof Error?H.message:String(H)}}})}let $=[];for(let X=0;X<Z.length;X+=Y){let W=Z.slice(X,X+Y).map((H)=>H());$.push(...await Promise.all(W))}return $}async function eJ(G=50){return(await rG(G)).reduce((Y,Z)=>Y+(Z.size??0),0)}q();class eG{state;constructor(G){this.state=G}async getState(){return await this.state.storage.get("coordinator_state")||{knownShards:[],shardStats:{},strategy:"round-robin",roundRobinIndex:0}}async saveState(G){await this.state.storage.put("coordinator_state",G)}async fetch(G){let Y=new URL(G.url).pathname,Z=G.method;try{switch(`${Z} ${Y}`){case"GET /shards":return this.handleListShards();case"POST /shards":return this.handleAddShard(G);case"DELETE /shards":return this.handleRemoveShard(G);case"GET /stats":return this.handleGetStats();case"POST /stats":return this.handleUpdateStats(G);case"POST /allocate":return this.handleAllocateShard(G);case"POST /flush":return this.handleFlush();case"GET /health":return new Response("OK",{status:200});default:return new Response("Not Found",{status:404})}}catch($){return console.error("ShardCoordinator error:",$),new Response("Internal Server Error",{status:500})}}async handleListShards(){let G=await this.getState();return new Response(JSON.stringify(G.knownShards),{headers:{"Content-Type":"application/json"}})}async handleAddShard(G){let{shard:J}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Y=await this.getState();if(!Y.knownShards.includes(J))Y.knownShards.push(J),Y.shardStats[J]={binding:J,count:0,lastUpdated:Date.now()},await this.saveState(Y);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleRemoveShard(G){let{shard:J}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Y=await this.getState(),Z=Y.knownShards.indexOf(J);if(Z>-1){if(Y.knownShards.splice(Z,1),delete Y.shardStats[J],Y.roundRobinIndex>=Y.knownShards.length)Y.roundRobinIndex=0;await this.saveState(Y)}return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleGetStats(){let G=await this.getState(),J=Object.values(G.shardStats);return new Response(JSON.stringify(J),{headers:{"Content-Type":"application/json"}})}async handleUpdateStats(G){let{shard:J,count:Y}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid shard parameter"}),{status:400,headers:{"Content-Type":"application/json"}});if(Y===void 0||typeof Y!=="number")return new Response(JSON.stringify({error:"Missing or invalid count parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let Z=await this.getState();if(Z.shardStats[J])Z.shardStats[J].count=Y,Z.shardStats[J].lastUpdated=Date.now(),await this.saveState(Z);return new Response(JSON.stringify({success:!0}),{headers:{"Content-Type":"application/json"}})}async handleAllocateShard(G){let{primaryKey:J,strategy:Y,operationType:Z,availableShards:$}=await G.json();if(!J||typeof J!=="string")return new Response(JSON.stringify({error:"Missing or invalid primaryKey parameter"}),{status:400,headers:{"Content-Type":"application/json"}});let X=await this.getState(),W=$||X.knownShards;if(W.length===0)return new Response(JSON.stringify({error:"No shards available"}),{status:400,headers:{"Content-Type":"application/json"}});let H=this.resolveStrategy(X.strategy,Y,Z||"write"),U=this.selectShard(J,X,H,W);if(H==="round-robin")X.roundRobinIndex=(X.roundRobinIndex+1)%W.length,await this.saveState(X);return new Response(JSON.stringify({shard:U}),{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(G,J,Y="write"){if(J)return J;if(typeof G==="string")return G;return G[Y]}selectShard(G,J,Y,Z){let $=Z||J.knownShards;if($.length===0)throw new F("No shards available","NO_SHARDS");switch(Y){case"round-robin":return $[J.roundRobinIndex]??$[0];case"random":return $[Math.floor(Math.random()*$.length)];case"hash":{let X=0;for(let H=0;H<G.length;H++){let U=G.charCodeAt(H);X=(X<<5)-X+U,X=X&X}let W=Math.abs(X)%$.length;return $[W]}case"location":{let X=J.targetRegion,W=J.shardLocations||{},H=$.filter((L)=>W[L]);if(!X||H.length===0){let L=0;for(let R=0;R<G.length;R++){let D=G.charCodeAt(R);L=(L<<5)-L+D,L=L&L}let j=Math.abs(L)%$.length;return $[j]}let U={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}},_=(L,j)=>(j in L),O=(L)=>_(U,L)?L:"wnam",V=(L,j)=>{let R=U[O(L)],D=U[O(j)],E=R.lat-D.lat,I=R.lon-D.lon;return Math.sqrt(E*E+I*I)},A=H.map((L)=>{let j=W[L],R=V(X,j.region),D=j.priority||1;return{shard:L,score:R-D*0.1}});A.sort((L,j)=>L.score-j.score);let P=A[0].score,Q=A.filter((L)=>Math.abs(L.score-P)<0.01);if(Q.length===1)return Q[0].shard;let x=0;for(let L=0;L<G.length;L++){let j=G.charCodeAt(L);x=(x<<5)-x+j,x=x&x}let w=Math.abs(x)%Q.length;return Q[w].shard}default:return $[0]}}async incrementShardCount(G){let J=await this.getState();if(J.shardStats[G])J.shardStats[G].count++,J.shardStats[G].lastUpdated=Date.now(),await this.saveState(J)}async decrementShardCount(G){let J=await this.getState();if(J.shardStats[G]&&J.shardStats[G].count>0)J.shardStats[G].count--,J.shardStats[G].lastUpdated=Date.now(),await this.saveState(J)}}q();g();q();var GY=500;function YJ(G,J={}){let Y=J.scanCount??GY;return{async get(Z,$="text"){let X=await G.get(Z);if(X===null)return null;if($!=="json")return X;try{return JSON.parse(X)}catch(W){throw new F(`Failed to parse JSON from Redis for key ${Z}: ${W instanceof Error?W.message:String(W)}`,"KV_JSON_PARSE_FAILED")}},async put(Z,$){await G.set(Z,$)},async delete(Z){await G.del(Z)},async list(Z){let $=Z?.prefix??"",X=`${$}*`,W=Z?.cursor??"0",H=Z?.limit,U=[];do{let _=await UY(G,W,X,Y);W=_.cursor;for(let O of _.keys){if(!$||O.startsWith($))U.push(O);if(H&&U.length>=H)break}if(H&&U.length>=H)break}while(W!=="0");return{keys:U.map((_)=>({name:_})),cursor:W,list_complete:W==="0"}}}}function JY(G,J={}){return YJ(G,J)}function ZJ(G,J){if(J)return ZG(G,J);return{prepare(Y){return new TG(G,Y)}}}function $J(G,J){if(J)return ZG(G,J);return{prepare(Y){return new DG(G,Y)}}}function YY(G,J){if(J)return ZG(G,J);return{prepare(Y){return new RG(G,Y)}}}function ZG(G,J){return{prepare(Y){return new xG(G,J,Y)}}}function ZY(G){return{async get(J,Y="text"){let Z=await VY(G,J);if(Z===null||Z===void 0)return null;if(Y==="json"){if(typeof Z==="string")try{return JSON.parse(Z)}catch($){throw new F(`Failed to parse JSON from NuxtHub KV for key ${J}: ${$ instanceof Error?$.message:String($)}`,"KV_JSON_PARSE_FAILED")}return Z}return typeof Z==="string"?Z:JSON.stringify(Z)},async put(J,Y){await AY(G,J,Y)},async delete(J){await LY(G,J)},async list(J){let Y=J?.prefix??"",Z=await jY(G,Y);return{keys:(typeof J?.limit==="number"?Z.slice(0,J.limit):Z).map((X)=>({name:X})),list_complete:!0}}}}function $Y(G,J){return ZJ({query:async(Z,$=[])=>{let X=J(G.connectionString);if(typeof X.connect==="function")await X.connect();try{return await X.query(Z,$)}finally{if(typeof X.release==="function")X.release();else if(typeof X.end==="function")await X.end()}}})}function XY(G,J){return $J({execute:async(Z,$=[])=>{let X=J(G.connectionString);try{if(typeof X.execute==="function")return await X.execute(Z,$);if(typeof X.query==="function")return await X.query(Z,$);throw new F("Hyperdrive MySQL client is missing execute/query methods","MYSQL_CLIENT_INVALID")}finally{if(typeof X.end==="function")await X.end();else if(typeof X.close==="function")await X.close();else if(typeof X.destroy==="function")X.destroy()}}})}function WY(G){if(!G||typeof G!=="object")return!1;return typeof G.prepare==="function"}function HY(G){if(!G||typeof G!=="object")return!1;let J=G;return typeof J.get==="function"&&typeof J.put==="function"&&typeof J.delete==="function"&&typeof J.list==="function"}class TG{client;sql;bindings;constructor(G,J,Y=[]){this.client=G,this.sql=J,this.bindings=Y}bind(...G){return new TG(this.client,this.sql,G)}async run(){let G=Date.now(),J=EG(this.sql),Y=await this.client.query(J,this.bindings);return{success:!0,results:Y.rows??[],meta:B(G,{changes:typeof Y.rowCount==="number"?Y.rowCount:void 0,command:Y.command})}}async all(){let G=Date.now(),J=EG(this.sql),Y=await this.client.query(J,this.bindings);return{success:!0,results:Y.rows??[],meta:B(G,{changes:typeof Y.rowCount==="number"?Y.rowCount:void 0,command:Y.command})}}async first(){let G=EG(this.sql);return(await this.client.query(G,this.bindings)).rows?.[0]??null}}class DG{client;sql;bindings;constructor(G,J,Y=[]){this.client=G,this.sql=J,this.bindings=Y}bind(...G){return new DG(this.client,this.sql,G)}async run(){let G=Date.now(),J=await jG(this.client,this.sql,this.bindings);if(Array.isArray(J))return{success:!0,results:J,meta:B(G)};let Y=J;return{success:!0,results:[],meta:B(G,{changes:Y.affectedRows,last_row_id:Y.insertId,warningStatus:Y.warningStatus})}}async all(){let G=Date.now(),J=await jG(this.client,this.sql,this.bindings);return{success:!0,results:Array.isArray(J)?J:[],meta:B(G,{changes:!Array.isArray(J)?J.affectedRows:void 0})}}async first(){let G=await jG(this.client,this.sql,this.bindings);if(!Array.isArray(G)||G.length===0)return null;return G[0]}}class RG{client;sql;bindings;constructor(G,J,Y=[]){this.client=G,this.sql=J,this.bindings=Y}bind(...G){return new RG(this.client,this.sql,G)}async run(){let G=Date.now();if(typeof this.client.execute==="function"){let $=await this.client.execute(this.sql,this.bindings);return{success:!0,results:IG($),meta:B(G)}}let J=this.client.prepare?.(this.sql);if(!J||typeof J.run!=="function")throw new F("SQLite client must expose execute() or prepare().run()","SQLITE_CLIENT_INVALID");let Z=await J.run(...this.bindings)??{};return{success:!0,results:[],meta:B(G,{changes:YG(Z.changes),last_row_id:Z.lastInsertRowid??Z.lastID})}}async all(){let G=Date.now();if(typeof this.client.execute==="function"){let Z=await this.client.execute(this.sql,this.bindings);return{success:!0,results:IG(Z),meta:B(G)}}let J=this.client.prepare?.(this.sql);if(!J||typeof J.all!=="function")throw new F("SQLite client must expose execute() or prepare().all()","SQLITE_CLIENT_INVALID");let Y=await J.all(...this.bindings);return{success:!0,results:Array.isArray(Y)?Y:[],meta:B(G)}}async first(){if(typeof this.client.execute==="function"){let J=await this.client.execute(this.sql,this.bindings);return IG(J)[0]??null}let G=this.client.prepare?.(this.sql);if(!G)throw new F("SQLite client must expose execute() or prepare().get()","SQLITE_CLIENT_INVALID");if(typeof G.get==="function"){let J=await G.get(...this.bindings);return J===void 0||J===null?null:J}if(typeof G.all==="function"){let J=await G.all(...this.bindings);if(!Array.isArray(J)||J.length===0)return null;let Y=J[0];return Y===void 0||Y===null?null:Y}throw new F("SQLite prepare() result must expose get() or all()","SQLITE_CLIENT_INVALID")}}class xG{client;sqlTag;sqlText;bindings;constructor(G,J,Y,Z=[]){this.client=G,this.sqlTag=J,this.sqlText=Y,this.bindings=Z}bind(...G){return new xG(this.client,this.sqlTag,this.sqlText,G)}async run(){let G=Date.now(),J=PG(this.sqlTag,this.sqlText,this.bindings),Y=await _Y(this.client,J);return{success:!0,results:QG(Y),meta:B(G,JJ(Y))}}async all(){let G=Date.now(),J=PG(this.sqlTag,this.sqlText,this.bindings),Y=await XJ(this.client,J);return{success:!0,results:QG(Y),meta:B(G,JJ(Y))}}async first(){let G=PG(this.sqlTag,this.sqlText,this.bindings),J=await OY(this.client,G),Y=QG(J);if(Y.length>0)return Y[0]??null;if(J&&typeof J==="object"&&"row"in J){let Z=J.row;return Z===void 0||Z===null?null:Z}if(J&&typeof J==="object"&&!Array.isArray(J)&&!("rows"in J)&&!("results"in J)&&!("data"in J))return J;return null}}async function UY(G,J,Y,Z){try{let $=await G.scan(J,{MATCH:Y,COUNT:Z});return GJ($)}catch{let $=await G.scan(J,"MATCH",Y,"COUNT",String(Z));return GJ($)}}function GJ(G){if(Array.isArray(G))return{cursor:String(G[0]??"0"),keys:Array.isArray(G[1])?G[1]:[]};return{cursor:String(G.cursor??"0"),keys:Array.isArray(G.keys)?G.keys:[]}}async function jG(G,J,Y){if(typeof G.execute==="function"){let Z=await G.execute(J,Y);if(Array.isArray(Z))return Z[0];return Z}if(typeof G.query==="function"){let Z=await G.query(J,Y);if(Array.isArray(Z))return Z[0];return Z}throw new F("MySQL client must expose execute() or query()","MYSQL_CLIENT_INVALID")}async function _Y(G,J){if(typeof G.run==="function")return await G.run(J);if(typeof G.execute==="function")return await G.execute(J);if(typeof G.all==="function")return await G.all(J);throw new F("Drizzle client must expose run(), execute(), or all()","DRIZZLE_CLIENT_INVALID")}async function XJ(G,J){if(typeof G.all==="function")return await G.all(J);if(typeof G.execute==="function")return await G.execute(J);if(typeof G.run==="function")return await G.run(J);throw new F("Drizzle client must expose all(), execute(), or run()","DRIZZLE_CLIENT_INVALID")}async function OY(G,J){if(typeof G.get==="function")return await G.get(J);return await XJ(G,J)}function PG(G,J,Y){let Z=FY(J),$=Z.length-1;if($!==Y.length)throw new F(`Drizzle binding mismatch: expected ${$} bindings, received ${Y.length}`,"DRIZZLE_BINDINGS_MISMATCH");if($===0)return G.raw(J);let X=typeof G.empty==="function"?G.empty():G.raw("");for(let W=0;W<Z.length;W++){let H=Z[W];if(H)X.append(G.raw(H));if(W<$)X.append(G`${Y[W]}`)}return X}function FY(G){let J=[],Y=0,Z=!1,$=!1,X=!1,W=!1;for(let H=0;H<G.length;H++){let U=G[H],_=H+1<G.length?G[H+1]:"";if(X){if(U===`
|
|
17
|
+
`)X=!1;continue}if(W){if(U==="*"&&_==="/")H++,W=!1;continue}if(!Z&&!$){if(U==="-"&&_==="-"){H++,X=!0;continue}if(U==="/"&&_==="*"){H++,W=!0;continue}}if(U==="'"&&!$){if(Z&&_==="'"){H++;continue}Z=!Z;continue}if(U==='"'&&!Z){if($&&_==='"'){H++;continue}$=!$;continue}if(U==="?"&&!Z&&!$)J.push(G.slice(Y,H)),Y=H+1}return J.push(G.slice(Y)),J}function QG(G){let J=(Z)=>{if(!Z||typeof Z!=="object"||Array.isArray(Z))return;let $=Z;if(Array.isArray($.rows))return $.rows;if(Array.isArray($.results))return $.results;if(Array.isArray($.data))return $.data;return},Y=(Z)=>{if(!Z||typeof Z!=="object"||Array.isArray(Z))return!1;return Object.keys(Z).length>0};if(Array.isArray(G)){if(G.length===2){let Z=J(G[0]);if(Z)return Z;let $=J(G[1]);if($)return $;if(!Array.isArray(G[0])&&!Array.isArray(G[1])){if(Y(G[0]))return[G[0]];if(Y(G[1]))return[G[1]]}if(Array.isArray(G[0]))return G[0];if(Array.isArray(G[1]))return G[1]}return G}if(G&&typeof G==="object"){let Z=J(G);if(Z)return Z}return[]}function JJ(G){if(!G)return{};let J;if(Array.isArray(G)){if(G.length===2){if(G[0]&&typeof G[0]==="object"&&!Array.isArray(G[0]))J=G[0];else if(G[1]&&typeof G[1]==="object"&&!Array.isArray(G[1]))J=G[1]}}else if(typeof G==="object"&&!Array.isArray(G))J=G;if(!J)return{};let Y={},Z=YG(J.rowCount)??YG(J.changes)??YG(J.affectedRows);if(Z!==void 0)Y.changes=Z;let $=J.lastInsertRowid??J.lastInsertId??J.lastID??J.lastRowID??J.insertId??J.insertID;if(typeof $==="number"||typeof $==="string")Y.last_row_id=$;if(J.meta&&typeof J.meta==="object")Object.assign(Y,J.meta);return Y}async function VY(G,J){if(typeof G.get==="function")return await G.get(J);if(typeof G.getItem==="function")return await G.getItem(J);throw new F("NuxtHub KV client must expose get() or getItem()","NUXTHUB_KV_CLIENT_INVALID")}async function AY(G,J,Y){if(typeof G.set==="function"){await G.set(J,Y);return}if(typeof G.setItem==="function"){await G.setItem(J,Y);return}throw new F("NuxtHub KV client must expose set() or setItem()","NUXTHUB_KV_CLIENT_INVALID")}async function LY(G,J){if(typeof G.del==="function"){await G.del(J);return}if(typeof G.removeItem==="function"){await G.removeItem(J);return}throw new F("NuxtHub KV client must expose del() or removeItem()","NUXTHUB_KV_CLIENT_INVALID")}async function jY(G,J){let Y;if(typeof G.keys==="function")Y=await G.keys(J);else if(typeof G.getKeys==="function")Y=await G.getKeys(J);else throw new F("NuxtHub KV client must expose keys() or getKeys()","NUXTHUB_KV_CLIENT_INVALID");if(!Array.isArray(Y))return[];if(!J)return[...Y];return Y.filter((Z)=>Z.startsWith(J))}function IG(G){if(Array.isArray(G))return G;if(G&&typeof G==="object"){let J=G;if(Array.isArray(J.rows))return J.rows;if(Array.isArray(J.results))return J.results}return[]}function B(G,J={}){return{duration:Date.now()-G,...J}}function YG(G){if(typeof G==="number"&&Number.isFinite(G))return G;return}var n=new Map;function EG(G){let J=n.get(G);if(J)return J;let Y="",Z=0,$=!1,X=!1,W=!1,H=!1;for(let U=0;U<G.length;U++){let _=G[U],O=U+1<G.length?G[U+1]:"";if(W){if(Y+=_,_===`
|
|
18
|
+
`)W=!1;continue}if(H){if(Y+=_,_==="*"&&O==="/")Y+="/",U++,H=!1;continue}if(!$&&!X){if(_==="-"&&O==="-"){Y+="--",U++,W=!0;continue}if(_==="/"&&O==="*"){Y+="/*",U++,H=!0;continue}}if(_==="'"&&!X){$=!$,Y+=_;continue}if(_==='"'&&!$){X=!X,Y+=_;continue}if(_==="?"&&!$&&!X){Z++,Y+=`$${Z}`;continue}Y+=_}if(n.set(G,Y),n.size>5000){let U=n.keys().next().value;if(U)n.delete(U)}return Y}c();export{t as validateTableForSharding,OG as schemaExists,FG as runShard,sG as runAllShards,dG as run,PJ as resetConfig,qJ as reassignShard,e as prepare,CG as migrateRecord,h as listTables,SJ as listKnownShards,WY as isSQLDatabase,HY as isKVStorage,qG as integrateExistingDatabase,wJ as insertShard,vJ as insert,yG as initializeAsync,LJ as initialize,dJ as indexShard,oJ as indexAllShards,cJ as index,eJ as getTotalDatabaseSize,KJ as getShardStats,rG as getDatabaseSizesAllShards,mJ as getDatabaseSizeForShard,rJ as getDatabaseSizeForKey,EJ as getClosestRegionFromIP,yJ as flush,VG as firstShard,kJ as firstByLookupKey,pJ as firstAllShardsGlobal,aG as firstAllShards,lG as first,lJ as explainShard,sJ as explainAllShards,nJ as explain,wG as dropSchema,i as discoverExistingRecordsWithColumns,s as discoverExistingPrimaryKeys,JY as createValkeyKVProvider,vG as createSchemaAcrossShards,MJ as createSchema,YY as createSQLiteProvider,YJ as createRedisKVProvider,ZJ as createPostgreSQLProvider,ZY as createNuxtHubKVProvider,$J as createMySQLProvider,kG as createMappingsForExistingKeys,$Y as createHyperdrivePostgresProvider,XY as createHyperdriveMySQLProvider,ZG as createDrizzleSQLProvider,tJ as countShard,aJ as countAllShards,iJ as count,jJ as collegedb,bG as clearShardMigrationCache,fG as clearMigrationCache,KG as checkMigrationNeeded,SG as autoDetectAndMigrate,GG as allShard,CJ as allByLookupKey,tG as allAllShardsGlobal,JG as allAllShards,nG as all,eG as ShardCoordinator,S as KVShardMapper,F as CollegeDBError};
|
|
19
19
|
|
|
20
|
-
//# debugId=
|
|
20
|
+
//# debugId=46EBE6102EC18AED64756E2164756E21
|
|
21
21
|
//# sourceMappingURL=index.js.map
|