jsql-neo 4.3.0 → 4.4.0
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 +64 -0
- package/bin/jsql +138 -0
- package/index.d.ts +351 -0
- package/index.js +18 -0
- package/lib/migrate.js +242 -0
- package/lib/mysql_server.js +51 -1
- package/lib/redis_server.js +448 -0
- package/lib/sql.js +125 -51
- package/lib/web_ui.js +226 -0
- package/package.json +66 -56
- package/test/smoke.js +58 -0
- package/wasm/browser.d.ts +88 -0
package/package.json
CHANGED
|
@@ -1,60 +1,70 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"./lib/*": "./lib/*",
|
|
13
|
-
"./package.json": "./package.json"
|
|
2
|
+
"name": "jsql-neo",
|
|
3
|
+
"version": "4.4.0",
|
|
4
|
+
"description": "JSQL-NEO — Rust-powered embedded database with WASM, REST API, B-Tree indexes, WAL, crash recovery",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"browser": "./wasm/browser.mjs",
|
|
11
|
+
"default": "./index.js"
|
|
14
12
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
13
|
+
"./wasm/browser.mjs": {
|
|
14
|
+
"types": "./wasm/browser.d.ts",
|
|
15
|
+
"default": "./wasm/browser.mjs"
|
|
17
16
|
},
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
17
|
+
"./wasm/*": "./wasm/*",
|
|
18
|
+
"./lib/*": "./lib/*",
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"bin": {
|
|
22
|
+
"jsql": "./bin/jsql"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"index.js",
|
|
26
|
+
"index.d.ts",
|
|
27
|
+
"lib/",
|
|
28
|
+
"bin/",
|
|
29
|
+
"wasm/",
|
|
30
|
+
"native/",
|
|
31
|
+
"nativesrc/",
|
|
32
|
+
"!nativesrc/**/target/",
|
|
33
|
+
"postinstall.js",
|
|
34
|
+
"test/",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"postinstall": "node postinstall.js",
|
|
40
|
+
"test": "node test/smoke.js",
|
|
41
|
+
"test:orms": "node examples/orms/run-all.js"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"database",
|
|
45
|
+
"sql",
|
|
46
|
+
"embedded",
|
|
47
|
+
"rust",
|
|
48
|
+
"wasm",
|
|
49
|
+
"json",
|
|
50
|
+
"javascript",
|
|
51
|
+
"jsql",
|
|
52
|
+
"nosql",
|
|
53
|
+
"rest-api",
|
|
54
|
+
"high-performance"
|
|
55
|
+
],
|
|
56
|
+
"author": "Vexify",
|
|
57
|
+
"license": "Apache-2.0",
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "https://github.com/vexify-org/JSQL-neo.git"
|
|
61
|
+
},
|
|
62
|
+
"bugs": "https://github.com/vexify-org/JSQL-neo/issues",
|
|
63
|
+
"homepage": "https://github.com/vexify-org/JSQL-neo#readme",
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=14.0.0"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@vexify-org/yaggs": "^8.1.0"
|
|
69
|
+
}
|
|
60
70
|
}
|
package/test/smoke.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Zero-dependency smoke test for the SQL engine core.
|
|
3
|
+
* npm test (or: node test/smoke.js)
|
|
4
|
+
*/
|
|
5
|
+
const { executeSQL, parseSQL, applyParams } = require('../lib/sql.js');
|
|
6
|
+
const { createMysqlServer } = require('../lib/mysql_server.js');
|
|
7
|
+
|
|
8
|
+
let pass = 0, fail = 0;
|
|
9
|
+
const ok = (name, cond, extra) => {
|
|
10
|
+
if (cond) { pass++; console.log('[OK]', name); }
|
|
11
|
+
else { fail++; console.log('[FAIL]', name, extra !== undefined ? '→ ' + JSON.stringify(extra) : ''); }
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const engine = {
|
|
15
|
+
hasTable: () => true,
|
|
16
|
+
truncate: async () => {},
|
|
17
|
+
flush: async () => {},
|
|
18
|
+
find: async () => [
|
|
19
|
+
{ id: 1, name: 'A', age: 30 },
|
|
20
|
+
{ id: 2, name: 'B', age: 40 },
|
|
21
|
+
{ id: 3, name: 'C', age: 25 },
|
|
22
|
+
],
|
|
23
|
+
getTableSchema: async () => ({
|
|
24
|
+
id: { type: 'integer', primaryKey: true },
|
|
25
|
+
name: { type: 'string' },
|
|
26
|
+
age: { type: 'integer' },
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
(async () => {
|
|
31
|
+
const opts = { safety: false };
|
|
32
|
+
|
|
33
|
+
const agg = await executeSQL(engine, 'SELECT COUNT(*) AS n, MAX(age) AS m, SUM(age) AS s, AVG(age) AS a FROM users', opts);
|
|
34
|
+
ok('multi-aggregate SELECT returns all columns', JSON.stringify(agg.columns) === JSON.stringify(['n', 'm', 's', 'a'])
|
|
35
|
+
&& JSON.stringify(agg.rows[0]) === JSON.stringify([3, 40, 95, 31.666666666666668]), { cols: agg.columns, row: agg.rows[0] });
|
|
36
|
+
|
|
37
|
+
const w = await executeSQL(engine, 'SELECT name, age FROM users WHERE age > 29 ORDER BY age DESC', opts);
|
|
38
|
+
ok('WHERE + ORDER BY', w.rows.length === 2 && w.rows[0][1] === 40, w.rows);
|
|
39
|
+
|
|
40
|
+
const funcs = await executeSQL(engine, "SELECT CONCAT(name, '!') AS c, UPPER(name) AS u, IFNULL(age, 0) AS f FROM users LIMIT 1", opts);
|
|
41
|
+
ok('scalar functions CONCAT/UPPER/IFNULL', funcs.rows[0][0] === 'A!' && funcs.rows[0][1] === 'A', funcs.rows);
|
|
42
|
+
|
|
43
|
+
const c1 = await executeSQL(engine, 'SELECT COUNT(1) AS n FROM users', opts);
|
|
44
|
+
ok('COUNT(1) literal', c1.rows[0][0] === 3, c1.rows);
|
|
45
|
+
|
|
46
|
+
ok('parseSQL TRUNCATE', parseSQL('TRUNCATE TABLE users').type === 'truncate');
|
|
47
|
+
ok('parseSQL START TRANSACTION', parseSQL('START TRANSACTION').type === 'begin');
|
|
48
|
+
ok('parseSQL VALUES DEFAULT', parseSQL(applyParams('INSERT INTO t (id, name) VALUES (DEFAULT, ?)', ['x'])).dataRows[0].id._default === true);
|
|
49
|
+
|
|
50
|
+
const srv = createMysqlServer({ port: 0, host: '127.0.0.1', dataDir: ':memory:', noAuth: true });
|
|
51
|
+
await new Promise(r => srv.listen(r));
|
|
52
|
+
const addr = srv.address;
|
|
53
|
+
ok('createMysqlServer listens on ephemeral port', addr && addr.port > 0, addr);
|
|
54
|
+
srv.close();
|
|
55
|
+
|
|
56
|
+
console.log(fail === 0 ? '\nALL SMOKE TESTS PASSED' : `\n${fail} FAILURES`);
|
|
57
|
+
process.exit(fail === 0 ? 0 : 1);
|
|
58
|
+
})().catch(e => { console.error('FATAL', e.message); process.exit(1); });
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSQL-NEO browser (WASM + IndexedDB) — ESM entry `jsql-neo/wasm/browser.mjs`.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type FieldType =
|
|
6
|
+
| 'string' | 'integer' | 'float' | 'boolean' | 'date' | 'datetime' | 'timestamp'
|
|
7
|
+
| 'object' | 'array' | 'any';
|
|
8
|
+
|
|
9
|
+
export interface FieldDef {
|
|
10
|
+
type: FieldType;
|
|
11
|
+
primaryKey?: boolean;
|
|
12
|
+
autoIncrement?: boolean;
|
|
13
|
+
unique?: boolean;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
length?: number;
|
|
16
|
+
default?: unknown;
|
|
17
|
+
computed?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type Schema = Record<string, FieldDef>;
|
|
21
|
+
|
|
22
|
+
export interface Row {
|
|
23
|
+
id: number | string;
|
|
24
|
+
fields?: Record<string, unknown>;
|
|
25
|
+
created_at?: string;
|
|
26
|
+
updated_at?: string;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface FindOptions {
|
|
31
|
+
limit?: number;
|
|
32
|
+
offset?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type JSQLHook =
|
|
36
|
+
| 'beforeInsert' | 'afterInsert'
|
|
37
|
+
| 'beforeUpdate' | 'afterUpdate'
|
|
38
|
+
| 'beforeDelete' | 'afterDelete'
|
|
39
|
+
| 'beforeFind' | 'afterFind'
|
|
40
|
+
| 'beforeCreateTable' | 'afterCreateTable'
|
|
41
|
+
| 'beforeDropTable' | 'afterDropTable'
|
|
42
|
+
| 'beforeFlush' | 'afterFlush'
|
|
43
|
+
| 'beforeCount' | 'afterCount'
|
|
44
|
+
| 'onStart' | 'onStop';
|
|
45
|
+
|
|
46
|
+
export interface JSQLOptions {
|
|
47
|
+
dbName?: string;
|
|
48
|
+
persistence?: boolean;
|
|
49
|
+
flushThreshold?: number;
|
|
50
|
+
pageSize?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class JSQL {
|
|
54
|
+
constructor(opts?: JSQLOptions);
|
|
55
|
+
on(event: JSQLHook, fn: (...args: any[]) => unknown): this;
|
|
56
|
+
onEvent(fn: (event: string, data: unknown) => void): this;
|
|
57
|
+
start(): Promise<void>;
|
|
58
|
+
stop(): Promise<void>;
|
|
59
|
+
flush(): Promise<void>;
|
|
60
|
+
createTable(name: string, schema: Schema): Promise<unknown>;
|
|
61
|
+
dropTable(name: string): Promise<unknown>;
|
|
62
|
+
insert(table: string, data: Record<string, unknown> | Record<string, unknown>[]): Promise<unknown>;
|
|
63
|
+
findById(table: string, id: number | string): Promise<Row | null>;
|
|
64
|
+
findByIds(table: string, ids: Array<number | string>): Promise<Row[] | null>;
|
|
65
|
+
find(table: string, filter?: Record<string, unknown>, opts?: FindOptions): Promise<Row[]>;
|
|
66
|
+
count(table: string): Promise<number>;
|
|
67
|
+
updateById(table: string, id: number | string, data: Record<string, unknown>): Promise<unknown>;
|
|
68
|
+
updateByIds(table: string, entries: Array<[number | string, Record<string, unknown>]>): Promise<unknown>;
|
|
69
|
+
removeById(table: string, id: number | string): Promise<unknown>;
|
|
70
|
+
removeByIds(table: string, ids: Array<number | string>): Promise<unknown>;
|
|
71
|
+
hasTable(name: string): Promise<boolean>;
|
|
72
|
+
getTables(): Promise<string[]>;
|
|
73
|
+
getTableSchema(name: string): Promise<Schema | null>;
|
|
74
|
+
beginTx(): Promise<void>;
|
|
75
|
+
commitTx(): Promise<void>;
|
|
76
|
+
rollbackTx(): Promise<void>;
|
|
77
|
+
begin(): Promise<void>;
|
|
78
|
+
commit(): Promise<void>;
|
|
79
|
+
rollback(): Promise<void>;
|
|
80
|
+
listDatabases(): Promise<string[]>;
|
|
81
|
+
createDatabase(name: string): Promise<void>;
|
|
82
|
+
dropDatabase(name: string): Promise<void>;
|
|
83
|
+
useDatabase(name: string): Promise<void>;
|
|
84
|
+
executeSQL(sql: string, params?: unknown[]): Promise<unknown>;
|
|
85
|
+
export default?: never;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function init(input?: Uint8Array | ArrayBuffer | Response | WebAssembly.Module | URL | string): Promise<JSQL | void>;
|