polystore 0.21.3 → 0.23.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/index.d.ts +11 -11
- package/index.js +189 -189
- package/package.json +70 -53
- package/readme.md +134 -59
- package/src/plugins/axios-cache-interceptor/index.d.ts +17 -0
- package/src/plugins/axios-cache-interceptor/index.js +49 -0
- package/src/plugins/better-auth/index.d.ts +18 -0
- package/src/plugins/better-auth/index.js +27 -0
- package/src/plugins/express/index.d.ts +20 -0
- package/src/{integrations/express.js → plugins/express/index.js} +3 -3
- package/src/plugins/hono-sessions/index.d.ts +15 -0
- package/src/{integrations/hono-sessions.js → plugins/hono-sessions/index.js} +3 -3
- package/src/integrations/express.d.ts +0 -307
- package/src/integrations/hono-sessions.d.ts +0 -299
package/index.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
1
|
+
// src/adapters/Adapter.ts
|
|
2
|
+
var Adapter = class {
|
|
3
3
|
TYPE;
|
|
4
4
|
HAS_EXPIRATION = false;
|
|
5
|
-
|
|
5
|
+
lib;
|
|
6
6
|
encode = (val) => JSON.stringify(val, null, 2);
|
|
7
7
|
decode = (val) => val ? JSON.parse(val) : null;
|
|
8
|
-
constructor(
|
|
9
|
-
this.
|
|
8
|
+
constructor(lib) {
|
|
9
|
+
this.lib = lib;
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
// src/
|
|
14
|
-
var Api = class extends
|
|
13
|
+
// src/adapters/api.ts
|
|
14
|
+
var Api = class extends Adapter {
|
|
15
15
|
TYPE = "API";
|
|
16
16
|
// Indicate that the file handler DOES handle expirations
|
|
17
17
|
HAS_EXPIRATION = true;
|
|
18
|
-
static test = (
|
|
18
|
+
static test = (raw) => typeof raw === "string" && /^https?:\/\//.test(raw);
|
|
19
19
|
#api = async (key, opts = "", method = "GET", body) => {
|
|
20
|
-
const url = `${this.
|
|
20
|
+
const url = `${this.lib.replace(/\/$/, "")}/${encodeURIComponent(key)}${opts}`;
|
|
21
21
|
const headers = {
|
|
22
22
|
accept: "application/json",
|
|
23
23
|
"content-type": "application/json"
|
|
@@ -45,14 +45,14 @@ var Api = class extends Client {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
// src/
|
|
49
|
-
var Cloudflare = class extends
|
|
48
|
+
// src/adapters/cloudflare.ts
|
|
49
|
+
var Cloudflare = class extends Adapter {
|
|
50
50
|
TYPE = "CLOUDFLARE";
|
|
51
51
|
// It handles expirations natively
|
|
52
52
|
HAS_EXPIRATION = true;
|
|
53
53
|
static testKeys = ["getWithMetadata", "get", "list", "delete"];
|
|
54
54
|
get = async (key) => {
|
|
55
|
-
const value = await this.
|
|
55
|
+
const value = await this.lib.get(key);
|
|
56
56
|
return this.decode(value);
|
|
57
57
|
};
|
|
58
58
|
set = async (key, data, expires) => {
|
|
@@ -60,15 +60,15 @@ var Cloudflare = class extends Client {
|
|
|
60
60
|
if (expirationTtl && expirationTtl < 60) {
|
|
61
61
|
throw new Error("Cloudflare's min expiration is '60s'");
|
|
62
62
|
}
|
|
63
|
-
await this.
|
|
63
|
+
await this.lib.put(key, this.encode(data), { expirationTtl });
|
|
64
64
|
};
|
|
65
|
-
del = (key) => this.
|
|
65
|
+
del = (key) => this.lib.delete(key);
|
|
66
66
|
// Since we have pagination, we don't want to get all of the
|
|
67
67
|
// keys at once if we can avoid it
|
|
68
68
|
async *iterate(prefix = "") {
|
|
69
69
|
let cursor;
|
|
70
70
|
do {
|
|
71
|
-
const raw = await this.
|
|
71
|
+
const raw = await this.lib.list({ prefix, cursor });
|
|
72
72
|
const keys = raw.keys.map((k) => k.name);
|
|
73
73
|
for (let key of keys) {
|
|
74
74
|
const value = await this.get(key);
|
|
@@ -81,7 +81,7 @@ var Cloudflare = class extends Client {
|
|
|
81
81
|
const keys = [];
|
|
82
82
|
let cursor;
|
|
83
83
|
do {
|
|
84
|
-
const raw = await this.
|
|
84
|
+
const raw = await this.lib.list({ prefix, cursor });
|
|
85
85
|
keys.push(...raw.keys.map((k) => k.name));
|
|
86
86
|
cursor = raw.list_complete ? void 0 : raw.cursor;
|
|
87
87
|
} while (cursor);
|
|
@@ -94,14 +94,14 @@ var Cloudflare = class extends Client {
|
|
|
94
94
|
};
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
-
// src/
|
|
98
|
-
var Cookie = class extends
|
|
97
|
+
// src/adapters/cookie.ts
|
|
98
|
+
var Cookie = class extends Adapter {
|
|
99
99
|
TYPE = "COOKIE";
|
|
100
100
|
// It handles expirations natively
|
|
101
101
|
HAS_EXPIRATION = true;
|
|
102
102
|
// Check if this is the right class for the given client
|
|
103
|
-
static test = (
|
|
104
|
-
return
|
|
103
|
+
static test = (raw) => {
|
|
104
|
+
return raw === "cookie" || raw === "cookies";
|
|
105
105
|
};
|
|
106
106
|
// Group methods
|
|
107
107
|
#read = () => {
|
|
@@ -141,35 +141,35 @@ var Cookie = class extends Client {
|
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
|
|
144
|
-
// src/
|
|
145
|
-
var Etcd = class extends
|
|
144
|
+
// src/adapters/etcd.ts
|
|
145
|
+
var Etcd = class extends Adapter {
|
|
146
146
|
TYPE = "ETCD3";
|
|
147
147
|
// It desn't handle expirations natively
|
|
148
148
|
HAS_EXPIRATION = false;
|
|
149
149
|
// Check if this is the right class for the given client
|
|
150
150
|
static testKeys = ["leaseClient", "watchClient", "watchManager"];
|
|
151
151
|
get = async (key) => {
|
|
152
|
-
const data = await this.
|
|
152
|
+
const data = await this.lib.get(key).json();
|
|
153
153
|
return data;
|
|
154
154
|
};
|
|
155
155
|
set = async (key, value) => {
|
|
156
|
-
await this.
|
|
156
|
+
await this.lib.put(key).value(this.encode(value));
|
|
157
157
|
};
|
|
158
|
-
del = (key) => this.
|
|
158
|
+
del = (key) => this.lib.delete().key(key).exec();
|
|
159
159
|
async *iterate(prefix = "") {
|
|
160
|
-
const keys = await this.
|
|
160
|
+
const keys = await this.lib.getAll().prefix(prefix).keys();
|
|
161
161
|
for (const key of keys) {
|
|
162
162
|
yield [key, await this.get(key)];
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
clear = async (prefix = "") => {
|
|
166
|
-
if (!prefix) return this.
|
|
167
|
-
return this.
|
|
166
|
+
if (!prefix) return this.lib.delete().all();
|
|
167
|
+
return this.lib.delete().prefix(prefix);
|
|
168
168
|
};
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
-
// src/
|
|
172
|
-
var File = class extends
|
|
171
|
+
// src/adapters/file.ts
|
|
172
|
+
var File = class extends Adapter {
|
|
173
173
|
TYPE = "FILE";
|
|
174
174
|
// It desn't handle expirations natively
|
|
175
175
|
HAS_EXPIRATION = false;
|
|
@@ -177,16 +177,16 @@ var File = class extends Client {
|
|
|
177
177
|
file = "";
|
|
178
178
|
#lock = Promise.resolve();
|
|
179
179
|
// Check if this is the right class for the given client
|
|
180
|
-
static test = (
|
|
181
|
-
if (
|
|
182
|
-
return typeof
|
|
180
|
+
static test = (raw) => {
|
|
181
|
+
if (raw instanceof URL) raw = raw.href;
|
|
182
|
+
return typeof raw === "string" && raw.startsWith("file://") && raw.endsWith(".json");
|
|
183
183
|
};
|
|
184
184
|
// We want to make sure the file already exists, so attempt to
|
|
185
185
|
// create the folders and the file (but not OVERWRITE it, that's why the x flag)
|
|
186
186
|
// It fails if it already exists, hence the catch case
|
|
187
187
|
promise = (async () => {
|
|
188
188
|
this.fsp = await import("fs/promises");
|
|
189
|
-
this.file = (this.
|
|
189
|
+
this.file = (this.lib?.href || this.lib).replace(/^file:\/\//, "");
|
|
190
190
|
const folder = this.file.split("/").slice(0, -1).join("/");
|
|
191
191
|
await this.fsp.mkdir(folder, { recursive: true }).catch(() => {
|
|
192
192
|
});
|
|
@@ -260,27 +260,27 @@ var File = class extends Client {
|
|
|
260
260
|
};
|
|
261
261
|
};
|
|
262
262
|
|
|
263
|
-
// src/
|
|
263
|
+
// src/adapters/folder.ts
|
|
264
264
|
var noFileOk = (error) => {
|
|
265
265
|
if (error.code === "ENOENT") return null;
|
|
266
266
|
throw error;
|
|
267
267
|
};
|
|
268
|
-
var Folder = class extends
|
|
268
|
+
var Folder = class extends Adapter {
|
|
269
269
|
TYPE = "FOLDER";
|
|
270
270
|
// It desn't handle expirations natively
|
|
271
271
|
HAS_EXPIRATION = false;
|
|
272
272
|
fsp;
|
|
273
273
|
folder;
|
|
274
274
|
// Check if this is the right class for the given client
|
|
275
|
-
static test = (
|
|
276
|
-
if (
|
|
277
|
-
return typeof
|
|
275
|
+
static test = (raw) => {
|
|
276
|
+
if (raw instanceof URL) raw = raw.href;
|
|
277
|
+
return typeof raw === "string" && raw.startsWith("file://") && raw.endsWith("/");
|
|
278
278
|
};
|
|
279
279
|
// Make sure the folder already exists, so attempt to create it
|
|
280
280
|
// It fails if it already exists, hence the catch case
|
|
281
281
|
promise = (async () => {
|
|
282
282
|
this.fsp = await import("fs/promises");
|
|
283
|
-
this.folder = (this.
|
|
283
|
+
this.folder = (this.lib?.href || this.lib).replace(/^file:\/\//, "");
|
|
284
284
|
await this.fsp.mkdir(this.folder, { recursive: true }).catch(() => {
|
|
285
285
|
});
|
|
286
286
|
})();
|
|
@@ -310,18 +310,18 @@ var Folder = class extends Client {
|
|
|
310
310
|
}
|
|
311
311
|
};
|
|
312
312
|
|
|
313
|
-
// src/
|
|
314
|
-
var Forage = class extends
|
|
313
|
+
// src/adapters/forage.ts
|
|
314
|
+
var Forage = class extends Adapter {
|
|
315
315
|
TYPE = "FORAGE";
|
|
316
316
|
// It desn't handle expirations natively
|
|
317
317
|
HAS_EXPIRATION = false;
|
|
318
318
|
// Check if this is the right class for the given client
|
|
319
|
-
static test = (
|
|
320
|
-
get = (key) => this.
|
|
321
|
-
set = (key, value) => this.
|
|
322
|
-
del = (key) => this.
|
|
319
|
+
static test = (raw) => raw?.defineDriver && raw?.dropInstance && raw?.INDEXEDDB;
|
|
320
|
+
get = (key) => this.lib.getItem(key);
|
|
321
|
+
set = (key, value) => this.lib.setItem(key, value);
|
|
322
|
+
del = (key) => this.lib.removeItem(key);
|
|
323
323
|
async *iterate(prefix = "") {
|
|
324
|
-
const keys = await this.
|
|
324
|
+
const keys = await this.lib.keys();
|
|
325
325
|
const list = keys.filter((k) => k.startsWith(prefix));
|
|
326
326
|
for (const key of list) {
|
|
327
327
|
const value = await this.get(key);
|
|
@@ -331,38 +331,38 @@ var Forage = class extends Client {
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
entries = async (prefix = "") => {
|
|
334
|
-
const all = await this.
|
|
334
|
+
const all = await this.lib.keys();
|
|
335
335
|
const keys = all.filter((k) => k.startsWith(prefix));
|
|
336
336
|
const values = await Promise.all(keys.map((key) => this.get(key)));
|
|
337
337
|
return keys.map((key, i) => [key, values[i]]);
|
|
338
338
|
};
|
|
339
|
-
clearAll = () => this.
|
|
339
|
+
clearAll = () => this.lib.clear();
|
|
340
340
|
};
|
|
341
341
|
|
|
342
|
-
// src/
|
|
342
|
+
// src/adapters/level.ts
|
|
343
343
|
var valueEncoding = "json";
|
|
344
344
|
var notFound = (error) => {
|
|
345
345
|
if (error?.code === "LEVEL_NOT_FOUND") return null;
|
|
346
346
|
throw error;
|
|
347
347
|
};
|
|
348
|
-
var Level = class extends
|
|
348
|
+
var Level = class extends Adapter {
|
|
349
349
|
TYPE = "LEVEL";
|
|
350
350
|
// It desn't handle expirations natively
|
|
351
351
|
HAS_EXPIRATION = false;
|
|
352
352
|
// Check if this is the right class for the given client
|
|
353
353
|
static testKeys = ["attachResource", "detachResource", "prependOnceListener"];
|
|
354
|
-
get = (key) => this.
|
|
355
|
-
set = (key, value) => this.
|
|
356
|
-
del = (key) => this.
|
|
354
|
+
get = (key) => this.lib.get(key, { valueEncoding }).catch(notFound);
|
|
355
|
+
set = (key, value) => this.lib.put(key, value, { valueEncoding });
|
|
356
|
+
del = (key) => this.lib.del(key);
|
|
357
357
|
async *iterate(prefix = "") {
|
|
358
|
-
const keys = await this.
|
|
358
|
+
const keys = await this.lib.keys().all();
|
|
359
359
|
const list = keys.filter((k) => k.startsWith(prefix));
|
|
360
360
|
for (const key of list) {
|
|
361
361
|
yield [key, await this.get(key)];
|
|
362
362
|
}
|
|
363
363
|
}
|
|
364
364
|
entries = async (prefix = "") => {
|
|
365
|
-
const keys = await this.
|
|
365
|
+
const keys = await this.lib.keys().all();
|
|
366
366
|
const list = keys.filter((k) => k.startsWith(prefix));
|
|
367
367
|
return Promise.all(
|
|
368
368
|
list.map(async (k) => [k, await this.get(k)])
|
|
@@ -370,37 +370,37 @@ var Level = class extends Client {
|
|
|
370
370
|
};
|
|
371
371
|
clear = async (prefix = "") => {
|
|
372
372
|
if (!prefix) {
|
|
373
|
-
return await this.
|
|
373
|
+
return await this.lib.clear();
|
|
374
374
|
}
|
|
375
|
-
const keys = await this.
|
|
375
|
+
const keys = await this.lib.keys().all();
|
|
376
376
|
const list = keys.filter((k) => k.startsWith(prefix));
|
|
377
|
-
return this.
|
|
377
|
+
return this.lib.batch(
|
|
378
378
|
list.map((key) => ({ type: "del", key }))
|
|
379
379
|
);
|
|
380
380
|
};
|
|
381
|
-
close = () => this.
|
|
381
|
+
close = () => this.lib.close();
|
|
382
382
|
};
|
|
383
383
|
|
|
384
|
-
// src/
|
|
385
|
-
var Memory = class extends
|
|
384
|
+
// src/adapters/memory.ts
|
|
385
|
+
var Memory = class extends Adapter {
|
|
386
386
|
TYPE = "MEMORY";
|
|
387
387
|
// It desn't handle expirations natively
|
|
388
388
|
HAS_EXPIRATION = false;
|
|
389
389
|
// Check if this is the right class for the given client
|
|
390
|
-
static test = (
|
|
391
|
-
get = (key) => this.
|
|
392
|
-
set = (key, data) => this.
|
|
393
|
-
del = (key) => this.
|
|
390
|
+
static test = (raw) => raw instanceof Map;
|
|
391
|
+
get = (key) => this.lib.get(key) ?? null;
|
|
392
|
+
set = (key, data) => this.lib.set(key, data);
|
|
393
|
+
del = (key) => this.lib.delete(key);
|
|
394
394
|
*iterate(prefix = "") {
|
|
395
|
-
for (const entry of this.
|
|
395
|
+
for (const entry of this.lib.entries()) {
|
|
396
396
|
if (entry[0].startsWith(prefix)) yield entry;
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
|
-
clearAll = () => this.
|
|
399
|
+
clearAll = () => this.lib.clear();
|
|
400
400
|
};
|
|
401
401
|
|
|
402
|
-
// src/
|
|
403
|
-
var Postgres = class extends
|
|
402
|
+
// src/adapters/postgres.ts
|
|
403
|
+
var Postgres = class extends Adapter {
|
|
404
404
|
TYPE = "POSTGRES";
|
|
405
405
|
// This one is doing manual time management internally even though
|
|
406
406
|
// sqlite does not natively support expirations. This is because it does
|
|
@@ -414,22 +414,22 @@ var Postgres = class extends Client {
|
|
|
414
414
|
if (!/^[a-zA-Z_]+$/.test(this.table)) {
|
|
415
415
|
throw new Error(`Invalid table name ${this.table}`);
|
|
416
416
|
}
|
|
417
|
-
await this.
|
|
417
|
+
await this.lib.query(`
|
|
418
418
|
CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
419
419
|
id TEXT PRIMARY KEY,
|
|
420
420
|
value TEXT NOT NULL,
|
|
421
421
|
expires_at TIMESTAMPTZ
|
|
422
422
|
)
|
|
423
423
|
`);
|
|
424
|
-
await this.
|
|
424
|
+
await this.lib.query(
|
|
425
425
|
`CREATE INDEX IF NOT EXISTS idx_${this.table}_expires_at ON ${this.table} (expires_at)`
|
|
426
426
|
);
|
|
427
427
|
})();
|
|
428
|
-
static test = (
|
|
429
|
-
return
|
|
428
|
+
static test = (raw) => {
|
|
429
|
+
return raw && raw.query && !raw.filename;
|
|
430
430
|
};
|
|
431
431
|
get = async (id) => {
|
|
432
|
-
const result = await this.
|
|
432
|
+
const result = await this.lib.query(
|
|
433
433
|
`SELECT value
|
|
434
434
|
FROM ${this.table}
|
|
435
435
|
WHERE id = $1 AND (expires_at IS NULL OR expires_at > NOW())`,
|
|
@@ -441,7 +441,7 @@ var Postgres = class extends Client {
|
|
|
441
441
|
set = async (id, data, expires) => {
|
|
442
442
|
const value = this.encode(data);
|
|
443
443
|
const expires_at = expires ? new Date(Date.now() + expires * 1e3) : null;
|
|
444
|
-
await this.
|
|
444
|
+
await this.lib.query(
|
|
445
445
|
`INSERT INTO ${this.table} (id, value, expires_at)
|
|
446
446
|
VALUES ($1, $2, $3)
|
|
447
447
|
ON CONFLICT (id) DO UPDATE
|
|
@@ -450,10 +450,10 @@ var Postgres = class extends Client {
|
|
|
450
450
|
);
|
|
451
451
|
};
|
|
452
452
|
del = async (id) => {
|
|
453
|
-
await this.
|
|
453
|
+
await this.lib.query(`DELETE FROM ${this.table} WHERE id = $1`, [id]);
|
|
454
454
|
};
|
|
455
455
|
async *iterate(prefix = "") {
|
|
456
|
-
const result = await this.
|
|
456
|
+
const result = await this.lib.query(
|
|
457
457
|
`SELECT id, value FROM ${this.table}
|
|
458
458
|
WHERE (expires_at IS NULL OR expires_at > NOW()) ${prefix ? `AND id LIKE $1` : ""}`,
|
|
459
459
|
prefix ? [`${prefix}%`] : []
|
|
@@ -463,7 +463,7 @@ var Postgres = class extends Client {
|
|
|
463
463
|
}
|
|
464
464
|
}
|
|
465
465
|
async keys(prefix = "") {
|
|
466
|
-
const result = await this.
|
|
466
|
+
const result = await this.lib.query(
|
|
467
467
|
`SELECT id FROM ${this.table}
|
|
468
468
|
WHERE (expires_at IS NULL OR expires_at > NOW())
|
|
469
469
|
${prefix ? `AND id LIKE $1` : ""}`,
|
|
@@ -472,42 +472,42 @@ var Postgres = class extends Client {
|
|
|
472
472
|
return result.rows.map((r) => r.id);
|
|
473
473
|
}
|
|
474
474
|
prune = async () => {
|
|
475
|
-
await this.
|
|
475
|
+
await this.lib.query(
|
|
476
476
|
`DELETE FROM ${this.table}
|
|
477
477
|
WHERE expires_at IS NOT NULL AND expires_at <= NOW()`
|
|
478
478
|
);
|
|
479
479
|
};
|
|
480
480
|
clear = async (prefix = "") => {
|
|
481
|
-
await this.
|
|
481
|
+
await this.lib.query(
|
|
482
482
|
`DELETE FROM ${this.table} ${prefix ? `WHERE id LIKE $1` : ""}`,
|
|
483
483
|
prefix ? [`${prefix}%`] : []
|
|
484
484
|
);
|
|
485
485
|
};
|
|
486
486
|
close = async () => {
|
|
487
|
-
if (this.
|
|
488
|
-
await this.
|
|
487
|
+
if (this.lib.end) {
|
|
488
|
+
await this.lib.end();
|
|
489
489
|
}
|
|
490
490
|
};
|
|
491
491
|
};
|
|
492
492
|
|
|
493
|
-
// src/
|
|
494
|
-
var Redis = class extends
|
|
493
|
+
// src/adapters/redis.ts
|
|
494
|
+
var Redis = class extends Adapter {
|
|
495
495
|
TYPE = "REDIS";
|
|
496
496
|
// Indicate if this client handles expirations (true = it does)
|
|
497
497
|
HAS_EXPIRATION = true;
|
|
498
498
|
// Check if this is the right class for the given client
|
|
499
|
-
static test = (
|
|
500
|
-
get = async (key) => this.decode(await this.
|
|
499
|
+
static test = (raw) => raw && raw.pSubscribe && raw.sSubscribe;
|
|
500
|
+
get = async (key) => this.decode(await this.lib.get(key));
|
|
501
501
|
set = async (key, value, expires) => {
|
|
502
502
|
const EX = expires ? Math.round(expires) : void 0;
|
|
503
|
-
return this.
|
|
503
|
+
return this.lib.set(key, this.encode(value), { EX });
|
|
504
504
|
};
|
|
505
|
-
del = (key) => this.
|
|
506
|
-
has = async (key) => Boolean(await this.
|
|
505
|
+
del = (key) => this.lib.del(key);
|
|
506
|
+
has = async (key) => Boolean(await this.lib.exists(key));
|
|
507
507
|
// Go through each of the [key, value] in the set
|
|
508
508
|
async *iterate(prefix = "") {
|
|
509
509
|
const MATCH = prefix + "*";
|
|
510
|
-
for await (const key of this.
|
|
510
|
+
for await (const key of this.lib.scanIterator({ MATCH })) {
|
|
511
511
|
const keys = typeof key === "string" ? [key] : key;
|
|
512
512
|
for (const key2 of keys) {
|
|
513
513
|
const value = await this.get(key2);
|
|
@@ -521,7 +521,7 @@ var Redis = class extends Client {
|
|
|
521
521
|
keys = async (prefix = "") => {
|
|
522
522
|
const MATCH = prefix + "*";
|
|
523
523
|
const keys = [];
|
|
524
|
-
for await (const key of this.
|
|
524
|
+
for await (const key of this.lib.scanIterator({ MATCH })) {
|
|
525
525
|
keys.push(...typeof key === "string" ? [key] : key);
|
|
526
526
|
}
|
|
527
527
|
return keys;
|
|
@@ -533,12 +533,12 @@ var Redis = class extends Client {
|
|
|
533
533
|
const values = await Promise.all(keys.map((k) => this.get(k)));
|
|
534
534
|
return keys.map((k, i) => [k, values[i]]);
|
|
535
535
|
};
|
|
536
|
-
clearAll = () => this.
|
|
537
|
-
close = () => this.
|
|
536
|
+
clearAll = () => this.lib.flushAll();
|
|
537
|
+
close = () => this.lib.quit();
|
|
538
538
|
};
|
|
539
539
|
|
|
540
|
-
// src/
|
|
541
|
-
var SQLite = class extends
|
|
540
|
+
// src/adapters/sqlite.ts
|
|
541
|
+
var SQLite = class extends Adapter {
|
|
542
542
|
TYPE = "SQLITE";
|
|
543
543
|
// This one is doing manual time management internally even though
|
|
544
544
|
// sqlite does not natively support expirations. This is because it does
|
|
@@ -553,22 +553,22 @@ var SQLite = class extends Client {
|
|
|
553
553
|
if (!/^[a-zA-Z_]+$/.test(this.table)) {
|
|
554
554
|
throw new Error(`Invalid table name ${this.table}`);
|
|
555
555
|
}
|
|
556
|
-
this.
|
|
556
|
+
this.lib.exec(`
|
|
557
557
|
CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
558
558
|
id TEXT PRIMARY KEY,
|
|
559
559
|
value TEXT NOT NULL,
|
|
560
560
|
expires_at INTEGER
|
|
561
561
|
)
|
|
562
562
|
`);
|
|
563
|
-
this.
|
|
563
|
+
this.lib.exec(
|
|
564
564
|
`CREATE INDEX IF NOT EXISTS idx_${this.table}_expires_at ON ${this.table} (expires_at)`
|
|
565
565
|
);
|
|
566
566
|
})();
|
|
567
|
-
static test = (
|
|
568
|
-
return typeof
|
|
567
|
+
static test = (raw) => {
|
|
568
|
+
return typeof raw?.prepare === "function" && typeof raw?.exec === "function";
|
|
569
569
|
};
|
|
570
570
|
get = (id) => {
|
|
571
|
-
const value = this.
|
|
571
|
+
const value = this.lib.prepare(
|
|
572
572
|
`SELECT value, expires_at FROM kv WHERE id = ? AND (expires_at IS NULL OR expires_at > ?)`
|
|
573
573
|
).get(id, Date.now())?.value;
|
|
574
574
|
if (!value) return null;
|
|
@@ -577,15 +577,15 @@ var SQLite = class extends Client {
|
|
|
577
577
|
set = (id, data, expires) => {
|
|
578
578
|
const value = this.encode(data);
|
|
579
579
|
const expires_at = expires ? Date.now() + expires * 1e3 : null;
|
|
580
|
-
this.
|
|
580
|
+
this.lib.prepare(
|
|
581
581
|
`INSERT INTO kv (id, value, expires_at) VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET value = excluded.value, expires_at = excluded.expires_at`
|
|
582
582
|
).run(id, value, expires_at);
|
|
583
583
|
};
|
|
584
584
|
del = (id) => {
|
|
585
|
-
this.
|
|
585
|
+
this.lib.prepare(`DELETE FROM kv WHERE id = ?`).run(id);
|
|
586
586
|
};
|
|
587
587
|
has = (id) => {
|
|
588
|
-
const row = this.
|
|
588
|
+
const row = this.lib.prepare(`SELECT expires_at FROM kv WHERE id = ?`).get(id);
|
|
589
589
|
if (!row) return false;
|
|
590
590
|
if (row.expires_at && row.expires_at < Date.now()) {
|
|
591
591
|
this.del(id);
|
|
@@ -597,7 +597,7 @@ var SQLite = class extends Client {
|
|
|
597
597
|
const sql = `SELECT id, value FROM kv WHERE (expires_at IS NULL OR expires_at > ?) ${prefix ? "AND id LIKE ?" : ""}
|
|
598
598
|
`;
|
|
599
599
|
const params = prefix ? [Date.now(), `${prefix}%`] : [Date.now()];
|
|
600
|
-
for (const row of this.
|
|
600
|
+
for (const row of this.lib.prepare(sql).all(...params)) {
|
|
601
601
|
yield [row.id, this.decode(row.value)];
|
|
602
602
|
}
|
|
603
603
|
}
|
|
@@ -606,41 +606,41 @@ var SQLite = class extends Client {
|
|
|
606
606
|
${prefix ? "AND id LIKE ?" : ""}
|
|
607
607
|
`;
|
|
608
608
|
const params = prefix ? [Date.now(), `${prefix}%`] : [Date.now()];
|
|
609
|
-
const rows = this.
|
|
609
|
+
const rows = this.lib.prepare(sql).all(...params);
|
|
610
610
|
return rows.map((r) => r.id);
|
|
611
611
|
};
|
|
612
612
|
prune = () => {
|
|
613
|
-
this.
|
|
613
|
+
this.lib.prepare(`DELETE FROM kv WHERE expires_at <= ?`).run(Date.now());
|
|
614
614
|
};
|
|
615
615
|
clear = (prefix = "") => {
|
|
616
616
|
if (!prefix) {
|
|
617
|
-
this.
|
|
617
|
+
this.lib.prepare(`DELETE FROM ${this.table}`).run();
|
|
618
618
|
return;
|
|
619
619
|
}
|
|
620
|
-
this.
|
|
620
|
+
this.lib.prepare(`DELETE FROM ${this.table} WHERE id LIKE ?`).run(`${prefix}%`);
|
|
621
621
|
};
|
|
622
622
|
close = () => {
|
|
623
|
-
this.
|
|
623
|
+
this.lib.close?.();
|
|
624
624
|
};
|
|
625
625
|
};
|
|
626
626
|
|
|
627
|
-
// src/
|
|
628
|
-
var WebStorage = class extends
|
|
627
|
+
// src/adapters/storage.ts
|
|
628
|
+
var WebStorage = class extends Adapter {
|
|
629
629
|
TYPE = "STORAGE";
|
|
630
630
|
// It desn't handle expirations natively
|
|
631
631
|
HAS_EXPIRATION = false;
|
|
632
632
|
// Check if this is the right class for the given client
|
|
633
|
-
static test(
|
|
633
|
+
static test(raw) {
|
|
634
634
|
if (typeof Storage === "undefined") return false;
|
|
635
|
-
return
|
|
635
|
+
return raw instanceof Storage;
|
|
636
636
|
}
|
|
637
637
|
// Item methods
|
|
638
|
-
get = (key) => this.decode(this.
|
|
639
|
-
set = (key, data) => this.
|
|
640
|
-
del = (key) => this.
|
|
638
|
+
get = (key) => this.decode(this.lib.getItem(key));
|
|
639
|
+
set = (key, data) => this.lib.setItem(key, this.encode(data));
|
|
640
|
+
del = (key) => this.lib.removeItem(key);
|
|
641
641
|
*iterate(prefix = "") {
|
|
642
|
-
for (let i = 0; i < this.
|
|
643
|
-
const key = this.
|
|
642
|
+
for (let i = 0; i < this.lib.length; i++) {
|
|
643
|
+
const key = this.lib.key(i);
|
|
644
644
|
if (!key || !key.startsWith(prefix)) continue;
|
|
645
645
|
const value = this.get(key);
|
|
646
646
|
if (value !== null && value !== void 0) {
|
|
@@ -648,11 +648,11 @@ var WebStorage = class extends Client {
|
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
}
|
|
651
|
-
clearAll = () => this.
|
|
651
|
+
clearAll = () => this.lib.clear();
|
|
652
652
|
};
|
|
653
653
|
|
|
654
|
-
// src/
|
|
655
|
-
var
|
|
654
|
+
// src/adapters/index.ts
|
|
655
|
+
var adapters_default = {
|
|
656
656
|
api: Api,
|
|
657
657
|
cloudflare: Cloudflare,
|
|
658
658
|
cookie: Cookie,
|
|
@@ -709,32 +709,32 @@ var Store = class _Store {
|
|
|
709
709
|
PREFIX = "";
|
|
710
710
|
EXPIRES = null;
|
|
711
711
|
promise;
|
|
712
|
-
|
|
712
|
+
adapter;
|
|
713
713
|
type = "UNKNOWN";
|
|
714
|
-
constructor(
|
|
714
|
+
constructor(adapterInput = /* @__PURE__ */ new Map(), options = {
|
|
715
715
|
prefix: "",
|
|
716
716
|
expires: null
|
|
717
717
|
}) {
|
|
718
718
|
this.PREFIX = options.prefix || "";
|
|
719
719
|
this.EXPIRES = parse(options.expires || null);
|
|
720
|
-
this.promise = Promise.resolve(
|
|
721
|
-
this.
|
|
722
|
-
this.#validate(this.
|
|
720
|
+
this.promise = Promise.resolve(adapterInput).then(async (raw) => {
|
|
721
|
+
this.adapter = this.#find(raw);
|
|
722
|
+
this.#validate(this.adapter);
|
|
723
723
|
this.promise = null;
|
|
724
|
-
await this.
|
|
725
|
-
this.type = this.
|
|
726
|
-
return
|
|
724
|
+
await this.adapter.promise;
|
|
725
|
+
this.type = this.adapter?.TYPE || this.type;
|
|
726
|
+
return raw;
|
|
727
727
|
});
|
|
728
728
|
}
|
|
729
729
|
#find(store) {
|
|
730
|
-
if (store instanceof _Store) return store.
|
|
731
|
-
for (let
|
|
732
|
-
if ("test" in
|
|
733
|
-
return new
|
|
730
|
+
if (store instanceof _Store) return store.adapter;
|
|
731
|
+
for (let A of Object.values(adapters_default)) {
|
|
732
|
+
if ("test" in A && A.test(store)) {
|
|
733
|
+
return new A(store);
|
|
734
734
|
}
|
|
735
|
-
if ("testKeys" in
|
|
736
|
-
if (
|
|
737
|
-
return new
|
|
735
|
+
if ("testKeys" in A && typeof store === "object") {
|
|
736
|
+
if (A.testKeys.every((key) => store[key])) {
|
|
737
|
+
return new A(store);
|
|
738
738
|
}
|
|
739
739
|
}
|
|
740
740
|
}
|
|
@@ -743,15 +743,15 @@ var Store = class _Store {
|
|
|
743
743
|
}
|
|
744
744
|
return store;
|
|
745
745
|
}
|
|
746
|
-
#validate(
|
|
747
|
-
if (!
|
|
748
|
-
if (!
|
|
749
|
-
throw new Error("
|
|
746
|
+
#validate(adapter) {
|
|
747
|
+
if (!adapter) throw new Error("No adapter received");
|
|
748
|
+
if (!adapter.set || !adapter.get || !adapter.iterate) {
|
|
749
|
+
throw new Error("Adapter should have .get(), .set() and .iterate()");
|
|
750
750
|
}
|
|
751
|
-
if (
|
|
751
|
+
if (adapter.HAS_EXPIRATION) return;
|
|
752
752
|
for (let method of ["has", "keys", "values"]) {
|
|
753
|
-
if (
|
|
754
|
-
const msg = `You can only define
|
|
753
|
+
if (adapter[method]) {
|
|
754
|
+
const msg = `You can only define adapter.${method}() when the adapter manages the expiration.`;
|
|
755
755
|
throw new Error(msg);
|
|
756
756
|
}
|
|
757
757
|
}
|
|
@@ -771,11 +771,11 @@ var Store = class _Store {
|
|
|
771
771
|
await this.promise;
|
|
772
772
|
const expires = this.#expiration(options?.expires);
|
|
773
773
|
const prefix = options?.prefix || this.PREFIX;
|
|
774
|
-
if (this.
|
|
775
|
-
if (this.
|
|
776
|
-
return this.
|
|
774
|
+
if (this.adapter.add) {
|
|
775
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
776
|
+
return this.adapter.add(prefix, value, expires);
|
|
777
777
|
}
|
|
778
|
-
return this.
|
|
778
|
+
return this.adapter.add(prefix, { expires: unix(expires), value });
|
|
779
779
|
}
|
|
780
780
|
return this.set(createId(), value, { prefix, expires });
|
|
781
781
|
}
|
|
@@ -787,22 +787,22 @@ var Store = class _Store {
|
|
|
787
787
|
if (value === null || typeof expires === "number" && expires <= 0) {
|
|
788
788
|
return this.del(key);
|
|
789
789
|
}
|
|
790
|
-
if (this.
|
|
791
|
-
await this.
|
|
790
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
791
|
+
await this.adapter.set(id, value, expires);
|
|
792
792
|
return key;
|
|
793
793
|
}
|
|
794
|
-
await this.
|
|
794
|
+
await this.adapter.set(id, { expires: unix(expires), value });
|
|
795
795
|
return key;
|
|
796
796
|
}
|
|
797
797
|
async get(key) {
|
|
798
798
|
await this.promise;
|
|
799
799
|
const id = this.PREFIX + key;
|
|
800
|
-
if (this.
|
|
801
|
-
const data = await this.
|
|
800
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
801
|
+
const data = await this.adapter.get(id) ?? null;
|
|
802
802
|
if (data === null) return null;
|
|
803
803
|
return data;
|
|
804
804
|
} else {
|
|
805
|
-
const data = await this.
|
|
805
|
+
const data = await this.adapter.get(id) ?? null;
|
|
806
806
|
if (data === null) return null;
|
|
807
807
|
if (!this.#isFresh(data, key)) return null;
|
|
808
808
|
return data.value;
|
|
@@ -827,8 +827,8 @@ var Store = class _Store {
|
|
|
827
827
|
async has(key) {
|
|
828
828
|
await this.promise;
|
|
829
829
|
const id = this.PREFIX + key;
|
|
830
|
-
if (this.
|
|
831
|
-
return this.
|
|
830
|
+
if (this.adapter.has) {
|
|
831
|
+
return this.adapter.has(id);
|
|
832
832
|
}
|
|
833
833
|
return await this.get(key) !== null;
|
|
834
834
|
}
|
|
@@ -844,14 +844,14 @@ var Store = class _Store {
|
|
|
844
844
|
async del(key) {
|
|
845
845
|
await this.promise;
|
|
846
846
|
const id = this.PREFIX + key;
|
|
847
|
-
if (this.
|
|
848
|
-
await this.
|
|
847
|
+
if (this.adapter.del) {
|
|
848
|
+
await this.adapter.del(id);
|
|
849
849
|
return key;
|
|
850
850
|
}
|
|
851
|
-
if (this.
|
|
852
|
-
await this.
|
|
851
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
852
|
+
await this.adapter.set(id, null, 0);
|
|
853
853
|
} else {
|
|
854
|
-
await this.
|
|
854
|
+
await this.adapter.set(id, null);
|
|
855
855
|
}
|
|
856
856
|
return key;
|
|
857
857
|
}
|
|
@@ -870,14 +870,14 @@ var Store = class _Store {
|
|
|
870
870
|
}
|
|
871
871
|
async *[Symbol.asyncIterator]() {
|
|
872
872
|
await this.promise;
|
|
873
|
-
if (this.
|
|
874
|
-
for await (const [name, data] of this.
|
|
873
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
874
|
+
for await (const [name, data] of this.adapter.iterate(this.PREFIX)) {
|
|
875
875
|
const key = name.slice(this.PREFIX.length);
|
|
876
876
|
yield [key, data];
|
|
877
877
|
}
|
|
878
878
|
return;
|
|
879
879
|
}
|
|
880
|
-
for await (const [name, data] of this.
|
|
880
|
+
for await (const [name, data] of this.adapter.iterate(this.PREFIX)) {
|
|
881
881
|
const key = name.slice(this.PREFIX.length);
|
|
882
882
|
if (this.#isFresh(data, key)) {
|
|
883
883
|
yield [key, data.value];
|
|
@@ -887,24 +887,24 @@ var Store = class _Store {
|
|
|
887
887
|
async entries() {
|
|
888
888
|
await this.promise;
|
|
889
889
|
const trim = (key) => key.slice(this.PREFIX.length);
|
|
890
|
-
if (this.
|
|
891
|
-
if (this.
|
|
892
|
-
const entries = await this.
|
|
890
|
+
if (this.adapter.entries) {
|
|
891
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
892
|
+
const entries = await this.adapter.entries(this.PREFIX);
|
|
893
893
|
return entries.map(([k, v]) => [trim(k), v]);
|
|
894
894
|
} else {
|
|
895
|
-
const entries = await this.
|
|
895
|
+
const entries = await this.adapter.entries(this.PREFIX);
|
|
896
896
|
return entries.map(([k, v]) => [trim(k), v]).filter(([key, data]) => this.#isFresh(data, key)).map(([key, data]) => [key, data.value]);
|
|
897
897
|
}
|
|
898
898
|
}
|
|
899
|
-
if (this.
|
|
899
|
+
if (this.adapter.HAS_EXPIRATION) {
|
|
900
900
|
const list = [];
|
|
901
|
-
for await (const [k, v] of this.
|
|
901
|
+
for await (const [k, v] of this.adapter.iterate(this.PREFIX)) {
|
|
902
902
|
list.push([trim(k), v]);
|
|
903
903
|
}
|
|
904
904
|
return list;
|
|
905
905
|
} else {
|
|
906
906
|
const list = [];
|
|
907
|
-
for await (const [k, data] of this.
|
|
907
|
+
for await (const [k, data] of this.adapter.iterate(this.PREFIX)) {
|
|
908
908
|
if (this.#isFresh(data, trim(k))) {
|
|
909
909
|
list.push([trim(k), data.value]);
|
|
910
910
|
}
|
|
@@ -927,8 +927,8 @@ var Store = class _Store {
|
|
|
927
927
|
*/
|
|
928
928
|
async keys() {
|
|
929
929
|
await this.promise;
|
|
930
|
-
if (this.
|
|
931
|
-
const list = await this.
|
|
930
|
+
if (this.adapter.keys) {
|
|
931
|
+
const list = await this.adapter.keys(this.PREFIX);
|
|
932
932
|
if (!this.PREFIX) return list;
|
|
933
933
|
return list.map((k) => k.slice(this.PREFIX.length));
|
|
934
934
|
}
|
|
@@ -937,9 +937,9 @@ var Store = class _Store {
|
|
|
937
937
|
}
|
|
938
938
|
async values() {
|
|
939
939
|
await this.promise;
|
|
940
|
-
if (this.
|
|
941
|
-
if (this.
|
|
942
|
-
const list = await this.
|
|
940
|
+
if (this.adapter.values) {
|
|
941
|
+
if (this.adapter.HAS_EXPIRATION) return this.adapter.values(this.PREFIX);
|
|
942
|
+
const list = await this.adapter.values(this.PREFIX);
|
|
943
943
|
return list.filter((data) => this.#isFresh(data)).map((data) => data.value);
|
|
944
944
|
}
|
|
945
945
|
const entries = await this.entries();
|
|
@@ -966,7 +966,7 @@ var Store = class _Store {
|
|
|
966
966
|
*/
|
|
967
967
|
prefix(prefix = "") {
|
|
968
968
|
const store = new _Store(
|
|
969
|
-
Promise.resolve(this.promise).then(() => this.
|
|
969
|
+
Promise.resolve(this.promise).then(() => this.adapter)
|
|
970
970
|
);
|
|
971
971
|
store.PREFIX = this.PREFIX + prefix;
|
|
972
972
|
store.EXPIRES = this.EXPIRES;
|
|
@@ -989,7 +989,7 @@ var Store = class _Store {
|
|
|
989
989
|
*/
|
|
990
990
|
expires(expires = null) {
|
|
991
991
|
const store = new _Store(
|
|
992
|
-
Promise.resolve(this.promise).then(() => this.
|
|
992
|
+
Promise.resolve(this.promise).then(() => this.adapter)
|
|
993
993
|
);
|
|
994
994
|
store.EXPIRES = parse(expires);
|
|
995
995
|
store.PREFIX = this.PREFIX;
|
|
@@ -1008,11 +1008,11 @@ var Store = class _Store {
|
|
|
1008
1008
|
*/
|
|
1009
1009
|
async clear() {
|
|
1010
1010
|
await this.promise;
|
|
1011
|
-
if (!this.PREFIX && this.
|
|
1012
|
-
return this.
|
|
1011
|
+
if (!this.PREFIX && this.adapter.clearAll) {
|
|
1012
|
+
return this.adapter.clearAll();
|
|
1013
1013
|
}
|
|
1014
|
-
if (this.
|
|
1015
|
-
return this.
|
|
1014
|
+
if (this.adapter.clear) {
|
|
1015
|
+
return this.adapter.clear(this.PREFIX);
|
|
1016
1016
|
}
|
|
1017
1017
|
const keys = await this.keys();
|
|
1018
1018
|
await Promise.all(keys.map((key) => this.del(key)));
|
|
@@ -1028,9 +1028,9 @@ var Store = class _Store {
|
|
|
1028
1028
|
*/
|
|
1029
1029
|
async prune() {
|
|
1030
1030
|
await this.promise;
|
|
1031
|
-
if (this.
|
|
1032
|
-
if (this.
|
|
1033
|
-
await this.
|
|
1031
|
+
if (this.adapter.HAS_EXPIRATION) return;
|
|
1032
|
+
if (this.adapter.prune) {
|
|
1033
|
+
await this.adapter.prune();
|
|
1034
1034
|
}
|
|
1035
1035
|
}
|
|
1036
1036
|
/**
|
|
@@ -1046,13 +1046,13 @@ var Store = class _Store {
|
|
|
1046
1046
|
*/
|
|
1047
1047
|
async close() {
|
|
1048
1048
|
await this.promise;
|
|
1049
|
-
if (this.
|
|
1050
|
-
return this.
|
|
1049
|
+
if (this.adapter.close) {
|
|
1050
|
+
return this.adapter.close();
|
|
1051
1051
|
}
|
|
1052
1052
|
}
|
|
1053
1053
|
};
|
|
1054
|
-
function createStore(
|
|
1055
|
-
return new Store(
|
|
1054
|
+
function createStore(adapter, options) {
|
|
1055
|
+
return new Store(adapter, options);
|
|
1056
1056
|
}
|
|
1057
1057
|
export {
|
|
1058
1058
|
createStore as default
|