polystore 0.22.0 → 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polystore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "A small compatibility layer for many popular KV stores like localStorage, Redis, FileSystem, etc.",
|
|
5
5
|
"homepage": "https://polystore.dev",
|
|
6
6
|
"repository": "github:franciscop/polystore",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"size": "echo $(gzip -c index.js | wc -c) bytes",
|
|
20
|
-
"build": "bunx tsup src/index.ts --format esm --dts --out-dir . --target node24 && bunx tsup src/plugins/express/index.ts --format esm --dts --out-dir src/plugins/express --target node24 --external polystore --external express-session && bunx tsup src/plugins/hono-sessions/index.ts --format esm --dts --out-dir src/plugins/hono-sessions --target node24 --external polystore --external hono-sessions && bunx tsup src/plugins/better-auth/index.ts --format esm --dts --out-dir src/plugins/better-auth --target node24 --external polystore",
|
|
20
|
+
"build": "bunx tsup src/index.ts --format esm --dts --out-dir . --target node24 && bunx tsup src/plugins/express/index.ts --format esm --dts --out-dir src/plugins/express --target node24 --external polystore --external express-session && bunx tsup src/plugins/hono-sessions/index.ts --format esm --dts --out-dir src/plugins/hono-sessions --target node24 --external polystore --external hono-sessions && bunx tsup src/plugins/better-auth/index.ts --format esm --dts --out-dir src/plugins/better-auth --target node24 --external polystore && bunx tsup src/plugins/axios-cache-interceptor/index.ts --format esm --dts --out-dir src/plugins/axios-cache-interceptor --target node24 --external polystore --external axios-cache-interceptor",
|
|
21
21
|
"lint": "tsc",
|
|
22
22
|
"start": "bun test --watch",
|
|
23
23
|
"service:db": "etcd",
|
|
@@ -43,7 +43,9 @@
|
|
|
43
43
|
"src/plugins/hono-sessions/index.js",
|
|
44
44
|
"src/plugins/hono-sessions/index.d.ts",
|
|
45
45
|
"src/plugins/better-auth/index.js",
|
|
46
|
-
"src/plugins/better-auth/index.d.ts"
|
|
46
|
+
"src/plugins/better-auth/index.d.ts",
|
|
47
|
+
"src/plugins/axios-cache-interceptor/index.js",
|
|
48
|
+
"src/plugins/axios-cache-interceptor/index.d.ts"
|
|
47
49
|
],
|
|
48
50
|
"exports": {
|
|
49
51
|
".": {
|
|
@@ -61,6 +63,10 @@
|
|
|
61
63
|
"./better-auth": {
|
|
62
64
|
"types": "./src/plugins/better-auth/index.d.ts",
|
|
63
65
|
"import": "./src/plugins/better-auth/index.js"
|
|
66
|
+
},
|
|
67
|
+
"./axios-cache-interceptor": {
|
|
68
|
+
"types": "./src/plugins/axios-cache-interceptor/index.d.ts",
|
|
69
|
+
"import": "./src/plugins/axios-cache-interceptor/index.js"
|
|
64
70
|
}
|
|
65
71
|
},
|
|
66
72
|
"documentation.page": {
|
|
@@ -74,6 +80,7 @@
|
|
|
74
80
|
"Github": "https://github.com/franciscop/polystore"
|
|
75
81
|
}
|
|
76
82
|
},
|
|
83
|
+
"dependencies": {},
|
|
77
84
|
"devDependencies": {
|
|
78
85
|
"@deno/kv": "^0.8.1",
|
|
79
86
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -84,6 +91,8 @@
|
|
|
84
91
|
"@types/jsdom": "^27.0.0",
|
|
85
92
|
"@types/pg": "^8.11.10",
|
|
86
93
|
"@types/supertest": "^7.2.0",
|
|
94
|
+
"axios": "^1.9.0",
|
|
95
|
+
"axios-cache-interceptor": "^1.12.0",
|
|
87
96
|
"better-sqlite3": "^12.6.0",
|
|
88
97
|
"concurrently": "^9.2.1",
|
|
89
98
|
"dotenv": "^16.3.1",
|
package/readme.md
CHANGED
|
@@ -639,7 +639,7 @@ Quick overview:
|
|
|
639
639
|
| [Local Forage](#local-forage) | Browser | ✅ | ❓ | Better capacity than localStorage |
|
|
640
640
|
| [Redis](#redis) | Node.js | ✅ | ✅ | Good distributed cache backend |
|
|
641
641
|
| [SQLite](#sqlite) | Node.js | ✅ | ❌ | Simple local persistence |
|
|
642
|
-
| [Fetch API](#fetch-api) |
|
|
642
|
+
| [Fetch API](#fetch-api) | Node.js + Browser | ❓ | ❓ | Bring your own API |
|
|
643
643
|
| [File](#file) | Node.js | ✅ | ❌ | Single JSON file store |
|
|
644
644
|
| [Folder](#folder) | Node.js | ✅ | ❌ | One-file-per-key store |
|
|
645
645
|
| [Cloudflare KV](#cloudflare-kv) | Cloudflare | ✅ | ✅ | Edge-native KV |
|
|
@@ -1350,6 +1350,47 @@ Use `.prefix()` to namespace keys in a shared store:
|
|
|
1350
1350
|
secondaryStorage: betterAuthStorage(createClient().connect()).prefix("auth:")
|
|
1351
1351
|
```
|
|
1352
1352
|
|
|
1353
|
+
### Axios Cache Interceptor
|
|
1354
|
+
|
|
1355
|
+
> [Full example →](https://github.com/franciscop/polystore/tree/master/examples/axios-cache-interceptor)
|
|
1356
|
+
|
|
1357
|
+
Use any Polystore-compatible store as the cache storage for [axios-cache-interceptor](https://axios-cache-interceptor.js.org/):
|
|
1358
|
+
|
|
1359
|
+
```js
|
|
1360
|
+
import axios from "axios";
|
|
1361
|
+
import { setupCache } from "axios-cache-interceptor";
|
|
1362
|
+
import axiosCacheStorage from "polystore/axios-cache-interceptor";
|
|
1363
|
+
|
|
1364
|
+
const http = setupCache(axios, {
|
|
1365
|
+
storage: axiosCacheStorage(), // in-memory by default
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
// First request hits the network, second is served from cache
|
|
1369
|
+
const { data } = await http.get("https://api.example.com/users");
|
|
1370
|
+
await http.get("https://api.example.com/users"); // cached
|
|
1371
|
+
```
|
|
1372
|
+
|
|
1373
|
+
For production, swap in any Polystore adapter:
|
|
1374
|
+
|
|
1375
|
+
```js
|
|
1376
|
+
import { createClient } from "redis";
|
|
1377
|
+
import axiosCacheStorage from "polystore/axios-cache-interceptor";
|
|
1378
|
+
|
|
1379
|
+
const http = setupCache(axios, {
|
|
1380
|
+
storage: axiosCacheStorage(createClient().connect()),
|
|
1381
|
+
});
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
Use `.prefix()` to namespace cache keys in a shared store:
|
|
1385
|
+
|
|
1386
|
+
```js
|
|
1387
|
+
const http = setupCache(axios, {
|
|
1388
|
+
storage: axiosCacheStorage(createClient().connect()).prefix("api-cache:"),
|
|
1389
|
+
});
|
|
1390
|
+
```
|
|
1391
|
+
|
|
1392
|
+
Cache TTL is derived automatically from each response's cache headers (via `Cache-Control: max-age`, `Expires`, etc.) so you don't need to configure it separately. The cache entry is stored with a matching expiration so backends like Redis will evict it automatically.
|
|
1393
|
+
|
|
1353
1394
|
### fch
|
|
1354
1395
|
|
|
1355
1396
|
[Fch](https://www.npmjs.com/package/fch) is a lightweight fetch wrapper that uses Polystore natively for caching. Pass any Polystore store as the `cache` option and GET responses are cached automatically:
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Store } from 'polystore';
|
|
2
|
+
import { AxiosStorage, CacheRequestConfig, StorageValue, NotEmptyStorageValue } from 'axios-cache-interceptor';
|
|
3
|
+
|
|
4
|
+
declare class PolystoreAxiosCacheStorage implements AxiosStorage {
|
|
5
|
+
"is-storage": number;
|
|
6
|
+
private store;
|
|
7
|
+
private _storage;
|
|
8
|
+
constructor(store: Store);
|
|
9
|
+
prefix(prefix?: string): PolystoreAxiosCacheStorage;
|
|
10
|
+
get(key: string, currentRequest?: CacheRequestConfig): Promise<StorageValue>;
|
|
11
|
+
set(key: string, value: NotEmptyStorageValue, currentRequest?: CacheRequestConfig): Promise<void>;
|
|
12
|
+
remove(key: string, currentRequest?: CacheRequestConfig): Promise<void>;
|
|
13
|
+
clear(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare function axiosCacheStorage(store?: any): PolystoreAxiosCacheStorage;
|
|
16
|
+
|
|
17
|
+
export { PolystoreAxiosCacheStorage, axiosCacheStorage as default };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// src/plugins/axios-cache-interceptor/index.ts
|
|
2
|
+
import { buildStorage } from "axios-cache-interceptor";
|
|
3
|
+
import kv from "polystore";
|
|
4
|
+
var MAX_STALE_AGE = 36e5;
|
|
5
|
+
var ttlFromValue = (value) => {
|
|
6
|
+
if (value.ttl === void 0 || value.createdAt === void 0) return void 0;
|
|
7
|
+
const staleTtl = value.state === "cached" ? value.staleTtl ?? 0 : 0;
|
|
8
|
+
const removableAt = value.createdAt + value.ttl + Math.max(staleTtl, MAX_STALE_AGE);
|
|
9
|
+
const secs = Math.ceil((removableAt - Date.now()) / 1e3);
|
|
10
|
+
return secs > 0 ? { expires: secs } : void 0;
|
|
11
|
+
};
|
|
12
|
+
var PolystoreAxiosCacheStorage = class _PolystoreAxiosCacheStorage {
|
|
13
|
+
// Marks this object as a valid storage so `setupCache()` accepts it (it calls
|
|
14
|
+
// the internal `isStorage()`, which checks for this exact property).
|
|
15
|
+
"is-storage" = 1;
|
|
16
|
+
store;
|
|
17
|
+
_storage;
|
|
18
|
+
constructor(store) {
|
|
19
|
+
this.store = store;
|
|
20
|
+
this._storage = buildStorage({
|
|
21
|
+
find: (key) => this.store.get(key).then((v) => v ?? void 0),
|
|
22
|
+
set: (key, value) => this.store.set(key, value, ttlFromValue(value)),
|
|
23
|
+
remove: (key) => this.store.del(key),
|
|
24
|
+
clear: () => this.store.clear()
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
prefix(prefix = "") {
|
|
28
|
+
return new _PolystoreAxiosCacheStorage(this.store.prefix(prefix));
|
|
29
|
+
}
|
|
30
|
+
get(key, currentRequest) {
|
|
31
|
+
return this._storage.get(key, currentRequest);
|
|
32
|
+
}
|
|
33
|
+
set(key, value, currentRequest) {
|
|
34
|
+
return this._storage.set(key, value, currentRequest);
|
|
35
|
+
}
|
|
36
|
+
remove(key, currentRequest) {
|
|
37
|
+
return this._storage.remove(key, currentRequest);
|
|
38
|
+
}
|
|
39
|
+
clear() {
|
|
40
|
+
return Promise.resolve(this._storage.clear?.());
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
function axiosCacheStorage(store = /* @__PURE__ */ new Map()) {
|
|
44
|
+
return new PolystoreAxiosCacheStorage(kv(store));
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
PolystoreAxiosCacheStorage,
|
|
48
|
+
axiosCacheStorage as default
|
|
49
|
+
};
|