node-sqlite-kv 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/index.cjs +221 -0
- package/dist/index.d.cts +46 -0
- package/dist/index.d.mts +40 -26
- package/dist/index.mjs +186 -178
- package/package.json +15 -8
- package/dist/index.d.ts +0 -32
- package/dist/index.js +0 -217
package/README.md
CHANGED
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
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) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
let node_sqlite = require("node:sqlite");
|
|
29
|
+
let node_v8 = require("node:v8");
|
|
30
|
+
let node_fs = require("node:fs");
|
|
31
|
+
node_fs = __toESM(node_fs);
|
|
32
|
+
let node_path = require("node:path");
|
|
33
|
+
node_path = __toESM(node_path);
|
|
34
|
+
|
|
35
|
+
//#region src/classes/KVError.ts
|
|
36
|
+
/**
|
|
37
|
+
* Class representing a KVError
|
|
38
|
+
*/
|
|
39
|
+
var KVError = class extends Error {
|
|
40
|
+
static name = "KVError";
|
|
41
|
+
scope;
|
|
42
|
+
constructor(scope, ...args) {
|
|
43
|
+
super(args.join(" "));
|
|
44
|
+
this.scope = scope;
|
|
45
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
46
|
+
}
|
|
47
|
+
get name() {
|
|
48
|
+
return `${this.constructor.name} (${this.scope})`;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/utils/index.ts
|
|
54
|
+
/**
|
|
55
|
+
* A list of journal modes SQLite supports
|
|
56
|
+
*/
|
|
57
|
+
const journalModes = {
|
|
58
|
+
Delete: "DELETE",
|
|
59
|
+
Memory: "MEMORY",
|
|
60
|
+
Off: "OFF",
|
|
61
|
+
Persist: "PERSIST",
|
|
62
|
+
Truncate: "TRUNCATE",
|
|
63
|
+
WAL: "WAL"
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/classes/KVSync.ts
|
|
68
|
+
/**
|
|
69
|
+
* Class representing a synchronous key-value store
|
|
70
|
+
*/
|
|
71
|
+
var KVSync = class {
|
|
72
|
+
#db;
|
|
73
|
+
/**
|
|
74
|
+
* Instantiate a new key-value store
|
|
75
|
+
* @param options KVSync options
|
|
76
|
+
*/
|
|
77
|
+
constructor(options) {
|
|
78
|
+
const dbPath = options?.path ?? ":memory:";
|
|
79
|
+
if (dbPath !== ":memory:") node_fs.default.mkdirSync(node_path.default.dirname(dbPath), { recursive: true });
|
|
80
|
+
this.#db = new node_sqlite.DatabaseSync(dbPath);
|
|
81
|
+
this.setJournalMode(options?.journalMode ?? (dbPath !== ":memory:" ? journalModes.WAL : journalModes.Delete));
|
|
82
|
+
this.#db.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY NOT NULL, value BLOB NOT NULL) STRICT;");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Set a key in the database
|
|
86
|
+
* @param key Key name
|
|
87
|
+
* @param value Key value
|
|
88
|
+
* @returns Provided value
|
|
89
|
+
*/
|
|
90
|
+
set(key, value) {
|
|
91
|
+
if (!this.#db.isOpen) throw new KVError("set", "Database is not open");
|
|
92
|
+
if (!key || typeof key !== "string") throw new KVError("set", "Key must be provided and be a non-empty string");
|
|
93
|
+
if (value === void 0) throw new KVError("set", "Provided value is undefined, did you mean to use delete()?");
|
|
94
|
+
this.#db.prepare("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)").run(key, (0, node_v8.serialize)(value));
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get a value from the database
|
|
99
|
+
* @param key Key name
|
|
100
|
+
* @returns Value or null
|
|
101
|
+
*/
|
|
102
|
+
get(key) {
|
|
103
|
+
if (!this.#db.isOpen) throw new KVError("get", "Database is not open");
|
|
104
|
+
if (!key || typeof key !== "string") throw new KVError("get", "Key must be provided and be a non-empty string.");
|
|
105
|
+
const row = this.#db.prepare("SELECT value FROM kv WHERE key = ?;").get(key);
|
|
106
|
+
return row ? (0, node_v8.deserialize)(row.value) : null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Delete a key from the database
|
|
110
|
+
* @param key Key name
|
|
111
|
+
* @returns KVSync instance
|
|
112
|
+
*/
|
|
113
|
+
delete(key) {
|
|
114
|
+
if (!this.#db.isOpen) throw new KVError("delete", "Database is not open");
|
|
115
|
+
if (!key || typeof key !== "string") throw new KVError("delete", "Key must be provided and be a non-empty string.");
|
|
116
|
+
this.#db.prepare("DELETE FROM kv WHERE key = ?;").run(key);
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get all data in the database
|
|
121
|
+
* @returns Array of objects containing keys and values
|
|
122
|
+
*/
|
|
123
|
+
all(filter) {
|
|
124
|
+
if (!this.#db.isOpen) throw new KVError("all", "Database is not open");
|
|
125
|
+
const rows = this.#db.prepare("SELECT key, value FROM kv").iterate();
|
|
126
|
+
const result = [];
|
|
127
|
+
for (const row of rows) {
|
|
128
|
+
const key = row.key;
|
|
129
|
+
const value = (0, node_v8.deserialize)(row.value);
|
|
130
|
+
if (!filter || filter(key, value)) result.push({
|
|
131
|
+
key,
|
|
132
|
+
value
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Remove all entries from the database
|
|
139
|
+
*/
|
|
140
|
+
clear() {
|
|
141
|
+
if (!this.#db.isOpen) throw new KVError("clear", "Database is not open");
|
|
142
|
+
this.#db.exec("DELETE FROM kv;");
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Update the journal mode
|
|
147
|
+
* @param mode New journal mode
|
|
148
|
+
*/
|
|
149
|
+
setJournalMode(mode) {
|
|
150
|
+
if (!this.#db.isOpen) throw new KVError("setJournalMode", "Database is not open");
|
|
151
|
+
if (!Object.values(journalModes).includes(mode)) throw new KVError("setJournalMode", `Invalid journal mode specified - received: "${mode}", expected one of: ${Object.values(journalModes).join(", ")}`);
|
|
152
|
+
this.#db.exec(`PRAGMA journal_mode = ${mode};`);
|
|
153
|
+
return this;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Perform a transaction
|
|
157
|
+
* @param callback Callback with KVSync instance
|
|
158
|
+
* @returns Object containing oldValues and newValues each containing arrays of keys and values
|
|
159
|
+
*/
|
|
160
|
+
transaction(callback) {
|
|
161
|
+
if (!this.#db.isOpen) throw new KVError("transaction", "Database is not open");
|
|
162
|
+
if (!callback) throw new KVError("transaction", "A callback must be provided when using transaction().");
|
|
163
|
+
if (typeof callback !== "function") throw new KVError("transaction", `Transaction callback must be of type function. Received: ${typeof callback}`);
|
|
164
|
+
const oldMap = /* @__PURE__ */ new Map();
|
|
165
|
+
const newMap = /* @__PURE__ */ new Map();
|
|
166
|
+
const tx = Object.create(this);
|
|
167
|
+
tx.set = (key, value) => {
|
|
168
|
+
if (!oldMap.has(key)) {
|
|
169
|
+
const oldValue = this.get(key);
|
|
170
|
+
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
171
|
+
}
|
|
172
|
+
newMap.set(key, value);
|
|
173
|
+
return value ?? null;
|
|
174
|
+
};
|
|
175
|
+
tx.delete = (key) => {
|
|
176
|
+
if (!oldMap.has(key)) {
|
|
177
|
+
const oldValue = this.get(key);
|
|
178
|
+
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
179
|
+
}
|
|
180
|
+
newMap.set(key, null);
|
|
181
|
+
return tx;
|
|
182
|
+
};
|
|
183
|
+
try {
|
|
184
|
+
this.#db.exec("BEGIN TRANSACTION;");
|
|
185
|
+
callback(tx);
|
|
186
|
+
for (const [key, value] of newMap.entries()) if (value === null) this.delete(key);
|
|
187
|
+
else this.set(key, value);
|
|
188
|
+
this.#db.exec("COMMIT;");
|
|
189
|
+
} catch (error) {
|
|
190
|
+
this.#db.exec("ROLLBACK;");
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
oldValues: Array.from(oldMap.entries()).map(([key, value]) => ({
|
|
195
|
+
key,
|
|
196
|
+
value
|
|
197
|
+
})),
|
|
198
|
+
newValues: Array.from(newMap.entries()).map(([key, value]) => ({
|
|
199
|
+
key,
|
|
200
|
+
value
|
|
201
|
+
}))
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Open the database
|
|
206
|
+
*/
|
|
207
|
+
open() {
|
|
208
|
+
if (this.#db.isOpen) throw new KVError("open", "Database is open");
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Close the database
|
|
212
|
+
*/
|
|
213
|
+
close() {
|
|
214
|
+
if (!this.#db.isOpen) throw new KVError("close", "Database is not open");
|
|
215
|
+
this.#db.close();
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
//#endregion
|
|
220
|
+
exports.KVSync = KVSync;
|
|
221
|
+
exports.journalModes = journalModes;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/utils/index.d.ts
|
|
2
|
+
declare const journalModes: {
|
|
3
|
+
readonly Delete: "DELETE";
|
|
4
|
+
readonly Memory: "MEMORY";
|
|
5
|
+
readonly Off: "OFF";
|
|
6
|
+
readonly Persist: "PERSIST";
|
|
7
|
+
readonly Truncate: "TRUNCATE";
|
|
8
|
+
readonly WAL: "WAL";
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/types.d.ts
|
|
12
|
+
type JournalMode = (typeof journalModes)[keyof typeof journalModes];
|
|
13
|
+
interface KVSyncOptions {
|
|
14
|
+
path?: SQLitePath;
|
|
15
|
+
journalMode?: JournalMode;
|
|
16
|
+
}
|
|
17
|
+
type SQLitePath = ":memory:" | (string & {});
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/classes/KVSync.d.ts
|
|
20
|
+
declare class KVSync<T = any> {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(options?: KVSyncOptions);
|
|
23
|
+
set<K = T>(key: string, value: K | undefined): K;
|
|
24
|
+
get<K = T>(key: string): K | null;
|
|
25
|
+
delete(key: string): KVSync;
|
|
26
|
+
all<K = T>(filter?: (key: string, value: K) => boolean): {
|
|
27
|
+
key: string;
|
|
28
|
+
value: K;
|
|
29
|
+
}[];
|
|
30
|
+
clear(): KVSync;
|
|
31
|
+
setJournalMode(mode: JournalMode): this;
|
|
32
|
+
transaction<R>(callback: (kv: KVSync<T>) => R): {
|
|
33
|
+
oldValues: {
|
|
34
|
+
key: string;
|
|
35
|
+
value: T | null | undefined;
|
|
36
|
+
}[];
|
|
37
|
+
newValues: {
|
|
38
|
+
key: string;
|
|
39
|
+
value: T | null;
|
|
40
|
+
}[];
|
|
41
|
+
};
|
|
42
|
+
open(): void;
|
|
43
|
+
close(): void;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { JournalMode, KVSync, KVSyncOptions, SQLitePath, journalModes };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/utils/index.d.ts
|
|
2
|
+
declare const journalModes: {
|
|
3
|
+
readonly Delete: "DELETE";
|
|
4
|
+
readonly Memory: "MEMORY";
|
|
5
|
+
readonly Off: "OFF";
|
|
6
|
+
readonly Persist: "PERSIST";
|
|
7
|
+
readonly Truncate: "TRUNCATE";
|
|
8
|
+
readonly WAL: "WAL";
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/types.d.ts
|
|
12
|
+
type JournalMode = (typeof journalModes)[keyof typeof journalModes];
|
|
2
13
|
interface KVSyncOptions {
|
|
3
|
-
|
|
4
|
-
|
|
14
|
+
path?: SQLitePath;
|
|
15
|
+
journalMode?: JournalMode;
|
|
5
16
|
}
|
|
6
17
|
type SQLitePath = ":memory:" | (string & {});
|
|
7
|
-
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/classes/KVSync.d.ts
|
|
8
20
|
declare class KVSync<T = any> {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
#private;
|
|
22
|
+
constructor(options?: KVSyncOptions);
|
|
23
|
+
set<K = T>(key: string, value: K | undefined): K;
|
|
24
|
+
get<K = T>(key: string): K | null;
|
|
25
|
+
delete(key: string): KVSync;
|
|
26
|
+
all<K = T>(filter?: (key: string, value: K) => boolean): {
|
|
27
|
+
key: string;
|
|
28
|
+
value: K;
|
|
29
|
+
}[];
|
|
30
|
+
clear(): KVSync;
|
|
31
|
+
setJournalMode(mode: JournalMode): this;
|
|
32
|
+
transaction<R>(callback: (kv: KVSync<T>) => R): {
|
|
33
|
+
oldValues: {
|
|
34
|
+
key: string;
|
|
35
|
+
value: T | null | undefined;
|
|
17
36
|
}[];
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
newValues: {
|
|
26
|
-
key: string;
|
|
27
|
-
value: T | null;
|
|
28
|
-
}[];
|
|
29
|
-
};
|
|
37
|
+
newValues: {
|
|
38
|
+
key: string;
|
|
39
|
+
value: T | null;
|
|
40
|
+
}[];
|
|
41
|
+
};
|
|
42
|
+
open(): void;
|
|
43
|
+
close(): void;
|
|
30
44
|
}
|
|
31
|
-
|
|
32
|
-
export {
|
|
45
|
+
//#endregion
|
|
46
|
+
export { JournalMode, KVSync, KVSyncOptions, SQLitePath, journalModes };
|
package/dist/index.mjs
CHANGED
|
@@ -1,183 +1,191 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
|
-
// src/index.ts
|
|
5
1
|
import { DatabaseSync } from "node:sqlite";
|
|
6
|
-
import {
|
|
2
|
+
import { deserialize, serialize } from "node:v8";
|
|
7
3
|
import fs from "node:fs";
|
|
8
4
|
import path from "node:path";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Set a key in the database
|
|
42
|
-
* @param key Key name
|
|
43
|
-
* @param value Key value
|
|
44
|
-
* @returns Provided value
|
|
45
|
-
*/
|
|
46
|
-
set(key, value) {
|
|
47
|
-
if (!key || typeof key !== "string") {
|
|
48
|
-
throw new Error(
|
|
49
|
-
"[KVSync]: Key must be provided and be a non-empty string."
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
if (value === void 0) {
|
|
53
|
-
this.delete(key);
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
this.#db.prepare("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)").run(key, serialize(value));
|
|
57
|
-
return value;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Get a value from the database
|
|
61
|
-
* @param key Key name
|
|
62
|
-
* @returns Value or null
|
|
63
|
-
*/
|
|
64
|
-
get(key) {
|
|
65
|
-
if (!key || typeof key !== "string") {
|
|
66
|
-
throw new Error(
|
|
67
|
-
"[KVSync]: Key must be provided and be a non-empty string."
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
const row = this.#db.prepare("SELECT value FROM kv WHERE key = ?").get(key);
|
|
71
|
-
return row ? deserialize(row.value) : null;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Delete a key from the database
|
|
75
|
-
* @param key Key name
|
|
76
|
-
* @returns KVSync instance
|
|
77
|
-
*/
|
|
78
|
-
delete(key) {
|
|
79
|
-
if (!key || typeof key !== "string") {
|
|
80
|
-
throw new Error(
|
|
81
|
-
"[KVSync]: Key must be provided and be a non-empty string."
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
this.#db.prepare("DELETE FROM kv WHERE key = ?").run(key);
|
|
85
|
-
return this;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Get all data in the database
|
|
89
|
-
* @returns Array of objects containing keys and values
|
|
90
|
-
*/
|
|
91
|
-
all(filter) {
|
|
92
|
-
const rows = this.#db.prepare("SELECT key, value FROM kv").iterate();
|
|
93
|
-
const result = [];
|
|
94
|
-
for (const row of rows) {
|
|
95
|
-
const key = row.key;
|
|
96
|
-
const value = deserialize(row.value);
|
|
97
|
-
if (!filter || filter(key, value)) {
|
|
98
|
-
result.push({ key, value });
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Remove all entries from the database
|
|
105
|
-
*/
|
|
106
|
-
clear() {
|
|
107
|
-
this.#db.exec("DELETE FROM kv;");
|
|
108
|
-
return this;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Update the journal mode
|
|
112
|
-
* @param mode New journal mode
|
|
113
|
-
*/
|
|
114
|
-
setJournalMode(mode) {
|
|
115
|
-
if (!journalModes.includes(mode)) {
|
|
116
|
-
throw new Error(
|
|
117
|
-
`[KVSync]: Invalid journal mode specified. Received: "${mode}", expected one of: ${journalModes.join(", ")}`
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
this.#db.exec(`PRAGMA journal_mode = ${mode};`);
|
|
121
|
-
return this;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Perform a transaction
|
|
125
|
-
* @param callback Callback with KVSync instance
|
|
126
|
-
* @returns Object containing oldValues and newValues each containing arrays of keys and values
|
|
127
|
-
*/
|
|
128
|
-
transaction(callback) {
|
|
129
|
-
if (!callback) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
"[KVSync]: A callback must be provided when using transaction()."
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
if (typeof callback !== "function") {
|
|
135
|
-
throw new Error(
|
|
136
|
-
`[KVSync]: Transaction callback must be of type function. Received: ${typeof callback}`
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
this.#db.exec("BEGIN TRANSACTION;");
|
|
140
|
-
const oldMap = /* @__PURE__ */ new Map();
|
|
141
|
-
const newMap = /* @__PURE__ */ new Map();
|
|
142
|
-
const tx = Object.create(this);
|
|
143
|
-
tx.set = (key, value) => {
|
|
144
|
-
if (!oldMap.has(key)) {
|
|
145
|
-
const oldValue = this.get(key);
|
|
146
|
-
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
147
|
-
}
|
|
148
|
-
const result = this.set(key, value);
|
|
149
|
-
newMap.set(key, result);
|
|
150
|
-
return result;
|
|
151
|
-
};
|
|
152
|
-
tx.delete = (key) => {
|
|
153
|
-
if (!oldMap.has(key)) {
|
|
154
|
-
const oldValue = this.get(key);
|
|
155
|
-
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
156
|
-
}
|
|
157
|
-
newMap.set(key, null);
|
|
158
|
-
this.delete(key);
|
|
159
|
-
return tx;
|
|
160
|
-
};
|
|
161
|
-
try {
|
|
162
|
-
callback(tx);
|
|
163
|
-
this.#db.exec("COMMIT;");
|
|
164
|
-
} catch (error) {
|
|
165
|
-
this.#db.exec("ROLLBACK;");
|
|
166
|
-
throw error;
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
oldValues: Array.from(oldMap.entries()).map(([key, value]) => ({
|
|
170
|
-
key,
|
|
171
|
-
value
|
|
172
|
-
})),
|
|
173
|
-
newValues: Array.from(newMap.entries()).map(([key, value]) => ({
|
|
174
|
-
key,
|
|
175
|
-
value
|
|
176
|
-
}))
|
|
177
|
-
};
|
|
178
|
-
}
|
|
5
|
+
|
|
6
|
+
//#region src/classes/KVError.ts
|
|
7
|
+
/**
|
|
8
|
+
* Class representing a KVError
|
|
9
|
+
*/
|
|
10
|
+
var KVError = class extends Error {
|
|
11
|
+
static name = "KVError";
|
|
12
|
+
scope;
|
|
13
|
+
constructor(scope, ...args) {
|
|
14
|
+
super(args.join(" "));
|
|
15
|
+
this.scope = scope;
|
|
16
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
17
|
+
}
|
|
18
|
+
get name() {
|
|
19
|
+
return `${this.constructor.name} (${this.scope})`;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/utils/index.ts
|
|
25
|
+
/**
|
|
26
|
+
* A list of journal modes SQLite supports
|
|
27
|
+
*/
|
|
28
|
+
const journalModes = {
|
|
29
|
+
Delete: "DELETE",
|
|
30
|
+
Memory: "MEMORY",
|
|
31
|
+
Off: "OFF",
|
|
32
|
+
Persist: "PERSIST",
|
|
33
|
+
Truncate: "TRUNCATE",
|
|
34
|
+
WAL: "WAL"
|
|
179
35
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/classes/KVSync.ts
|
|
39
|
+
/**
|
|
40
|
+
* Class representing a synchronous key-value store
|
|
41
|
+
*/
|
|
42
|
+
var KVSync = class {
|
|
43
|
+
#db;
|
|
44
|
+
/**
|
|
45
|
+
* Instantiate a new key-value store
|
|
46
|
+
* @param options KVSync options
|
|
47
|
+
*/
|
|
48
|
+
constructor(options) {
|
|
49
|
+
const dbPath = options?.path ?? ":memory:";
|
|
50
|
+
if (dbPath !== ":memory:") fs.mkdirSync(path.dirname(dbPath), { recursive: true });
|
|
51
|
+
this.#db = new DatabaseSync(dbPath);
|
|
52
|
+
this.setJournalMode(options?.journalMode ?? (dbPath !== ":memory:" ? journalModes.WAL : journalModes.Delete));
|
|
53
|
+
this.#db.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY NOT NULL, value BLOB NOT NULL) STRICT;");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Set a key in the database
|
|
57
|
+
* @param key Key name
|
|
58
|
+
* @param value Key value
|
|
59
|
+
* @returns Provided value
|
|
60
|
+
*/
|
|
61
|
+
set(key, value) {
|
|
62
|
+
if (!this.#db.isOpen) throw new KVError("set", "Database is not open");
|
|
63
|
+
if (!key || typeof key !== "string") throw new KVError("set", "Key must be provided and be a non-empty string");
|
|
64
|
+
if (value === void 0) throw new KVError("set", "Provided value is undefined, did you mean to use delete()?");
|
|
65
|
+
this.#db.prepare("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)").run(key, serialize(value));
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get a value from the database
|
|
70
|
+
* @param key Key name
|
|
71
|
+
* @returns Value or null
|
|
72
|
+
*/
|
|
73
|
+
get(key) {
|
|
74
|
+
if (!this.#db.isOpen) throw new KVError("get", "Database is not open");
|
|
75
|
+
if (!key || typeof key !== "string") throw new KVError("get", "Key must be provided and be a non-empty string.");
|
|
76
|
+
const row = this.#db.prepare("SELECT value FROM kv WHERE key = ?;").get(key);
|
|
77
|
+
return row ? deserialize(row.value) : null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Delete a key from the database
|
|
81
|
+
* @param key Key name
|
|
82
|
+
* @returns KVSync instance
|
|
83
|
+
*/
|
|
84
|
+
delete(key) {
|
|
85
|
+
if (!this.#db.isOpen) throw new KVError("delete", "Database is not open");
|
|
86
|
+
if (!key || typeof key !== "string") throw new KVError("delete", "Key must be provided and be a non-empty string.");
|
|
87
|
+
this.#db.prepare("DELETE FROM kv WHERE key = ?;").run(key);
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get all data in the database
|
|
92
|
+
* @returns Array of objects containing keys and values
|
|
93
|
+
*/
|
|
94
|
+
all(filter) {
|
|
95
|
+
if (!this.#db.isOpen) throw new KVError("all", "Database is not open");
|
|
96
|
+
const rows = this.#db.prepare("SELECT key, value FROM kv").iterate();
|
|
97
|
+
const result = [];
|
|
98
|
+
for (const row of rows) {
|
|
99
|
+
const key = row.key;
|
|
100
|
+
const value = deserialize(row.value);
|
|
101
|
+
if (!filter || filter(key, value)) result.push({
|
|
102
|
+
key,
|
|
103
|
+
value
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Remove all entries from the database
|
|
110
|
+
*/
|
|
111
|
+
clear() {
|
|
112
|
+
if (!this.#db.isOpen) throw new KVError("clear", "Database is not open");
|
|
113
|
+
this.#db.exec("DELETE FROM kv;");
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Update the journal mode
|
|
118
|
+
* @param mode New journal mode
|
|
119
|
+
*/
|
|
120
|
+
setJournalMode(mode) {
|
|
121
|
+
if (!this.#db.isOpen) throw new KVError("setJournalMode", "Database is not open");
|
|
122
|
+
if (!Object.values(journalModes).includes(mode)) throw new KVError("setJournalMode", `Invalid journal mode specified - received: "${mode}", expected one of: ${Object.values(journalModes).join(", ")}`);
|
|
123
|
+
this.#db.exec(`PRAGMA journal_mode = ${mode};`);
|
|
124
|
+
return this;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Perform a transaction
|
|
128
|
+
* @param callback Callback with KVSync instance
|
|
129
|
+
* @returns Object containing oldValues and newValues each containing arrays of keys and values
|
|
130
|
+
*/
|
|
131
|
+
transaction(callback) {
|
|
132
|
+
if (!this.#db.isOpen) throw new KVError("transaction", "Database is not open");
|
|
133
|
+
if (!callback) throw new KVError("transaction", "A callback must be provided when using transaction().");
|
|
134
|
+
if (typeof callback !== "function") throw new KVError("transaction", `Transaction callback must be of type function. Received: ${typeof callback}`);
|
|
135
|
+
const oldMap = /* @__PURE__ */ new Map();
|
|
136
|
+
const newMap = /* @__PURE__ */ new Map();
|
|
137
|
+
const tx = Object.create(this);
|
|
138
|
+
tx.set = (key, value) => {
|
|
139
|
+
if (!oldMap.has(key)) {
|
|
140
|
+
const oldValue = this.get(key);
|
|
141
|
+
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
142
|
+
}
|
|
143
|
+
newMap.set(key, value);
|
|
144
|
+
return value ?? null;
|
|
145
|
+
};
|
|
146
|
+
tx.delete = (key) => {
|
|
147
|
+
if (!oldMap.has(key)) {
|
|
148
|
+
const oldValue = this.get(key);
|
|
149
|
+
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
150
|
+
}
|
|
151
|
+
newMap.set(key, null);
|
|
152
|
+
return tx;
|
|
153
|
+
};
|
|
154
|
+
try {
|
|
155
|
+
this.#db.exec("BEGIN TRANSACTION;");
|
|
156
|
+
callback(tx);
|
|
157
|
+
for (const [key, value] of newMap.entries()) if (value === null) this.delete(key);
|
|
158
|
+
else this.set(key, value);
|
|
159
|
+
this.#db.exec("COMMIT;");
|
|
160
|
+
} catch (error) {
|
|
161
|
+
this.#db.exec("ROLLBACK;");
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
oldValues: Array.from(oldMap.entries()).map(([key, value]) => ({
|
|
166
|
+
key,
|
|
167
|
+
value
|
|
168
|
+
})),
|
|
169
|
+
newValues: Array.from(newMap.entries()).map(([key, value]) => ({
|
|
170
|
+
key,
|
|
171
|
+
value
|
|
172
|
+
}))
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Open the database
|
|
177
|
+
*/
|
|
178
|
+
open() {
|
|
179
|
+
if (this.#db.isOpen) throw new KVError("open", "Database is open");
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Close the database
|
|
183
|
+
*/
|
|
184
|
+
close() {
|
|
185
|
+
if (!this.#db.isOpen) throw new KVError("close", "Database is not open");
|
|
186
|
+
this.#db.close();
|
|
187
|
+
}
|
|
183
188
|
};
|
|
189
|
+
|
|
190
|
+
//#endregion
|
|
191
|
+
export { KVSync, journalModes };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-sqlite-kv",
|
|
3
3
|
"description": "Key-value store with node:sqlite",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/e60m5ss/node-sqlite-kv"
|
|
7
7
|
},
|
|
@@ -9,16 +9,23 @@
|
|
|
9
9
|
"name": "e60m5ss",
|
|
10
10
|
"url": "https://github.com/e60m5ss"
|
|
11
11
|
},
|
|
12
|
-
"main": "./dist/index.
|
|
12
|
+
"main": "./dist/index.mjs",
|
|
13
13
|
"module": "./dist/index.mjs",
|
|
14
|
-
"types": "./dist/index.d.
|
|
14
|
+
"types": "./dist/index.d.mts",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"exports": {
|
|
17
|
+
"default": "./dist/index.cjs",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.cjs",
|
|
20
|
+
"types": "./dist/index.d.cts"
|
|
21
|
+
},
|
|
15
22
|
"engineStrict": true,
|
|
16
23
|
"engines": {
|
|
17
24
|
"node": ">=22.5.0"
|
|
18
25
|
},
|
|
19
26
|
"prettier": {
|
|
20
27
|
"jsxSingleQuote": false,
|
|
21
|
-
"printWidth":
|
|
28
|
+
"printWidth": 80,
|
|
22
29
|
"semi": true,
|
|
23
30
|
"singleQuote": false,
|
|
24
31
|
"tabWidth": 4,
|
|
@@ -26,15 +33,15 @@
|
|
|
26
33
|
"useTabs": false
|
|
27
34
|
},
|
|
28
35
|
"devDependencies": {
|
|
29
|
-
"@types/node": "^25.
|
|
36
|
+
"@types/node": "^25.2.0",
|
|
30
37
|
"prettier": "^3.8.1",
|
|
31
|
-
"
|
|
38
|
+
"tsdown": "^0.20.1",
|
|
32
39
|
"typescript": "^5.9.3"
|
|
33
40
|
},
|
|
34
41
|
"scripts": {
|
|
35
|
-
"build": "
|
|
42
|
+
"build": "tsdown",
|
|
36
43
|
"format": "prettier ./src --write --ignore-path=.prettierignore",
|
|
37
44
|
"lint": "tsc --noEmit; prettier ./src --check --ignore-path=.prettierignore",
|
|
38
|
-
"prepublish": "
|
|
45
|
+
"prepublish": "tsdown"
|
|
39
46
|
}
|
|
40
47
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
type JournalMode = "DELETE" | "MEMORY" | "OFF" | "PERSIST" | "TRUNCATE" | "WAL";
|
|
2
|
-
interface KVSyncOptions {
|
|
3
|
-
path?: SQLitePath;
|
|
4
|
-
journalMode?: JournalMode;
|
|
5
|
-
}
|
|
6
|
-
type SQLitePath = ":memory:" | (string & {});
|
|
7
|
-
declare const journalModes: JournalMode[];
|
|
8
|
-
declare class KVSync<T = any> {
|
|
9
|
-
#private;
|
|
10
|
-
constructor(options?: KVSyncOptions);
|
|
11
|
-
set<K = T>(key: string, value: K | undefined): K | null;
|
|
12
|
-
get<K = T>(key: string): K | null;
|
|
13
|
-
delete(key: string): KVSync;
|
|
14
|
-
all<K = T>(filter?: (key: string, value: K) => boolean): {
|
|
15
|
-
key: string;
|
|
16
|
-
value: K;
|
|
17
|
-
}[];
|
|
18
|
-
clear(): KVSync;
|
|
19
|
-
setJournalMode(mode: JournalMode): this;
|
|
20
|
-
transaction<R>(callback: (kv: KVSync<T>) => R): {
|
|
21
|
-
oldValues: {
|
|
22
|
-
key: string;
|
|
23
|
-
value: T | null | undefined;
|
|
24
|
-
}[];
|
|
25
|
-
newValues: {
|
|
26
|
-
key: string;
|
|
27
|
-
value: T | null;
|
|
28
|
-
}[];
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export { type JournalMode, KVSync, type KVSyncOptions, type SQLitePath, journalModes };
|
package/dist/index.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
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 __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
-
var __export = (target, all) => {
|
|
10
|
-
for (var name in all)
|
|
11
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
-
};
|
|
13
|
-
var __copyProps = (to, from, except, desc) => {
|
|
14
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
-
for (let key of __getOwnPropNames(from))
|
|
16
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
-
}
|
|
19
|
-
return to;
|
|
20
|
-
};
|
|
21
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
-
mod
|
|
28
|
-
));
|
|
29
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
-
|
|
31
|
-
// src/index.ts
|
|
32
|
-
var index_exports = {};
|
|
33
|
-
__export(index_exports, {
|
|
34
|
-
KVSync: () => KVSync,
|
|
35
|
-
journalModes: () => journalModes
|
|
36
|
-
});
|
|
37
|
-
module.exports = __toCommonJS(index_exports);
|
|
38
|
-
var import_node_sqlite = require("node:sqlite");
|
|
39
|
-
var import_node_v8 = require("node:v8");
|
|
40
|
-
var import_node_fs = __toESM(require("node:fs"));
|
|
41
|
-
var import_node_path = __toESM(require("node:path"));
|
|
42
|
-
var journalModes = [
|
|
43
|
-
"DELETE",
|
|
44
|
-
"MEMORY",
|
|
45
|
-
"OFF",
|
|
46
|
-
"PERSIST",
|
|
47
|
-
"TRUNCATE",
|
|
48
|
-
"WAL"
|
|
49
|
-
];
|
|
50
|
-
var KVSync = class {
|
|
51
|
-
static {
|
|
52
|
-
__name(this, "KVSync");
|
|
53
|
-
}
|
|
54
|
-
#db;
|
|
55
|
-
/**
|
|
56
|
-
* Instantiate a new key-value store
|
|
57
|
-
* @param path Where the database is stored, or `:memory:` for in-memory storage
|
|
58
|
-
*/
|
|
59
|
-
constructor(options) {
|
|
60
|
-
const dbPath = options?.path ?? ":memory:";
|
|
61
|
-
if (dbPath !== ":memory:") {
|
|
62
|
-
import_node_fs.default.mkdirSync(import_node_path.default.dirname(dbPath), { recursive: true });
|
|
63
|
-
}
|
|
64
|
-
this.#db = new import_node_sqlite.DatabaseSync(dbPath);
|
|
65
|
-
this.setJournalMode(options?.journalMode ?? "DELETE");
|
|
66
|
-
this.#db.exec(`
|
|
67
|
-
CREATE TABLE IF NOT EXISTS kv (
|
|
68
|
-
key TEXT PRIMARY KEY NOT NULL,
|
|
69
|
-
value BLOB NOT NULL
|
|
70
|
-
) STRICT;
|
|
71
|
-
`);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Set a key in the database
|
|
75
|
-
* @param key Key name
|
|
76
|
-
* @param value Key value
|
|
77
|
-
* @returns Provided value
|
|
78
|
-
*/
|
|
79
|
-
set(key, value) {
|
|
80
|
-
if (!key || typeof key !== "string") {
|
|
81
|
-
throw new Error(
|
|
82
|
-
"[KVSync]: Key must be provided and be a non-empty string."
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
if (value === void 0) {
|
|
86
|
-
this.delete(key);
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
this.#db.prepare("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)").run(key, (0, import_node_v8.serialize)(value));
|
|
90
|
-
return value;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Get a value from the database
|
|
94
|
-
* @param key Key name
|
|
95
|
-
* @returns Value or null
|
|
96
|
-
*/
|
|
97
|
-
get(key) {
|
|
98
|
-
if (!key || typeof key !== "string") {
|
|
99
|
-
throw new Error(
|
|
100
|
-
"[KVSync]: Key must be provided and be a non-empty string."
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
const row = this.#db.prepare("SELECT value FROM kv WHERE key = ?").get(key);
|
|
104
|
-
return row ? (0, import_node_v8.deserialize)(row.value) : null;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Delete a key from the database
|
|
108
|
-
* @param key Key name
|
|
109
|
-
* @returns KVSync instance
|
|
110
|
-
*/
|
|
111
|
-
delete(key) {
|
|
112
|
-
if (!key || typeof key !== "string") {
|
|
113
|
-
throw new Error(
|
|
114
|
-
"[KVSync]: Key must be provided and be a non-empty string."
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
this.#db.prepare("DELETE FROM kv WHERE key = ?").run(key);
|
|
118
|
-
return this;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Get all data in the database
|
|
122
|
-
* @returns Array of objects containing keys and values
|
|
123
|
-
*/
|
|
124
|
-
all(filter) {
|
|
125
|
-
const rows = this.#db.prepare("SELECT key, value FROM kv").iterate();
|
|
126
|
-
const result = [];
|
|
127
|
-
for (const row of rows) {
|
|
128
|
-
const key = row.key;
|
|
129
|
-
const value = (0, import_node_v8.deserialize)(row.value);
|
|
130
|
-
if (!filter || filter(key, value)) {
|
|
131
|
-
result.push({ key, value });
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return result;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Remove all entries from the database
|
|
138
|
-
*/
|
|
139
|
-
clear() {
|
|
140
|
-
this.#db.exec("DELETE FROM kv;");
|
|
141
|
-
return this;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Update the journal mode
|
|
145
|
-
* @param mode New journal mode
|
|
146
|
-
*/
|
|
147
|
-
setJournalMode(mode) {
|
|
148
|
-
if (!journalModes.includes(mode)) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`[KVSync]: Invalid journal mode specified. Received: "${mode}", expected one of: ${journalModes.join(", ")}`
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
this.#db.exec(`PRAGMA journal_mode = ${mode};`);
|
|
154
|
-
return this;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Perform a transaction
|
|
158
|
-
* @param callback Callback with KVSync instance
|
|
159
|
-
* @returns Object containing oldValues and newValues each containing arrays of keys and values
|
|
160
|
-
*/
|
|
161
|
-
transaction(callback) {
|
|
162
|
-
if (!callback) {
|
|
163
|
-
throw new Error(
|
|
164
|
-
"[KVSync]: A callback must be provided when using transaction()."
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
if (typeof callback !== "function") {
|
|
168
|
-
throw new Error(
|
|
169
|
-
`[KVSync]: Transaction callback must be of type function. Received: ${typeof callback}`
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
this.#db.exec("BEGIN TRANSACTION;");
|
|
173
|
-
const oldMap = /* @__PURE__ */ new Map();
|
|
174
|
-
const newMap = /* @__PURE__ */ new Map();
|
|
175
|
-
const tx = Object.create(this);
|
|
176
|
-
tx.set = (key, value) => {
|
|
177
|
-
if (!oldMap.has(key)) {
|
|
178
|
-
const oldValue = this.get(key);
|
|
179
|
-
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
180
|
-
}
|
|
181
|
-
const result = this.set(key, value);
|
|
182
|
-
newMap.set(key, result);
|
|
183
|
-
return result;
|
|
184
|
-
};
|
|
185
|
-
tx.delete = (key) => {
|
|
186
|
-
if (!oldMap.has(key)) {
|
|
187
|
-
const oldValue = this.get(key);
|
|
188
|
-
oldMap.set(key, oldValue === null ? void 0 : oldValue);
|
|
189
|
-
}
|
|
190
|
-
newMap.set(key, null);
|
|
191
|
-
this.delete(key);
|
|
192
|
-
return tx;
|
|
193
|
-
};
|
|
194
|
-
try {
|
|
195
|
-
callback(tx);
|
|
196
|
-
this.#db.exec("COMMIT;");
|
|
197
|
-
} catch (error) {
|
|
198
|
-
this.#db.exec("ROLLBACK;");
|
|
199
|
-
throw error;
|
|
200
|
-
}
|
|
201
|
-
return {
|
|
202
|
-
oldValues: Array.from(oldMap.entries()).map(([key, value]) => ({
|
|
203
|
-
key,
|
|
204
|
-
value
|
|
205
|
-
})),
|
|
206
|
-
newValues: Array.from(newMap.entries()).map(([key, value]) => ({
|
|
207
|
-
key,
|
|
208
|
-
value
|
|
209
|
-
}))
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
214
|
-
0 && (module.exports = {
|
|
215
|
-
KVSync,
|
|
216
|
-
journalModes
|
|
217
|
-
});
|