@voyant-travel/utils 0.105.5 → 0.106.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/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-kv.d.ts +26 -0
- package/dist/memory-kv.d.ts.map +1 -0
- package/dist/memory-kv.js +58 -0
- package/dist/memory-kv.js.map +1 -0
- package/dist/redis-client.d.ts +18 -0
- package/dist/redis-client.d.ts.map +1 -0
- package/dist/redis-client.js +30 -0
- package/dist/redis-client.js.map +1 -0
- package/dist/redis-kv.d.ts +7 -0
- package/dist/redis-kv.d.ts.map +1 -0
- package/dist/redis-kv.js +47 -0
- package/dist/redis-kv.js.map +1 -0
- package/dist/tiered-kv.d.ts +10 -0
- package/dist/tiered-kv.d.ts.map +1 -0
- package/dist/tiered-kv.js +35 -0
- package/dist/tiered-kv.js.map +1 -0
- package/package.json +25 -2
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,12 @@ export * from "./kms.js";
|
|
|
6
6
|
export * from "./kv.js";
|
|
7
7
|
export * from "./languages.js";
|
|
8
8
|
export * from "./localized-countries-regions.js";
|
|
9
|
+
export * from "./memory-kv.js";
|
|
9
10
|
export * from "./pdf-renderer.js";
|
|
11
|
+
export * from "./redis-client.js";
|
|
12
|
+
export * from "./redis-kv.js";
|
|
10
13
|
export * from "./resilience.js";
|
|
11
14
|
export * from "./template-renderer.js";
|
|
15
|
+
export * from "./tiered-kv.js";
|
|
12
16
|
export * from "./timezones.js";
|
|
13
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,8 +6,12 @@ export * from "./kms.js";
|
|
|
6
6
|
export * from "./kv.js";
|
|
7
7
|
export * from "./languages.js";
|
|
8
8
|
export * from "./localized-countries-regions.js";
|
|
9
|
+
export * from "./memory-kv.js";
|
|
9
10
|
export * from "./pdf-renderer.js";
|
|
11
|
+
export * from "./redis-client.js";
|
|
12
|
+
export * from "./redis-kv.js";
|
|
10
13
|
export * from "./resilience.js";
|
|
11
14
|
export * from "./template-renderer.js";
|
|
15
|
+
export * from "./tiered-kv.js";
|
|
12
16
|
export * from "./timezones.js";
|
|
13
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { KVStore } from "./cache.js";
|
|
2
|
+
export type KvValueType = "text" | "json";
|
|
3
|
+
export interface KvGetOptions {
|
|
4
|
+
type?: KvValueType;
|
|
5
|
+
}
|
|
6
|
+
export interface KvPutOptions {
|
|
7
|
+
/** TTL in seconds. The entry is treated as absent once it elapses. */
|
|
8
|
+
expirationTtl?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Minimal KV surface consumed across Voyant packages. */
|
|
11
|
+
export interface KvNamespaceShim extends KVStore {
|
|
12
|
+
get(key: string): Promise<string | null>;
|
|
13
|
+
get<T = unknown>(key: string, type: "json"): Promise<T | null>;
|
|
14
|
+
get<T = unknown>(key: string, options: KvGetOptions): Promise<T | string | null>;
|
|
15
|
+
}
|
|
16
|
+
export interface MemoryKvOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Cap on resident entries before least-recently-used eviction. Defaults to
|
|
19
|
+
* 10,000. Set `0` to disable eviction.
|
|
20
|
+
*/
|
|
21
|
+
maxEntries?: number;
|
|
22
|
+
/** Injectable clock (ms) for deterministic TTL tests. Defaults to `Date.now`. */
|
|
23
|
+
now?: () => number;
|
|
24
|
+
}
|
|
25
|
+
export declare function createMemoryKvNamespace(options?: MemoryKvOptions): KvNamespaceShim;
|
|
26
|
+
//# sourceMappingURL=memory-kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-kv.d.ts","sourceRoot":"","sources":["../src/memory-kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAA;AAEzC,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACxC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC9D,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,CAAA;CACjF;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iFAAiF;IACjF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAUD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,eAAoB,GAAG,eAAe,CA0DtF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const DEFAULT_MAX_ENTRIES = 10_000;
|
|
2
|
+
export function createMemoryKvNamespace(options = {}) {
|
|
3
|
+
const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
4
|
+
const now = options.now ?? Date.now;
|
|
5
|
+
const map = new Map();
|
|
6
|
+
function readFresh(key) {
|
|
7
|
+
const entry = map.get(key);
|
|
8
|
+
if (!entry)
|
|
9
|
+
return null;
|
|
10
|
+
if (entry.expiresAt <= now()) {
|
|
11
|
+
map.delete(key);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
map.delete(key);
|
|
15
|
+
map.set(key, entry);
|
|
16
|
+
return entry.value;
|
|
17
|
+
}
|
|
18
|
+
async function get(key, typeOrOptions) {
|
|
19
|
+
const type = typeof typeOrOptions === "string" ? typeOrOptions : (typeOrOptions?.type ?? "text");
|
|
20
|
+
const raw = readFresh(key);
|
|
21
|
+
if (raw === null)
|
|
22
|
+
return null;
|
|
23
|
+
return type === "json" ? JSON.parse(raw) : raw;
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
get: get,
|
|
27
|
+
async put(key, value, putOptions) {
|
|
28
|
+
if (map.has(key))
|
|
29
|
+
map.delete(key);
|
|
30
|
+
const expiresAt = putOptions?.expirationTtl === undefined
|
|
31
|
+
? Number.POSITIVE_INFINITY
|
|
32
|
+
: now() + putOptions.expirationTtl * 1000;
|
|
33
|
+
map.set(key, { value, expiresAt });
|
|
34
|
+
if (maxEntries > 0) {
|
|
35
|
+
while (map.size > maxEntries) {
|
|
36
|
+
const oldest = map.keys().next().value;
|
|
37
|
+
if (oldest === undefined)
|
|
38
|
+
break;
|
|
39
|
+
map.delete(oldest);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
async delete(key) {
|
|
44
|
+
map.delete(key);
|
|
45
|
+
},
|
|
46
|
+
async list(options) {
|
|
47
|
+
const prefix = options?.prefix ?? "";
|
|
48
|
+
const keys = [];
|
|
49
|
+
for (const key of [...map.keys()]) {
|
|
50
|
+
if (readFresh(key) !== null && key.startsWith(prefix)) {
|
|
51
|
+
keys.push({ name: key });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { keys };
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=memory-kv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-kv.js","sourceRoot":"","sources":["../src/memory-kv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface RedisClient {
|
|
2
|
+
get<T = unknown>(key: string): Promise<T | null>;
|
|
3
|
+
set(key: string, value: string, options?: {
|
|
4
|
+
ex?: number;
|
|
5
|
+
}): Promise<unknown>;
|
|
6
|
+
del(key: string): Promise<unknown>;
|
|
7
|
+
scan?(cursor: number, options?: {
|
|
8
|
+
match?: string;
|
|
9
|
+
count?: number;
|
|
10
|
+
}): Promise<[number | string, string[]]>;
|
|
11
|
+
incr(key: string): Promise<number>;
|
|
12
|
+
expire(key: string, seconds: number): Promise<unknown>;
|
|
13
|
+
}
|
|
14
|
+
export interface LazyRedisClient {
|
|
15
|
+
get(): Promise<RedisClient>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createLazyRedisClient(redisUrl: string): LazyRedisClient;
|
|
18
|
+
//# sourceMappingURL=redis-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-client.d.ts","sourceRoot":"","sources":["../src/redis-client.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAClC,IAAI,CAAC,CACH,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IACvC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACvD;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CAC5B;AAsBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAYvE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function parseRedisRestUrl(rawUrl) {
|
|
2
|
+
const parsed = new URL(rawUrl);
|
|
3
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
4
|
+
throw new Error("REDIS_URL must be an HTTP(S) Redis REST URL.");
|
|
5
|
+
}
|
|
6
|
+
const token = parsed.password || parsed.searchParams.get("token") || "";
|
|
7
|
+
if (!token) {
|
|
8
|
+
throw new Error("REDIS_URL must include a Redis REST token as the URL password or token query.");
|
|
9
|
+
}
|
|
10
|
+
parsed.username = "";
|
|
11
|
+
parsed.password = "";
|
|
12
|
+
parsed.searchParams.delete("token");
|
|
13
|
+
return {
|
|
14
|
+
url: parsed.toString().replace(/\/$/, ""),
|
|
15
|
+
token: decodeURIComponent(token),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function createLazyRedisClient(redisUrl) {
|
|
19
|
+
let clientPromise;
|
|
20
|
+
return {
|
|
21
|
+
get() {
|
|
22
|
+
clientPromise ??= import("@upstash/redis").then((mod) => {
|
|
23
|
+
const { url, token } = parseRedisRestUrl(redisUrl);
|
|
24
|
+
return new mod.Redis({ url, token });
|
|
25
|
+
});
|
|
26
|
+
return clientPromise;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=redis-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-client.js","sourceRoot":"","sources":["../src/redis-client.ts"],"names":[],"mappings":"AAwBA,SAAS,iBAAiB,CAAC,MAAc;IACvC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;IACvE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;IAClG,CAAC;IAED,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAA;IACpB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAA;IACpB,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACnC,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACzC,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC;KACjC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,IAAI,aAA+C,CAAA;IAEnD,OAAO;QACL,GAAG;YACD,aAAa,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAgB,EAAE,EAAE;gBACnE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;gBAClD,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAA;YACtC,CAAC,CAAC,CAAA;YACF,OAAO,aAAa,CAAA;QACtB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { KVStore } from "./cache.js";
|
|
2
|
+
import { type LazyRedisClient } from "./redis-client.js";
|
|
3
|
+
export interface RedisKvStoreOptions {
|
|
4
|
+
client?: LazyRedisClient;
|
|
5
|
+
}
|
|
6
|
+
export declare function createRedisKvStore(redisUrl: string, options?: RedisKvStoreOptions): KVStore;
|
|
7
|
+
//# sourceMappingURL=redis-kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-kv.d.ts","sourceRoot":"","sources":["../src/redis-kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAE/E,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,eAAe,CAAA;CACzB;AAUD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAyC/F"}
|
package/dist/redis-kv.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createLazyRedisClient } from "./redis-client.js";
|
|
2
|
+
function getType(options) {
|
|
3
|
+
return typeof options === "string" ? options : (options?.type ?? "text");
|
|
4
|
+
}
|
|
5
|
+
function scanPattern(prefix) {
|
|
6
|
+
return `${prefix.replaceAll("[", "\\[").replaceAll("*", "\\*")}*`;
|
|
7
|
+
}
|
|
8
|
+
export function createRedisKvStore(redisUrl, options = {}) {
|
|
9
|
+
const lazyClient = options.client ?? createLazyRedisClient(redisUrl);
|
|
10
|
+
return {
|
|
11
|
+
async get(key, options) {
|
|
12
|
+
const client = await lazyClient.get();
|
|
13
|
+
const value = await client.get(key);
|
|
14
|
+
if (value === null || value === undefined)
|
|
15
|
+
return null;
|
|
16
|
+
return (getType(options) === "json" && typeof value === "string" ? JSON.parse(value) : value);
|
|
17
|
+
},
|
|
18
|
+
async put(key, value, options) {
|
|
19
|
+
const client = await lazyClient.get();
|
|
20
|
+
if (options?.expirationTtl !== undefined) {
|
|
21
|
+
await client.set(key, value, { ex: Math.max(1, Math.ceil(options.expirationTtl)) });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
await client.set(key, value);
|
|
25
|
+
},
|
|
26
|
+
async delete(key) {
|
|
27
|
+
const client = await lazyClient.get();
|
|
28
|
+
await client.del(key);
|
|
29
|
+
},
|
|
30
|
+
async list(options) {
|
|
31
|
+
const client = await lazyClient.get();
|
|
32
|
+
if (!client.scan)
|
|
33
|
+
return { keys: [] };
|
|
34
|
+
const keys = [];
|
|
35
|
+
let cursor = 0;
|
|
36
|
+
const match = scanPattern(options?.prefix ?? "");
|
|
37
|
+
do {
|
|
38
|
+
const [nextCursor, batch] = await client.scan(Number(cursor), { match, count: 100 });
|
|
39
|
+
for (const name of batch)
|
|
40
|
+
keys.push({ name });
|
|
41
|
+
cursor = nextCursor;
|
|
42
|
+
} while (String(cursor) !== "0");
|
|
43
|
+
return { keys };
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=redis-kv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-kv.js","sourceRoot":"","sources":["../src/redis-kv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { KVStore } from "./cache.js";
|
|
2
|
+
export interface TieredKvOptions {
|
|
3
|
+
/**
|
|
4
|
+
* TTL for L2 hits promoted into L1 when the original remaining TTL is not
|
|
5
|
+
* visible through KVStore. Defaults to 60s to bound remote invalidation lag.
|
|
6
|
+
*/
|
|
7
|
+
l2PromotionTtlSeconds?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function createTieredKvStore(l1: KVStore, l2: KVStore | null | undefined, options?: TieredKvOptions): KVStore;
|
|
10
|
+
//# sourceMappingURL=tiered-kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiered-kv.d.ts","sourceRoot":"","sources":["../src/tiered-kv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAMD,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,OAAO,EACX,EAAE,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EAC9B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CA+BT"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
function getType(options) {
|
|
2
|
+
return typeof options === "string" ? options : (options?.type ?? "text");
|
|
3
|
+
}
|
|
4
|
+
export function createTieredKvStore(l1, l2, options = {}) {
|
|
5
|
+
const promotionTtl = options.l2PromotionTtlSeconds ?? 60;
|
|
6
|
+
if (!l2)
|
|
7
|
+
return l1;
|
|
8
|
+
return {
|
|
9
|
+
async get(key, getOptions) {
|
|
10
|
+
const l1Hit = await l1.get(key, getOptions);
|
|
11
|
+
if (l1Hit !== null && l1Hit !== undefined)
|
|
12
|
+
return l1Hit;
|
|
13
|
+
const raw = await l2.get(key);
|
|
14
|
+
if (raw === null || raw === undefined)
|
|
15
|
+
return null;
|
|
16
|
+
await l1.put(key, raw, { expirationTtl: promotionTtl }).catch(() => { });
|
|
17
|
+
return (getType(getOptions) === "json" ? JSON.parse(raw) : raw);
|
|
18
|
+
},
|
|
19
|
+
async put(key, value, putOptions) {
|
|
20
|
+
await Promise.all([
|
|
21
|
+
l2.put(key, value, putOptions),
|
|
22
|
+
l1.put(key, value, putOptions).catch(() => { }),
|
|
23
|
+
]);
|
|
24
|
+
},
|
|
25
|
+
async delete(key) {
|
|
26
|
+
await Promise.all([l2.delete(key), l1.delete(key).catch(() => { })]);
|
|
27
|
+
},
|
|
28
|
+
async list(options) {
|
|
29
|
+
if (l2.list)
|
|
30
|
+
return l2.list(options);
|
|
31
|
+
return l1.list ? l1.list(options) : { keys: [] };
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=tiered-kv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiered-kv.js","sourceRoot":"","sources":["../src/tiered-kv.ts"],"names":[],"mappings":"AAUA,SAAS,OAAO,CAAC,OAA6C;IAC5D,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,MAAM,CAAC,CAAA;AAC1E,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,EAAW,EACX,EAA8B,EAC9B,UAA2B,EAAE;IAE7B,MAAM,YAAY,GAAG,OAAO,CAAC,qBAAqB,IAAI,EAAE,CAAA;IACxD,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAA;IAElB,OAAO;QACL,KAAK,CAAC,GAAG,CACP,GAAW,EACX,UAAgD;YAEhD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAI,GAAG,EAAE,UAAwC,CAAC,CAAA;YAC5E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAA;YAEvD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,GAAG,CAAS,GAAG,CAAC,CAAA;YACrC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAA;YAClD,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACvE,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAM,CAAA;QACtE,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,UAAuC;YAC3E,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC;gBAC9B,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;aAC/C,CAAC,CAAA;QACJ,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,GAAW;YACtB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QACrE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAA6B;YACtC,IAAI,EAAE,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACpC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;QAClD,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.106.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -75,6 +75,26 @@
|
|
|
75
75
|
"import": "./dist/cache.js",
|
|
76
76
|
"default": "./dist/cache.js"
|
|
77
77
|
},
|
|
78
|
+
"./memory-kv": {
|
|
79
|
+
"types": "./dist/memory-kv.d.ts",
|
|
80
|
+
"import": "./dist/memory-kv.js",
|
|
81
|
+
"default": "./dist/memory-kv.js"
|
|
82
|
+
},
|
|
83
|
+
"./redis-client": {
|
|
84
|
+
"types": "./dist/redis-client.d.ts",
|
|
85
|
+
"import": "./dist/redis-client.js",
|
|
86
|
+
"default": "./dist/redis-client.js"
|
|
87
|
+
},
|
|
88
|
+
"./redis-kv": {
|
|
89
|
+
"types": "./dist/redis-kv.d.ts",
|
|
90
|
+
"import": "./dist/redis-kv.js",
|
|
91
|
+
"default": "./dist/redis-kv.js"
|
|
92
|
+
},
|
|
93
|
+
"./tiered-kv": {
|
|
94
|
+
"types": "./dist/tiered-kv.d.ts",
|
|
95
|
+
"import": "./dist/tiered-kv.js",
|
|
96
|
+
"default": "./dist/tiered-kv.js"
|
|
97
|
+
},
|
|
78
98
|
"./resilience": {
|
|
79
99
|
"types": "./dist/resilience.d.ts",
|
|
80
100
|
"import": "./dist/resilience.js",
|
|
@@ -102,7 +122,10 @@
|
|
|
102
122
|
"pdf-lib": "^1.17.1",
|
|
103
123
|
"zod": "^4.4.3",
|
|
104
124
|
"@voyant-travel/templating": "^0.104.1",
|
|
105
|
-
"@voyant-travel/types": "^0.
|
|
125
|
+
"@voyant-travel/types": "^0.107.1"
|
|
126
|
+
},
|
|
127
|
+
"optionalDependencies": {
|
|
128
|
+
"@upstash/redis": "^1.35.6"
|
|
106
129
|
},
|
|
107
130
|
"devDependencies": {
|
|
108
131
|
"@types/node": "^25.5.2",
|