js-bao 0.3.0-alpha.2 → 0.3.0-alpha.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 +148 -0
- package/dist/BaseModel-5YQCROYE.js +17 -0
- package/dist/BaseModel-5YQCROYE.js.map +1 -0
- package/dist/BaseModel-FCNWDJBH.js +17 -0
- package/dist/BaseModel-FCNWDJBH.js.map +1 -0
- package/dist/BrowserDatabaseFactory-PXOTK2DQ.js +119 -0
- package/dist/BrowserDatabaseFactory-PXOTK2DQ.js.map +1 -0
- package/dist/BrowserDatabaseFactory-WD4VX2VZ.js +119 -0
- package/dist/BrowserDatabaseFactory-WD4VX2VZ.js.map +1 -0
- package/dist/IncludeResolver-RCKQGNPZ.js +385 -0
- package/dist/IncludeResolver-RCKQGNPZ.js.map +1 -0
- package/dist/IncludeResolver-WGSQDMS7.js +385 -0
- package/dist/IncludeResolver-WGSQDMS7.js.map +1 -0
- package/dist/NodeDatabaseFactory-J4Z36UF3.js +165 -0
- package/dist/NodeDatabaseFactory-J4Z36UF3.js.map +1 -0
- package/dist/NodeDatabaseFactory-QIEKAXBM.js +10 -0
- package/dist/NodeDatabaseFactory-QIEKAXBM.js.map +1 -0
- package/dist/NodeSqliteEngine-HJSAYE4E.js +383 -0
- package/dist/NodeSqliteEngine-HJSAYE4E.js.map +1 -0
- package/dist/NodeSqliteEngine-I5SLWLME.js +383 -0
- package/dist/NodeSqliteEngine-I5SLWLME.js.map +1 -0
- package/dist/browser.cjs +3778 -3369
- package/dist/browser.d.cts +18 -1
- package/dist/browser.d.ts +18 -1
- package/dist/browser.js +3749 -3340
- package/dist/chunk-3PZWHUZO.js +4153 -0
- package/dist/chunk-3PZWHUZO.js.map +1 -0
- package/dist/chunk-53MS4MN7.js +373 -0
- package/dist/chunk-53MS4MN7.js.map +1 -0
- package/dist/chunk-65G2P4GL.js +709 -0
- package/dist/chunk-65G2P4GL.js.map +1 -0
- package/dist/chunk-6UX3YSCW.js +4151 -0
- package/dist/chunk-6UX3YSCW.js.map +1 -0
- package/dist/chunk-DANSD6BE.js +709 -0
- package/dist/chunk-DANSD6BE.js.map +1 -0
- package/dist/chunk-DF3JEQXA.js +373 -0
- package/dist/chunk-DF3JEQXA.js.map +1 -0
- package/dist/chunk-GO3APTPX.js +61 -0
- package/dist/chunk-GO3APTPX.js.map +1 -0
- package/dist/chunk-ID4U6IQC.js +53 -0
- package/dist/chunk-ID4U6IQC.js.map +1 -0
- package/dist/chunk-RQVS3LVL.js +165 -0
- package/dist/chunk-RQVS3LVL.js.map +1 -0
- package/dist/client.cjs +141 -70
- package/dist/client.d.cts +18 -1
- package/dist/client.d.ts +18 -1
- package/dist/client.js +135 -62
- package/dist/cloudflare-do.cjs +335 -2
- package/dist/cloudflare-do.d.cts +38 -0
- package/dist/cloudflare-do.d.ts +38 -0
- package/dist/cloudflare-do.js +335 -2
- package/dist/cloudflare.cjs +142 -71
- package/dist/cloudflare.d.cts +18 -1
- package/dist/cloudflare.d.ts +18 -1
- package/dist/cloudflare.js +135 -62
- package/dist/codegen.cjs +2 -2
- package/dist/environment-TOTQICSE.js +17 -0
- package/dist/environment-TOTQICSE.js.map +1 -0
- package/dist/index.cjs +1898 -1489
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +1863 -1454
- package/dist/node.cjs +4772 -4363
- package/dist/node.d.cts +18 -1
- package/dist/node.d.ts +18 -1
- package/dist/node.js +4751 -4342
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -848,6 +848,154 @@ const productSummary = await Product.query(
|
|
|
848
848
|
// Returns: [{ id: "...", name: "...", price: ... }, ...]
|
|
849
849
|
```
|
|
850
850
|
|
|
851
|
+
### Includes (Related Data)
|
|
852
|
+
|
|
853
|
+
Load related records alongside query results using `include`. Each include spec tells the engine how to resolve a relationship between models.
|
|
854
|
+
|
|
855
|
+
**Include types:**
|
|
856
|
+
|
|
857
|
+
| Type | Relationship | Example |
|
|
858
|
+
|------|-------------|---------|
|
|
859
|
+
| `refersTo` | Record has a FK field pointing to one target | Order → Customer |
|
|
860
|
+
| `hasMany` | Target records have a FK field pointing back to this record | Customer → Orders |
|
|
861
|
+
| `refersToMany` | Record has a StringSet field containing multiple target IDs | Post → Tags |
|
|
862
|
+
|
|
863
|
+
#### refersTo — Scalar foreign key
|
|
864
|
+
|
|
865
|
+
Load a single related record via a foreign key field on the source.
|
|
866
|
+
|
|
867
|
+
```typescript
|
|
868
|
+
// Schema: Order has a `customerId` field
|
|
869
|
+
const orders = await Order.query({}, {
|
|
870
|
+
include: [{
|
|
871
|
+
model: "customers",
|
|
872
|
+
type: "refersTo",
|
|
873
|
+
sourceField: "customerId", // FK field on Order
|
|
874
|
+
as: "customer", // result key (optional, defaults to model name)
|
|
875
|
+
projection: { name: 1 }, // only load specific fields
|
|
876
|
+
}],
|
|
877
|
+
});
|
|
878
|
+
// Each order gets: order._related.customer = { id, name }
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
#### hasMany — Reverse foreign key
|
|
882
|
+
|
|
883
|
+
Load multiple related records that reference this record.
|
|
884
|
+
|
|
885
|
+
```typescript
|
|
886
|
+
// Schema: Comment has an `articleId` field pointing to Article
|
|
887
|
+
const articles = await Article.query({}, {
|
|
888
|
+
include: [{
|
|
889
|
+
model: "comments",
|
|
890
|
+
type: "hasMany",
|
|
891
|
+
foreignKey: "articleId", // FK field on Comment pointing back
|
|
892
|
+
as: "comments",
|
|
893
|
+
limit: 10, // cap per parent
|
|
894
|
+
sort: { createdAt: -1 }, // newest first
|
|
895
|
+
}],
|
|
896
|
+
});
|
|
897
|
+
// Each article gets: article._related.comments = [{ id, text, ... }, ...]
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
#### refersToMany — StringSet of IDs
|
|
901
|
+
|
|
902
|
+
Load multiple related records referenced by a StringSet field.
|
|
903
|
+
|
|
904
|
+
```typescript
|
|
905
|
+
// Schema: Post has a `tagIds` StringSet field containing Tag IDs
|
|
906
|
+
const posts = await Post.query({}, {
|
|
907
|
+
include: [{
|
|
908
|
+
model: "tags",
|
|
909
|
+
type: "refersToMany",
|
|
910
|
+
sourceField: "tagIds", // StringSet field on Post
|
|
911
|
+
as: "tags",
|
|
912
|
+
projection: { name: 1 },
|
|
913
|
+
}],
|
|
914
|
+
});
|
|
915
|
+
// Each post gets: post._related.tags = [{ id, name }, ...]
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
#### End-to-end example: write and query
|
|
919
|
+
|
|
920
|
+
```typescript
|
|
921
|
+
// 1. Create tags
|
|
922
|
+
const techTag = await Tag.create({ id: generateULID(), name: "Tech" });
|
|
923
|
+
const newsTag = await Tag.create({ id: generateULID(), name: "News" });
|
|
924
|
+
|
|
925
|
+
// 2. Create a post with references to tags via StringSet
|
|
926
|
+
const post = await Post.create({ id: generateULID(), title: "Hello World" });
|
|
927
|
+
await Post.addToSet(post.id, { tagIds: [techTag.id, newsTag.id] });
|
|
928
|
+
|
|
929
|
+
// 3. Create a comment referencing the post
|
|
930
|
+
await Comment.create({
|
|
931
|
+
id: generateULID(),
|
|
932
|
+
postId: post.id,
|
|
933
|
+
text: "Great post!",
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
// 4. Query posts with all related data in one call
|
|
937
|
+
const results = await Post.query({}, {
|
|
938
|
+
include: [
|
|
939
|
+
{
|
|
940
|
+
model: "tags",
|
|
941
|
+
type: "refersToMany",
|
|
942
|
+
sourceField: "tagIds",
|
|
943
|
+
as: "tags",
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
model: "comments",
|
|
947
|
+
type: "hasMany",
|
|
948
|
+
foreignKey: "postId",
|
|
949
|
+
as: "comments",
|
|
950
|
+
sort: { createdAt: -1 },
|
|
951
|
+
},
|
|
952
|
+
],
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// Result:
|
|
956
|
+
// results.data[0]._related.tags = [{ id: "...", name: "Tech" }, { id: "...", name: "News" }]
|
|
957
|
+
// results.data[0]._related.comments = [{ id: "...", postId: "...", text: "Great post!" }]
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
#### Nested includes
|
|
961
|
+
|
|
962
|
+
Includes can be nested to load relationships on related records:
|
|
963
|
+
|
|
964
|
+
```typescript
|
|
965
|
+
const articles = await Article.query({}, {
|
|
966
|
+
include: [{
|
|
967
|
+
model: "comments",
|
|
968
|
+
type: "hasMany",
|
|
969
|
+
foreignKey: "articleId",
|
|
970
|
+
as: "comments",
|
|
971
|
+
include: [{
|
|
972
|
+
model: "users",
|
|
973
|
+
type: "refersTo",
|
|
974
|
+
sourceField: "authorId",
|
|
975
|
+
as: "author",
|
|
976
|
+
projection: { name: 1 },
|
|
977
|
+
}],
|
|
978
|
+
}],
|
|
979
|
+
});
|
|
980
|
+
// article._related.comments[0]._related.author = { id, name }
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
#### Filtering included records
|
|
984
|
+
|
|
985
|
+
Apply filters to narrow which related records are loaded:
|
|
986
|
+
|
|
987
|
+
```typescript
|
|
988
|
+
const posts = await Post.query({}, {
|
|
989
|
+
include: [{
|
|
990
|
+
model: "comments",
|
|
991
|
+
type: "hasMany",
|
|
992
|
+
foreignKey: "postId",
|
|
993
|
+
filter: { status: "approved" }, // only approved comments
|
|
994
|
+
as: "comments",
|
|
995
|
+
}],
|
|
996
|
+
});
|
|
997
|
+
```
|
|
998
|
+
|
|
851
999
|
### Single Document Queries
|
|
852
1000
|
|
|
853
1001
|
```typescript
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseModel,
|
|
3
|
+
LogLevel,
|
|
4
|
+
Logger,
|
|
5
|
+
RecordNotFoundError,
|
|
6
|
+
UniqueConstraintViolationError,
|
|
7
|
+
generateULID
|
|
8
|
+
} from "./chunk-3PZWHUZO.js";
|
|
9
|
+
export {
|
|
10
|
+
BaseModel,
|
|
11
|
+
LogLevel,
|
|
12
|
+
Logger,
|
|
13
|
+
RecordNotFoundError,
|
|
14
|
+
UniqueConstraintViolationError,
|
|
15
|
+
generateULID
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=BaseModel-5YQCROYE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseModel,
|
|
3
|
+
LogLevel,
|
|
4
|
+
Logger,
|
|
5
|
+
RecordNotFoundError,
|
|
6
|
+
UniqueConstraintViolationError,
|
|
7
|
+
generateULID
|
|
8
|
+
} from "./chunk-6UX3YSCW.js";
|
|
9
|
+
export {
|
|
10
|
+
BaseModel,
|
|
11
|
+
LogLevel,
|
|
12
|
+
Logger,
|
|
13
|
+
RecordNotFoundError,
|
|
14
|
+
UniqueConstraintViolationError,
|
|
15
|
+
generateULID
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=BaseModel-FCNWDJBH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SqljsEngine
|
|
3
|
+
} from "./chunk-53MS4MN7.js";
|
|
4
|
+
import {
|
|
5
|
+
features
|
|
6
|
+
} from "./chunk-GO3APTPX.js";
|
|
7
|
+
import {
|
|
8
|
+
Logger
|
|
9
|
+
} from "./chunk-6UX3YSCW.js";
|
|
10
|
+
|
|
11
|
+
// src/engines/BrowserDatabaseFactory.ts
|
|
12
|
+
var BrowserDatabaseFactory = class {
|
|
13
|
+
/**
|
|
14
|
+
* Dynamically loads browser-compatible engines only
|
|
15
|
+
*/
|
|
16
|
+
static async loadBrowserEngines() {
|
|
17
|
+
Logger.debug("[BrowserDatabaseFactory] Browser engines ready");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Auto-detects the best available engine for browser
|
|
21
|
+
*/
|
|
22
|
+
static getRecommendedEngineType() {
|
|
23
|
+
if (features.hasWebAssembly) {
|
|
24
|
+
return "sqljs";
|
|
25
|
+
}
|
|
26
|
+
throw new Error(
|
|
27
|
+
"No compatible database engine found. WebAssembly is required for browser environments."
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a fallback engine when the requested engine is not available
|
|
32
|
+
*/
|
|
33
|
+
static async createFallbackEngine(requestedType, config) {
|
|
34
|
+
const fallbackType = this.getRecommendedEngineType();
|
|
35
|
+
console.warn(
|
|
36
|
+
`[BrowserDatabaseFactory] Requested engine '${requestedType}' is not available. Falling back to '${fallbackType}'.`
|
|
37
|
+
);
|
|
38
|
+
const fallbackConfig = { ...config, type: fallbackType };
|
|
39
|
+
return this.createEngine(fallbackConfig, false);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates the specified database engine (browser-compatible only)
|
|
43
|
+
*/
|
|
44
|
+
static async createEngine(config, allowFallback = true) {
|
|
45
|
+
const { type, options } = config;
|
|
46
|
+
const typeStr = type;
|
|
47
|
+
switch (type) {
|
|
48
|
+
case "sqljs":
|
|
49
|
+
const sqljsEngine = new SqljsEngine(options);
|
|
50
|
+
await sqljsEngine.ensureReady();
|
|
51
|
+
return sqljsEngine;
|
|
52
|
+
case "alasql":
|
|
53
|
+
throw new Error("AlaSQLEngine not yet implemented.");
|
|
54
|
+
default:
|
|
55
|
+
if (typeStr === "duckdb") {
|
|
56
|
+
if (allowFallback) {
|
|
57
|
+
console.warn(
|
|
58
|
+
"[BrowserDatabaseFactory] DuckDB engine is no longer supported, falling back to alternative engine"
|
|
59
|
+
);
|
|
60
|
+
return this.createFallbackEngine(typeStr, config);
|
|
61
|
+
}
|
|
62
|
+
throw new Error("DuckDB engine is no longer supported");
|
|
63
|
+
}
|
|
64
|
+
if (typeStr === "node-sqlite" || typeStr === "node-duckdb") {
|
|
65
|
+
if (allowFallback) {
|
|
66
|
+
console.warn(
|
|
67
|
+
`[BrowserDatabaseFactory] Engine '${typeStr}' is not available in browser. Falling back to browser-compatible engine.`
|
|
68
|
+
);
|
|
69
|
+
return this.createFallbackEngine(typeStr, config);
|
|
70
|
+
}
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Engine '${typeStr}' is only available in Node.js environments`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`Unsupported database engine type: ${typeStr}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
static async getEngine(config) {
|
|
79
|
+
await this.loadBrowserEngines();
|
|
80
|
+
Logger.debug(
|
|
81
|
+
`[BrowserDatabaseFactory] Creating engine for type: ${config.type}`
|
|
82
|
+
);
|
|
83
|
+
try {
|
|
84
|
+
const engine = await this.createEngine(config);
|
|
85
|
+
Logger.debug(
|
|
86
|
+
`[BrowserDatabaseFactory] Engine for type ${config.type} is ready.`
|
|
87
|
+
);
|
|
88
|
+
return engine;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error(
|
|
91
|
+
`[BrowserDatabaseFactory] Failed to create engine for type ${config.type}:`,
|
|
92
|
+
error
|
|
93
|
+
);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets information about available engines in browser environment
|
|
99
|
+
*/
|
|
100
|
+
static getAvailableEngines() {
|
|
101
|
+
const engines = [
|
|
102
|
+
{
|
|
103
|
+
type: "sqljs",
|
|
104
|
+
available: features.hasWebAssembly,
|
|
105
|
+
reason: !features.hasWebAssembly ? "WebAssembly not supported" : void 0
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: "node-sqlite",
|
|
109
|
+
available: false,
|
|
110
|
+
reason: "Node.js engines not available in browser"
|
|
111
|
+
}
|
|
112
|
+
];
|
|
113
|
+
return engines;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
export {
|
|
117
|
+
BrowserDatabaseFactory
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=BrowserDatabaseFactory-PXOTK2DQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engines/BrowserDatabaseFactory.ts"],"sourcesContent":["import { DatabaseConfig } from \"../types/databaseTypes\";\nimport { DatabaseEngine } from \"./DatabaseEngine\";\nimport { SqljsEngine } from \"./SqljsEngine\";\nimport { features } from \"../utils/environment\";\nimport { Logger } from \"../models/BaseModel\";\n\nexport class BrowserDatabaseFactory {\n /**\n * Dynamically loads browser-compatible engines only\n */\n private static async loadBrowserEngines() {\n // No dynamic loading needed for SQL.js as it's imported statically\n Logger.debug(\"[BrowserDatabaseFactory] Browser engines ready\");\n }\n\n /**\n * Auto-detects the best available engine for browser\n */\n private static getRecommendedEngineType(): string {\n // In browser, prefer SQL.js as it's more stable than DuckDB-WASM\n if (features.hasWebAssembly) {\n return \"sqljs\";\n }\n\n throw new Error(\n \"No compatible database engine found. WebAssembly is required for browser environments.\"\n );\n }\n\n /**\n * Creates a fallback engine when the requested engine is not available\n */\n private static async createFallbackEngine(\n requestedType: string,\n config: DatabaseConfig\n ): Promise<DatabaseEngine> {\n const fallbackType = this.getRecommendedEngineType();\n\n console.warn(\n `[BrowserDatabaseFactory] Requested engine '${requestedType}' is not available. ` +\n `Falling back to '${fallbackType}'.`\n );\n\n const fallbackConfig = { ...config, type: fallbackType as any };\n return this.createEngine(fallbackConfig, false); // Prevent infinite recursion\n }\n\n /**\n * Creates the specified database engine (browser-compatible only)\n */\n private static async createEngine(\n config: DatabaseConfig,\n allowFallback: boolean = true\n ): Promise<DatabaseEngine> {\n const { type, options } = config;\n const typeStr = type as string; // Cast to handle legacy engine types\n\n switch (type) {\n case \"sqljs\":\n const sqljsEngine = new SqljsEngine(options as any);\n await sqljsEngine.ensureReady();\n return sqljsEngine;\n\n case \"alasql\":\n throw new Error(\"AlaSQLEngine not yet implemented.\");\n\n default:\n // Handle removed engine types and unsupported types\n if (typeStr === \"duckdb\") {\n if (allowFallback) {\n console.warn(\n \"[BrowserDatabaseFactory] DuckDB engine is no longer supported, falling back to alternative engine\"\n );\n return this.createFallbackEngine(typeStr, config);\n }\n throw new Error(\"DuckDB engine is no longer supported\");\n }\n\n if (typeStr === \"node-sqlite\" || typeStr === \"node-duckdb\") {\n if (allowFallback) {\n console.warn(\n `[BrowserDatabaseFactory] Engine '${typeStr}' is not available in browser. Falling back to browser-compatible engine.`\n );\n return this.createFallbackEngine(typeStr, config);\n }\n throw new Error(\n `Engine '${typeStr}' is only available in Node.js environments`\n );\n }\n\n throw new Error(`Unsupported database engine type: ${typeStr}`);\n }\n }\n\n public static async getEngine(\n config: DatabaseConfig\n ): Promise<DatabaseEngine> {\n // Load browser engines\n await this.loadBrowserEngines();\n\n Logger.debug(\n `[BrowserDatabaseFactory] Creating engine for type: ${config.type}`\n );\n\n try {\n const engine = await this.createEngine(config);\n\n Logger.debug(\n `[BrowserDatabaseFactory] Engine for type ${config.type} is ready.`\n );\n return engine;\n } catch (error) {\n console.error(\n `[BrowserDatabaseFactory] Failed to create engine for type ${config.type}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Gets information about available engines in browser environment\n */\n public static getAvailableEngines(): {\n type: string;\n available: boolean;\n reason?: string;\n }[] {\n const engines = [\n {\n type: \"sqljs\",\n available: features.hasWebAssembly,\n reason: !features.hasWebAssembly\n ? \"WebAssembly not supported\"\n : undefined,\n },\n {\n type: \"node-sqlite\",\n available: false,\n reason: \"Node.js engines not available in browser\",\n },\n ];\n\n return engines;\n }\n}\n"],"mappings":";;;;;;;;;;;AAMO,IAAM,yBAAN,MAA6B;AAAA;AAAA;AAAA;AAAA,EAIlC,aAAqB,qBAAqB;AAExC,WAAO,MAAM,gDAAgD;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,2BAAmC;AAEhD,QAAI,SAAS,gBAAgB;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,qBACnB,eACA,QACyB;AACzB,UAAM,eAAe,KAAK,yBAAyB;AAEnD,YAAQ;AAAA,MACN,8CAA8C,aAAa,wCACrC,YAAY;AAAA,IACpC;AAEA,UAAM,iBAAiB,EAAE,GAAG,QAAQ,MAAM,aAAoB;AAC9D,WAAO,KAAK,aAAa,gBAAgB,KAAK;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,aACnB,QACA,gBAAyB,MACA;AACzB,UAAM,EAAE,MAAM,QAAQ,IAAI;AAC1B,UAAM,UAAU;AAEhB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,cAAM,cAAc,IAAI,YAAY,OAAc;AAClD,cAAM,YAAY,YAAY;AAC9B,eAAO;AAAA,MAET,KAAK;AACH,cAAM,IAAI,MAAM,mCAAmC;AAAA,MAErD;AAEE,YAAI,YAAY,UAAU;AACxB,cAAI,eAAe;AACjB,oBAAQ;AAAA,cACN;AAAA,YACF;AACA,mBAAO,KAAK,qBAAqB,SAAS,MAAM;AAAA,UAClD;AACA,gBAAM,IAAI,MAAM,sCAAsC;AAAA,QACxD;AAEA,YAAI,YAAY,iBAAiB,YAAY,eAAe;AAC1D,cAAI,eAAe;AACjB,oBAAQ;AAAA,cACN,oCAAoC,OAAO;AAAA,YAC7C;AACA,mBAAO,KAAK,qBAAqB,SAAS,MAAM;AAAA,UAClD;AACA,gBAAM,IAAI;AAAA,YACR,WAAW,OAAO;AAAA,UACpB;AAAA,QACF;AAEA,cAAM,IAAI,MAAM,qCAAqC,OAAO,EAAE;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,aAAoB,UAClB,QACyB;AAEzB,UAAM,KAAK,mBAAmB;AAE9B,WAAO;AAAA,MACL,sDAAsD,OAAO,IAAI;AAAA,IACnE;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,aAAa,MAAM;AAE7C,aAAO;AAAA,QACL,4CAA4C,OAAO,IAAI;AAAA,MACzD;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,6DAA6D,OAAO,IAAI;AAAA,QACxE;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,sBAIV;AACF,UAAM,UAAU;AAAA,MACd;AAAA,QACE,MAAM;AAAA,QACN,WAAW,SAAS;AAAA,QACpB,QAAQ,CAAC,SAAS,iBACd,8BACA;AAAA,MACN;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SqljsEngine
|
|
3
|
+
} from "./chunk-DF3JEQXA.js";
|
|
4
|
+
import {
|
|
5
|
+
features
|
|
6
|
+
} from "./chunk-ID4U6IQC.js";
|
|
7
|
+
import {
|
|
8
|
+
Logger
|
|
9
|
+
} from "./chunk-3PZWHUZO.js";
|
|
10
|
+
|
|
11
|
+
// src/engines/BrowserDatabaseFactory.ts
|
|
12
|
+
var BrowserDatabaseFactory = class {
|
|
13
|
+
/**
|
|
14
|
+
* Dynamically loads browser-compatible engines only
|
|
15
|
+
*/
|
|
16
|
+
static async loadBrowserEngines() {
|
|
17
|
+
Logger.debug("[BrowserDatabaseFactory] Browser engines ready");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Auto-detects the best available engine for browser
|
|
21
|
+
*/
|
|
22
|
+
static getRecommendedEngineType() {
|
|
23
|
+
if (features.hasWebAssembly) {
|
|
24
|
+
return "sqljs";
|
|
25
|
+
}
|
|
26
|
+
throw new Error(
|
|
27
|
+
"No compatible database engine found. WebAssembly is required for browser environments."
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a fallback engine when the requested engine is not available
|
|
32
|
+
*/
|
|
33
|
+
static async createFallbackEngine(requestedType, config) {
|
|
34
|
+
const fallbackType = this.getRecommendedEngineType();
|
|
35
|
+
console.warn(
|
|
36
|
+
`[BrowserDatabaseFactory] Requested engine '${requestedType}' is not available. Falling back to '${fallbackType}'.`
|
|
37
|
+
);
|
|
38
|
+
const fallbackConfig = { ...config, type: fallbackType };
|
|
39
|
+
return this.createEngine(fallbackConfig, false);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates the specified database engine (browser-compatible only)
|
|
43
|
+
*/
|
|
44
|
+
static async createEngine(config, allowFallback = true) {
|
|
45
|
+
const { type, options } = config;
|
|
46
|
+
const typeStr = type;
|
|
47
|
+
switch (type) {
|
|
48
|
+
case "sqljs":
|
|
49
|
+
const sqljsEngine = new SqljsEngine(options);
|
|
50
|
+
await sqljsEngine.ensureReady();
|
|
51
|
+
return sqljsEngine;
|
|
52
|
+
case "alasql":
|
|
53
|
+
throw new Error("AlaSQLEngine not yet implemented.");
|
|
54
|
+
default:
|
|
55
|
+
if (typeStr === "duckdb") {
|
|
56
|
+
if (allowFallback) {
|
|
57
|
+
console.warn(
|
|
58
|
+
"[BrowserDatabaseFactory] DuckDB engine is no longer supported, falling back to alternative engine"
|
|
59
|
+
);
|
|
60
|
+
return this.createFallbackEngine(typeStr, config);
|
|
61
|
+
}
|
|
62
|
+
throw new Error("DuckDB engine is no longer supported");
|
|
63
|
+
}
|
|
64
|
+
if (typeStr === "node-sqlite" || typeStr === "node-duckdb") {
|
|
65
|
+
if (allowFallback) {
|
|
66
|
+
console.warn(
|
|
67
|
+
`[BrowserDatabaseFactory] Engine '${typeStr}' is not available in browser. Falling back to browser-compatible engine.`
|
|
68
|
+
);
|
|
69
|
+
return this.createFallbackEngine(typeStr, config);
|
|
70
|
+
}
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Engine '${typeStr}' is only available in Node.js environments`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
throw new Error(`Unsupported database engine type: ${typeStr}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
static async getEngine(config) {
|
|
79
|
+
await this.loadBrowserEngines();
|
|
80
|
+
Logger.debug(
|
|
81
|
+
`[BrowserDatabaseFactory] Creating engine for type: ${config.type}`
|
|
82
|
+
);
|
|
83
|
+
try {
|
|
84
|
+
const engine = await this.createEngine(config);
|
|
85
|
+
Logger.debug(
|
|
86
|
+
`[BrowserDatabaseFactory] Engine for type ${config.type} is ready.`
|
|
87
|
+
);
|
|
88
|
+
return engine;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error(
|
|
91
|
+
`[BrowserDatabaseFactory] Failed to create engine for type ${config.type}:`,
|
|
92
|
+
error
|
|
93
|
+
);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets information about available engines in browser environment
|
|
99
|
+
*/
|
|
100
|
+
static getAvailableEngines() {
|
|
101
|
+
const engines = [
|
|
102
|
+
{
|
|
103
|
+
type: "sqljs",
|
|
104
|
+
available: features.hasWebAssembly,
|
|
105
|
+
reason: !features.hasWebAssembly ? "WebAssembly not supported" : void 0
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
type: "node-sqlite",
|
|
109
|
+
available: false,
|
|
110
|
+
reason: "Node.js engines not available in browser"
|
|
111
|
+
}
|
|
112
|
+
];
|
|
113
|
+
return engines;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
export {
|
|
117
|
+
BrowserDatabaseFactory
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=BrowserDatabaseFactory-WD4VX2VZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engines/BrowserDatabaseFactory.ts"],"sourcesContent":["import { DatabaseConfig } from \"../types/databaseTypes\";\nimport { DatabaseEngine } from \"./DatabaseEngine\";\nimport { SqljsEngine } from \"./SqljsEngine\";\nimport { features } from \"../utils/environment\";\nimport { Logger } from \"../models/BaseModel\";\n\nexport class BrowserDatabaseFactory {\n /**\n * Dynamically loads browser-compatible engines only\n */\n private static async loadBrowserEngines() {\n // No dynamic loading needed for SQL.js as it's imported statically\n Logger.debug(\"[BrowserDatabaseFactory] Browser engines ready\");\n }\n\n /**\n * Auto-detects the best available engine for browser\n */\n private static getRecommendedEngineType(): string {\n // In browser, prefer SQL.js as it's more stable than DuckDB-WASM\n if (features.hasWebAssembly) {\n return \"sqljs\";\n }\n\n throw new Error(\n \"No compatible database engine found. WebAssembly is required for browser environments.\"\n );\n }\n\n /**\n * Creates a fallback engine when the requested engine is not available\n */\n private static async createFallbackEngine(\n requestedType: string,\n config: DatabaseConfig\n ): Promise<DatabaseEngine> {\n const fallbackType = this.getRecommendedEngineType();\n\n console.warn(\n `[BrowserDatabaseFactory] Requested engine '${requestedType}' is not available. ` +\n `Falling back to '${fallbackType}'.`\n );\n\n const fallbackConfig = { ...config, type: fallbackType as any };\n return this.createEngine(fallbackConfig, false); // Prevent infinite recursion\n }\n\n /**\n * Creates the specified database engine (browser-compatible only)\n */\n private static async createEngine(\n config: DatabaseConfig,\n allowFallback: boolean = true\n ): Promise<DatabaseEngine> {\n const { type, options } = config;\n const typeStr = type as string; // Cast to handle legacy engine types\n\n switch (type) {\n case \"sqljs\":\n const sqljsEngine = new SqljsEngine(options as any);\n await sqljsEngine.ensureReady();\n return sqljsEngine;\n\n case \"alasql\":\n throw new Error(\"AlaSQLEngine not yet implemented.\");\n\n default:\n // Handle removed engine types and unsupported types\n if (typeStr === \"duckdb\") {\n if (allowFallback) {\n console.warn(\n \"[BrowserDatabaseFactory] DuckDB engine is no longer supported, falling back to alternative engine\"\n );\n return this.createFallbackEngine(typeStr, config);\n }\n throw new Error(\"DuckDB engine is no longer supported\");\n }\n\n if (typeStr === \"node-sqlite\" || typeStr === \"node-duckdb\") {\n if (allowFallback) {\n console.warn(\n `[BrowserDatabaseFactory] Engine '${typeStr}' is not available in browser. Falling back to browser-compatible engine.`\n );\n return this.createFallbackEngine(typeStr, config);\n }\n throw new Error(\n `Engine '${typeStr}' is only available in Node.js environments`\n );\n }\n\n throw new Error(`Unsupported database engine type: ${typeStr}`);\n }\n }\n\n public static async getEngine(\n config: DatabaseConfig\n ): Promise<DatabaseEngine> {\n // Load browser engines\n await this.loadBrowserEngines();\n\n Logger.debug(\n `[BrowserDatabaseFactory] Creating engine for type: ${config.type}`\n );\n\n try {\n const engine = await this.createEngine(config);\n\n Logger.debug(\n `[BrowserDatabaseFactory] Engine for type ${config.type} is ready.`\n );\n return engine;\n } catch (error) {\n console.error(\n `[BrowserDatabaseFactory] Failed to create engine for type ${config.type}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Gets information about available engines in browser environment\n */\n public static getAvailableEngines(): {\n type: string;\n available: boolean;\n reason?: string;\n }[] {\n const engines = [\n {\n type: \"sqljs\",\n available: features.hasWebAssembly,\n reason: !features.hasWebAssembly\n ? \"WebAssembly not supported\"\n : undefined,\n },\n {\n type: \"node-sqlite\",\n available: false,\n reason: \"Node.js engines not available in browser\",\n },\n ];\n\n return engines;\n }\n}\n"],"mappings":";;;;;;;;;;;AAMO,IAAM,yBAAN,MAA6B;AAAA;AAAA;AAAA;AAAA,EAIlC,aAAqB,qBAAqB;AAExC,WAAO,MAAM,gDAAgD;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,2BAAmC;AAEhD,QAAI,SAAS,gBAAgB;AAC3B,aAAO;AAAA,IACT;AAEA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,qBACnB,eACA,QACyB;AACzB,UAAM,eAAe,KAAK,yBAAyB;AAEnD,YAAQ;AAAA,MACN,8CAA8C,aAAa,wCACrC,YAAY;AAAA,IACpC;AAEA,UAAM,iBAAiB,EAAE,GAAG,QAAQ,MAAM,aAAoB;AAC9D,WAAO,KAAK,aAAa,gBAAgB,KAAK;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,aACnB,QACA,gBAAyB,MACA;AACzB,UAAM,EAAE,MAAM,QAAQ,IAAI;AAC1B,UAAM,UAAU;AAEhB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,cAAM,cAAc,IAAI,YAAY,OAAc;AAClD,cAAM,YAAY,YAAY;AAC9B,eAAO;AAAA,MAET,KAAK;AACH,cAAM,IAAI,MAAM,mCAAmC;AAAA,MAErD;AAEE,YAAI,YAAY,UAAU;AACxB,cAAI,eAAe;AACjB,oBAAQ;AAAA,cACN;AAAA,YACF;AACA,mBAAO,KAAK,qBAAqB,SAAS,MAAM;AAAA,UAClD;AACA,gBAAM,IAAI,MAAM,sCAAsC;AAAA,QACxD;AAEA,YAAI,YAAY,iBAAiB,YAAY,eAAe;AAC1D,cAAI,eAAe;AACjB,oBAAQ;AAAA,cACN,oCAAoC,OAAO;AAAA,YAC7C;AACA,mBAAO,KAAK,qBAAqB,SAAS,MAAM;AAAA,UAClD;AACA,gBAAM,IAAI;AAAA,YACR,WAAW,OAAO;AAAA,UACpB;AAAA,QACF;AAEA,cAAM,IAAI,MAAM,qCAAqC,OAAO,EAAE;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,aAAoB,UAClB,QACyB;AAEzB,UAAM,KAAK,mBAAmB;AAE9B,WAAO;AAAA,MACL,sDAAsD,OAAO,IAAI;AAAA,IACnE;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,aAAa,MAAM;AAE7C,aAAO;AAAA,QACL,4CAA4C,OAAO,IAAI;AAAA,MACzD;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,6DAA6D,OAAO,IAAI;AAAA,QACxE;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAc,sBAIV;AACF,UAAM,UAAU;AAAA,MACd;AAAA,QACE,MAAM;AAAA,QACN,WAAW,SAAS;AAAA,QACpB,QAAQ,CAAC,SAAS,iBACd,8BACA;AAAA,MACN;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
|