@yorozu/db-sqlite 0.5.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/LICENSE +21 -0
- package/README.md +37 -0
- package/driver.d.ts +8 -0
- package/handle.d.ts +14 -0
- package/index.d.ts +3 -0
- package/index.js +2365 -0
- package/package.json +26 -0
package/index.js
ADDED
|
@@ -0,0 +1,2365 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
24
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
25
|
+
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/handle.ts
|
|
29
|
+
function bindArgs(params) {
|
|
30
|
+
return params === void 0 ? [] : [...params];
|
|
31
|
+
}
|
|
32
|
+
/** Wrap a better-sqlite3 Database. Array bind: `stmt.run(...params)`. */
|
|
33
|
+
function wrapBetterSqlite3(db) {
|
|
34
|
+
return {
|
|
35
|
+
exec(sql) {
|
|
36
|
+
db.exec(sql);
|
|
37
|
+
},
|
|
38
|
+
prepare(sql) {
|
|
39
|
+
let stmt = db.prepare(sql);
|
|
40
|
+
return {
|
|
41
|
+
run(params) {
|
|
42
|
+
stmt.run(...bindArgs(params));
|
|
43
|
+
},
|
|
44
|
+
all(params) {
|
|
45
|
+
return stmt.all(...bindArgs(params));
|
|
46
|
+
},
|
|
47
|
+
get(params) {
|
|
48
|
+
return stmt.get(...bindArgs(params));
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
transaction(fn) {
|
|
53
|
+
return db.transaction(fn)();
|
|
54
|
+
},
|
|
55
|
+
close() {
|
|
56
|
+
db.close();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region __vite-browser-external
|
|
62
|
+
var require___vite_browser_external = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
63
|
+
module.exports = {};
|
|
64
|
+
}));
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/util.js
|
|
67
|
+
var require_util = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
68
|
+
exports.getBooleanOption = (options, key) => {
|
|
69
|
+
let value = false;
|
|
70
|
+
if (key in options && typeof (value = options[key]) !== "boolean") throw new TypeError(`Expected the "${key}" option to be a boolean`);
|
|
71
|
+
return value;
|
|
72
|
+
};
|
|
73
|
+
exports.cppdb = Symbol();
|
|
74
|
+
exports.inspect = Symbol.for("nodejs.util.inspect.custom");
|
|
75
|
+
}));
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/sqlite-error.js
|
|
78
|
+
var require_sqlite_error = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
79
|
+
var descriptor = {
|
|
80
|
+
value: "SqliteError",
|
|
81
|
+
writable: true,
|
|
82
|
+
enumerable: false,
|
|
83
|
+
configurable: true
|
|
84
|
+
};
|
|
85
|
+
function SqliteError(message, code) {
|
|
86
|
+
if (new.target !== SqliteError) return new SqliteError(message, code);
|
|
87
|
+
if (typeof code !== "string") throw new TypeError("Expected second argument to be a string");
|
|
88
|
+
Error.call(this, message);
|
|
89
|
+
descriptor.value = "" + message;
|
|
90
|
+
Object.defineProperty(this, "message", descriptor);
|
|
91
|
+
Error.captureStackTrace(this, SqliteError);
|
|
92
|
+
this.code = code;
|
|
93
|
+
}
|
|
94
|
+
Object.setPrototypeOf(SqliteError, Error);
|
|
95
|
+
Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
|
|
96
|
+
Object.defineProperty(SqliteError.prototype, "name", descriptor);
|
|
97
|
+
module.exports = SqliteError;
|
|
98
|
+
}));
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region ../../node_modules/.pnpm/file-uri-to-path@1.0.0/node_modules/file-uri-to-path/index.js
|
|
101
|
+
var require_file_uri_to_path = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
102
|
+
/**
|
|
103
|
+
* Module dependencies.
|
|
104
|
+
*/
|
|
105
|
+
var sep = require___vite_browser_external().sep || "/";
|
|
106
|
+
/**
|
|
107
|
+
* Module exports.
|
|
108
|
+
*/
|
|
109
|
+
module.exports = fileUriToPath;
|
|
110
|
+
/**
|
|
111
|
+
* File URI to Path function.
|
|
112
|
+
*
|
|
113
|
+
* @param {String} uri
|
|
114
|
+
* @return {String} path
|
|
115
|
+
* @api public
|
|
116
|
+
*/
|
|
117
|
+
function fileUriToPath(uri) {
|
|
118
|
+
if ("string" != typeof uri || uri.length <= 7 || "file://" != uri.substring(0, 7)) throw new TypeError("must pass in a file:// URI to convert to a file path");
|
|
119
|
+
var rest = decodeURI(uri.substring(7));
|
|
120
|
+
var firstSlash = rest.indexOf("/");
|
|
121
|
+
var host = rest.substring(0, firstSlash);
|
|
122
|
+
var path = rest.substring(firstSlash + 1);
|
|
123
|
+
if ("localhost" == host) host = "";
|
|
124
|
+
if (host) host = sep + sep + host;
|
|
125
|
+
path = path.replace(/^(.+)\|/, "$1:");
|
|
126
|
+
if (sep == "\\") path = path.replace(/\//g, "\\");
|
|
127
|
+
if (/^.+\:/.test(path)) {} else path = sep + path;
|
|
128
|
+
return host + path;
|
|
129
|
+
}
|
|
130
|
+
}));
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region ../../node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js
|
|
133
|
+
var require_bindings = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
134
|
+
/**
|
|
135
|
+
* Module dependencies.
|
|
136
|
+
*/
|
|
137
|
+
var fs = require___vite_browser_external(), path = require___vite_browser_external(), fileURLToPath = require_file_uri_to_path(), join = path.join, dirname = path.dirname, exists = fs.accessSync && function(path) {
|
|
138
|
+
try {
|
|
139
|
+
fs.accessSync(path);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
} || fs.existsSync || path.existsSync, defaults = {
|
|
145
|
+
arrow: process.env.NODE_BINDINGS_ARROW || " → ",
|
|
146
|
+
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
|
|
147
|
+
platform: process.platform,
|
|
148
|
+
arch: process.arch,
|
|
149
|
+
nodePreGyp: "node-v" + process.versions.modules + "-" + process.platform + "-" + process.arch,
|
|
150
|
+
version: process.versions.node,
|
|
151
|
+
bindings: "bindings.node",
|
|
152
|
+
try: [
|
|
153
|
+
[
|
|
154
|
+
"module_root",
|
|
155
|
+
"build",
|
|
156
|
+
"bindings"
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
"module_root",
|
|
160
|
+
"build",
|
|
161
|
+
"Debug",
|
|
162
|
+
"bindings"
|
|
163
|
+
],
|
|
164
|
+
[
|
|
165
|
+
"module_root",
|
|
166
|
+
"build",
|
|
167
|
+
"Release",
|
|
168
|
+
"bindings"
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
"module_root",
|
|
172
|
+
"out",
|
|
173
|
+
"Debug",
|
|
174
|
+
"bindings"
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
"module_root",
|
|
178
|
+
"Debug",
|
|
179
|
+
"bindings"
|
|
180
|
+
],
|
|
181
|
+
[
|
|
182
|
+
"module_root",
|
|
183
|
+
"out",
|
|
184
|
+
"Release",
|
|
185
|
+
"bindings"
|
|
186
|
+
],
|
|
187
|
+
[
|
|
188
|
+
"module_root",
|
|
189
|
+
"Release",
|
|
190
|
+
"bindings"
|
|
191
|
+
],
|
|
192
|
+
[
|
|
193
|
+
"module_root",
|
|
194
|
+
"build",
|
|
195
|
+
"default",
|
|
196
|
+
"bindings"
|
|
197
|
+
],
|
|
198
|
+
[
|
|
199
|
+
"module_root",
|
|
200
|
+
"compiled",
|
|
201
|
+
"version",
|
|
202
|
+
"platform",
|
|
203
|
+
"arch",
|
|
204
|
+
"bindings"
|
|
205
|
+
],
|
|
206
|
+
[
|
|
207
|
+
"module_root",
|
|
208
|
+
"addon-build",
|
|
209
|
+
"release",
|
|
210
|
+
"install-root",
|
|
211
|
+
"bindings"
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
"module_root",
|
|
215
|
+
"addon-build",
|
|
216
|
+
"debug",
|
|
217
|
+
"install-root",
|
|
218
|
+
"bindings"
|
|
219
|
+
],
|
|
220
|
+
[
|
|
221
|
+
"module_root",
|
|
222
|
+
"addon-build",
|
|
223
|
+
"default",
|
|
224
|
+
"install-root",
|
|
225
|
+
"bindings"
|
|
226
|
+
],
|
|
227
|
+
[
|
|
228
|
+
"module_root",
|
|
229
|
+
"lib",
|
|
230
|
+
"binding",
|
|
231
|
+
"nodePreGyp",
|
|
232
|
+
"bindings"
|
|
233
|
+
]
|
|
234
|
+
]
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* The main `bindings()` function loads the compiled bindings for a given module.
|
|
238
|
+
* It uses V8's Error API to determine the parent filename that this function is
|
|
239
|
+
* being invoked from, which is then used to find the root directory.
|
|
240
|
+
*/
|
|
241
|
+
function bindings(opts) {
|
|
242
|
+
if (typeof opts == "string") opts = { bindings: opts };
|
|
243
|
+
else if (!opts) opts = {};
|
|
244
|
+
Object.keys(defaults).map(function(i) {
|
|
245
|
+
if (!(i in opts)) opts[i] = defaults[i];
|
|
246
|
+
});
|
|
247
|
+
if (!opts.module_root) opts.module_root = exports.getRoot(exports.getFileName());
|
|
248
|
+
if (path.extname(opts.bindings) != ".node") opts.bindings += ".node";
|
|
249
|
+
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
250
|
+
var tries = [], i = 0, l = opts.try.length, n, b, err;
|
|
251
|
+
for (; i < l; i++) {
|
|
252
|
+
n = join.apply(null, opts.try[i].map(function(p) {
|
|
253
|
+
return opts[p] || p;
|
|
254
|
+
}));
|
|
255
|
+
tries.push(n);
|
|
256
|
+
try {
|
|
257
|
+
b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
|
|
258
|
+
if (!opts.path) b.path = n;
|
|
259
|
+
return b;
|
|
260
|
+
} catch (e) {
|
|
261
|
+
if (e.code !== "MODULE_NOT_FOUND" && e.code !== "QUALIFIED_PATH_RESOLUTION_FAILED" && !/not find/i.test(e.message)) throw e;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
err = /* @__PURE__ */ new Error("Could not locate the bindings file. Tried:\n" + tries.map(function(a) {
|
|
265
|
+
return opts.arrow + a;
|
|
266
|
+
}).join("\n"));
|
|
267
|
+
err.tries = tries;
|
|
268
|
+
throw err;
|
|
269
|
+
}
|
|
270
|
+
module.exports = exports = bindings;
|
|
271
|
+
/**
|
|
272
|
+
* Gets the filename of the JavaScript file that invokes this function.
|
|
273
|
+
* Used to help find the root directory of a module.
|
|
274
|
+
* Optionally accepts an filename argument to skip when searching for the invoking filename
|
|
275
|
+
*/
|
|
276
|
+
exports.getFileName = function getFileName(calling_file) {
|
|
277
|
+
var origPST = Error.prepareStackTrace, origSTL = Error.stackTraceLimit, dummy = {}, fileName;
|
|
278
|
+
Error.stackTraceLimit = 10;
|
|
279
|
+
Error.prepareStackTrace = function(e, st) {
|
|
280
|
+
for (var i = 0, l = st.length; i < l; i++) {
|
|
281
|
+
fileName = st[i].getFileName();
|
|
282
|
+
if (fileName !== __filename) if (calling_file) {
|
|
283
|
+
if (fileName !== calling_file) return;
|
|
284
|
+
} else return;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
Error.captureStackTrace(dummy);
|
|
288
|
+
dummy.stack;
|
|
289
|
+
Error.prepareStackTrace = origPST;
|
|
290
|
+
Error.stackTraceLimit = origSTL;
|
|
291
|
+
if (fileName.indexOf("file://") === 0) fileName = fileURLToPath(fileName);
|
|
292
|
+
return fileName;
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Gets the root directory of a module, given an arbitrary filename
|
|
296
|
+
* somewhere in the module tree. The "root directory" is the directory
|
|
297
|
+
* containing the `package.json` file.
|
|
298
|
+
*
|
|
299
|
+
* In: /home/nate/node-native-module/lib/index.js
|
|
300
|
+
* Out: /home/nate/node-native-module
|
|
301
|
+
*/
|
|
302
|
+
exports.getRoot = function getRoot(file) {
|
|
303
|
+
var dir = dirname(file), prev;
|
|
304
|
+
while (true) {
|
|
305
|
+
if (dir === ".") dir = process.cwd();
|
|
306
|
+
if (exists(join(dir, "package.json")) || exists(join(dir, "node_modules"))) return dir;
|
|
307
|
+
if (prev === dir) throw new Error("Could not find module root given file: \"" + file + "\". Do you have a `package.json` file? ");
|
|
308
|
+
prev = dir;
|
|
309
|
+
dir = join(dir, "..");
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
}));
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/wrappers.js
|
|
315
|
+
var require_wrappers = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
316
|
+
var { cppdb } = require_util();
|
|
317
|
+
exports.prepare = function prepare(sql) {
|
|
318
|
+
return this[cppdb].prepare(sql, this, false);
|
|
319
|
+
};
|
|
320
|
+
exports.exec = function exec(sql) {
|
|
321
|
+
this[cppdb].exec(sql);
|
|
322
|
+
return this;
|
|
323
|
+
};
|
|
324
|
+
exports.close = function close() {
|
|
325
|
+
this[cppdb].close();
|
|
326
|
+
return this;
|
|
327
|
+
};
|
|
328
|
+
exports.loadExtension = function loadExtension(...args) {
|
|
329
|
+
this[cppdb].loadExtension(...args);
|
|
330
|
+
return this;
|
|
331
|
+
};
|
|
332
|
+
exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
|
|
333
|
+
this[cppdb].defaultSafeIntegers(...args);
|
|
334
|
+
return this;
|
|
335
|
+
};
|
|
336
|
+
exports.unsafeMode = function unsafeMode(...args) {
|
|
337
|
+
this[cppdb].unsafeMode(...args);
|
|
338
|
+
return this;
|
|
339
|
+
};
|
|
340
|
+
exports.getters = {
|
|
341
|
+
name: {
|
|
342
|
+
get: function name() {
|
|
343
|
+
return this[cppdb].name;
|
|
344
|
+
},
|
|
345
|
+
enumerable: true
|
|
346
|
+
},
|
|
347
|
+
open: {
|
|
348
|
+
get: function open() {
|
|
349
|
+
return this[cppdb].open;
|
|
350
|
+
},
|
|
351
|
+
enumerable: true
|
|
352
|
+
},
|
|
353
|
+
inTransaction: {
|
|
354
|
+
get: function inTransaction() {
|
|
355
|
+
return this[cppdb].inTransaction;
|
|
356
|
+
},
|
|
357
|
+
enumerable: true
|
|
358
|
+
},
|
|
359
|
+
readonly: {
|
|
360
|
+
get: function readonly() {
|
|
361
|
+
return this[cppdb].readonly;
|
|
362
|
+
},
|
|
363
|
+
enumerable: true
|
|
364
|
+
},
|
|
365
|
+
memory: {
|
|
366
|
+
get: function memory() {
|
|
367
|
+
return this[cppdb].memory;
|
|
368
|
+
},
|
|
369
|
+
enumerable: true
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}));
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/transaction.js
|
|
375
|
+
var require_transaction = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
376
|
+
var { cppdb } = require_util();
|
|
377
|
+
var controllers = /* @__PURE__ */ new WeakMap();
|
|
378
|
+
module.exports = function transaction(fn) {
|
|
379
|
+
if (typeof fn !== "function") throw new TypeError("Expected first argument to be a function");
|
|
380
|
+
const db = this[cppdb];
|
|
381
|
+
const controller = getController(db, this);
|
|
382
|
+
const { apply } = Function.prototype;
|
|
383
|
+
const properties = {
|
|
384
|
+
default: { value: wrapTransaction(apply, fn, db, controller.default) },
|
|
385
|
+
deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
|
|
386
|
+
immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
|
|
387
|
+
exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
|
|
388
|
+
database: {
|
|
389
|
+
value: this,
|
|
390
|
+
enumerable: true
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
Object.defineProperties(properties.default.value, properties);
|
|
394
|
+
Object.defineProperties(properties.deferred.value, properties);
|
|
395
|
+
Object.defineProperties(properties.immediate.value, properties);
|
|
396
|
+
Object.defineProperties(properties.exclusive.value, properties);
|
|
397
|
+
return properties.default.value;
|
|
398
|
+
};
|
|
399
|
+
var getController = (db, self) => {
|
|
400
|
+
let controller = controllers.get(db);
|
|
401
|
+
if (!controller) {
|
|
402
|
+
const shared = {
|
|
403
|
+
commit: db.prepare("COMMIT", self, false),
|
|
404
|
+
rollback: db.prepare("ROLLBACK", self, false),
|
|
405
|
+
savepoint: db.prepare("SAVEPOINT ` _bs3. `", self, false),
|
|
406
|
+
release: db.prepare("RELEASE ` _bs3. `", self, false),
|
|
407
|
+
rollbackTo: db.prepare("ROLLBACK TO ` _bs3. `", self, false)
|
|
408
|
+
};
|
|
409
|
+
controllers.set(db, controller = {
|
|
410
|
+
default: Object.assign({ begin: db.prepare("BEGIN", self, false) }, shared),
|
|
411
|
+
deferred: Object.assign({ begin: db.prepare("BEGIN DEFERRED", self, false) }, shared),
|
|
412
|
+
immediate: Object.assign({ begin: db.prepare("BEGIN IMMEDIATE", self, false) }, shared),
|
|
413
|
+
exclusive: Object.assign({ begin: db.prepare("BEGIN EXCLUSIVE", self, false) }, shared)
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
return controller;
|
|
417
|
+
};
|
|
418
|
+
var wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
|
|
419
|
+
let before, after, undo;
|
|
420
|
+
if (db.inTransaction) {
|
|
421
|
+
before = savepoint;
|
|
422
|
+
after = release;
|
|
423
|
+
undo = rollbackTo;
|
|
424
|
+
} else {
|
|
425
|
+
before = begin;
|
|
426
|
+
after = commit;
|
|
427
|
+
undo = rollback;
|
|
428
|
+
}
|
|
429
|
+
before.run();
|
|
430
|
+
try {
|
|
431
|
+
const result = apply.call(fn, this, arguments);
|
|
432
|
+
if (result && typeof result.then === "function") throw new TypeError("Transaction function cannot return a promise");
|
|
433
|
+
after.run();
|
|
434
|
+
return result;
|
|
435
|
+
} catch (ex) {
|
|
436
|
+
if (db.inTransaction) {
|
|
437
|
+
undo.run();
|
|
438
|
+
if (undo !== rollback) after.run();
|
|
439
|
+
}
|
|
440
|
+
throw ex;
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
}));
|
|
444
|
+
//#endregion
|
|
445
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/pragma.js
|
|
446
|
+
var require_pragma = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
447
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
448
|
+
module.exports = function pragma(source, options) {
|
|
449
|
+
if (options == null) options = {};
|
|
450
|
+
if (typeof source !== "string") throw new TypeError("Expected first argument to be a string");
|
|
451
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
452
|
+
const simple = getBooleanOption(options, "simple");
|
|
453
|
+
const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
|
|
454
|
+
return simple ? stmt.pluck().get() : stmt.all();
|
|
455
|
+
};
|
|
456
|
+
}));
|
|
457
|
+
//#endregion
|
|
458
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/backup.js
|
|
459
|
+
var require_backup = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
460
|
+
var fs = require___vite_browser_external();
|
|
461
|
+
var path = require___vite_browser_external();
|
|
462
|
+
var { promisify } = require___vite_browser_external();
|
|
463
|
+
var { cppdb } = require_util();
|
|
464
|
+
var fsAccess = promisify(fs.access);
|
|
465
|
+
module.exports = async function backup(filename, options) {
|
|
466
|
+
if (options == null) options = {};
|
|
467
|
+
if (typeof filename !== "string") throw new TypeError("Expected first argument to be a string");
|
|
468
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
469
|
+
filename = filename.trim();
|
|
470
|
+
const attachedName = "attached" in options ? options.attached : "main";
|
|
471
|
+
const handler = "progress" in options ? options.progress : null;
|
|
472
|
+
if (!filename) throw new TypeError("Backup filename cannot be an empty string");
|
|
473
|
+
if (filename === ":memory:") throw new TypeError("Invalid backup filename \":memory:\"");
|
|
474
|
+
if (typeof attachedName !== "string") throw new TypeError("Expected the \"attached\" option to be a string");
|
|
475
|
+
if (!attachedName) throw new TypeError("The \"attached\" option cannot be an empty string");
|
|
476
|
+
if (handler != null && typeof handler !== "function") throw new TypeError("Expected the \"progress\" option to be a function");
|
|
477
|
+
await fsAccess(path.dirname(filename)).catch(() => {
|
|
478
|
+
throw new TypeError("Cannot save backup because the directory does not exist");
|
|
479
|
+
});
|
|
480
|
+
const isNewFile = await fsAccess(filename).then(() => false, () => true);
|
|
481
|
+
return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
|
|
482
|
+
};
|
|
483
|
+
var runBackup = (backup, handler) => {
|
|
484
|
+
let rate = 0;
|
|
485
|
+
let useDefault = true;
|
|
486
|
+
return new Promise((resolve, reject) => {
|
|
487
|
+
setImmediate(function step() {
|
|
488
|
+
try {
|
|
489
|
+
const progress = backup.transfer(rate);
|
|
490
|
+
if (!progress.remainingPages) {
|
|
491
|
+
backup.close();
|
|
492
|
+
resolve(progress);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
if (useDefault) {
|
|
496
|
+
useDefault = false;
|
|
497
|
+
rate = 100;
|
|
498
|
+
}
|
|
499
|
+
if (handler) {
|
|
500
|
+
const ret = handler(progress);
|
|
501
|
+
if (ret !== void 0) if (typeof ret === "number" && ret === ret) rate = Math.max(0, Math.min(2147483647, Math.round(ret)));
|
|
502
|
+
else throw new TypeError("Expected progress callback to return a number or undefined");
|
|
503
|
+
}
|
|
504
|
+
setImmediate(step);
|
|
505
|
+
} catch (err) {
|
|
506
|
+
backup.close();
|
|
507
|
+
reject(err);
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
});
|
|
511
|
+
};
|
|
512
|
+
}));
|
|
513
|
+
//#endregion
|
|
514
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/serialize.js
|
|
515
|
+
var require_serialize = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
516
|
+
var { cppdb } = require_util();
|
|
517
|
+
module.exports = function serialize(options) {
|
|
518
|
+
if (options == null) options = {};
|
|
519
|
+
if (typeof options !== "object") throw new TypeError("Expected first argument to be an options object");
|
|
520
|
+
const attachedName = "attached" in options ? options.attached : "main";
|
|
521
|
+
if (typeof attachedName !== "string") throw new TypeError("Expected the \"attached\" option to be a string");
|
|
522
|
+
if (!attachedName) throw new TypeError("The \"attached\" option cannot be an empty string");
|
|
523
|
+
return this[cppdb].serialize(attachedName);
|
|
524
|
+
};
|
|
525
|
+
}));
|
|
526
|
+
//#endregion
|
|
527
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/function.js
|
|
528
|
+
var require_function = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
529
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
530
|
+
module.exports = function defineFunction(name, options, fn) {
|
|
531
|
+
if (options == null) options = {};
|
|
532
|
+
if (typeof options === "function") {
|
|
533
|
+
fn = options;
|
|
534
|
+
options = {};
|
|
535
|
+
}
|
|
536
|
+
if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
|
|
537
|
+
if (typeof fn !== "function") throw new TypeError("Expected last argument to be a function");
|
|
538
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
539
|
+
if (!name) throw new TypeError("User-defined function name cannot be an empty string");
|
|
540
|
+
const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
|
|
541
|
+
const deterministic = getBooleanOption(options, "deterministic");
|
|
542
|
+
const directOnly = getBooleanOption(options, "directOnly");
|
|
543
|
+
const varargs = getBooleanOption(options, "varargs");
|
|
544
|
+
let argCount = -1;
|
|
545
|
+
if (!varargs) {
|
|
546
|
+
argCount = fn.length;
|
|
547
|
+
if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError("Expected function.length to be a positive integer");
|
|
548
|
+
if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
|
|
549
|
+
}
|
|
550
|
+
this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
|
|
551
|
+
return this;
|
|
552
|
+
};
|
|
553
|
+
}));
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/aggregate.js
|
|
556
|
+
var require_aggregate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
557
|
+
var { getBooleanOption, cppdb } = require_util();
|
|
558
|
+
module.exports = function defineAggregate(name, options) {
|
|
559
|
+
if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
|
|
560
|
+
if (typeof options !== "object" || options === null) throw new TypeError("Expected second argument to be an options object");
|
|
561
|
+
if (!name) throw new TypeError("User-defined function name cannot be an empty string");
|
|
562
|
+
const start = "start" in options ? options.start : null;
|
|
563
|
+
const step = getFunctionOption(options, "step", true);
|
|
564
|
+
const inverse = getFunctionOption(options, "inverse", false);
|
|
565
|
+
const result = getFunctionOption(options, "result", false);
|
|
566
|
+
const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
|
|
567
|
+
const deterministic = getBooleanOption(options, "deterministic");
|
|
568
|
+
const directOnly = getBooleanOption(options, "directOnly");
|
|
569
|
+
const varargs = getBooleanOption(options, "varargs");
|
|
570
|
+
let argCount = -1;
|
|
571
|
+
if (!varargs) {
|
|
572
|
+
argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
|
|
573
|
+
if (argCount > 0) argCount -= 1;
|
|
574
|
+
if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
|
|
575
|
+
}
|
|
576
|
+
this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
|
|
577
|
+
return this;
|
|
578
|
+
};
|
|
579
|
+
var getFunctionOption = (options, key, required) => {
|
|
580
|
+
const value = key in options ? options[key] : null;
|
|
581
|
+
if (typeof value === "function") return value;
|
|
582
|
+
if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`);
|
|
583
|
+
if (required) throw new TypeError(`Missing required option "${key}"`);
|
|
584
|
+
return null;
|
|
585
|
+
};
|
|
586
|
+
var getLength = ({ length }) => {
|
|
587
|
+
if (Number.isInteger(length) && length >= 0) return length;
|
|
588
|
+
throw new TypeError("Expected function.length to be a positive integer");
|
|
589
|
+
};
|
|
590
|
+
}));
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/table.js
|
|
593
|
+
var require_table = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
594
|
+
var { cppdb } = require_util();
|
|
595
|
+
module.exports = function defineTable(name, factory) {
|
|
596
|
+
if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
|
|
597
|
+
if (!name) throw new TypeError("Virtual table module name cannot be an empty string");
|
|
598
|
+
let eponymous = false;
|
|
599
|
+
if (typeof factory === "object" && factory !== null) {
|
|
600
|
+
eponymous = true;
|
|
601
|
+
factory = defer(parseTableDefinition(factory, "used", name));
|
|
602
|
+
} else {
|
|
603
|
+
if (typeof factory !== "function") throw new TypeError("Expected second argument to be a function or a table definition object");
|
|
604
|
+
factory = wrapFactory(factory);
|
|
605
|
+
}
|
|
606
|
+
this[cppdb].table(factory, name, eponymous);
|
|
607
|
+
return this;
|
|
608
|
+
};
|
|
609
|
+
function wrapFactory(factory) {
|
|
610
|
+
return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
|
|
611
|
+
const thisObject = {
|
|
612
|
+
module: moduleName,
|
|
613
|
+
database: databaseName,
|
|
614
|
+
table: tableName
|
|
615
|
+
};
|
|
616
|
+
const def = apply.call(factory, thisObject, args);
|
|
617
|
+
if (typeof def !== "object" || def === null) throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
|
|
618
|
+
return parseTableDefinition(def, "returned", moduleName);
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
function parseTableDefinition(def, verb, moduleName) {
|
|
622
|
+
if (!hasOwnProperty.call(def, "rows")) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
|
|
623
|
+
if (!hasOwnProperty.call(def, "columns")) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
|
|
624
|
+
const rows = def.rows;
|
|
625
|
+
if (typeof rows !== "function" || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
|
|
626
|
+
let columns = def.columns;
|
|
627
|
+
if (!Array.isArray(columns) || !(columns = [...columns]).every((x) => typeof x === "string")) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
|
|
628
|
+
if (columns.length !== new Set(columns).size) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
|
|
629
|
+
if (!columns.length) throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
|
|
630
|
+
let parameters;
|
|
631
|
+
if (hasOwnProperty.call(def, "parameters")) {
|
|
632
|
+
parameters = def.parameters;
|
|
633
|
+
if (!Array.isArray(parameters) || !(parameters = [...parameters]).every((x) => typeof x === "string")) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
|
|
634
|
+
} else parameters = inferParameters(rows);
|
|
635
|
+
if (parameters.length !== new Set(parameters).size) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
|
|
636
|
+
if (parameters.length > 32) throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
|
|
637
|
+
for (const parameter of parameters) if (columns.includes(parameter)) throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
|
|
638
|
+
let safeIntegers = 2;
|
|
639
|
+
if (hasOwnProperty.call(def, "safeIntegers")) {
|
|
640
|
+
const bool = def.safeIntegers;
|
|
641
|
+
if (typeof bool !== "boolean") throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
|
|
642
|
+
safeIntegers = +bool;
|
|
643
|
+
}
|
|
644
|
+
let directOnly = false;
|
|
645
|
+
if (hasOwnProperty.call(def, "directOnly")) {
|
|
646
|
+
directOnly = def.directOnly;
|
|
647
|
+
if (typeof directOnly !== "boolean") throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
|
|
648
|
+
}
|
|
649
|
+
return [
|
|
650
|
+
`CREATE TABLE x(${[...parameters.map(identifier).map((str) => `${str} HIDDEN`), ...columns.map(identifier)].join(", ")});`,
|
|
651
|
+
wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),
|
|
652
|
+
parameters,
|
|
653
|
+
safeIntegers,
|
|
654
|
+
directOnly
|
|
655
|
+
];
|
|
656
|
+
}
|
|
657
|
+
function wrapGenerator(generator, columnMap, moduleName) {
|
|
658
|
+
return function* virtualTable(...args) {
|
|
659
|
+
const output = args.map((x) => Buffer.isBuffer(x) ? Buffer.from(x) : x);
|
|
660
|
+
for (let i = 0; i < columnMap.size; ++i) output.push(null);
|
|
661
|
+
for (const row of generator(...args)) if (Array.isArray(row)) {
|
|
662
|
+
extractRowArray(row, output, columnMap.size, moduleName);
|
|
663
|
+
yield output;
|
|
664
|
+
} else if (typeof row === "object" && row !== null) {
|
|
665
|
+
extractRowObject(row, output, columnMap, moduleName);
|
|
666
|
+
yield output;
|
|
667
|
+
} else throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function extractRowArray(row, output, columnCount, moduleName) {
|
|
671
|
+
if (row.length !== columnCount) throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
|
|
672
|
+
const offset = output.length - columnCount;
|
|
673
|
+
for (let i = 0; i < columnCount; ++i) output[i + offset] = row[i];
|
|
674
|
+
}
|
|
675
|
+
function extractRowObject(row, output, columnMap, moduleName) {
|
|
676
|
+
let count = 0;
|
|
677
|
+
for (const key of Object.keys(row)) {
|
|
678
|
+
const index = columnMap.get(key);
|
|
679
|
+
if (index === void 0) throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
|
|
680
|
+
output[index] = row[key];
|
|
681
|
+
count += 1;
|
|
682
|
+
}
|
|
683
|
+
if (count !== columnMap.size) throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
|
|
684
|
+
}
|
|
685
|
+
function inferParameters({ length }) {
|
|
686
|
+
if (!Number.isInteger(length) || length < 0) throw new TypeError("Expected function.length to be a positive integer");
|
|
687
|
+
const params = [];
|
|
688
|
+
for (let i = 0; i < length; ++i) params.push(`$${i + 1}`);
|
|
689
|
+
return params;
|
|
690
|
+
}
|
|
691
|
+
var { hasOwnProperty } = Object.prototype;
|
|
692
|
+
var { apply } = Function.prototype;
|
|
693
|
+
var GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {});
|
|
694
|
+
var identifier = (str) => `"${str.replace(/"/g, "\"\"")}"`;
|
|
695
|
+
var defer = (x) => () => x;
|
|
696
|
+
}));
|
|
697
|
+
//#endregion
|
|
698
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/methods/inspect.js
|
|
699
|
+
var require_inspect = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
700
|
+
var DatabaseInspection = function Database() {};
|
|
701
|
+
module.exports = function inspect(depth, opts) {
|
|
702
|
+
return Object.assign(new DatabaseInspection(), this);
|
|
703
|
+
};
|
|
704
|
+
}));
|
|
705
|
+
//#endregion
|
|
706
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/database.js
|
|
707
|
+
var require_database = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
708
|
+
var fs = require___vite_browser_external();
|
|
709
|
+
var path = require___vite_browser_external();
|
|
710
|
+
var util = require_util();
|
|
711
|
+
var SqliteError = require_sqlite_error();
|
|
712
|
+
var DEFAULT_ADDON;
|
|
713
|
+
function Database(filenameGiven, options) {
|
|
714
|
+
if (new.target == null) return new Database(filenameGiven, options);
|
|
715
|
+
let buffer;
|
|
716
|
+
if (Buffer.isBuffer(filenameGiven)) {
|
|
717
|
+
buffer = filenameGiven;
|
|
718
|
+
filenameGiven = ":memory:";
|
|
719
|
+
}
|
|
720
|
+
if (filenameGiven == null) filenameGiven = "";
|
|
721
|
+
if (options == null) options = {};
|
|
722
|
+
if (typeof filenameGiven !== "string") throw new TypeError("Expected first argument to be a string");
|
|
723
|
+
if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
|
|
724
|
+
if ("readOnly" in options) throw new TypeError("Misspelled option \"readOnly\" should be \"readonly\"");
|
|
725
|
+
if ("memory" in options) throw new TypeError("Option \"memory\" was removed in v7.0.0 (use \":memory:\" filename instead)");
|
|
726
|
+
const filename = filenameGiven.trim();
|
|
727
|
+
const anonymous = filename === "" || filename === ":memory:";
|
|
728
|
+
const readonly = util.getBooleanOption(options, "readonly");
|
|
729
|
+
const fileMustExist = util.getBooleanOption(options, "fileMustExist");
|
|
730
|
+
const timeout = "timeout" in options ? options.timeout : 5e3;
|
|
731
|
+
const verbose = "verbose" in options ? options.verbose : null;
|
|
732
|
+
const nativeBinding = "nativeBinding" in options ? options.nativeBinding : null;
|
|
733
|
+
if (readonly && anonymous && !buffer) throw new TypeError("In-memory/temporary databases cannot be readonly");
|
|
734
|
+
if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError("Expected the \"timeout\" option to be a positive integer");
|
|
735
|
+
if (timeout > 2147483647) throw new RangeError("Option \"timeout\" cannot be greater than 2147483647");
|
|
736
|
+
if (verbose != null && typeof verbose !== "function") throw new TypeError("Expected the \"verbose\" option to be a function");
|
|
737
|
+
if (nativeBinding != null && typeof nativeBinding !== "string" && typeof nativeBinding !== "object") throw new TypeError("Expected the \"nativeBinding\" option to be a string or addon object");
|
|
738
|
+
let addon;
|
|
739
|
+
if (nativeBinding == null) addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
|
|
740
|
+
else if (typeof nativeBinding === "string") addon = (typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require)(path.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
|
|
741
|
+
else addon = nativeBinding;
|
|
742
|
+
if (!addon.isInitialized) {
|
|
743
|
+
addon.setErrorConstructor(SqliteError);
|
|
744
|
+
addon.isInitialized = true;
|
|
745
|
+
}
|
|
746
|
+
if (!anonymous && !filename.startsWith("file:") && !fs.existsSync(path.dirname(filename))) throw new TypeError("Cannot open database because the directory does not exist");
|
|
747
|
+
Object.defineProperties(this, {
|
|
748
|
+
[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
|
|
749
|
+
...wrappers.getters
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
var wrappers = require_wrappers();
|
|
753
|
+
Database.prototype.prepare = wrappers.prepare;
|
|
754
|
+
Database.prototype.transaction = require_transaction();
|
|
755
|
+
Database.prototype.pragma = require_pragma();
|
|
756
|
+
Database.prototype.backup = require_backup();
|
|
757
|
+
Database.prototype.serialize = require_serialize();
|
|
758
|
+
Database.prototype.function = require_function();
|
|
759
|
+
Database.prototype.aggregate = require_aggregate();
|
|
760
|
+
Database.prototype.table = require_table();
|
|
761
|
+
Database.prototype.loadExtension = wrappers.loadExtension;
|
|
762
|
+
Database.prototype.exec = wrappers.exec;
|
|
763
|
+
Database.prototype.close = wrappers.close;
|
|
764
|
+
Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
|
|
765
|
+
Database.prototype.unsafeMode = wrappers.unsafeMode;
|
|
766
|
+
Database.prototype[util.inspect] = require_inspect();
|
|
767
|
+
module.exports = Database;
|
|
768
|
+
}));
|
|
769
|
+
//#endregion
|
|
770
|
+
//#region ../../node_modules/.pnpm/better-sqlite3@12.11.1/node_modules/better-sqlite3/lib/index.js
|
|
771
|
+
var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
772
|
+
module.exports = require_database();
|
|
773
|
+
module.exports.SqliteError = require_sqlite_error();
|
|
774
|
+
}));
|
|
775
|
+
//#endregion
|
|
776
|
+
//#region ../db/src/bounds.ts
|
|
777
|
+
function rankOf(value) {
|
|
778
|
+
if (typeof value === "number") {
|
|
779
|
+
if (Number.isNaN(value)) throw new TypeError("NaN is not a valid index key");
|
|
780
|
+
return 0;
|
|
781
|
+
}
|
|
782
|
+
if (typeof value === "string") return 1;
|
|
783
|
+
if (Array.isArray(value)) {
|
|
784
|
+
for (let item of value) rankOf(item);
|
|
785
|
+
return 2;
|
|
786
|
+
}
|
|
787
|
+
throw new TypeError(`unsupported index key type: ${value === null ? "null" : typeof value}`);
|
|
788
|
+
}
|
|
789
|
+
function cmp(a, b) {
|
|
790
|
+
let ra = rankOf(a);
|
|
791
|
+
let rb = rankOf(b);
|
|
792
|
+
if (ra < rb) return -1;
|
|
793
|
+
if (ra > rb) return 1;
|
|
794
|
+
if (ra === 0) {
|
|
795
|
+
let na = a;
|
|
796
|
+
let nb = b;
|
|
797
|
+
if (na < nb) return -1;
|
|
798
|
+
if (na > nb) return 1;
|
|
799
|
+
return 0;
|
|
800
|
+
}
|
|
801
|
+
if (ra === 1) {
|
|
802
|
+
let sa = a;
|
|
803
|
+
let sb = b;
|
|
804
|
+
if (sa < sb) return -1;
|
|
805
|
+
if (sa > sb) return 1;
|
|
806
|
+
return 0;
|
|
807
|
+
}
|
|
808
|
+
let aa = a;
|
|
809
|
+
let ba = b;
|
|
810
|
+
let n = Math.min(aa.length, ba.length);
|
|
811
|
+
for (let i = 0; i < n; i++) {
|
|
812
|
+
let c = cmp(aa[i], ba[i]);
|
|
813
|
+
if (c !== 0) return c;
|
|
814
|
+
}
|
|
815
|
+
if (aa.length < ba.length) return -1;
|
|
816
|
+
if (aa.length > ba.length) return 1;
|
|
817
|
+
return 0;
|
|
818
|
+
}
|
|
819
|
+
/** number < string < array; prefix-equal shorter array is less. */
|
|
820
|
+
function compareIndexKey(a, b) {
|
|
821
|
+
return cmp(a, b);
|
|
822
|
+
}
|
|
823
|
+
/** Inclusive/exclusive bounds using compareIndexKey. limit / keysOnly are ignored. */
|
|
824
|
+
function inRange(indexKey, bound = {}) {
|
|
825
|
+
if (bound.gt !== void 0 && compareIndexKey(indexKey, bound.gt) <= 0) return false;
|
|
826
|
+
if (bound.gte !== void 0 && compareIndexKey(indexKey, bound.gte) < 0) return false;
|
|
827
|
+
if (bound.lt !== void 0 && compareIndexKey(indexKey, bound.lt) >= 0) return false;
|
|
828
|
+
if (bound.lte !== void 0 && compareIndexKey(indexKey, bound.lte) > 0) return false;
|
|
829
|
+
return true;
|
|
830
|
+
}
|
|
831
|
+
//#endregion
|
|
832
|
+
//#region ../../node_modules/.pnpm/halua@5.0.0/node_modules/halua/lib/index.js
|
|
833
|
+
function toarray(value) {
|
|
834
|
+
return Array.isArray(value) ? value : typeof value === "undefined" ? [] : [value];
|
|
835
|
+
}
|
|
836
|
+
function unknownToError(err) {
|
|
837
|
+
if (err instanceof Error) return err;
|
|
838
|
+
if (typeof err === "string") return new Error(err);
|
|
839
|
+
let error = "";
|
|
840
|
+
try {
|
|
841
|
+
error = JSON.stringify(err);
|
|
842
|
+
} catch (_) {}
|
|
843
|
+
return new Error(error, { cause: err });
|
|
844
|
+
}
|
|
845
|
+
var HaluaFailedToCallDispatcher = class extends Error {
|
|
846
|
+
constructor(message, options = {}) {
|
|
847
|
+
super(`HaluaFailedToCallDispatcherError: ${message}`, options);
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
var HaluaUnableToDetermineDispatcher = class extends Error {
|
|
851
|
+
constructor(message, options = {}) {
|
|
852
|
+
super(`HaluaUnableToDetermineDispatcherError: ${message}`, options);
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
function getType(arg) {
|
|
856
|
+
if (typeof arg === "undefined") return "undefined";
|
|
857
|
+
if (typeof arg === "object" && String(arg) === "null") return "null";
|
|
858
|
+
if (Array.isArray(arg)) return "array";
|
|
859
|
+
if (ArrayBuffer.isView(arg)) return "typedarray";
|
|
860
|
+
if (arg instanceof ArrayBuffer) return "arraybuffer";
|
|
861
|
+
if (arg instanceof Map) return "map";
|
|
862
|
+
if (arg instanceof Set) return "set";
|
|
863
|
+
if (arg instanceof WeakMap) return "weakmap";
|
|
864
|
+
if (arg instanceof WeakSet) return "weakset";
|
|
865
|
+
if (arg instanceof Date) return "date";
|
|
866
|
+
if (arg instanceof Error) return "error";
|
|
867
|
+
if (Number.isNaN(arg)) return "nan";
|
|
868
|
+
if (typeof arg === "number" && !Number.isFinite(arg)) return "infinity";
|
|
869
|
+
return typeof arg;
|
|
870
|
+
}
|
|
871
|
+
var Level = /* @__PURE__ */ ((Level2) => {
|
|
872
|
+
Level2["Trace"] = "TRACE";
|
|
873
|
+
Level2["Debug"] = "DEBUG";
|
|
874
|
+
Level2["Info"] = "INFO";
|
|
875
|
+
Level2["Notice"] = "NOTICE";
|
|
876
|
+
Level2["Warn"] = "WARN";
|
|
877
|
+
Level2["Error"] = "ERROR";
|
|
878
|
+
Level2["Fatal"] = "FATAL";
|
|
879
|
+
return Level2;
|
|
880
|
+
})(Level || {});
|
|
881
|
+
function extractLevels(level) {
|
|
882
|
+
if (typeof level !== "string") return [Level.Info, 0];
|
|
883
|
+
let s = level.toUpperCase().trim();
|
|
884
|
+
let data = s.split("+");
|
|
885
|
+
let major;
|
|
886
|
+
let minor;
|
|
887
|
+
if (data.length >= 2) {
|
|
888
|
+
major = data[0].trim() || Level.Info;
|
|
889
|
+
let n = Number(data[1].trim());
|
|
890
|
+
minor = Number.isFinite(n) ? Math.trunc(n) : 0;
|
|
891
|
+
} else {
|
|
892
|
+
major = s || Level.Info;
|
|
893
|
+
minor = 0;
|
|
894
|
+
}
|
|
895
|
+
if (minor < 0) minor = 0;
|
|
896
|
+
return [major, minor];
|
|
897
|
+
}
|
|
898
|
+
var REDACTION_TOKEN = "^_^";
|
|
899
|
+
function redact(value, regexp) {
|
|
900
|
+
if (!regexp) return value;
|
|
901
|
+
return redactRec(value, regexp, /* @__PURE__ */ new WeakSet());
|
|
902
|
+
}
|
|
903
|
+
function redactRec(value, re, seen) {
|
|
904
|
+
if (value == null) return value;
|
|
905
|
+
let type = getType(value);
|
|
906
|
+
if (type === "string") return redactString(value, re);
|
|
907
|
+
if (type === "array") {
|
|
908
|
+
if (seen.has(value)) return "[Circular]";
|
|
909
|
+
seen.add(value);
|
|
910
|
+
let result = [];
|
|
911
|
+
for (let entry of value) result.push(redactRec(entry, re, seen));
|
|
912
|
+
seen.delete(value);
|
|
913
|
+
return result;
|
|
914
|
+
}
|
|
915
|
+
if (type === "object") {
|
|
916
|
+
if (seen.has(value)) return "[Circular]";
|
|
917
|
+
seen.add(value);
|
|
918
|
+
let result = {};
|
|
919
|
+
for (let key of Object.keys(value)) {
|
|
920
|
+
let k = key;
|
|
921
|
+
re.lastIndex = 0;
|
|
922
|
+
if (re.test(k)) result[k] = REDACTION_TOKEN;
|
|
923
|
+
else result[k] = redactRec(value[k], re, seen);
|
|
924
|
+
}
|
|
925
|
+
seen.delete(value);
|
|
926
|
+
return result;
|
|
927
|
+
}
|
|
928
|
+
if (type === "map") {
|
|
929
|
+
if (seen.has(value)) return "[Circular]";
|
|
930
|
+
seen.add(value);
|
|
931
|
+
let result = /* @__PURE__ */ new Map();
|
|
932
|
+
for (let [k, v] of value) {
|
|
933
|
+
let keyStr = typeof k === "string" ? k : String(k ?? "");
|
|
934
|
+
re.lastIndex = 0;
|
|
935
|
+
if (re.test(keyStr)) result.set(k, REDACTION_TOKEN);
|
|
936
|
+
else result.set(k, redactRec(v, re, seen));
|
|
937
|
+
}
|
|
938
|
+
seen.delete(value);
|
|
939
|
+
return result;
|
|
940
|
+
}
|
|
941
|
+
if (type === "set") {
|
|
942
|
+
if (seen.has(value)) return "[Circular]";
|
|
943
|
+
seen.add(value);
|
|
944
|
+
let result = /* @__PURE__ */ new Set();
|
|
945
|
+
for (let item of value) result.add(redactRec(item, re, seen));
|
|
946
|
+
seen.delete(value);
|
|
947
|
+
return result;
|
|
948
|
+
}
|
|
949
|
+
if (type === "error") {
|
|
950
|
+
let msg = value.message;
|
|
951
|
+
if (typeof msg === "string") msg = redactString(msg, re);
|
|
952
|
+
let Ctor = value.constructor || Error;
|
|
953
|
+
let redacted;
|
|
954
|
+
try {
|
|
955
|
+
redacted = new Ctor(msg);
|
|
956
|
+
if (value.name) redacted.name = value.name;
|
|
957
|
+
if (value.stack) redacted.stack = value.stack;
|
|
958
|
+
} catch (_) {
|
|
959
|
+
redacted = value;
|
|
960
|
+
}
|
|
961
|
+
return redacted;
|
|
962
|
+
}
|
|
963
|
+
return value;
|
|
964
|
+
}
|
|
965
|
+
function redactString(str, re) {
|
|
966
|
+
if (!re || typeof str !== "string") return str;
|
|
967
|
+
let flags = re.flags || "";
|
|
968
|
+
if (!flags.includes("g")) flags = flags + "g";
|
|
969
|
+
let searchRe;
|
|
970
|
+
try {
|
|
971
|
+
searchRe = new RegExp(re.source, flags);
|
|
972
|
+
} catch (_) {
|
|
973
|
+
return str;
|
|
974
|
+
}
|
|
975
|
+
searchRe.lastIndex = 0;
|
|
976
|
+
let result = "";
|
|
977
|
+
let last = 0;
|
|
978
|
+
let match;
|
|
979
|
+
while ((match = searchRe.exec(str)) !== null) {
|
|
980
|
+
let matchEnd = searchRe.lastIndex;
|
|
981
|
+
let replacement = REDACTION_TOKEN;
|
|
982
|
+
let newLast = matchEnd;
|
|
983
|
+
let assign = str.slice(matchEnd).match(/^(\s*[=:]\s*)(".*?"|'.*?'|\S+)?/);
|
|
984
|
+
if (assign) {
|
|
985
|
+
newLast = matchEnd + assign[0].length;
|
|
986
|
+
replacement = REDACTION_TOKEN;
|
|
987
|
+
searchRe.lastIndex = newLast;
|
|
988
|
+
}
|
|
989
|
+
result += str.slice(last, match.index) + replacement;
|
|
990
|
+
last = newLast;
|
|
991
|
+
}
|
|
992
|
+
result += str.slice(last);
|
|
993
|
+
return result;
|
|
994
|
+
}
|
|
995
|
+
var DispatcherBase = class {
|
|
996
|
+
sendMethod;
|
|
997
|
+
formatArg = void 0;
|
|
998
|
+
level;
|
|
999
|
+
exact = null;
|
|
1000
|
+
printTimestamp = true;
|
|
1001
|
+
printLevel = true;
|
|
1002
|
+
redactDataRegExp;
|
|
1003
|
+
_lastTimestampSec = -1;
|
|
1004
|
+
_lastTimestampStr = "";
|
|
1005
|
+
constructor(send = () => {}, options = {}) {
|
|
1006
|
+
this.dispatch = this.dispatch.bind(this);
|
|
1007
|
+
this.sendMethod = send;
|
|
1008
|
+
this.printTimestamp = options.printTimestamp ?? true;
|
|
1009
|
+
this.printLevel = options.printLevel ?? true;
|
|
1010
|
+
this.level = options.level;
|
|
1011
|
+
this.exact = options.exact ? toarray(options.exact) : null;
|
|
1012
|
+
this.redactDataRegExp = options.redactDataRegExp;
|
|
1013
|
+
}
|
|
1014
|
+
dispatch(meta, args, errorMeta) {
|
|
1015
|
+
let effectiveRe = this.redactDataRegExp || meta.redactDataRegExp;
|
|
1016
|
+
let processedArgs = effectiveRe ? args.map((v) => redact(v, effectiveRe)) : args;
|
|
1017
|
+
let processedErrorMeta = errorMeta;
|
|
1018
|
+
if (effectiveRe && errorMeta != null) processedErrorMeta = redact(errorMeta, effectiveRe);
|
|
1019
|
+
let parts = [];
|
|
1020
|
+
if (this.printTimestamp) parts.push(this.formatTimestamp(meta.timestamp));
|
|
1021
|
+
if (this.printLevel) parts.push(meta.level);
|
|
1022
|
+
for (let value of processedArgs) {
|
|
1023
|
+
let formatted;
|
|
1024
|
+
if (typeof this.formatArg === "function") formatted = this.formatArg(value);
|
|
1025
|
+
else formatted = value;
|
|
1026
|
+
parts.push(formatted);
|
|
1027
|
+
}
|
|
1028
|
+
this.sendMethod(parts.join(" "), processedErrorMeta);
|
|
1029
|
+
}
|
|
1030
|
+
formatTimestamp(t) {
|
|
1031
|
+
let sec = Math.floor(t / 1e3);
|
|
1032
|
+
if (sec === this._lastTimestampSec) return this._lastTimestampStr;
|
|
1033
|
+
let d = new Date(t);
|
|
1034
|
+
let s = `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`;
|
|
1035
|
+
this._lastTimestampSec = sec;
|
|
1036
|
+
this._lastTimestampStr = s;
|
|
1037
|
+
return s;
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
function prepareDispatchArgs(redactDataRegExp, meta, rawArgs, errorMeta) {
|
|
1041
|
+
let effectiveRe = redactDataRegExp || meta.redactDataRegExp;
|
|
1042
|
+
let processedRawArgs = effectiveRe ? rawArgs.map((v) => redact(v, effectiveRe)) : rawArgs;
|
|
1043
|
+
let processedErrorMeta = errorMeta;
|
|
1044
|
+
if (effectiveRe && errorMeta != null) processedErrorMeta = redact(errorMeta, effectiveRe);
|
|
1045
|
+
return {
|
|
1046
|
+
processedRawArgs,
|
|
1047
|
+
processedErrorMeta
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
function routeConsoleCall(target, level, args) {
|
|
1051
|
+
let ul = level.toUpperCase();
|
|
1052
|
+
if (ul.startsWith("DEBUG")) {
|
|
1053
|
+
target.debug(...args);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (ul.startsWith("WARN")) {
|
|
1057
|
+
target.warn(...args);
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
if (ul.startsWith("ERROR") || ul.startsWith("FATAL")) {
|
|
1061
|
+
target.error(...args);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
target.info(...args);
|
|
1065
|
+
}
|
|
1066
|
+
function NewConsoleDispatcher(console, options) {
|
|
1067
|
+
return () => new class ConsoleDispatcher extends DispatcherBase {
|
|
1068
|
+
constructor(console2, options2 = {}) {
|
|
1069
|
+
super(() => {}, options2);
|
|
1070
|
+
this.console = console2;
|
|
1071
|
+
}
|
|
1072
|
+
dispatch(meta, rawArgs, errorMeta) {
|
|
1073
|
+
let { processedRawArgs, processedErrorMeta } = prepareDispatchArgs(this.redactDataRegExp, meta, rawArgs, errorMeta);
|
|
1074
|
+
let args = [];
|
|
1075
|
+
if (this.printTimestamp) args.push(`${this.formatTimestamp(meta.timestamp)}`);
|
|
1076
|
+
if (this.printLevel) {
|
|
1077
|
+
let margin = this.printTimestamp ? " " : "";
|
|
1078
|
+
args.push(`${margin}${meta.level}`);
|
|
1079
|
+
}
|
|
1080
|
+
for (let value of processedRawArgs) {
|
|
1081
|
+
let formatted;
|
|
1082
|
+
if (typeof this.formatArg === "function") formatted = this.formatArg(value);
|
|
1083
|
+
else formatted = value;
|
|
1084
|
+
args.push(formatted);
|
|
1085
|
+
}
|
|
1086
|
+
if (processedErrorMeta !== void 0) {
|
|
1087
|
+
let m = typeof this.formatArg === "function" ? this.formatArg(processedErrorMeta) : processedErrorMeta;
|
|
1088
|
+
args.push(m);
|
|
1089
|
+
}
|
|
1090
|
+
routeConsoleCall(this.console, meta.level, args);
|
|
1091
|
+
}
|
|
1092
|
+
}(console, options);
|
|
1093
|
+
}
|
|
1094
|
+
typeof process !== "undefined" && process.versions != null && process.versions.node;
|
|
1095
|
+
function tryReportAnError(err) {
|
|
1096
|
+
try {
|
|
1097
|
+
(typeof self !== "undefined" ? self.console : console).error(err);
|
|
1098
|
+
} catch (_) {}
|
|
1099
|
+
}
|
|
1100
|
+
var MajorLevelMap = /* @__PURE__ */ new Map([
|
|
1101
|
+
[Level.Fatal, /* @__PURE__ */ new Set([Level.Fatal])],
|
|
1102
|
+
[Level.Error, /* @__PURE__ */ new Set([Level.Fatal, Level.Error])],
|
|
1103
|
+
[Level.Warn, /* @__PURE__ */ new Set([
|
|
1104
|
+
Level.Fatal,
|
|
1105
|
+
Level.Error,
|
|
1106
|
+
Level.Warn
|
|
1107
|
+
])],
|
|
1108
|
+
[Level.Notice, /* @__PURE__ */ new Set([
|
|
1109
|
+
Level.Fatal,
|
|
1110
|
+
Level.Error,
|
|
1111
|
+
Level.Warn,
|
|
1112
|
+
Level.Notice
|
|
1113
|
+
])],
|
|
1114
|
+
[Level.Info, /* @__PURE__ */ new Set([
|
|
1115
|
+
Level.Fatal,
|
|
1116
|
+
Level.Error,
|
|
1117
|
+
Level.Warn,
|
|
1118
|
+
Level.Notice,
|
|
1119
|
+
Level.Info
|
|
1120
|
+
])],
|
|
1121
|
+
[Level.Debug, /* @__PURE__ */ new Set([
|
|
1122
|
+
Level.Fatal,
|
|
1123
|
+
Level.Error,
|
|
1124
|
+
Level.Warn,
|
|
1125
|
+
Level.Notice,
|
|
1126
|
+
Level.Info,
|
|
1127
|
+
Level.Debug
|
|
1128
|
+
])],
|
|
1129
|
+
[Level.Trace, /* @__PURE__ */ new Set([
|
|
1130
|
+
Level.Fatal,
|
|
1131
|
+
Level.Error,
|
|
1132
|
+
Level.Warn,
|
|
1133
|
+
Level.Notice,
|
|
1134
|
+
Level.Info,
|
|
1135
|
+
Level.Debug,
|
|
1136
|
+
Level.Trace
|
|
1137
|
+
])]
|
|
1138
|
+
]);
|
|
1139
|
+
var DispatchersBalancer = class {
|
|
1140
|
+
constructor(level, dispatchers) {
|
|
1141
|
+
this.level = level;
|
|
1142
|
+
this.dispatchers = dispatchers;
|
|
1143
|
+
this.sendLog = this.sendLog.bind(this);
|
|
1144
|
+
this.hasHandlers = this.hasHandlers.bind(this);
|
|
1145
|
+
}
|
|
1146
|
+
map = /* @__PURE__ */ new Map();
|
|
1147
|
+
sendLog(meta, args, errorMeta) {
|
|
1148
|
+
this.discover(meta.level);
|
|
1149
|
+
if ((this.map.get(meta.level) ?? []).length === 0) return;
|
|
1150
|
+
this.send(meta, args, errorMeta);
|
|
1151
|
+
}
|
|
1152
|
+
hasHandlers(level) {
|
|
1153
|
+
this.discover(level);
|
|
1154
|
+
let hs = this.map.get(level);
|
|
1155
|
+
return !!(hs && hs.length > 0);
|
|
1156
|
+
}
|
|
1157
|
+
discover(level) {
|
|
1158
|
+
if (this.map.get(level)) return;
|
|
1159
|
+
let discovered = [];
|
|
1160
|
+
this.map.set(level, discovered);
|
|
1161
|
+
for (let h of this.dispatchers) {
|
|
1162
|
+
if (h.exact) {
|
|
1163
|
+
if (h.exact.some((l) => l === level)) discovered.push(h);
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
if (this.canSend(level, h.level ?? this.level)) discovered.push(h);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
send(meta, args, errorMeta) {
|
|
1170
|
+
try {
|
|
1171
|
+
this.sendToDispatchers(meta, args, errorMeta);
|
|
1172
|
+
} catch (e) {
|
|
1173
|
+
tryReportAnError(new HaluaFailedToCallDispatcher(`Unable to call dispatch method of a dispatcher`, { cause: e }));
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
sendToDispatchers(meta, args, errorMeta) {
|
|
1177
|
+
let hs = this.map.get(meta.level) ?? [];
|
|
1178
|
+
for (let h of hs) try {
|
|
1179
|
+
h.dispatch(meta, args, errorMeta);
|
|
1180
|
+
} catch (e) {
|
|
1181
|
+
tryReportAnError(new HaluaFailedToCallDispatcher(`Unable to call dispatch method of a dispatcher`, { cause: e }));
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
canSend(l, to = this.level || Level.Trace) {
|
|
1185
|
+
let lvl = extractLevels(l);
|
|
1186
|
+
let toLvl = extractLevels(to);
|
|
1187
|
+
return this.majorLevelCheck(lvl[0], toLvl[0]) + this.minorLevelCheck(lvl[1], toLvl[1]) > 0;
|
|
1188
|
+
}
|
|
1189
|
+
majorLevelCheck(l, to) {
|
|
1190
|
+
if (l === to) return 0;
|
|
1191
|
+
let toSet = MajorLevelMap.get(to);
|
|
1192
|
+
if (!toSet || !toSet.has(l)) return -1;
|
|
1193
|
+
return 1;
|
|
1194
|
+
}
|
|
1195
|
+
minorLevelCheck(l, to) {
|
|
1196
|
+
return l >= to ? 1 : 0;
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
var NOOP = () => {};
|
|
1200
|
+
function instantiate(passed, options = {}, features = []) {
|
|
1201
|
+
return new Halua(passed, options, features);
|
|
1202
|
+
}
|
|
1203
|
+
var Halua = class {
|
|
1204
|
+
constructor(passed, options = {}, features = []) {
|
|
1205
|
+
this.options = options;
|
|
1206
|
+
this.passedDispatchers = passed;
|
|
1207
|
+
this.features = features;
|
|
1208
|
+
this.dispatchers = this.buildDispatchers(this.mergeFeatureDispatchers(passed));
|
|
1209
|
+
this.balancer = new DispatchersBalancer(this.options.level || Level.Trace, this.dispatchers);
|
|
1210
|
+
this.bindCoreMethods();
|
|
1211
|
+
this.refreshLevelMethods();
|
|
1212
|
+
this.applyFeatures();
|
|
1213
|
+
}
|
|
1214
|
+
passedDispatchers = [];
|
|
1215
|
+
features = [];
|
|
1216
|
+
dispatchers = [];
|
|
1217
|
+
balancer;
|
|
1218
|
+
stamps = /* @__PURE__ */ new Map();
|
|
1219
|
+
trace;
|
|
1220
|
+
debug;
|
|
1221
|
+
info;
|
|
1222
|
+
warn;
|
|
1223
|
+
notice;
|
|
1224
|
+
error;
|
|
1225
|
+
fatal;
|
|
1226
|
+
assert;
|
|
1227
|
+
logTo;
|
|
1228
|
+
create(arg1 = this.passedDispatchers, arg2 = this.options) {
|
|
1229
|
+
if (this.isDispatcherSpec(arg1)) return instantiate(arg1, { ...arg2 ?? this.options }, this.features);
|
|
1230
|
+
return instantiate(this.passedDispatchers, { ...arg1 }, this.features);
|
|
1231
|
+
}
|
|
1232
|
+
child(...args) {
|
|
1233
|
+
return instantiate(this.passedDispatchers, {
|
|
1234
|
+
...this.options,
|
|
1235
|
+
withArgs: (this.options.withArgs || []).concat(args)
|
|
1236
|
+
}, this.features);
|
|
1237
|
+
}
|
|
1238
|
+
setDispatchers(dispatcher) {
|
|
1239
|
+
this.dispatchers = this.buildDispatchers(this.mergeFeatureDispatchers(dispatcher));
|
|
1240
|
+
this.updateBalancer();
|
|
1241
|
+
}
|
|
1242
|
+
appendDispatchers(dispatcher) {
|
|
1243
|
+
let dispatchers = this.buildDispatchers(dispatcher);
|
|
1244
|
+
this.dispatchers.push(...dispatchers);
|
|
1245
|
+
this.updateBalancer();
|
|
1246
|
+
}
|
|
1247
|
+
_logTo(level, ...args) {
|
|
1248
|
+
this.sendToBalancer(level, args);
|
|
1249
|
+
}
|
|
1250
|
+
_trace(...args) {
|
|
1251
|
+
this.sendToBalancer(Level.Trace, args);
|
|
1252
|
+
}
|
|
1253
|
+
_debug(...args) {
|
|
1254
|
+
this.sendToBalancer(Level.Debug, args);
|
|
1255
|
+
}
|
|
1256
|
+
_info(...args) {
|
|
1257
|
+
this.sendToBalancer(Level.Info, args);
|
|
1258
|
+
}
|
|
1259
|
+
_warn(...args) {
|
|
1260
|
+
this.sendToBalancer(Level.Warn, args);
|
|
1261
|
+
}
|
|
1262
|
+
_notice(...args) {
|
|
1263
|
+
this.sendToBalancer(Level.Notice, args);
|
|
1264
|
+
}
|
|
1265
|
+
_error(error, meta) {
|
|
1266
|
+
let e = unknownToError(error);
|
|
1267
|
+
let payload = [e];
|
|
1268
|
+
let finalMeta = meta != null ? {
|
|
1269
|
+
...meta,
|
|
1270
|
+
error: e
|
|
1271
|
+
} : void 0;
|
|
1272
|
+
this.sendToBalancer(Level.Error, payload, finalMeta);
|
|
1273
|
+
}
|
|
1274
|
+
_fatal(...args) {
|
|
1275
|
+
this.sendToBalancer(Level.Fatal, args);
|
|
1276
|
+
}
|
|
1277
|
+
_assert(assertion, error, meta) {
|
|
1278
|
+
if (assertion) return;
|
|
1279
|
+
let e = unknownToError(error);
|
|
1280
|
+
let payload = [e];
|
|
1281
|
+
let finalMeta = meta != null ? {
|
|
1282
|
+
...meta,
|
|
1283
|
+
error: e
|
|
1284
|
+
} : void 0;
|
|
1285
|
+
this.sendToBalancer(Level.Error, payload, finalMeta);
|
|
1286
|
+
}
|
|
1287
|
+
stamp(label, id) {
|
|
1288
|
+
let start = performance.now();
|
|
1289
|
+
if (id != null) this.stamps.set(id, {
|
|
1290
|
+
label,
|
|
1291
|
+
start
|
|
1292
|
+
});
|
|
1293
|
+
let ended = false;
|
|
1294
|
+
let duration = 0;
|
|
1295
|
+
const ender = () => {
|
|
1296
|
+
if (ended) return duration;
|
|
1297
|
+
ended = true;
|
|
1298
|
+
if (id != null) {
|
|
1299
|
+
let current = this.stamps.get(id);
|
|
1300
|
+
if (current && current.start === start) this.stamps.delete(id);
|
|
1301
|
+
}
|
|
1302
|
+
duration = this.endStamp(label, start);
|
|
1303
|
+
return duration;
|
|
1304
|
+
};
|
|
1305
|
+
return ender;
|
|
1306
|
+
}
|
|
1307
|
+
stampEnd(id) {
|
|
1308
|
+
let entry = this.stamps.get(id);
|
|
1309
|
+
if (!entry) return;
|
|
1310
|
+
this.stamps.delete(id);
|
|
1311
|
+
return this.endStamp(entry.label, entry.start);
|
|
1312
|
+
}
|
|
1313
|
+
endStamp(label, start) {
|
|
1314
|
+
let duration = performance.now() - start;
|
|
1315
|
+
let ms = duration.toFixed(2);
|
|
1316
|
+
this.info(label, `took ${ms}ms`);
|
|
1317
|
+
return duration;
|
|
1318
|
+
}
|
|
1319
|
+
updateBalancer() {
|
|
1320
|
+
this.balancer = new DispatchersBalancer(this.options.level || Level.Trace, this.dispatchers);
|
|
1321
|
+
this.refreshLevelMethods();
|
|
1322
|
+
}
|
|
1323
|
+
sendToBalancer(level, args, errorMeta) {
|
|
1324
|
+
let finalArgs = args.concat(this.options.withArgs ?? []);
|
|
1325
|
+
let dispatchMeta = {
|
|
1326
|
+
level,
|
|
1327
|
+
timestamp: Date.now()
|
|
1328
|
+
};
|
|
1329
|
+
if (this.options.redactDataRegExp) dispatchMeta.redactDataRegExp = this.options.redactDataRegExp;
|
|
1330
|
+
this.balancer.sendLog(dispatchMeta, finalArgs, errorMeta);
|
|
1331
|
+
}
|
|
1332
|
+
supposeIsDispatcher(v, reportError = true) {
|
|
1333
|
+
let isDispatcher = typeof v?.dispatch === "function";
|
|
1334
|
+
if (!isDispatcher && reportError) tryReportAnError(new HaluaUnableToDetermineDispatcher(`Unable to find dispatch method of a dispatcher`));
|
|
1335
|
+
return isDispatcher;
|
|
1336
|
+
}
|
|
1337
|
+
isDispatcherSpec(v) {
|
|
1338
|
+
if (Array.isArray(v)) return v.every((x) => typeof x === "function");
|
|
1339
|
+
return typeof v === "function";
|
|
1340
|
+
}
|
|
1341
|
+
mergeFeatureDispatchers(passed) {
|
|
1342
|
+
let extras = [];
|
|
1343
|
+
for (let f of this.features) if (f.contributeDispatchers) extras.push(...f.contributeDispatchers());
|
|
1344
|
+
return toarray(passed).concat(extras);
|
|
1345
|
+
}
|
|
1346
|
+
applyFeatures() {
|
|
1347
|
+
for (let f of this.features) Object.assign(this, f.apply(this));
|
|
1348
|
+
}
|
|
1349
|
+
buildDispatchers(passed) {
|
|
1350
|
+
return toarray(passed).map((b) => b()).filter((h) => this.supposeIsDispatcher(h));
|
|
1351
|
+
}
|
|
1352
|
+
bindCoreMethods() {
|
|
1353
|
+
this.create = this.create.bind(this);
|
|
1354
|
+
this.child = this.child.bind(this);
|
|
1355
|
+
this.setDispatchers = this.setDispatchers.bind(this);
|
|
1356
|
+
this.appendDispatchers = this.appendDispatchers.bind(this);
|
|
1357
|
+
this.stamp = this.stamp.bind(this);
|
|
1358
|
+
this.stampEnd = this.stampEnd.bind(this);
|
|
1359
|
+
this.supposeIsDispatcher = this.supposeIsDispatcher.bind(this);
|
|
1360
|
+
}
|
|
1361
|
+
refreshLevelMethods() {
|
|
1362
|
+
const isEnabled = (level) => this.balancer.hasHandlers(level);
|
|
1363
|
+
this.trace = isEnabled(Level.Trace) ? this._trace.bind(this) : NOOP;
|
|
1364
|
+
this.debug = isEnabled(Level.Debug) ? this._debug.bind(this) : NOOP;
|
|
1365
|
+
this.info = isEnabled(Level.Info) ? this._info.bind(this) : NOOP;
|
|
1366
|
+
this.warn = isEnabled(Level.Warn) ? this._warn.bind(this) : NOOP;
|
|
1367
|
+
this.notice = isEnabled(Level.Notice) ? this._notice.bind(this) : NOOP;
|
|
1368
|
+
this.error = isEnabled(Level.Error) ? this._error.bind(this) : NOOP;
|
|
1369
|
+
this.fatal = isEnabled(Level.Fatal) ? this._fatal.bind(this) : NOOP;
|
|
1370
|
+
this.assert = isEnabled(Level.Error) ? this._assert.bind(this) : NOOP;
|
|
1371
|
+
this.logTo = this._logTo.bind(this);
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
var Builder = class {
|
|
1375
|
+
userDispatchers = [];
|
|
1376
|
+
opts = {};
|
|
1377
|
+
features = [];
|
|
1378
|
+
dispatchers(d) {
|
|
1379
|
+
this.userDispatchers = d;
|
|
1380
|
+
return this;
|
|
1381
|
+
}
|
|
1382
|
+
level(level) {
|
|
1383
|
+
this.opts = {
|
|
1384
|
+
...this.opts,
|
|
1385
|
+
level
|
|
1386
|
+
};
|
|
1387
|
+
return this;
|
|
1388
|
+
}
|
|
1389
|
+
redact(redactDataRegExp) {
|
|
1390
|
+
this.opts = {
|
|
1391
|
+
...this.opts,
|
|
1392
|
+
redactDataRegExp
|
|
1393
|
+
};
|
|
1394
|
+
return this;
|
|
1395
|
+
}
|
|
1396
|
+
withArgs(withArgs) {
|
|
1397
|
+
this.opts = {
|
|
1398
|
+
...this.opts,
|
|
1399
|
+
withArgs
|
|
1400
|
+
};
|
|
1401
|
+
return this;
|
|
1402
|
+
}
|
|
1403
|
+
use(feature) {
|
|
1404
|
+
this.features = this.features.concat(feature);
|
|
1405
|
+
return this;
|
|
1406
|
+
}
|
|
1407
|
+
build() {
|
|
1408
|
+
return instantiate(this.userDispatchers, this.opts, this.features);
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
function createHalua() {
|
|
1412
|
+
return new Builder();
|
|
1413
|
+
}
|
|
1414
|
+
function flattenCtx(ctx) {
|
|
1415
|
+
if (ctx == null || typeof ctx !== "object" || Array.isArray(ctx)) return [];
|
|
1416
|
+
let pairs = [];
|
|
1417
|
+
let keys = Object.keys(ctx);
|
|
1418
|
+
for (let k of keys) pairs.push(k, ctx[k]);
|
|
1419
|
+
return pairs;
|
|
1420
|
+
}
|
|
1421
|
+
function isThenable$1(v) {
|
|
1422
|
+
return v != null && typeof v.then === "function";
|
|
1423
|
+
}
|
|
1424
|
+
function spanFlow() {
|
|
1425
|
+
return { apply(host) {
|
|
1426
|
+
let flow = (name, ctx) => {
|
|
1427
|
+
return host.child("flow", name, ...flattenCtx(ctx));
|
|
1428
|
+
};
|
|
1429
|
+
let closeSuccess = (log, label, start) => {
|
|
1430
|
+
let elapsedMs = performance.now() - start;
|
|
1431
|
+
log.info("done", {
|
|
1432
|
+
span: label,
|
|
1433
|
+
elapsedMs
|
|
1434
|
+
});
|
|
1435
|
+
return elapsedMs;
|
|
1436
|
+
};
|
|
1437
|
+
let closeFailure = (log, label, start, err) => {
|
|
1438
|
+
let elapsedMs = performance.now() - start;
|
|
1439
|
+
if (err instanceof Error) log.error(err, {
|
|
1440
|
+
span: label,
|
|
1441
|
+
elapsedMs
|
|
1442
|
+
});
|
|
1443
|
+
else log.warn("never-happen", {
|
|
1444
|
+
span: label,
|
|
1445
|
+
elapsedMs,
|
|
1446
|
+
err
|
|
1447
|
+
});
|
|
1448
|
+
return elapsedMs;
|
|
1449
|
+
};
|
|
1450
|
+
let startSpan = (label) => {
|
|
1451
|
+
let log = host.child("span", label);
|
|
1452
|
+
let start = performance.now();
|
|
1453
|
+
log.info("start", { span: label });
|
|
1454
|
+
return {
|
|
1455
|
+
log,
|
|
1456
|
+
start
|
|
1457
|
+
};
|
|
1458
|
+
};
|
|
1459
|
+
let span = (label, fn) => {
|
|
1460
|
+
if (typeof fn !== "function") {
|
|
1461
|
+
let started2 = startSpan(label);
|
|
1462
|
+
let ended = false;
|
|
1463
|
+
let duration = 0;
|
|
1464
|
+
return () => {
|
|
1465
|
+
if (ended) return duration;
|
|
1466
|
+
ended = true;
|
|
1467
|
+
duration = closeSuccess(started2.log, label, started2.start);
|
|
1468
|
+
return duration;
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
let started = startSpan(label);
|
|
1472
|
+
try {
|
|
1473
|
+
let result = fn(started.log);
|
|
1474
|
+
if (isThenable$1(result)) return result.then((value) => {
|
|
1475
|
+
closeSuccess(started.log, label, started.start);
|
|
1476
|
+
return value;
|
|
1477
|
+
}, (err) => {
|
|
1478
|
+
closeFailure(started.log, label, started.start, err);
|
|
1479
|
+
throw err;
|
|
1480
|
+
});
|
|
1481
|
+
closeSuccess(started.log, label, started.start);
|
|
1482
|
+
return result;
|
|
1483
|
+
} catch (err) {
|
|
1484
|
+
closeFailure(started.log, label, started.start, err);
|
|
1485
|
+
throw err;
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
return {
|
|
1489
|
+
flow,
|
|
1490
|
+
span
|
|
1491
|
+
};
|
|
1492
|
+
} };
|
|
1493
|
+
}
|
|
1494
|
+
var logConsole = (() => {
|
|
1495
|
+
try {
|
|
1496
|
+
return typeof self !== "undefined" ? self.console : console;
|
|
1497
|
+
} catch (_) {
|
|
1498
|
+
return null;
|
|
1499
|
+
}
|
|
1500
|
+
})();
|
|
1501
|
+
createHalua().dispatchers(logConsole ? NewConsoleDispatcher(logConsole) : []).use(spanFlow()).build();
|
|
1502
|
+
//#endregion
|
|
1503
|
+
//#region ../log/src/silent.ts
|
|
1504
|
+
function makeSilentLog() {
|
|
1505
|
+
return createHalua().use(spanFlow()).build();
|
|
1506
|
+
}
|
|
1507
|
+
//#endregion
|
|
1508
|
+
//#region ../log/src/make-log.ts
|
|
1509
|
+
function isThenable(v) {
|
|
1510
|
+
return v != null && typeof v.then === "function";
|
|
1511
|
+
}
|
|
1512
|
+
/** LDD catch-boundary: Error → flow.error, else never-happen. */
|
|
1513
|
+
function reportFlowFailure(flow, err, ctx) {
|
|
1514
|
+
if (err instanceof Error) flow.error(err, ctx);
|
|
1515
|
+
else flow.warn("never-happen", {
|
|
1516
|
+
err,
|
|
1517
|
+
...ctx
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Bind issueKey on .error / .assert. Intercepts child / flow / create / span so
|
|
1522
|
+
* descendants keep the same key (including spanFlow closeFailure).
|
|
1523
|
+
* Input must already be a spanFlow logger (halua.create / createTestLog).
|
|
1524
|
+
* A missing .flow throws — it does not invent a child.
|
|
1525
|
+
*/
|
|
1526
|
+
function makeLog(src, issueKey) {
|
|
1527
|
+
if (typeof src.flow !== "function") throw new Error("makeLog requires Logger.flow (halua.create / createTestLog with spanFlow)");
|
|
1528
|
+
const mergeMeta = (meta) => {
|
|
1529
|
+
if (!meta) return { issueKey };
|
|
1530
|
+
let { issueKey: _ignored, ...rest } = meta;
|
|
1531
|
+
return {
|
|
1532
|
+
issueKey,
|
|
1533
|
+
...rest
|
|
1534
|
+
};
|
|
1535
|
+
};
|
|
1536
|
+
function wrap(inner) {
|
|
1537
|
+
return new Proxy(inner, { get(target, prop, receiver) {
|
|
1538
|
+
if (prop === "error") return (err, meta) => {
|
|
1539
|
+
target.error(err, mergeMeta(meta));
|
|
1540
|
+
};
|
|
1541
|
+
if (prop === "assert") return (assertion, error, meta) => {
|
|
1542
|
+
target.assert(assertion, error, meta ? mergeMeta(meta) : { issueKey });
|
|
1543
|
+
};
|
|
1544
|
+
if (prop === "child") return (...args) => wrap(target.child(...args));
|
|
1545
|
+
if (prop === "flow") return (name, ctx) => wrap(target.flow(name, ctx));
|
|
1546
|
+
if (prop === "create") return (arg1, arg2) => wrap(target.create(arg1, arg2));
|
|
1547
|
+
if (prop === "span") return (label, fn) => {
|
|
1548
|
+
let spanLog = wrap(target.child("span", label));
|
|
1549
|
+
let start = performance.now();
|
|
1550
|
+
spanLog.info("start", { span: label });
|
|
1551
|
+
const closeOk = () => {
|
|
1552
|
+
let elapsedMs = performance.now() - start;
|
|
1553
|
+
spanLog.info("done", {
|
|
1554
|
+
span: label,
|
|
1555
|
+
elapsedMs
|
|
1556
|
+
});
|
|
1557
|
+
return elapsedMs;
|
|
1558
|
+
};
|
|
1559
|
+
const closeFail = (err) => {
|
|
1560
|
+
reportFlowFailure(spanLog, err, {
|
|
1561
|
+
span: label,
|
|
1562
|
+
elapsedMs: performance.now() - start
|
|
1563
|
+
});
|
|
1564
|
+
};
|
|
1565
|
+
if (typeof fn !== "function") {
|
|
1566
|
+
let ended = false;
|
|
1567
|
+
let duration = 0;
|
|
1568
|
+
return () => {
|
|
1569
|
+
if (ended) return duration;
|
|
1570
|
+
ended = true;
|
|
1571
|
+
duration = closeOk();
|
|
1572
|
+
return duration;
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
try {
|
|
1576
|
+
let result = fn(spanLog);
|
|
1577
|
+
if (isThenable(result)) return result.then((value) => {
|
|
1578
|
+
closeOk();
|
|
1579
|
+
return value;
|
|
1580
|
+
}, (err) => {
|
|
1581
|
+
closeFail(err);
|
|
1582
|
+
throw err;
|
|
1583
|
+
});
|
|
1584
|
+
closeOk();
|
|
1585
|
+
return result;
|
|
1586
|
+
} catch (err) {
|
|
1587
|
+
closeFail(err);
|
|
1588
|
+
throw err;
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
let value = Reflect.get(target, prop, receiver);
|
|
1592
|
+
if (typeof value === "function") return value.bind(target);
|
|
1593
|
+
return value;
|
|
1594
|
+
} });
|
|
1595
|
+
}
|
|
1596
|
+
return wrap(src);
|
|
1597
|
+
}
|
|
1598
|
+
//#endregion
|
|
1599
|
+
//#region src/driver.ts
|
|
1600
|
+
var import___vite_browser_external = require___vite_browser_external();
|
|
1601
|
+
var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
1602
|
+
var IDENT_RE = /^[A-Za-z0-9_-]+$/;
|
|
1603
|
+
var ISSUE_KEY = "yorozu-db-sqlite";
|
|
1604
|
+
function reportError(log, err) {
|
|
1605
|
+
if (err instanceof Error) log.error(err);
|
|
1606
|
+
else log.warn("never-happen", { err });
|
|
1607
|
+
}
|
|
1608
|
+
function quoteIdent(name) {
|
|
1609
|
+
if (!IDENT_RE.test(name)) throw new Error(`illegal identifier: ${name}`);
|
|
1610
|
+
return `"${name}"`;
|
|
1611
|
+
}
|
|
1612
|
+
function validateSchema(schema) {
|
|
1613
|
+
for (let col of schema.collections) {
|
|
1614
|
+
quoteIdent(col.name);
|
|
1615
|
+
for (let idx of col.indexes ?? []) quoteIdent(idx.name);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function indexFields(keyPath) {
|
|
1619
|
+
return typeof keyPath === "string" ? [keyPath] : [...keyPath];
|
|
1620
|
+
}
|
|
1621
|
+
function indexColId(indexName, i) {
|
|
1622
|
+
return `${indexName}__${i}`;
|
|
1623
|
+
}
|
|
1624
|
+
function allIndexColIds(def) {
|
|
1625
|
+
let out = [];
|
|
1626
|
+
for (let idx of def.indexes ?? []) {
|
|
1627
|
+
let n = indexFields(idx.keyPath).length;
|
|
1628
|
+
for (let i = 0; i < n; i++) out.push(indexColId(idx.name, i));
|
|
1629
|
+
}
|
|
1630
|
+
return out;
|
|
1631
|
+
}
|
|
1632
|
+
function isScalarKey(value) {
|
|
1633
|
+
return typeof value === "string" || typeof value === "number" && !Number.isNaN(value);
|
|
1634
|
+
}
|
|
1635
|
+
function projectIndexKey(row, keyPath) {
|
|
1636
|
+
if (typeof keyPath === "string") {
|
|
1637
|
+
let value = row[keyPath];
|
|
1638
|
+
if (!isScalarKey(value)) return void 0;
|
|
1639
|
+
return value;
|
|
1640
|
+
}
|
|
1641
|
+
let parts = [];
|
|
1642
|
+
for (let field of keyPath) {
|
|
1643
|
+
let value = row[field];
|
|
1644
|
+
if (!isScalarKey(value)) return void 0;
|
|
1645
|
+
parts.push(value);
|
|
1646
|
+
}
|
|
1647
|
+
return parts;
|
|
1648
|
+
}
|
|
1649
|
+
function primaryKeyOf(row, keyPath) {
|
|
1650
|
+
let raw = row[keyPath];
|
|
1651
|
+
if (raw === void 0 || raw === null) throw new Error(`missing primary key field: ${keyPath}`);
|
|
1652
|
+
return String(raw);
|
|
1653
|
+
}
|
|
1654
|
+
function withStringPk(row, keyPath, pk) {
|
|
1655
|
+
if (row[keyPath] === pk) return row;
|
|
1656
|
+
return {
|
|
1657
|
+
...row,
|
|
1658
|
+
[keyPath]: pk
|
|
1659
|
+
};
|
|
1660
|
+
}
|
|
1661
|
+
function indexKeyPath(def, name) {
|
|
1662
|
+
if (name === "__pk") return def.keyPath;
|
|
1663
|
+
let idx = (def.indexes ?? []).find((item) => item.name === name);
|
|
1664
|
+
if (!idx) throw new Error(`unknown index: ${name}`);
|
|
1665
|
+
return idx.keyPath;
|
|
1666
|
+
}
|
|
1667
|
+
function isBlobish(value) {
|
|
1668
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) return true;
|
|
1669
|
+
if (typeof ArrayBuffer !== "undefined" && value instanceof ArrayBuffer) return true;
|
|
1670
|
+
if (value instanceof Uint8Array) return true;
|
|
1671
|
+
return false;
|
|
1672
|
+
}
|
|
1673
|
+
async function toBytes(value) {
|
|
1674
|
+
if (Buffer.isBuffer(value)) return value;
|
|
1675
|
+
if (value instanceof ArrayBuffer) return Buffer.from(value);
|
|
1676
|
+
if (value instanceof Uint8Array) return Buffer.from(value);
|
|
1677
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) return Buffer.from(await value.arrayBuffer());
|
|
1678
|
+
throw new Error("expected blob field");
|
|
1679
|
+
}
|
|
1680
|
+
function rehydrate(data) {
|
|
1681
|
+
let bytes = Uint8Array.from(data);
|
|
1682
|
+
if (typeof Blob === "function") return new Blob([bytes]);
|
|
1683
|
+
return bytes;
|
|
1684
|
+
}
|
|
1685
|
+
async function splitRow(row) {
|
|
1686
|
+
let payload = {};
|
|
1687
|
+
let blobs = /* @__PURE__ */ new Map();
|
|
1688
|
+
for (let [key, value] of Object.entries(row)) if (isBlobish(value)) blobs.set(key, await toBytes(value));
|
|
1689
|
+
else payload[key] = value;
|
|
1690
|
+
return {
|
|
1691
|
+
payload,
|
|
1692
|
+
blobs
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
function indexBinds(row, def) {
|
|
1696
|
+
let values = [];
|
|
1697
|
+
for (let idx of def.indexes ?? []) for (let field of indexFields(idx.keyPath)) {
|
|
1698
|
+
let value = row[field];
|
|
1699
|
+
values.push(isScalarKey(value) ? value : null);
|
|
1700
|
+
}
|
|
1701
|
+
return values;
|
|
1702
|
+
}
|
|
1703
|
+
function lexSql(cols, parts, wantLess, inclusive) {
|
|
1704
|
+
let n = cols.length;
|
|
1705
|
+
let m = parts.length;
|
|
1706
|
+
let clauses = [];
|
|
1707
|
+
let params = [];
|
|
1708
|
+
let shared = Math.min(n, m);
|
|
1709
|
+
for (let i = 0; i < shared; i++) {
|
|
1710
|
+
let terms = [];
|
|
1711
|
+
for (let j = 0; j < i; j++) {
|
|
1712
|
+
terms.push(`${cols[j]} = ?`);
|
|
1713
|
+
params.push(parts[j]);
|
|
1714
|
+
}
|
|
1715
|
+
terms.push(`${cols[i]} ${wantLess ? "<" : ">"} ?`);
|
|
1716
|
+
params.push(parts[i]);
|
|
1717
|
+
clauses.push(`(${terms.join(" AND ")})`);
|
|
1718
|
+
}
|
|
1719
|
+
let eqTerms = [];
|
|
1720
|
+
let eqParams = [];
|
|
1721
|
+
for (let i = 0; i < shared; i++) {
|
|
1722
|
+
eqTerms.push(`${cols[i]} = ?`);
|
|
1723
|
+
eqParams.push(parts[i]);
|
|
1724
|
+
}
|
|
1725
|
+
if (n === m) {
|
|
1726
|
+
if (inclusive && eqTerms.length > 0) {
|
|
1727
|
+
clauses.push(`(${eqTerms.join(" AND ")})`);
|
|
1728
|
+
params.push(...eqParams);
|
|
1729
|
+
}
|
|
1730
|
+
} else if (n > m) {
|
|
1731
|
+
if (!wantLess) if (eqTerms.length > 0) {
|
|
1732
|
+
clauses.push(`(${eqTerms.join(" AND ")})`);
|
|
1733
|
+
params.push(...eqParams);
|
|
1734
|
+
} else clauses.push("1");
|
|
1735
|
+
} else if (wantLess) if (eqTerms.length > 0) {
|
|
1736
|
+
clauses.push(`(${eqTerms.join(" AND ")})`);
|
|
1737
|
+
params.push(...eqParams);
|
|
1738
|
+
} else clauses.push("1");
|
|
1739
|
+
if (clauses.length === 0) return {
|
|
1740
|
+
sql: "0",
|
|
1741
|
+
params: []
|
|
1742
|
+
};
|
|
1743
|
+
return {
|
|
1744
|
+
sql: `(${clauses.join(" OR ")})`,
|
|
1745
|
+
params
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
function edgeSql(cols, storedIsArray, key, wantLess, inclusive) {
|
|
1749
|
+
if (storedIsArray !== Array.isArray(key)) {
|
|
1750
|
+
if (storedIsArray) return wantLess ? {
|
|
1751
|
+
sql: "0",
|
|
1752
|
+
params: []
|
|
1753
|
+
} : {
|
|
1754
|
+
sql: "1",
|
|
1755
|
+
params: []
|
|
1756
|
+
};
|
|
1757
|
+
return wantLess ? {
|
|
1758
|
+
sql: "1",
|
|
1759
|
+
params: []
|
|
1760
|
+
} : {
|
|
1761
|
+
sql: "0",
|
|
1762
|
+
params: []
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
return lexSql(cols, Array.isArray(key) ? [...key] : [key], wantLess, inclusive);
|
|
1766
|
+
}
|
|
1767
|
+
function keyHasString(key) {
|
|
1768
|
+
if (typeof key === "string") return true;
|
|
1769
|
+
return Array.isArray(key) && key.some((part) => typeof part === "string");
|
|
1770
|
+
}
|
|
1771
|
+
/** SQLite TEXT is UTF-8; IndexKey strings compare as UTF-16. Do not use SQL WHERE as truth. */
|
|
1772
|
+
function trustSqlBounds(index, bound) {
|
|
1773
|
+
if (index === "__pk") return false;
|
|
1774
|
+
if (bound.lt !== void 0 && keyHasString(bound.lt)) return false;
|
|
1775
|
+
if (bound.lte !== void 0 && keyHasString(bound.lte)) return false;
|
|
1776
|
+
if (bound.gt !== void 0 && keyHasString(bound.gt)) return false;
|
|
1777
|
+
if (bound.gte !== void 0 && keyHasString(bound.gte)) return false;
|
|
1778
|
+
return true;
|
|
1779
|
+
}
|
|
1780
|
+
function boundSql(cols, storedIsArray, bound) {
|
|
1781
|
+
let parts = [];
|
|
1782
|
+
let params = [];
|
|
1783
|
+
let add = (key, wantLess, inclusive) => {
|
|
1784
|
+
if (key === void 0) return;
|
|
1785
|
+
let frag = edgeSql(cols, storedIsArray, key, wantLess, inclusive);
|
|
1786
|
+
parts.push(frag.sql);
|
|
1787
|
+
params.push(...frag.params);
|
|
1788
|
+
};
|
|
1789
|
+
add(bound.gt, false, false);
|
|
1790
|
+
add(bound.gte, false, true);
|
|
1791
|
+
add(bound.lt, true, false);
|
|
1792
|
+
add(bound.lte, true, true);
|
|
1793
|
+
if (parts.includes("0")) return {
|
|
1794
|
+
sql: "0",
|
|
1795
|
+
params: []
|
|
1796
|
+
};
|
|
1797
|
+
let rest = parts.filter((p) => p !== "1");
|
|
1798
|
+
if (rest.length === 0) return {
|
|
1799
|
+
sql: "1",
|
|
1800
|
+
params: []
|
|
1801
|
+
};
|
|
1802
|
+
return {
|
|
1803
|
+
sql: rest.join(" AND "),
|
|
1804
|
+
params
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
function applySchema(handle, schema) {
|
|
1808
|
+
for (let col of schema.collections) {
|
|
1809
|
+
let table = quoteIdent(col.name);
|
|
1810
|
+
let extra = [];
|
|
1811
|
+
for (let id of allIndexColIds(col)) extra.push(quoteIdent(id));
|
|
1812
|
+
let extraSql = extra.length === 0 ? "" : extra.map((c) => `,\n ${c}`).join("");
|
|
1813
|
+
handle.exec(`CREATE TABLE IF NOT EXISTS ${table} (\n pk TEXT PRIMARY KEY NOT NULL,\n payload TEXT NOT NULL${extraSql}\n)`);
|
|
1814
|
+
handle.exec(`CREATE TABLE IF NOT EXISTS ${quoteIdent(`${col.name}__blobs`)} (\n pk TEXT NOT NULL,\n field TEXT NOT NULL,\n data BLOB NOT NULL,\n PRIMARY KEY (pk, field)\n)`);
|
|
1815
|
+
for (let idx of col.indexes ?? []) {
|
|
1816
|
+
let cols = indexFields(idx.keyPath).map((_, i) => quoteIdent(indexColId(idx.name, i)));
|
|
1817
|
+
let unique = idx.unique === true ? "UNIQUE " : "";
|
|
1818
|
+
handle.exec(`CREATE ${unique}INDEX IF NOT EXISTS ${quoteIdent(`${col.name}_${idx.name}`)} ON ${table} (${cols.join(", ")})`);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
async function unlinkIfExists(path) {
|
|
1823
|
+
try {
|
|
1824
|
+
await (0, import___vite_browser_external.unlink)(path);
|
|
1825
|
+
} catch (err) {
|
|
1826
|
+
if (err.code !== "ENOENT") throw err;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
/** Reentrant in the owning async context so a pre-obtained collection used inside transact joins the SQL tx. */
|
|
1830
|
+
var SerialQueue = class {
|
|
1831
|
+
_tail = Promise.resolve();
|
|
1832
|
+
_held = new import___vite_browser_external.AsyncLocalStorage();
|
|
1833
|
+
with(fn) {
|
|
1834
|
+
if (this._held.getStore()) return fn();
|
|
1835
|
+
let run = this._tail.then(() => this._held.run(true, fn));
|
|
1836
|
+
this._tail = run.then(() => void 0, () => void 0);
|
|
1837
|
+
return run;
|
|
1838
|
+
}
|
|
1839
|
+
};
|
|
1840
|
+
var WriteGuardCollection = class {
|
|
1841
|
+
name;
|
|
1842
|
+
constructor(_inner, _mode) {
|
|
1843
|
+
this._inner = _inner;
|
|
1844
|
+
this._mode = _mode;
|
|
1845
|
+
this.name = _inner.name;
|
|
1846
|
+
}
|
|
1847
|
+
_assertWritable() {
|
|
1848
|
+
if (this._mode.value === "r") throw new Error("write is not allowed in a read-only transact");
|
|
1849
|
+
}
|
|
1850
|
+
get(key) {
|
|
1851
|
+
return this._inner.get(key);
|
|
1852
|
+
}
|
|
1853
|
+
getMany(keys) {
|
|
1854
|
+
return this._inner.getMany(keys);
|
|
1855
|
+
}
|
|
1856
|
+
async put(row, opts) {
|
|
1857
|
+
this._assertWritable();
|
|
1858
|
+
await this._inner.put(row, opts);
|
|
1859
|
+
}
|
|
1860
|
+
async putMany(rows, opts) {
|
|
1861
|
+
this._assertWritable();
|
|
1862
|
+
await this._inner.putMany(rows, opts);
|
|
1863
|
+
}
|
|
1864
|
+
async delete(keys) {
|
|
1865
|
+
this._assertWritable();
|
|
1866
|
+
await this._inner.delete(keys);
|
|
1867
|
+
}
|
|
1868
|
+
async clear() {
|
|
1869
|
+
this._assertWritable();
|
|
1870
|
+
await this._inner.clear();
|
|
1871
|
+
}
|
|
1872
|
+
count() {
|
|
1873
|
+
return this._inner.count();
|
|
1874
|
+
}
|
|
1875
|
+
getAll() {
|
|
1876
|
+
return this._inner.getAll();
|
|
1877
|
+
}
|
|
1878
|
+
scan(index, bound) {
|
|
1879
|
+
return this._inner.scan(index, bound);
|
|
1880
|
+
}
|
|
1881
|
+
};
|
|
1882
|
+
var NestedTxDb = class {
|
|
1883
|
+
constructor(_inner, _unlocked, _flushUnlocked, _mode) {
|
|
1884
|
+
this._inner = _inner;
|
|
1885
|
+
this._unlocked = _unlocked;
|
|
1886
|
+
this._flushUnlocked = _flushUnlocked;
|
|
1887
|
+
this._mode = _mode;
|
|
1888
|
+
}
|
|
1889
|
+
get schema() {
|
|
1890
|
+
return this._inner.schema;
|
|
1891
|
+
}
|
|
1892
|
+
collection(name) {
|
|
1893
|
+
return new WriteGuardCollection(this._unlocked(name), this._mode);
|
|
1894
|
+
}
|
|
1895
|
+
transact(_names, _mode, _fn) {
|
|
1896
|
+
return Promise.reject(/* @__PURE__ */ new Error("nested transact is not supported"));
|
|
1897
|
+
}
|
|
1898
|
+
flush() {
|
|
1899
|
+
if (this._mode.value === "r") return Promise.resolve();
|
|
1900
|
+
this._flushUnlocked();
|
|
1901
|
+
return Promise.resolve();
|
|
1902
|
+
}
|
|
1903
|
+
close() {
|
|
1904
|
+
return this._inner.close();
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1907
|
+
var GatedCollection = class {
|
|
1908
|
+
name;
|
|
1909
|
+
constructor(_inner, _lock) {
|
|
1910
|
+
this._inner = _inner;
|
|
1911
|
+
this._lock = _lock;
|
|
1912
|
+
this.name = _inner.name;
|
|
1913
|
+
}
|
|
1914
|
+
get(key) {
|
|
1915
|
+
return this._lock.with(() => this._inner.get(key));
|
|
1916
|
+
}
|
|
1917
|
+
getMany(keys) {
|
|
1918
|
+
return this._lock.with(() => this._inner.getMany(keys));
|
|
1919
|
+
}
|
|
1920
|
+
put(row, opts) {
|
|
1921
|
+
return this._lock.with(() => this._inner.put(row, opts));
|
|
1922
|
+
}
|
|
1923
|
+
putMany(rows, opts) {
|
|
1924
|
+
return this._lock.with(() => this._inner.putMany(rows, opts));
|
|
1925
|
+
}
|
|
1926
|
+
delete(keys) {
|
|
1927
|
+
return this._lock.with(() => this._inner.delete(keys));
|
|
1928
|
+
}
|
|
1929
|
+
clear() {
|
|
1930
|
+
return this._lock.with(() => this._inner.clear());
|
|
1931
|
+
}
|
|
1932
|
+
count() {
|
|
1933
|
+
return this._lock.with(() => this._inner.count());
|
|
1934
|
+
}
|
|
1935
|
+
getAll() {
|
|
1936
|
+
return this._lock.with(() => this._inner.getAll());
|
|
1937
|
+
}
|
|
1938
|
+
scan(index, bound) {
|
|
1939
|
+
return this._lock.with(() => this._inner.scan(index, bound));
|
|
1940
|
+
}
|
|
1941
|
+
};
|
|
1942
|
+
var SqliteCollection = class {
|
|
1943
|
+
name;
|
|
1944
|
+
_def;
|
|
1945
|
+
_keyPath;
|
|
1946
|
+
_indexes;
|
|
1947
|
+
_handle;
|
|
1948
|
+
_pending;
|
|
1949
|
+
_inSqlTx;
|
|
1950
|
+
_table;
|
|
1951
|
+
_blobTable;
|
|
1952
|
+
_indexColIds;
|
|
1953
|
+
constructor(def, handle, pending, inSqlTx) {
|
|
1954
|
+
this.name = def.name;
|
|
1955
|
+
this._def = def;
|
|
1956
|
+
this._keyPath = def.keyPath;
|
|
1957
|
+
this._indexes = /* @__PURE__ */ new Map();
|
|
1958
|
+
for (let index of def.indexes ?? []) this._indexes.set(index.name, index);
|
|
1959
|
+
this._handle = handle;
|
|
1960
|
+
this._pending = pending;
|
|
1961
|
+
this._inSqlTx = inSqlTx;
|
|
1962
|
+
this._table = quoteIdent(def.name);
|
|
1963
|
+
this._blobTable = quoteIdent(`${def.name}__blobs`);
|
|
1964
|
+
this._indexColIds = allIndexColIds(def);
|
|
1965
|
+
}
|
|
1966
|
+
_colPending() {
|
|
1967
|
+
return this._pending.get(this.name);
|
|
1968
|
+
}
|
|
1969
|
+
_ensurePending() {
|
|
1970
|
+
let map = this._pending.get(this.name);
|
|
1971
|
+
if (!map) {
|
|
1972
|
+
map = /* @__PURE__ */ new Map();
|
|
1973
|
+
this._pending.set(this.name, map);
|
|
1974
|
+
}
|
|
1975
|
+
return map;
|
|
1976
|
+
}
|
|
1977
|
+
_writeTx(fn) {
|
|
1978
|
+
if (this._inSqlTx.value) {
|
|
1979
|
+
fn();
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
this._handle.transaction(fn);
|
|
1983
|
+
}
|
|
1984
|
+
async _prepareWrite(row) {
|
|
1985
|
+
let pk = primaryKeyOf(row, this._keyPath);
|
|
1986
|
+
let stored = withStringPk(row, this._keyPath, pk);
|
|
1987
|
+
let split = await splitRow(stored);
|
|
1988
|
+
return {
|
|
1989
|
+
row: stored,
|
|
1990
|
+
pk,
|
|
1991
|
+
payloadJson: JSON.stringify(split.payload),
|
|
1992
|
+
blobs: split.blobs,
|
|
1993
|
+
indexBinds: indexBinds(stored, this._def)
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
insertWrite(write) {
|
|
1997
|
+
let cols = [
|
|
1998
|
+
"pk",
|
|
1999
|
+
"payload",
|
|
2000
|
+
...this._indexColIds.map(quoteIdent)
|
|
2001
|
+
];
|
|
2002
|
+
let ph = cols.map(() => "?").join(", ");
|
|
2003
|
+
this._handle.prepare(`INSERT OR REPLACE INTO ${this._table} (${cols.join(", ")}) VALUES (${ph})`).run([
|
|
2004
|
+
write.pk,
|
|
2005
|
+
write.payloadJson,
|
|
2006
|
+
...write.indexBinds
|
|
2007
|
+
]);
|
|
2008
|
+
this._handle.prepare(`DELETE FROM ${this._blobTable} WHERE pk = ?`).run([write.pk]);
|
|
2009
|
+
if (write.blobs.size === 0) return;
|
|
2010
|
+
let ins = this._handle.prepare(`INSERT INTO ${this._blobTable} (pk, field, data) VALUES (?, ?, ?)`);
|
|
2011
|
+
for (let [field, data] of write.blobs) ins.run([
|
|
2012
|
+
write.pk,
|
|
2013
|
+
field,
|
|
2014
|
+
data
|
|
2015
|
+
]);
|
|
2016
|
+
}
|
|
2017
|
+
_attachBlobs(byPk, pks) {
|
|
2018
|
+
if (pks.length === 0) return;
|
|
2019
|
+
let ph = pks.map(() => "?").join(", ");
|
|
2020
|
+
let blobRows = this._handle.prepare(`SELECT pk, field, data FROM ${this._blobTable} WHERE pk IN (${ph})`).all(pks);
|
|
2021
|
+
for (let blobRow of blobRows) {
|
|
2022
|
+
let pk = String(blobRow.pk);
|
|
2023
|
+
let row = byPk.get(pk);
|
|
2024
|
+
if (!row) continue;
|
|
2025
|
+
row[String(blobRow.field)] = rehydrate(blobRow.data);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
async get(key) {
|
|
2029
|
+
let pending = this._colPending()?.get(key);
|
|
2030
|
+
if (pending !== void 0) return pending.row;
|
|
2031
|
+
let found = this._handle.prepare(`SELECT payload FROM ${this._table} WHERE pk = ?`).get([key]);
|
|
2032
|
+
if (!found) return null;
|
|
2033
|
+
let row = JSON.parse(found.payload);
|
|
2034
|
+
this._attachBlobs(new Map([[key, row]]), [key]);
|
|
2035
|
+
return row;
|
|
2036
|
+
}
|
|
2037
|
+
async getMany(keys) {
|
|
2038
|
+
if (keys.length === 0) return [];
|
|
2039
|
+
let pending = this._colPending();
|
|
2040
|
+
let need = [];
|
|
2041
|
+
let seen = /* @__PURE__ */ new Set();
|
|
2042
|
+
for (let key of keys) {
|
|
2043
|
+
if (pending?.has(key) || seen.has(key)) continue;
|
|
2044
|
+
seen.add(key);
|
|
2045
|
+
need.push(key);
|
|
2046
|
+
}
|
|
2047
|
+
let loaded = /* @__PURE__ */ new Map();
|
|
2048
|
+
if (need.length > 0) {
|
|
2049
|
+
let ph = need.map(() => "?").join(", ");
|
|
2050
|
+
let rows = this._handle.prepare(`SELECT pk, payload FROM ${this._table} WHERE pk IN (${ph})`).all(need);
|
|
2051
|
+
let byPk = /* @__PURE__ */ new Map();
|
|
2052
|
+
for (let r of rows) byPk.set(String(r.pk), JSON.parse(String(r.payload)));
|
|
2053
|
+
this._attachBlobs(byPk, need);
|
|
2054
|
+
for (let [pk, row] of byPk) loaded.set(pk, row);
|
|
2055
|
+
}
|
|
2056
|
+
return keys.map((key) => {
|
|
2057
|
+
let hit = pending?.get(key);
|
|
2058
|
+
if (hit) return hit.row;
|
|
2059
|
+
return loaded.get(key) ?? null;
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
async put(row, opts) {
|
|
2063
|
+
let write = await this._prepareWrite(row);
|
|
2064
|
+
if ((opts?.flush ?? "now") === "batch") {
|
|
2065
|
+
this._ensurePending().set(write.pk, write);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
this._colPending()?.delete(write.pk);
|
|
2069
|
+
this._writeTx(() => this.insertWrite(write));
|
|
2070
|
+
}
|
|
2071
|
+
async putMany(rows, opts) {
|
|
2072
|
+
if (rows.length === 0) return;
|
|
2073
|
+
let writes = [];
|
|
2074
|
+
for (let row of rows) writes.push(await this._prepareWrite(row));
|
|
2075
|
+
if ((opts?.flush ?? "now") === "batch") {
|
|
2076
|
+
let pending = this._ensurePending();
|
|
2077
|
+
for (let write of writes) pending.set(write.pk, write);
|
|
2078
|
+
return;
|
|
2079
|
+
}
|
|
2080
|
+
let live = this._colPending();
|
|
2081
|
+
this._writeTx(() => {
|
|
2082
|
+
for (let write of writes) {
|
|
2083
|
+
live?.delete(write.pk);
|
|
2084
|
+
this.insertWrite(write);
|
|
2085
|
+
}
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
async delete(keys) {
|
|
2089
|
+
let pending = this._colPending();
|
|
2090
|
+
if (pending) for (let key of keys) pending.delete(key);
|
|
2091
|
+
if (keys.length === 0) return;
|
|
2092
|
+
let ph = keys.map(() => "?").join(", ");
|
|
2093
|
+
this._writeTx(() => {
|
|
2094
|
+
this._handle.prepare(`DELETE FROM ${this._table} WHERE pk IN (${ph})`).run(keys);
|
|
2095
|
+
this._handle.prepare(`DELETE FROM ${this._blobTable} WHERE pk IN (${ph})`).run(keys);
|
|
2096
|
+
});
|
|
2097
|
+
}
|
|
2098
|
+
async clear() {
|
|
2099
|
+
this._pending.delete(this.name);
|
|
2100
|
+
this._writeTx(() => {
|
|
2101
|
+
this._handle.exec(`DELETE FROM ${this._table}`);
|
|
2102
|
+
this._handle.exec(`DELETE FROM ${this._blobTable}`);
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
async count() {
|
|
2106
|
+
let pending = this._colPending();
|
|
2107
|
+
if (!pending || pending.size === 0) return this._handle.prepare(`SELECT COUNT(*) AS c FROM ${this._table}`).get().c;
|
|
2108
|
+
let rows = this._handle.prepare(`SELECT pk FROM ${this._table}`).all();
|
|
2109
|
+
let keys = new Set(rows.map((r) => String(r.pk)));
|
|
2110
|
+
for (let pk of pending.keys()) keys.add(pk);
|
|
2111
|
+
return keys.size;
|
|
2112
|
+
}
|
|
2113
|
+
async getAll() {
|
|
2114
|
+
let rows = this._handle.prepare(`SELECT pk, payload FROM ${this._table}`).all();
|
|
2115
|
+
let byPk = /* @__PURE__ */ new Map();
|
|
2116
|
+
for (let r of rows) byPk.set(String(r.pk), JSON.parse(r.payload));
|
|
2117
|
+
this._attachBlobs(byPk, [...byPk.keys()]);
|
|
2118
|
+
let pending = this._colPending();
|
|
2119
|
+
if (pending) for (let [pk, write] of pending) byPk.set(pk, write.row);
|
|
2120
|
+
let entries = [...byPk.entries()];
|
|
2121
|
+
entries.sort((a, b) => compareIndexKey(a[0], b[0]));
|
|
2122
|
+
return entries.map(([, row]) => row);
|
|
2123
|
+
}
|
|
2124
|
+
async scan(index, bound = {}) {
|
|
2125
|
+
if (index !== "__pk" && !this._indexes.has(index)) throw new Error(`unknown index: ${index}`);
|
|
2126
|
+
let keysOnly = bound.keysOnly === true;
|
|
2127
|
+
let storedIsArray = false;
|
|
2128
|
+
let rawCols = [];
|
|
2129
|
+
let cols = [];
|
|
2130
|
+
if (index === "__pk") {
|
|
2131
|
+
rawCols = ["pk"];
|
|
2132
|
+
cols = [quoteIdent("pk")];
|
|
2133
|
+
} else {
|
|
2134
|
+
let idx = this._indexes.get(index);
|
|
2135
|
+
storedIsArray = Array.isArray(idx.keyPath);
|
|
2136
|
+
rawCols = indexFields(idx.keyPath).map((_, i) => indexColId(index, i));
|
|
2137
|
+
cols = rawCols.map(quoteIdent);
|
|
2138
|
+
}
|
|
2139
|
+
let pending = this._colPending();
|
|
2140
|
+
let hits = [];
|
|
2141
|
+
let frag = trustSqlBounds(index, bound) ? boundSql(cols, storedIsArray, bound) : {
|
|
2142
|
+
sql: "1",
|
|
2143
|
+
params: []
|
|
2144
|
+
};
|
|
2145
|
+
if (frag.sql !== "0") {
|
|
2146
|
+
let selectList = index === "__pk" ? keysOnly ? ["pk"] : ["pk", "payload"] : keysOnly ? ["pk", ...cols] : [
|
|
2147
|
+
"pk",
|
|
2148
|
+
"payload",
|
|
2149
|
+
...cols
|
|
2150
|
+
];
|
|
2151
|
+
let whereParts = [];
|
|
2152
|
+
if (index !== "__pk") for (let col of cols) whereParts.push(`${col} IS NOT NULL`);
|
|
2153
|
+
let params = [...frag.params];
|
|
2154
|
+
if (frag.sql !== "1") whereParts.push(frag.sql);
|
|
2155
|
+
let where = whereParts.length > 0 ? `WHERE ${whereParts.join(" AND ")}` : "";
|
|
2156
|
+
let order = `ORDER BY ${cols.join(", ")}${index === "__pk" ? "" : ", pk"}`;
|
|
2157
|
+
let sql = `SELECT ${selectList.join(", ")} FROM ${this._table} ${where} ${order}`;
|
|
2158
|
+
let rows = this._handle.prepare(sql).all(params);
|
|
2159
|
+
let valueByPk = /* @__PURE__ */ new Map();
|
|
2160
|
+
for (let r of rows) {
|
|
2161
|
+
let pk = String(r.pk);
|
|
2162
|
+
let indexKey;
|
|
2163
|
+
if (index === "__pk") indexKey = pk;
|
|
2164
|
+
else if (storedIsArray) indexKey = rawCols.map((c) => r[c]);
|
|
2165
|
+
else indexKey = r[rawCols[0]];
|
|
2166
|
+
if (!inRange(indexKey, bound)) continue;
|
|
2167
|
+
if (keysOnly) hits.push({
|
|
2168
|
+
primaryKey: pk,
|
|
2169
|
+
indexKey
|
|
2170
|
+
});
|
|
2171
|
+
else {
|
|
2172
|
+
let value = JSON.parse(String(r.payload));
|
|
2173
|
+
valueByPk.set(pk, value);
|
|
2174
|
+
hits.push({
|
|
2175
|
+
primaryKey: pk,
|
|
2176
|
+
indexKey,
|
|
2177
|
+
value
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
if (!keysOnly && valueByPk.size > 0) this._attachBlobs(valueByPk, [...valueByPk.keys()]);
|
|
2182
|
+
}
|
|
2183
|
+
if (pending && pending.size > 0) hits = this._mergePending(index, bound, hits, pending);
|
|
2184
|
+
hits.sort((a, b) => {
|
|
2185
|
+
let c = compareIndexKey(a.indexKey, b.indexKey);
|
|
2186
|
+
if (c !== 0) return c;
|
|
2187
|
+
return compareIndexKey(a.primaryKey, b.primaryKey);
|
|
2188
|
+
});
|
|
2189
|
+
if (bound.limit !== void 0) hits = hits.slice(0, Math.max(0, bound.limit));
|
|
2190
|
+
return hits;
|
|
2191
|
+
}
|
|
2192
|
+
_mergePending(index, bound, hits, pending) {
|
|
2193
|
+
let replaced = new Set(pending.keys());
|
|
2194
|
+
let out = hits.filter((h) => !replaced.has(h.primaryKey));
|
|
2195
|
+
let keyPath = indexKeyPath(this._def, index);
|
|
2196
|
+
for (let [pk, write] of pending) {
|
|
2197
|
+
let indexKey = index === "__pk" ? pk : projectIndexKey(write.row, keyPath);
|
|
2198
|
+
if (indexKey === void 0) continue;
|
|
2199
|
+
if (!inRange(indexKey, bound)) continue;
|
|
2200
|
+
if (bound.keysOnly) out.push({
|
|
2201
|
+
primaryKey: pk,
|
|
2202
|
+
indexKey
|
|
2203
|
+
});
|
|
2204
|
+
else out.push({
|
|
2205
|
+
primaryKey: pk,
|
|
2206
|
+
indexKey,
|
|
2207
|
+
value: write.row
|
|
2208
|
+
});
|
|
2209
|
+
}
|
|
2210
|
+
out.sort((a, b) => {
|
|
2211
|
+
let c = compareIndexKey(a.indexKey, b.indexKey);
|
|
2212
|
+
if (c !== 0) return c;
|
|
2213
|
+
return compareIndexKey(a.primaryKey, b.primaryKey);
|
|
2214
|
+
});
|
|
2215
|
+
return out;
|
|
2216
|
+
}
|
|
2217
|
+
};
|
|
2218
|
+
var SqliteDb = class {
|
|
2219
|
+
schema;
|
|
2220
|
+
_handle;
|
|
2221
|
+
_collections;
|
|
2222
|
+
_gated;
|
|
2223
|
+
_pending = /* @__PURE__ */ new Map();
|
|
2224
|
+
_lock = new SerialQueue();
|
|
2225
|
+
_inTransact = new import___vite_browser_external.AsyncLocalStorage();
|
|
2226
|
+
_inSqlTx = { value: false };
|
|
2227
|
+
_txMode = { value: null };
|
|
2228
|
+
_txView;
|
|
2229
|
+
_onClose;
|
|
2230
|
+
_closed = false;
|
|
2231
|
+
constructor(schema, handle, onClose) {
|
|
2232
|
+
this.schema = schema;
|
|
2233
|
+
this._handle = handle;
|
|
2234
|
+
this._onClose = onClose;
|
|
2235
|
+
this._collections = /* @__PURE__ */ new Map();
|
|
2236
|
+
this._gated = /* @__PURE__ */ new Map();
|
|
2237
|
+
this._txView = new NestedTxDb(this, (name) => {
|
|
2238
|
+
let col = this._collections.get(name);
|
|
2239
|
+
if (!col) throw new Error(`unknown collection: ${name}`);
|
|
2240
|
+
return col;
|
|
2241
|
+
}, () => this._flushPending(), this._txMode);
|
|
2242
|
+
for (let def of schema.collections) {
|
|
2243
|
+
let col = new SqliteCollection(def, handle, this._pending, this._inSqlTx);
|
|
2244
|
+
this._collections.set(def.name, col);
|
|
2245
|
+
this._gated.set(def.name, new GatedCollection(col, this._lock));
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
collection(name) {
|
|
2249
|
+
let col = this._gated.get(name);
|
|
2250
|
+
if (!col) throw new Error(`unknown collection: ${name}`);
|
|
2251
|
+
return col;
|
|
2252
|
+
}
|
|
2253
|
+
transact(names, mode, fn) {
|
|
2254
|
+
for (let name of names) if (!this._collections.has(name)) throw new Error(`unknown collection: ${name}`);
|
|
2255
|
+
if (this._inTransact.getStore()) return Promise.reject(/* @__PURE__ */ new Error("nested transact is not supported"));
|
|
2256
|
+
return this._lock.with(() => this._inTransact.run(true, async () => {
|
|
2257
|
+
this._handle.exec("BEGIN IMMEDIATE");
|
|
2258
|
+
this._inSqlTx.value = true;
|
|
2259
|
+
this._txMode.value = mode;
|
|
2260
|
+
try {
|
|
2261
|
+
let result = await fn(this._txView);
|
|
2262
|
+
if (mode !== "r") this._flushPending();
|
|
2263
|
+
this._handle.exec("COMMIT");
|
|
2264
|
+
return result;
|
|
2265
|
+
} catch (err) {
|
|
2266
|
+
try {
|
|
2267
|
+
this._handle.exec("ROLLBACK");
|
|
2268
|
+
} catch {}
|
|
2269
|
+
throw err;
|
|
2270
|
+
} finally {
|
|
2271
|
+
this._inSqlTx.value = false;
|
|
2272
|
+
this._txMode.value = null;
|
|
2273
|
+
}
|
|
2274
|
+
}));
|
|
2275
|
+
}
|
|
2276
|
+
flush() {
|
|
2277
|
+
return this._lock.with(async () => {
|
|
2278
|
+
this._flushPending();
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
async close() {
|
|
2282
|
+
if (this._closed) return;
|
|
2283
|
+
this._closed = true;
|
|
2284
|
+
try {
|
|
2285
|
+
this._flushPending();
|
|
2286
|
+
} finally {
|
|
2287
|
+
this._handle.close();
|
|
2288
|
+
this._onClose();
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
_flushPending() {
|
|
2292
|
+
let snapshot = [];
|
|
2293
|
+
for (let [name, rows] of this._pending) {
|
|
2294
|
+
if (rows.size === 0) continue;
|
|
2295
|
+
snapshot.push([name, [...rows.values()]]);
|
|
2296
|
+
}
|
|
2297
|
+
if (snapshot.length === 0) return;
|
|
2298
|
+
let run = () => {
|
|
2299
|
+
for (let [name, writes] of snapshot) {
|
|
2300
|
+
let col = this._collections.get(name);
|
|
2301
|
+
if (!col) continue;
|
|
2302
|
+
for (let write of writes) col.insertWrite(write);
|
|
2303
|
+
}
|
|
2304
|
+
};
|
|
2305
|
+
if (this._inSqlTx.value) run();
|
|
2306
|
+
else this._handle.transaction(run);
|
|
2307
|
+
for (let [name, writes] of snapshot) {
|
|
2308
|
+
let live = this._pending.get(name);
|
|
2309
|
+
if (!live) continue;
|
|
2310
|
+
for (let write of writes) if (live.get(write.pk) === write) live.delete(write.pk);
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
var SqliteDriver = class {
|
|
2315
|
+
log;
|
|
2316
|
+
_filename;
|
|
2317
|
+
_native;
|
|
2318
|
+
_conns = /* @__PURE__ */ new Set();
|
|
2319
|
+
constructor(opts) {
|
|
2320
|
+
this.log = makeLog(opts.log ?? makeSilentLog(), ISSUE_KEY);
|
|
2321
|
+
this._filename = opts.filename;
|
|
2322
|
+
this._native = opts.native ?? import_lib.default;
|
|
2323
|
+
}
|
|
2324
|
+
async open(schema) {
|
|
2325
|
+
let raw;
|
|
2326
|
+
try {
|
|
2327
|
+
validateSchema(schema);
|
|
2328
|
+
let Native = this._native;
|
|
2329
|
+
raw = new Native(this._filename);
|
|
2330
|
+
try {
|
|
2331
|
+
raw.pragma("journal_mode = WAL");
|
|
2332
|
+
} catch {}
|
|
2333
|
+
let handle = wrapBetterSqlite3(raw);
|
|
2334
|
+
applySchema(handle, schema);
|
|
2335
|
+
let db = new SqliteDb(schema, handle, () => {
|
|
2336
|
+
this._conns.delete(db);
|
|
2337
|
+
});
|
|
2338
|
+
this._conns.add(db);
|
|
2339
|
+
return db;
|
|
2340
|
+
} catch (err) {
|
|
2341
|
+
try {
|
|
2342
|
+
raw?.close();
|
|
2343
|
+
} catch {}
|
|
2344
|
+
reportError(this.log, err);
|
|
2345
|
+
throw err;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
async drop(_schema) {
|
|
2349
|
+
try {
|
|
2350
|
+
for (let db of [...this._conns]) await db.close();
|
|
2351
|
+
if (this._filename === ":memory:") return;
|
|
2352
|
+
await unlinkIfExists(this._filename);
|
|
2353
|
+
await unlinkIfExists(`${this._filename}-wal`);
|
|
2354
|
+
await unlinkIfExists(`${this._filename}-shm`);
|
|
2355
|
+
} catch (err) {
|
|
2356
|
+
reportError(this.log, err);
|
|
2357
|
+
throw err;
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
};
|
|
2361
|
+
function createSqliteDriver(opts) {
|
|
2362
|
+
return new SqliteDriver(opts);
|
|
2363
|
+
}
|
|
2364
|
+
//#endregion
|
|
2365
|
+
export { createSqliteDriver, wrapBetterSqlite3 };
|