@evolu/sqlite-wasm 2.2.4 → 3.53.4-build1
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 +55 -218
- package/dist/src/CApi.d.ts +2108 -0
- package/dist/src/CApi.d.ts.map +1 -0
- package/dist/src/CApi.js +1919 -0
- package/dist/src/Constants.d.ts +868 -0
- package/dist/src/Constants.d.ts.map +1 -0
- package/dist/src/Constants.js +602 -0
- package/dist/src/Database.d.ts +641 -0
- package/dist/src/Database.d.ts.map +1 -0
- package/dist/src/Database.js +1177 -0
- package/dist/src/Memory.d.ts +119 -0
- package/dist/src/Memory.d.ts.map +1 -0
- package/dist/src/Memory.js +207 -0
- package/dist/src/Pointer.d.ts +100 -0
- package/dist/src/Pointer.d.ts.map +1 -0
- package/dist/src/Pointer.js +15 -0
- package/dist/src/SahPool.d.ts +744 -0
- package/dist/src/SahPool.d.ts.map +1 -0
- package/dist/src/SahPool.js +1985 -0
- package/dist/src/Wasm.d.ts +315 -0
- package/dist/src/Wasm.d.ts.map +1 -0
- package/dist/src/Wasm.js +756 -0
- package/dist/src/WasmUrl.d.ts +21 -0
- package/dist/src/WasmUrl.d.ts.map +1 -0
- package/dist/src/WasmUrl.js +20 -0
- package/dist/src/c-api/index.d.ts +9 -0
- package/dist/src/c-api/index.d.ts.map +1 -0
- package/dist/src/c-api/index.js +8 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +13 -0
- package/dist/wasm/sqlite3.wasm +0 -0
- package/package.json +60 -60
- package/src/CApi.test.ts +217 -0
- package/src/CApi.ts +3294 -0
- package/src/Constants.ts +803 -0
- package/src/Database.ts +1714 -0
- package/src/Memory.test.ts +319 -0
- package/src/Memory.ts +237 -0
- package/src/Pointer.ts +121 -0
- package/src/SahPool.test.ts +180 -0
- package/src/SahPool.ts +2627 -0
- package/src/Wasm.test.ts +444 -0
- package/src/Wasm.ts +1026 -0
- package/src/WasmUrl.ts +26 -0
- package/src/c-api/index.ts +9 -0
- package/src/index.ts +15 -0
- package/bin/index.js +0 -110
- package/index.d.ts +0 -8118
- package/index.mjs +0 -7
- package/node.mjs +0 -3
- package/sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs +0 -13659
- package/sqlite-wasm/jswasm/sqlite3-node.mjs +0 -11671
- package/sqlite-wasm/jswasm/sqlite3-opfs-async-proxy.js +0 -691
- package/sqlite-wasm/jswasm/sqlite3-worker1-bundler-friendly.mjs +0 -35
- package/sqlite-wasm/jswasm/sqlite3-worker1-promiser.js +0 -193
- package/sqlite-wasm/jswasm/sqlite3-worker1-promiser.mjs +0 -187
- package/sqlite-wasm/jswasm/sqlite3-worker1.js +0 -46
- package/sqlite-wasm/jswasm/sqlite3.js +0 -13697
- package/sqlite-wasm/jswasm/sqlite3.mjs +0 -13661
- package/sqlite-wasm/jswasm/sqlite3.wasm +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone helpers for wasm memory: allocation, UTF-8, bytes, scratch memory,
|
|
3
|
+
* and integer ranges.
|
|
4
|
+
*
|
|
5
|
+
* Like the CApi functions, each helper that touches the instance takes
|
|
6
|
+
* {@link SqliteWasmDep} and returns the operation, so a database binds it once.
|
|
7
|
+
*
|
|
8
|
+
* Rules the helpers follow and their callers must too:
|
|
9
|
+
*
|
|
10
|
+
* - Allocate at least one byte. `sqlite3_malloc(0)` returns NULL, and binding a
|
|
11
|
+
* NULL address binds SQL NULL, so an empty string or blob would silently
|
|
12
|
+
* become NULL.
|
|
13
|
+
* - Take the heap view after allocating. Growing memory detaches the previous
|
|
14
|
+
* `ArrayBuffer`, and writing to a detached view does nothing.
|
|
15
|
+
* - Decode by byte length with a decoder that keeps a leading byte order mark, so
|
|
16
|
+
* text round-trips exactly, including embedded NUL characters. The default
|
|
17
|
+
* `TextDecoder` strips it.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import { type Result, type Typed } from "@evolu/common";
|
|
22
|
+
import type { CStringPtr, SqliteOwnedCStringPtr, SqliteOwnedPtr, WasmPtr } from "./Pointer.ts";
|
|
23
|
+
import type { SqliteWasmDep } from "./Wasm.ts";
|
|
24
|
+
/** `sqlite3_malloc` returned NULL. */
|
|
25
|
+
export interface SqliteNoMemError extends Typed<"SqliteNoMem"> {
|
|
26
|
+
readonly byteLength: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Allocates at least one byte with `sqlite3_malloc`, so a zero-length value
|
|
30
|
+
* keeps a non-NULL address.
|
|
31
|
+
*
|
|
32
|
+
* A request above {@link maxInt32} fails without calling `sqlite3_malloc`, which
|
|
33
|
+
* takes a C int and would wrap it.
|
|
34
|
+
*/
|
|
35
|
+
export declare const allocWasm: (deps: SqliteWasmDep) => (byteLength: number) => Result<SqliteOwnedPtr, SqliteNoMemError>;
|
|
36
|
+
/**
|
|
37
|
+
* Copies a string into new memory as a NUL-terminated UTF-8 C string, which the
|
|
38
|
+
* caller frees with `sqlite3_free`.
|
|
39
|
+
*
|
|
40
|
+
* UTF-8 cannot encode a lone surrogate, which becomes U+FFFD, as with
|
|
41
|
+
* `TextEncoder`, so a caller that needs the exact text checks
|
|
42
|
+
* `String.prototype.isWellFormed` first.
|
|
43
|
+
*/
|
|
44
|
+
export declare const allocCString: (deps: SqliteWasmDep) => (value: string) => Result<SqliteOwnedCStringPtr, SqliteNoMemError>;
|
|
45
|
+
/**
|
|
46
|
+
* Encodes a string as UTF-8 into existing memory and returns the byte length,
|
|
47
|
+
* without a NUL terminator.
|
|
48
|
+
*
|
|
49
|
+
* The memory needs up to three bytes per UTF-16 code unit; text that does not
|
|
50
|
+
* fit is cut at a character boundary, so reserve `value.length * 3` bytes. A
|
|
51
|
+
* lone surrogate becomes U+FFFD, as in {@link allocCString}.
|
|
52
|
+
*/
|
|
53
|
+
export declare const writeUtf8: (deps: SqliteWasmDep) => (value: string, ptr: WasmPtr, capacity: number) => number;
|
|
54
|
+
/** Decodes a NUL-terminated C string, such as an error message or a column name. */
|
|
55
|
+
export declare const readCString: (deps: SqliteWasmDep) => (ptr: CStringPtr) => string;
|
|
56
|
+
/**
|
|
57
|
+
* Decodes UTF-8 of a known byte length, such as a text column, keeping a
|
|
58
|
+
* leading byte order mark and embedded NUL characters.
|
|
59
|
+
*/
|
|
60
|
+
export declare const readUtf8: (deps: SqliteWasmDep) => (ptr: WasmPtr, byteLength: number) => string;
|
|
61
|
+
/**
|
|
62
|
+
* Copies bytes out of wasm memory into a new `ArrayBuffer`, so the result can
|
|
63
|
+
* be transferred to another worker.
|
|
64
|
+
*/
|
|
65
|
+
export declare const copyWasmBytes: (deps: SqliteWasmDep) => (ptr: WasmPtr, byteLength: number) => Uint8Array<ArrayBuffer>;
|
|
66
|
+
/** Copies bytes into wasm memory. */
|
|
67
|
+
export declare const writeWasmBytes: (deps: SqliteWasmDep) => (ptr: WasmPtr, bytes: Uint8Array) => void;
|
|
68
|
+
/**
|
|
69
|
+
* Reusable memory for output parameters and bind values, allocated once per
|
|
70
|
+
* database instead of once per call.
|
|
71
|
+
*
|
|
72
|
+
* A callback inside a call, such as a collation-needed callback or a trace
|
|
73
|
+
* callback, can run another call on the same database, which reuses this
|
|
74
|
+
* memory. The outer call is unaffected, because SQLite copies a value bound
|
|
75
|
+
* with SQLITE_TRANSIENT at once and writes an output parameter after the
|
|
76
|
+
* callbacks of the call. What SQLite reads or writes before a callback and the
|
|
77
|
+
* caller uses after it needs memory of its own: SQL, which SQLite parses in
|
|
78
|
+
* place and copies only after the parse, and the size `sqlite3_serialize`
|
|
79
|
+
* writes before it finalizes its query.
|
|
80
|
+
*/
|
|
81
|
+
export interface SqliteScratch extends Disposable {
|
|
82
|
+
/**
|
|
83
|
+
* Sixteen bytes, 8-byte aligned, for output parameters such as `ppDb`,
|
|
84
|
+
* `ppStmt` and `pzTail`.
|
|
85
|
+
*/
|
|
86
|
+
readonly out: WasmPtr;
|
|
87
|
+
/**
|
|
88
|
+
* Returns memory of at least the given length, growing it when needed. The
|
|
89
|
+
* previous contents are not kept, and the address is valid until the next
|
|
90
|
+
* call. Growth doubles the capacity, so reallocations stay rare as values
|
|
91
|
+
* grow, or, when that much memory is not available, allocates the length
|
|
92
|
+
* alone. A failure leaves the scratch empty, so later calls are unaffected.
|
|
93
|
+
*
|
|
94
|
+
* Binding text or a blob from here with SQLITE_TRANSIENT is faster than
|
|
95
|
+
* allocating per value: SQLite copies into a buffer it reuses.
|
|
96
|
+
*/
|
|
97
|
+
readonly reserve: (byteLength: number) => Result<WasmPtr, SqliteNoMemError>;
|
|
98
|
+
}
|
|
99
|
+
/** Creates a {@link SqliteScratch}. */
|
|
100
|
+
export declare const createSqliteScratch: (deps: SqliteWasmDep) => Result<SqliteScratch, SqliteNoMemError>;
|
|
101
|
+
/** The largest C int. */
|
|
102
|
+
export declare const maxInt32 = 2147483647;
|
|
103
|
+
/**
|
|
104
|
+
* Whether a number is a 32-bit integer, which binds with `sqlite3_bind_int`
|
|
105
|
+
* without a BigInt.
|
|
106
|
+
*/
|
|
107
|
+
export declare const isInt32: (value: number) => boolean;
|
|
108
|
+
/** The largest SQLite INTEGER, 2^63 - 1. */
|
|
109
|
+
export declare const maxSqliteInt64: bigint;
|
|
110
|
+
/** The smallest SQLite INTEGER, -2^63. */
|
|
111
|
+
export declare const minSqliteInt64: bigint;
|
|
112
|
+
/**
|
|
113
|
+
* Whether a bigint fits a SQLite INTEGER.
|
|
114
|
+
*
|
|
115
|
+
* The wasm boundary converts a bigint to i64 modulo 2^64 without an error, so
|
|
116
|
+
* anything passed to `sqlite3_bind_int64` must be checked first.
|
|
117
|
+
*/
|
|
118
|
+
export declare const isSqliteInt64: (value: bigint) => boolean;
|
|
119
|
+
//# sourceMappingURL=Memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Memory.d.ts","sourceRoot":"","sources":["../../src/Memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAuB,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,KAAK,EACV,UAAU,EACV,qBAAqB,EACrB,cAAc,EACd,OAAO,EACR,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAO/C,sCAAsC;AACtC,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,aAAa,CAAC;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,SACb,aAAa,kBACP,MAAM,KAAG,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAM5D,CAAC;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,SAChB,aAAa,aACZ,MAAM,KAAG,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,CAS9D,CAAC;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,SACb,aAAa,aACZ,MAAM,OAAO,OAAO,YAAY,MAAM,KAAG,MAItC,CAAC;AAEd,oFAAoF;AACpF,eAAO,MAAM,WAAW,SACf,aAAa,WACd,UAAU,KAAG,MAGlB,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,QAAQ,SACZ,aAAa,WACd,OAAO,cAAc,MAAM,KAAG,MAGjC,CAAC;AAEN;;;GAGG;AACH,eAAO,MAAM,aAAa,SACjB,aAAa,WACd,OAAO,cAAc,MAAM,KAAG,UAAU,CAAC,WAAW,CACA,CAAC;AAE7D,qCAAqC;AACrC,eAAO,MAAM,cAAc,SAClB,aAAa,WACd,OAAO,SAAS,UAAU,KAAG,IAElC,CAAC;AAEJ;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;CAC7E;AAED,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,SACxB,aAAa,KAClB,MAAM,CAAC,aAAa,EAAE,gBAAgB,CA8CxC,CAAC;AAEF,yBAAyB;AACzB,eAAO,MAAM,QAAQ,aAAc,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,OAAO,UAAW,MAAM,KAAG,OACgC,CAAC;AAEzE,4CAA4C;AAC5C,eAAO,MAAM,cAAc,QAAiB,CAAC;AAE7C,0CAA0C;AAC1C,eAAO,MAAM,cAAc,QAAe,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,UAAW,MAAM,KAAG,OACV,CAAC"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone helpers for wasm memory: allocation, UTF-8, bytes, scratch memory,
|
|
3
|
+
* and integer ranges.
|
|
4
|
+
*
|
|
5
|
+
* Like the CApi functions, each helper that touches the instance takes
|
|
6
|
+
* {@link SqliteWasmDep} and returns the operation, so a database binds it once.
|
|
7
|
+
*
|
|
8
|
+
* Rules the helpers follow and their callers must too:
|
|
9
|
+
*
|
|
10
|
+
* - Allocate at least one byte. `sqlite3_malloc(0)` returns NULL, and binding a
|
|
11
|
+
* NULL address binds SQL NULL, so an empty string or blob would silently
|
|
12
|
+
* become NULL.
|
|
13
|
+
* - Take the heap view after allocating. Growing memory detaches the previous
|
|
14
|
+
* `ArrayBuffer`, and writing to a detached view does nothing.
|
|
15
|
+
* - Decode by byte length with a decoder that keeps a leading byte order mark, so
|
|
16
|
+
* text round-trips exactly, including embedded NUL characters. The default
|
|
17
|
+
* `TextDecoder` strips it.
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
22
|
+
if (value !== null && value !== void 0) {
|
|
23
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
24
|
+
var dispose, inner;
|
|
25
|
+
if (async) {
|
|
26
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
27
|
+
dispose = value[Symbol.asyncDispose];
|
|
28
|
+
}
|
|
29
|
+
if (dispose === void 0) {
|
|
30
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
31
|
+
dispose = value[Symbol.dispose];
|
|
32
|
+
if (async) inner = dispose;
|
|
33
|
+
}
|
|
34
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
35
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
36
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
37
|
+
}
|
|
38
|
+
else if (async) {
|
|
39
|
+
env.stack.push({ async: true });
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
};
|
|
43
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
44
|
+
return function (env) {
|
|
45
|
+
function fail(e) {
|
|
46
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
47
|
+
env.hasError = true;
|
|
48
|
+
}
|
|
49
|
+
var r, s = 0;
|
|
50
|
+
function next() {
|
|
51
|
+
while (r = env.stack.pop()) {
|
|
52
|
+
try {
|
|
53
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
54
|
+
if (r.dispose) {
|
|
55
|
+
var result = r.dispose.call(r.value);
|
|
56
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
57
|
+
}
|
|
58
|
+
else s |= 1;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
fail(e);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
65
|
+
if (env.hasError) throw env.error;
|
|
66
|
+
}
|
|
67
|
+
return next();
|
|
68
|
+
};
|
|
69
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
70
|
+
var e = new Error(message);
|
|
71
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
72
|
+
});
|
|
73
|
+
import { disposable, err, ok } from "@evolu/common";
|
|
74
|
+
const utf8Encoder = /*#__PURE__*/ new TextEncoder();
|
|
75
|
+
// Keeps a leading byte order mark, which the default decoder strips.
|
|
76
|
+
const utf8Decoder = /*#__PURE__*/ new TextDecoder("utf-8", { ignoreBOM: true });
|
|
77
|
+
/**
|
|
78
|
+
* Allocates at least one byte with `sqlite3_malloc`, so a zero-length value
|
|
79
|
+
* keeps a non-NULL address.
|
|
80
|
+
*
|
|
81
|
+
* A request above {@link maxInt32} fails without calling `sqlite3_malloc`, which
|
|
82
|
+
* takes a C int and would wrap it.
|
|
83
|
+
*/
|
|
84
|
+
export const allocWasm = (deps) => (byteLength) => {
|
|
85
|
+
const ptr = byteLength > maxInt32
|
|
86
|
+
? 0
|
|
87
|
+
: deps.sqliteWasm.exports.sqlite3_malloc(Math.max(1, byteLength));
|
|
88
|
+
return ptr === 0 ? err({ type: "SqliteNoMem", byteLength }) : ok(ptr);
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Copies a string into new memory as a NUL-terminated UTF-8 C string, which the
|
|
92
|
+
* caller frees with `sqlite3_free`.
|
|
93
|
+
*
|
|
94
|
+
* UTF-8 cannot encode a lone surrogate, which becomes U+FFFD, as with
|
|
95
|
+
* `TextEncoder`, so a caller that needs the exact text checks
|
|
96
|
+
* `String.prototype.isWellFormed` first.
|
|
97
|
+
*/
|
|
98
|
+
export const allocCString = (deps) => (value) => {
|
|
99
|
+
const bytes = utf8Encoder.encode(value);
|
|
100
|
+
const allocated = allocWasm(deps)(bytes.length + 1);
|
|
101
|
+
if (!allocated.ok)
|
|
102
|
+
return allocated;
|
|
103
|
+
const ptr = allocated.value;
|
|
104
|
+
const heap = deps.sqliteWasm.getHeapU8();
|
|
105
|
+
heap.set(bytes, ptr);
|
|
106
|
+
heap[ptr + bytes.length] = 0;
|
|
107
|
+
return ok(ptr);
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Encodes a string as UTF-8 into existing memory and returns the byte length,
|
|
111
|
+
* without a NUL terminator.
|
|
112
|
+
*
|
|
113
|
+
* The memory needs up to three bytes per UTF-16 code unit; text that does not
|
|
114
|
+
* fit is cut at a character boundary, so reserve `value.length * 3` bytes. A
|
|
115
|
+
* lone surrogate becomes U+FFFD, as in {@link allocCString}.
|
|
116
|
+
*/
|
|
117
|
+
export const writeUtf8 = (deps) => (value, ptr, capacity) => utf8Encoder.encodeInto(value, deps.sqliteWasm.getHeapU8().subarray(ptr, ptr + capacity)).written;
|
|
118
|
+
/** Decodes a NUL-terminated C string, such as an error message or a column name. */
|
|
119
|
+
export const readCString = (deps) => (ptr) => {
|
|
120
|
+
const heap = deps.sqliteWasm.getHeapU8();
|
|
121
|
+
return utf8Decoder.decode(heap.subarray(ptr, heap.indexOf(0, ptr)));
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Decodes UTF-8 of a known byte length, such as a text column, keeping a
|
|
125
|
+
* leading byte order mark and embedded NUL characters.
|
|
126
|
+
*/
|
|
127
|
+
export const readUtf8 = (deps) => (ptr, byteLength) => utf8Decoder.decode(deps.sqliteWasm.getHeapU8().subarray(ptr, ptr + byteLength));
|
|
128
|
+
/**
|
|
129
|
+
* Copies bytes out of wasm memory into a new `ArrayBuffer`, so the result can
|
|
130
|
+
* be transferred to another worker.
|
|
131
|
+
*/
|
|
132
|
+
export const copyWasmBytes = (deps) => (ptr, byteLength) => deps.sqliteWasm.getHeapU8().slice(ptr, ptr + byteLength);
|
|
133
|
+
/** Copies bytes into wasm memory. */
|
|
134
|
+
export const writeWasmBytes = (deps) => (ptr, bytes) => {
|
|
135
|
+
deps.sqliteWasm.getHeapU8().set(bytes, ptr);
|
|
136
|
+
};
|
|
137
|
+
/** Creates a {@link SqliteScratch}. */
|
|
138
|
+
export const createSqliteScratch = (deps) => {
|
|
139
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
140
|
+
try {
|
|
141
|
+
const out = allocWasm(deps)(16);
|
|
142
|
+
if (!out.ok)
|
|
143
|
+
return out;
|
|
144
|
+
let buffer = null;
|
|
145
|
+
let capacity = 0;
|
|
146
|
+
const disposer = __addDisposableResource(env_1, new DisposableStack(), false);
|
|
147
|
+
disposer.defer(() => {
|
|
148
|
+
deps.sqliteWasm.exports.sqlite3_free(out.value);
|
|
149
|
+
});
|
|
150
|
+
disposer.defer(() => {
|
|
151
|
+
if (buffer != null)
|
|
152
|
+
deps.sqliteWasm.exports.sqlite3_free(buffer);
|
|
153
|
+
});
|
|
154
|
+
return ok(disposable({
|
|
155
|
+
out: out.value,
|
|
156
|
+
reserve: (byteLength) => {
|
|
157
|
+
if (buffer != null) {
|
|
158
|
+
if (byteLength <= capacity)
|
|
159
|
+
return ok(buffer);
|
|
160
|
+
// The contents need not be kept, so the old memory goes first.
|
|
161
|
+
deps.sqliteWasm.exports.sqlite3_free(buffer);
|
|
162
|
+
buffer = null;
|
|
163
|
+
}
|
|
164
|
+
// Twice the capacity keeps reallocations rare, but when it is not
|
|
165
|
+
// available, the requested length alone may still be.
|
|
166
|
+
let newCapacity = Math.max(byteLength, capacity * 2);
|
|
167
|
+
let allocated = allocWasm(deps)(newCapacity);
|
|
168
|
+
if (!allocated.ok && newCapacity > byteLength) {
|
|
169
|
+
newCapacity = byteLength;
|
|
170
|
+
allocated = allocWasm(deps)(newCapacity);
|
|
171
|
+
}
|
|
172
|
+
if (!allocated.ok) {
|
|
173
|
+
capacity = 0;
|
|
174
|
+
return allocated;
|
|
175
|
+
}
|
|
176
|
+
buffer = allocated.value;
|
|
177
|
+
capacity = newCapacity;
|
|
178
|
+
return ok(buffer);
|
|
179
|
+
},
|
|
180
|
+
}, disposer));
|
|
181
|
+
}
|
|
182
|
+
catch (e_1) {
|
|
183
|
+
env_1.error = e_1;
|
|
184
|
+
env_1.hasError = true;
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
__disposeResources(env_1);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
/** The largest C int. */
|
|
191
|
+
export const maxInt32 = 0x7fff_ffff;
|
|
192
|
+
/**
|
|
193
|
+
* Whether a number is a 32-bit integer, which binds with `sqlite3_bind_int`
|
|
194
|
+
* without a BigInt.
|
|
195
|
+
*/
|
|
196
|
+
export const isInt32 = (value) => Number.isInteger(value) && value >= -maxInt32 - 1 && value <= maxInt32;
|
|
197
|
+
/** The largest SQLite INTEGER, 2^63 - 1. */
|
|
198
|
+
export const maxSqliteInt64 = 2n ** 63n - 1n;
|
|
199
|
+
/** The smallest SQLite INTEGER, -2^63. */
|
|
200
|
+
export const minSqliteInt64 = -(2n ** 63n);
|
|
201
|
+
/**
|
|
202
|
+
* Whether a bigint fits a SQLite INTEGER.
|
|
203
|
+
*
|
|
204
|
+
* The wasm boundary converts a bigint to i64 modulo 2^64 without an error, so
|
|
205
|
+
* anything passed to `sqlite3_bind_int64` must be checked first.
|
|
206
|
+
*/
|
|
207
|
+
export const isSqliteInt64 = (value) => BigInt.asIntN(64, value) === value;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branded pointers into SQLite's wasm memory and function table.
|
|
3
|
+
*
|
|
4
|
+
* At runtime every pointer is a wasm32 address, a plain number. The brands keep
|
|
5
|
+
* C types apart, so a statement cannot be passed where a connection is
|
|
6
|
+
* expected, borrowed memory cannot be freed, and no JavaScript string converts
|
|
7
|
+
* to a C string implicitly. Only this package creates pointer values, from what
|
|
8
|
+
* the wasm returns.
|
|
9
|
+
*
|
|
10
|
+
* The loader caps memory at 2 GiB (32768 pages), so every address is a
|
|
11
|
+
* non-negative i32 and reads with `getUint32` need no `>>> 0`.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { Brand } from "@evolu/common";
|
|
16
|
+
import type { SQLITE_STATIC, SQLITE_TRANSIENT } from "./Constants.ts";
|
|
17
|
+
/** An address in the wasm heap. */
|
|
18
|
+
export type WasmPtr = number & Brand<"WasmPtr">;
|
|
19
|
+
/**
|
|
20
|
+
* The C NULL pointer.
|
|
21
|
+
*
|
|
22
|
+
* Functions that can return NULL include it in their result type, and a `=== 0`
|
|
23
|
+
* check narrows it away.
|
|
24
|
+
*/
|
|
25
|
+
export type NullPtr = 0;
|
|
26
|
+
/**
|
|
27
|
+
* A NUL-terminated UTF-8 string.
|
|
28
|
+
*
|
|
29
|
+
* Returned C strings are borrowed from SQLite: copy them before the next call
|
|
30
|
+
* on the same object and never free them.
|
|
31
|
+
*/
|
|
32
|
+
export type CStringPtr = WasmPtr & Brand<"CString">;
|
|
33
|
+
/**
|
|
34
|
+
* Memory allocated with `sqlite3_malloc`.
|
|
35
|
+
*
|
|
36
|
+
* The holder frees it with `sqlite3_free` or hands it to SQLite, for example as
|
|
37
|
+
* a bind value with {@link SQLITE_WASM_DEALLOC}.
|
|
38
|
+
*/
|
|
39
|
+
export type SqliteOwnedPtr = WasmPtr & Brand<"SqliteOwned">;
|
|
40
|
+
/**
|
|
41
|
+
* A NUL-terminated UTF-8 string in memory allocated with `sqlite3_malloc`,
|
|
42
|
+
* which the holder frees with `sqlite3_free`.
|
|
43
|
+
*/
|
|
44
|
+
export type SqliteOwnedCStringPtr = SqliteOwnedPtr & CStringPtr;
|
|
45
|
+
/** An open database connection, `sqlite3*`. */
|
|
46
|
+
export type SqliteDbPtr = WasmPtr & Brand<"SqliteDb">;
|
|
47
|
+
/** A prepared statement, `sqlite3_stmt*`. */
|
|
48
|
+
export type SqliteStmtPtr = WasmPtr & Brand<"SqliteStmt">;
|
|
49
|
+
/**
|
|
50
|
+
* A dynamically typed SQL value, `sqlite3_value*`, such as a column value or an
|
|
51
|
+
* argument of an application-defined function.
|
|
52
|
+
*/
|
|
53
|
+
export type SqliteValuePtr = WasmPtr & Brand<"SqliteValue">;
|
|
54
|
+
/**
|
|
55
|
+
* A protected value copied with `sqlite3_value_dup`, which the holder frees
|
|
56
|
+
* with `sqlite3_value_free`.
|
|
57
|
+
*
|
|
58
|
+
* Column values, function arguments and the other values SQLite passes are
|
|
59
|
+
* borrowed, so `sqlite3_value_free` rejects them.
|
|
60
|
+
*/
|
|
61
|
+
export type SqliteOwnedValuePtr = SqliteValuePtr & Brand<"SqliteOwnedValue">;
|
|
62
|
+
/** The context of an application-defined function call, `sqlite3_context*`. */
|
|
63
|
+
export type SqliteContextPtr = WasmPtr & Brand<"SqliteContext">;
|
|
64
|
+
/** A VFS struct, `sqlite3_vfs*`. */
|
|
65
|
+
export type SqliteVfsPtr = WasmPtr & Brand<"SqliteVfs">;
|
|
66
|
+
/**
|
|
67
|
+
* A file SQLite opened through a VFS, `sqlite3_file*`.
|
|
68
|
+
*
|
|
69
|
+
* SQLite allocates it with the VFS's `szOsFile` bytes before calling `xOpen`.
|
|
70
|
+
*/
|
|
71
|
+
export type SqliteFilePtr = WasmPtr & Brand<"SqliteFile">;
|
|
72
|
+
/**
|
|
73
|
+
* A database filename SQLite created, `sqlite3_filename`, as `xOpen` receives
|
|
74
|
+
* it.
|
|
75
|
+
*
|
|
76
|
+
* SQLite stores the URI parameters after the name, where the `sqlite3_uri_*`
|
|
77
|
+
* functions read them, so no other C string can take its place.
|
|
78
|
+
*/
|
|
79
|
+
export type SqliteFilenamePtr = CStringPtr & Brand<"SqliteFilename">;
|
|
80
|
+
/**
|
|
81
|
+
* The query planner's exchange with a virtual table's `xBestIndex`,
|
|
82
|
+
* `sqlite3_index_info*`.
|
|
83
|
+
*/
|
|
84
|
+
export type SqliteIndexInfoPtr = WasmPtr & Brand<"SqliteIndexInfo">;
|
|
85
|
+
/**
|
|
86
|
+
* A C function pointer, which in wasm is an index into the function table, not
|
|
87
|
+
* a memory address.
|
|
88
|
+
*/
|
|
89
|
+
export type SqliteFunctionPtr = number & Brand<"SqliteFunctionPtr">;
|
|
90
|
+
/**
|
|
91
|
+
* The destructor argument of `sqlite3_bind_text`, `sqlite3_bind_blob`,
|
|
92
|
+
* `sqlite3_result_text` and `sqlite3_result_blob`.
|
|
93
|
+
*
|
|
94
|
+
* {@link SQLITE_STATIC} promises the memory outlives the value,
|
|
95
|
+
* {@link SQLITE_TRANSIENT} makes SQLite copy it, and a function pointer such as
|
|
96
|
+
* {@link SQLITE_WASM_DEALLOC} hands it to SQLite, which frees it even when the
|
|
97
|
+
* call fails.
|
|
98
|
+
*/
|
|
99
|
+
export type SqliteDestructor = typeof SQLITE_STATIC | typeof SQLITE_TRANSIENT | SqliteFunctionPtr;
|
|
100
|
+
//# sourceMappingURL=Pointer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pointer.d.ts","sourceRoot":"","sources":["../../src/Pointer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AAExB,mCAAmC;AACnC,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC;AAExB;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG,UAAU,CAAC;AAEhE,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;AAEtD,6CAA6C;AAC7C,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAE1D;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;AAE7E,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;AAEhE,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAEpE;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAC1B,OAAO,aAAa,GAAG,OAAO,gBAAgB,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branded pointers into SQLite's wasm memory and function table.
|
|
3
|
+
*
|
|
4
|
+
* At runtime every pointer is a wasm32 address, a plain number. The brands keep
|
|
5
|
+
* C types apart, so a statement cannot be passed where a connection is
|
|
6
|
+
* expected, borrowed memory cannot be freed, and no JavaScript string converts
|
|
7
|
+
* to a C string implicitly. Only this package creates pointer values, from what
|
|
8
|
+
* the wasm returns.
|
|
9
|
+
*
|
|
10
|
+
* The loader caps memory at 2 GiB (32768 pages), so every address is a
|
|
11
|
+
* non-negative i32 and reads with `getUint32` need no `>>> 0`.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
export {};
|