valkyries 0.6.2 → 0.7.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 +39 -0
- package/dist/delete.d.mts +8 -0
- package/dist/delete.d.mts.map +1 -1
- package/dist/delete.mjs +30 -13
- package/dist/delete.mjs.map +1 -1
- package/dist/expiry.d.mts +10 -0
- package/dist/expiry.d.mts.map +1 -0
- package/dist/expiry.mjs +70 -0
- package/dist/expiry.mjs.map +1 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/scan.d.mts +10 -0
- package/dist/scan.d.mts.map +1 -0
- package/dist/scan.mjs +24 -0
- package/dist/scan.mjs.map +1 -0
- package/dist/types.d.mts +37 -1
- package/dist/types.d.mts.map +1 -1
- package/docs/api.md +2 -0
- package/docs/utilities.md +48 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -113,6 +113,45 @@ const cache = new ValkeyCache({ prefix: "custom", ttlSeconds: 60, client });
|
|
|
113
113
|
|
|
114
114
|
Call `closeValkeyClients()` to close package-managed clients.
|
|
115
115
|
|
|
116
|
+
## Scan and Unlink Keys
|
|
117
|
+
|
|
118
|
+
Use `scanAndUnlinkKeys()` for cancellable, pattern-based cleanup with explicit scan and deletion
|
|
119
|
+
counts:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { scanAndUnlinkKeys } from "valkyries";
|
|
123
|
+
|
|
124
|
+
const result = await scanAndUnlinkKeys(client, "cache:*", {
|
|
125
|
+
matches: (key) => Buffer.from(key).toString("utf8").startsWith("cache:users:"),
|
|
126
|
+
signal: abortController.signal,
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The result reports `scannedKeys`, `matchedKeys`, and keys confirmed removed by `UNLINK` as
|
|
131
|
+
`unlinkedKeys`. `SCAN` is non-snapshot, so these counts can include duplicates or omit keys while
|
|
132
|
+
the keyspace changes.
|
|
133
|
+
|
|
134
|
+
## Expire Keys Without a TTL
|
|
135
|
+
|
|
136
|
+
Use `expireKeysWithNoExpiry()` to apply a TTL only when matching keys still have no expiry:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { expireKeysWithNoExpiry } from "valkyries";
|
|
140
|
+
|
|
141
|
+
const result = await expireKeysWithNoExpiry(client, {
|
|
142
|
+
pattern: "cache:*",
|
|
143
|
+
ttl: 86_400,
|
|
144
|
+
shouldExpire: (key) => Buffer.from(key).toString("utf8").startsWith("cache:users:"),
|
|
145
|
+
signal: abortController.signal,
|
|
146
|
+
batchSize: 250,
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The result reports `scannedKeys`, `matchedKeys`, and `expiredKeys`. The helper uses `EXPIRE NX`,
|
|
151
|
+
so it never replaces a TTL that was added concurrently. `SCAN` is non-snapshot, so counts can
|
|
152
|
+
include duplicates or omit keys while the keyspace changes. `scanCount` is a SCAN hint, while
|
|
153
|
+
`batchSize` independently bounds each EXPIRE pipeline.
|
|
154
|
+
|
|
116
155
|
## Documentation
|
|
117
156
|
|
|
118
157
|
- [Configuration](docs/configuration.md)
|
package/dist/delete.d.mts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import type { ScanAndUnlinkKeysOptions, ScanAndUnlinkKeysResult } from "./types.mts";
|
|
1
2
|
import type { GlideClient } from "@valkey/valkey-glide";
|
|
2
3
|
export declare function deleteKeysWithPrefix(client: GlideClient, pattern: string): Promise<void>;
|
|
3
4
|
export declare function deleteKeysWithLiteralPrefixes(client: GlideClient, pattern: string, prefixes: readonly string[]): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Scans keys matching a Valkey pattern and unlinks keys accepted by an optional predicate.
|
|
7
|
+
*
|
|
8
|
+
* SCAN is non-snapshot: concurrent writes can make the returned counts include duplicates,
|
|
9
|
+
* omit keys, or differ from the number of keys that exist when this function returns.
|
|
10
|
+
*/
|
|
11
|
+
export declare function scanAndUnlinkKeys(client: GlideClient, pattern: string, { signal, matches }?: ScanAndUnlinkKeysOptions): Promise<ScanAndUnlinkKeysResult>;
|
|
4
12
|
//# sourceMappingURL=delete.d.mts.map
|
package/dist/delete.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.d.mts","sourceRoot":"","sources":["../delete.mts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"delete.d.mts","sourceRoot":"","sources":["../delete.mts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIxD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9F;AAED,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,EACf,EAAE,MAAM,EAAE,OAAoB,EAAE,GAAE,wBAA6B,GAC9D,OAAO,CAAC,uBAAuB,CAAC,CA4BlC"}
|
package/dist/delete.mjs
CHANGED
|
@@ -1,30 +1,47 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
1
|
import { handleValkeyError } from "./errors.mjs";
|
|
2
|
+
import { glideStringToString, scanKeyPages, throwIfAborted } from "./scan.mjs";
|
|
3
3
|
const DEFAULT_SCAN_COUNT = 500;
|
|
4
4
|
export async function deleteKeysWithPrefix(client, pattern) {
|
|
5
|
-
await
|
|
5
|
+
await scanAndUnlinkKeys(client, pattern);
|
|
6
6
|
}
|
|
7
7
|
export async function deleteKeysWithLiteralPrefixes(client, pattern, prefixes) {
|
|
8
8
|
const uniquePrefixes = [...new Set(prefixes)].filter((prefix) => typeof prefix === "string");
|
|
9
9
|
if (uniquePrefixes.length === 0)
|
|
10
10
|
return;
|
|
11
|
-
await
|
|
11
|
+
await scanAndUnlinkKeys(client, pattern, {
|
|
12
|
+
matches: (key) => uniquePrefixes.some((prefix) => glideStringToString(key).startsWith(prefix)),
|
|
13
|
+
});
|
|
12
14
|
}
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Scans keys matching a Valkey pattern and unlinks keys accepted by an optional predicate.
|
|
17
|
+
*
|
|
18
|
+
* SCAN is non-snapshot: concurrent writes can make the returned counts include duplicates,
|
|
19
|
+
* omit keys, or differ from the number of keys that exist when this function returns.
|
|
20
|
+
*/
|
|
21
|
+
export async function scanAndUnlinkKeys(client, pattern, { signal, matches = () => true } = {}) {
|
|
14
22
|
try {
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
let scannedKeys = 0;
|
|
24
|
+
let matchedKeys = 0;
|
|
25
|
+
let unlinkedKeys = 0;
|
|
26
|
+
for await (const scanned of scanKeyPages(client, pattern, {
|
|
27
|
+
count: DEFAULT_SCAN_COUNT,
|
|
28
|
+
signal,
|
|
29
|
+
})) {
|
|
30
|
+
scannedKeys += scanned.length;
|
|
31
|
+
const keys = scanned.filter(matches);
|
|
32
|
+
throwIfAborted(signal);
|
|
33
|
+
matchedKeys += keys.length;
|
|
22
34
|
if (keys.length > 0) {
|
|
23
|
-
|
|
35
|
+
throwIfAborted(signal);
|
|
36
|
+
unlinkedKeys += await client.unlink(keys);
|
|
37
|
+
throwIfAborted(signal);
|
|
24
38
|
}
|
|
25
|
-
}
|
|
39
|
+
}
|
|
40
|
+
return { scannedKeys, matchedKeys, unlinkedKeys };
|
|
26
41
|
}
|
|
27
42
|
catch (err) {
|
|
43
|
+
if (signal?.aborted && err === signal.reason)
|
|
44
|
+
throw err;
|
|
28
45
|
handleValkeyError(err);
|
|
29
46
|
throw err;
|
|
30
47
|
}
|
package/dist/delete.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.mjs","sourceRoot":"","sources":["../delete.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"delete.mjs","sourceRoot":"","sources":["../delete.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI/E,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAmB,EAAE,OAAe;IAC7E,MAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAAmB,EACnB,OAAe,EACf,QAA2B;IAE3B,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,CAAU,QAAQ,CAAC,CAAC,CAAC,MAAM,CAC3D,CAAC,MAAM,EAAoB,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CACzD,CAAC;IACF,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAExC,MAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE;QACvC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;KAC/F,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAmB,EACnB,OAAe,EACf,EAAE,MAAM,EAAE,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,GAA6B,EAAE;IAE/D,IAAI,CAAC;QACH,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE;YACxD,KAAK,EAAE,kBAAkB;YACzB,MAAM;SACP,CAAC,EAAE,CAAC;YACH,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;YAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACrC,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC;YAE3B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,cAAc,CAAC,MAAM,CAAC,CAAC;gBACvB,YAAY,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC1C,cAAc,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;IACpD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,MAAM,EAAE,OAAO,IAAI,GAAG,KAAK,MAAM,CAAC,MAAM;YAAE,MAAM,GAAG,CAAC;QACxD,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACvB,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type GlideClient } from "@valkey/valkey-glide";
|
|
2
|
+
import type { ExpireKeysWithNoExpiryOptions, ExpireKeysWithNoExpiryResult } from "./types.mts";
|
|
3
|
+
/**
|
|
4
|
+
* Sets a TTL only on matching keys that have no existing expiry.
|
|
5
|
+
*
|
|
6
|
+
* SCAN is non-snapshot: concurrent writes can make the returned counts include duplicates,
|
|
7
|
+
* omit keys, or differ from the number of keys that exist when this function returns.
|
|
8
|
+
*/
|
|
9
|
+
export declare function expireKeysWithNoExpiry(client: GlideClient, { pattern, ttl, shouldExpire, signal, scanCount, batchSize, }: ExpireKeysWithNoExpiryOptions): Promise<ExpireKeysWithNoExpiryResult>;
|
|
10
|
+
//# sourceMappingURL=expiry.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expiry.d.mts","sourceRoot":"","sources":["../expiry.mts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,WAAW,EAAoB,MAAM,sBAAsB,CAAC;AAGhG,OAAO,KAAK,EAAE,6BAA6B,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAK/F;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,WAAW,EACnB,EACE,OAAO,EACP,GAAG,EACH,YAAyB,EACzB,MAAM,EACN,SAA8B,EAC9B,SAA8B,GAC/B,EAAE,6BAA6B,GAC/B,OAAO,CAAC,4BAA4B,CAAC,CAuBvC"}
|
package/dist/expiry.mjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Batch, ExpireOptions } from "@valkey/valkey-glide";
|
|
2
|
+
import { handleValkeyError } from "./errors.mjs";
|
|
3
|
+
import { scanKeyPages, throwIfAborted } from "./scan.mjs";
|
|
4
|
+
const DEFAULT_SCAN_COUNT = 500;
|
|
5
|
+
const DEFAULT_BATCH_SIZE = 500;
|
|
6
|
+
/**
|
|
7
|
+
* Sets a TTL only on matching keys that have no existing expiry.
|
|
8
|
+
*
|
|
9
|
+
* SCAN is non-snapshot: concurrent writes can make the returned counts include duplicates,
|
|
10
|
+
* omit keys, or differ from the number of keys that exist when this function returns.
|
|
11
|
+
*/
|
|
12
|
+
export async function expireKeysWithNoExpiry(client, { pattern, ttl, shouldExpire = () => true, signal, scanCount = DEFAULT_SCAN_COUNT, batchSize = DEFAULT_BATCH_SIZE, }) {
|
|
13
|
+
validateExpirySweepOptions(ttl, scanCount, batchSize);
|
|
14
|
+
try {
|
|
15
|
+
let scannedKeys = 0;
|
|
16
|
+
let matchedKeys = 0;
|
|
17
|
+
let expiredKeys = 0;
|
|
18
|
+
for await (const scanned of scanKeyPages(client, pattern, { count: scanCount, signal })) {
|
|
19
|
+
scannedKeys += scanned.length;
|
|
20
|
+
const keys = scanned.filter(shouldExpire);
|
|
21
|
+
throwIfAborted(signal);
|
|
22
|
+
matchedKeys += keys.length;
|
|
23
|
+
expiredKeys += await expireKeys(client, keys, ttl, batchSize, signal);
|
|
24
|
+
}
|
|
25
|
+
return { scannedKeys, matchedKeys, expiredKeys };
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (signal?.aborted && error === signal.reason)
|
|
29
|
+
throw error;
|
|
30
|
+
handleValkeyError(error);
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function expireKeys(client, keys, ttl, batchSize, signal) {
|
|
35
|
+
let expiredKeys = 0;
|
|
36
|
+
for (let offset = 0; offset < keys.length; offset += batchSize) {
|
|
37
|
+
expiredKeys += await expireBatch(client, keys.slice(offset, offset + batchSize), ttl, signal);
|
|
38
|
+
}
|
|
39
|
+
return expiredKeys;
|
|
40
|
+
}
|
|
41
|
+
async function expireBatch(client, keys, ttl, signal) {
|
|
42
|
+
throwIfAborted(signal);
|
|
43
|
+
const batch = new Batch(false);
|
|
44
|
+
for (const key of keys) {
|
|
45
|
+
batch.expire(key, ttl, { expireOption: ExpireOptions.HasNoExpiry });
|
|
46
|
+
}
|
|
47
|
+
const results = await client.exec(batch, true);
|
|
48
|
+
throwIfAborted(signal);
|
|
49
|
+
if (!Array.isArray(results) || results.length !== keys.length) {
|
|
50
|
+
throw new Error("expireKeysWithNoExpiry: unexpected EXPIRE batch response");
|
|
51
|
+
}
|
|
52
|
+
let expiredKeys = 0;
|
|
53
|
+
for (const result of results) {
|
|
54
|
+
if (result === true)
|
|
55
|
+
expiredKeys += 1;
|
|
56
|
+
}
|
|
57
|
+
return expiredKeys;
|
|
58
|
+
}
|
|
59
|
+
function validateExpirySweepOptions(ttl, scanCount, batchSize) {
|
|
60
|
+
if (!Number.isSafeInteger(ttl) || ttl <= 0) {
|
|
61
|
+
throw new RangeError("expireKeysWithNoExpiry: ttl must be a positive safe integer");
|
|
62
|
+
}
|
|
63
|
+
if (!Number.isSafeInteger(scanCount) || scanCount <= 0) {
|
|
64
|
+
throw new RangeError("expireKeysWithNoExpiry: scanCount must be a positive safe integer");
|
|
65
|
+
}
|
|
66
|
+
if (!Number.isSafeInteger(batchSize) || batchSize <= 0) {
|
|
67
|
+
throw new RangeError("expireKeysWithNoExpiry: batchSize must be a positive safe integer");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=expiry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expiry.mjs","sourceRoot":"","sources":["../expiry.mts"],"names":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -13,5 +13,7 @@ export * from "./errors.mts";
|
|
|
13
13
|
export * from "./key-normalization.mts";
|
|
14
14
|
export * from "./cache-metrics.mts";
|
|
15
15
|
export * from "./retry.mts";
|
|
16
|
-
export
|
|
16
|
+
export { scanAndUnlinkKeys } from "./delete.mts";
|
|
17
|
+
export { expireKeysWithNoExpiry } from "./expiry.mts";
|
|
18
|
+
export type { RateLimiterAddAndCheckWindowsOptions, RateLimiterOptions, RateLimiterWindow, ValkeyBloomFilterOptions, ValkeyCacheOptions, ValkeyCacheMode, ValkeyCacheResponse, DynamicConfigField, DynamicConfigFieldType, DynamicConfigOptions, ScanAndUnlinkKeysOptions, ScanAndUnlinkKeysResult, ExpireKeysWithNoExpiryOptions, ExpireKeysWithNoExpiryResult, } from "./types.mts";
|
|
17
19
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../index.mts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,YAAY,EACV,oCAAoC,EACpC,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../index.mts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EACV,oCAAoC,EACpC,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,aAAa,CAAC"}
|
package/dist/index.mjs
CHANGED
|
@@ -13,4 +13,6 @@ export * from "./errors.mjs";
|
|
|
13
13
|
export * from "./key-normalization.mjs";
|
|
14
14
|
export * from "./cache-metrics.mjs";
|
|
15
15
|
export * from "./retry.mjs";
|
|
16
|
+
export { scanAndUnlinkKeys } from "./delete.mjs";
|
|
17
|
+
export { expireKeysWithNoExpiry } from "./expiry.mjs";
|
|
16
18
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../index.mts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../index.mts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/scan.d.mts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type GlideClient, type GlideString } from "@valkey/valkey-glide";
|
|
2
|
+
type ScanKeyPagesOptions = {
|
|
3
|
+
count: number;
|
|
4
|
+
signal?: AbortSignal;
|
|
5
|
+
};
|
|
6
|
+
export declare function scanKeyPages(client: GlideClient, pattern: string, { count, signal }: ScanKeyPagesOptions): AsyncGenerator<GlideString[]>;
|
|
7
|
+
export declare function throwIfAborted(signal: AbortSignal | undefined): void;
|
|
8
|
+
export declare function glideStringToString(key: GlideString): string;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=scan.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.mts","sourceRoot":"","sources":["../scan.mts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnF,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,wBAAuB,YAAY,CACjC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,EACf,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,mBAAmB,GACrC,cAAc,CAAC,WAAW,EAAE,CAAC,CAa/B;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAEpE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAE5D"}
|
package/dist/scan.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { Decoder } from "@valkey/valkey-glide";
|
|
3
|
+
export async function* scanKeyPages(client, pattern, { count, signal }) {
|
|
4
|
+
let cursor = "0";
|
|
5
|
+
do {
|
|
6
|
+
throwIfAborted(signal);
|
|
7
|
+
const [nextCursor, keys] = await client.scan(cursor, {
|
|
8
|
+
match: pattern,
|
|
9
|
+
count,
|
|
10
|
+
decoder: Decoder.Bytes,
|
|
11
|
+
});
|
|
12
|
+
throwIfAborted(signal);
|
|
13
|
+
cursor = glideStringToString(nextCursor);
|
|
14
|
+
yield keys;
|
|
15
|
+
} while (cursor !== "0");
|
|
16
|
+
}
|
|
17
|
+
export function throwIfAborted(signal) {
|
|
18
|
+
if (signal?.aborted)
|
|
19
|
+
throw signal.reason;
|
|
20
|
+
}
|
|
21
|
+
export function glideStringToString(key) {
|
|
22
|
+
return typeof key === "string" ? key : Buffer.from(key).toString("utf8");
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=scan.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.mjs","sourceRoot":"","sources":["../scan.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAsC,MAAM,sBAAsB,CAAC;AAOnF,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,YAAY,CACjC,MAAmB,EACnB,OAAe,EACf,EAAE,KAAK,EAAE,MAAM,EAAuB;IAEtC,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,GAAG,CAAC;QACF,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE;YACnD,KAAK,EAAE,OAAO;YACd,KAAK;YACL,OAAO,EAAE,OAAO,CAAC,KAAK;SACvB,CAAC,CAAC;QACH,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC;IACb,CAAC,QAAQ,MAAM,KAAK,GAAG,EAAE;AAC3B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAA+B;IAC5D,IAAI,MAAM,EAAE,OAAO;QAAE,MAAM,MAAM,CAAC,MAAM,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAgB;IAClD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC3E,CAAC"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,4 +1,40 @@
|
|
|
1
|
-
import type { GlideClient } from "@valkey/valkey-glide";
|
|
1
|
+
import type { GlideClient, GlideString } from "@valkey/valkey-glide";
|
|
2
|
+
export type ScanAndUnlinkKeysOptions = {
|
|
3
|
+
/** Stops before or after each SCAN and UNLINK command boundary. */
|
|
4
|
+
signal?: AbortSignal;
|
|
5
|
+
/** Selects scanned string or Buffer keys to unlink. Defaults to every scanned key. */
|
|
6
|
+
matches?: (key: GlideString) => boolean;
|
|
7
|
+
};
|
|
8
|
+
export type ScanAndUnlinkKeysResult = {
|
|
9
|
+
/** Number of keys returned by SCAN, including any duplicates from its non-snapshot iteration. */
|
|
10
|
+
scannedKeys: number;
|
|
11
|
+
/** Number of scanned keys accepted by matches. */
|
|
12
|
+
matchedKeys: number;
|
|
13
|
+
/** Number of keys confirmed by UNLINK as removed. */
|
|
14
|
+
unlinkedKeys: number;
|
|
15
|
+
};
|
|
16
|
+
export type ExpireKeysWithNoExpiryOptions = {
|
|
17
|
+
/** Valkey SCAN pattern for keys to evaluate. */
|
|
18
|
+
pattern: string;
|
|
19
|
+
/** TTL in seconds to apply only where the key has no expiry. */
|
|
20
|
+
ttl: number;
|
|
21
|
+
/** Selects scanned string or Buffer keys to expire. Defaults to every scanned key. */
|
|
22
|
+
shouldExpire?: (key: GlideString) => boolean;
|
|
23
|
+
/** Stops before or after each SCAN and EXPIRE-batch command boundary. */
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
/** SCAN COUNT hint. Defaults to 500. */
|
|
26
|
+
scanCount?: number;
|
|
27
|
+
/** Maximum number of EXPIRE commands in one non-atomic pipeline. Defaults to 500. */
|
|
28
|
+
batchSize?: number;
|
|
29
|
+
};
|
|
30
|
+
export type ExpireKeysWithNoExpiryResult = {
|
|
31
|
+
/** Number of keys returned by SCAN, including any duplicates from its non-snapshot iteration. */
|
|
32
|
+
scannedKeys: number;
|
|
33
|
+
/** Number of scanned keys accepted by shouldExpire. */
|
|
34
|
+
matchedKeys: number;
|
|
35
|
+
/** Number of keys confirmed by EXPIRE NX as newly given a TTL. */
|
|
36
|
+
expiredKeys: number;
|
|
37
|
+
};
|
|
2
38
|
export type ValkeyClientsOption = {
|
|
3
39
|
cacheClient?: GlideClient;
|
|
4
40
|
rateLimiterClient?: GlideClient;
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../types.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../types.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,MAAM,wBAAwB,GAAG;IACrC,mEAAmE;IACnE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sFAAsF;IACtF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC;IAC7C,yEAAyE;IACzE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAChC,mBAAmB,CAAC,EAAE,WAAW,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,YAAY,GAAG,iBAAiB,CAAC;IACxC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAAC,CAAC,GAAG,MAAM,IAAI;IAC3C,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,oBAAoB,EAAE,iBAAiB,CAAC;IAC7D;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC;IACnC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,CAAC,CAAC,SAAS,MAAM,GACjB;IACE;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;CACpC,GACD;IACE;;;OAGG;IACH,aAAa,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;CACnC,CAAC,CAAC;AAEP,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AACzD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AAE5F,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AACrE,MAAM,MAAM,oBAAoB,GAAG;IACjC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACnD,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAClD,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC"}
|
package/docs/api.md
CHANGED
package/docs/utilities.md
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
These normalization helpers are exported from the package root.
|
|
4
4
|
|
|
5
|
+
## `scanAndUnlinkKeys(client, pattern, options)`
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
scanAndUnlinkKeys(
|
|
9
|
+
client: GlideClient,
|
|
10
|
+
pattern: string,
|
|
11
|
+
options?: {
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
matches?: (key: GlideString) => boolean;
|
|
14
|
+
},
|
|
15
|
+
): Promise<{ scannedKeys: number; matchedKeys: number; unlinkedKeys: number }>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Scans with `COUNT 500`, unlinks every scanned key accepted by `matches`, and returns the number of
|
|
19
|
+
keys scanned, predicate-matched, and confirmed removed by `UNLINK`. Keys are provided to `matches`
|
|
20
|
+
and `UNLINK` as their original string or `Buffer` `GlideString` values.
|
|
21
|
+
|
|
22
|
+
`SCAN` is non-snapshot: concurrent writes can make counts include duplicates, omit keys, or differ
|
|
23
|
+
from the keys that exist when the call returns. The optional `signal` is checked before and after
|
|
24
|
+
every SCAN and UNLINK boundary; its exact abort reason is rethrown without reporting it to the
|
|
25
|
+
configured Valkey error handler.
|
|
26
|
+
|
|
27
|
+
## `expireKeysWithNoExpiry(client, options)`
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
expireKeysWithNoExpiry(
|
|
31
|
+
client: GlideClient,
|
|
32
|
+
options: {
|
|
33
|
+
pattern: string;
|
|
34
|
+
ttl: number;
|
|
35
|
+
shouldExpire?: (key: GlideString) => boolean;
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
scanCount?: number;
|
|
38
|
+
batchSize?: number;
|
|
39
|
+
},
|
|
40
|
+
): Promise<{ scannedKeys: number; matchedKeys: number; expiredKeys: number }>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Scans matching keys and pipelines `EXPIRE NX` commands for every key accepted by `shouldExpire`.
|
|
44
|
+
`EXPIRE NX` atomically sets the TTL only when a key has no existing expiry, so a concurrent TTL
|
|
45
|
+
change is never overwritten. `scanCount` defaults to 500 as a SCAN hint. `batchSize` separately
|
|
46
|
+
defaults to 500 and bounds one non-atomic pipeline.
|
|
47
|
+
|
|
48
|
+
`SCAN` is non-snapshot: concurrent writes can make counts include duplicates, omit keys, or differ
|
|
49
|
+
from the keys that exist when the call returns. The optional `signal` is checked before and after
|
|
50
|
+
each SCAN and EXPIRE-batch boundary; its exact abort reason is rethrown without reporting it to the
|
|
51
|
+
configured Valkey error handler.
|
|
52
|
+
|
|
5
53
|
## `normalizeKey(key)`
|
|
6
54
|
|
|
7
55
|
```ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valkyries",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Valkey utilities for caches, bloom filters, dynamic configuration, and rate limiting.",
|
|
5
5
|
"homepage": "https://github.com/jonathanong/valkyries#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
"@types/node": "^26.1.0",
|
|
66
66
|
"@vitest/coverage-v8": "^4.1.6",
|
|
67
67
|
"github-actionlint": "^1.7.12",
|
|
68
|
-
"oxfmt": "^0.
|
|
68
|
+
"oxfmt": "^0.63.0",
|
|
69
69
|
"oxlint": "^1.65.0",
|
|
70
|
-
"oxlint-tsgolint": "^0.
|
|
70
|
+
"oxlint-tsgolint": "^7.0.2001",
|
|
71
71
|
"tsx": "^4.22.1",
|
|
72
72
|
"typescript": "^7.0.2",
|
|
73
73
|
"vitest": "^4.1.6"
|