unikvs 0.0.9 → 0.0.12

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.
Files changed (63) hide show
  1. package/README.md +3 -0
  2. package/dist/src/_logger.d.ts.map +1 -1
  3. package/dist/src/_merge-variables.d.ts +13 -0
  4. package/dist/src/_merge-variables.d.ts.map +1 -0
  5. package/dist/src/_merge-variables.js +12 -0
  6. package/dist/src/_storage.d.ts +11 -11
  7. package/dist/src/_storage.d.ts.map +1 -1
  8. package/dist/src/_storage.js +31 -22
  9. package/dist/src/_streams.d.ts +20 -0
  10. package/dist/src/_streams.d.ts.map +1 -0
  11. package/dist/src/_streams.js +36 -0
  12. package/dist/src/_to-value-stream.d.ts.map +1 -1
  13. package/dist/src/_to-value-stream.js +44 -6
  14. package/dist/src/_transformer.d.ts +7 -7
  15. package/dist/src/_transformer.d.ts.map +1 -1
  16. package/dist/src/_transformer.js +12 -12
  17. package/dist/src/_valibot.d.ts +6 -7
  18. package/dist/src/_valibot.d.ts.map +1 -1
  19. package/dist/src/_valibot.js +1 -1
  20. package/dist/src/_value-schemas.d.ts +179 -0
  21. package/dist/src/_value-schemas.d.ts.map +1 -0
  22. package/dist/src/_value-schemas.js +150 -0
  23. package/dist/src/errors.d.ts +218 -27
  24. package/dist/src/errors.d.ts.map +1 -1
  25. package/dist/src/errors.js +102 -47
  26. package/dist/src/index.d.ts +3 -3
  27. package/dist/src/index.d.ts.map +1 -1
  28. package/dist/src/index.js +2 -2
  29. package/dist/src/unikvs-config.d.ts +58 -139
  30. package/dist/src/unikvs-config.d.ts.map +1 -1
  31. package/dist/src/unikvs-config.js +41 -46
  32. package/dist/src/unikvs.d.ts +86 -161
  33. package/dist/src/unikvs.d.ts.map +1 -1
  34. package/dist/src/unikvs.js +374 -171
  35. package/dist/src/utils.types.d.ts +1 -3
  36. package/dist/src/utils.types.d.ts.map +1 -1
  37. package/dist/src/value-stream.types.d.ts +5 -6
  38. package/dist/src/value-stream.types.d.ts.map +1 -1
  39. package/dist/src/variables.types.d.ts +11 -0
  40. package/dist/src/variables.types.d.ts.map +1 -0
  41. package/package.json +26 -25
  42. package/src/_merge-variables.ts +19 -0
  43. package/src/_storage.ts +47 -24
  44. package/src/_streams.ts +47 -0
  45. package/src/_to-value-stream.ts +47 -8
  46. package/src/_transformer.ts +13 -13
  47. package/src/_valibot.ts +8 -6
  48. package/src/_value-schemas.ts +362 -0
  49. package/src/errors.ts +280 -68
  50. package/src/index.ts +2 -3
  51. package/src/unikvs-config.ts +142 -167
  52. package/src/unikvs.ts +523 -285
  53. package/src/utils.types.ts +1 -3
  54. package/src/value-stream.types.ts +5 -6
  55. package/src/variables.types.ts +13 -0
  56. package/dist/src/_merge-context.d.ts +0 -13
  57. package/dist/src/_merge-context.d.ts.map +0 -1
  58. package/dist/src/_merge-context.js +0 -12
  59. package/dist/src/context.types.d.ts +0 -17
  60. package/dist/src/context.types.d.ts.map +0 -1
  61. package/src/_merge-context.ts +0 -19
  62. package/src/context.types.ts +0 -19
  63. /package/dist/src/{context.types.js → variables.types.js} +0 -0
@@ -9,24 +9,68 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _UniKvs_instances, _UniKvs_con, _UniKvs_acSet, _UniKvs_context, _UniKvs_destinations, _UniKvs_transformers, _UniKvs_close;
12
+ var _UniKvs_instances, _UniKvs_con, _UniKvs_acSet, _UniKvs_vars, _UniKvs_destinations, _UniKvs_transformers, _UniKvs_valueSchemaResolver, _UniKvs_resolveValueSchema, _UniKvs_close;
13
13
  import { combineSignals } from "abort-signal-utils";
14
14
  import { asyncmux, Asyncmux } from "asyncmux";
15
15
  import logger from "./_logger.js";
16
- import mergeContext from "./_merge-context.js";
16
+ import mergeVariables from "./_merge-variables.js";
17
+ import { isReadableStream } from "./_streams.js";
17
18
  import toValueStream from "./_to-value-stream.js";
18
19
  import * as v from "./_valibot.js";
19
- import { KeyNotFoundError, UniKvsIsOpenError, PluginOperationAggregateError, UniKvsIsNotOpenError, } from "./errors.js";
20
+ import { KeyNotFoundError, UniKvsIsOpenError, UniKvsIsNotOpenError, PluginOperationAggregateError, } from "./errors.js";
20
21
  import UniKvsConfig from "./unikvs-config.js";
21
22
  // -------------------------------------------------------------------------------------------------
22
23
  //
24
+ // 値の検証
25
+ //
26
+ // -------------------------------------------------------------------------------------------------
27
+ /**
28
+ * プレーン値専用のスキーマに ReadableStream が渡されたことを報告するためのスキーマです。
29
+ */
30
+ const PlainValueInputSchema = v.pipe(v.unknown(), v.check((input) => !isReadableStream(input), "Expected a plain value, but received a ReadableStream"));
31
+ /**
32
+ * ストリーム専用のスキーマにプレーン値が渡されたことを報告するためのスキーマです。
33
+ */
34
+ const StreamValueInputSchema = v.pipe(v.unknown(), v.check(isReadableStream, "Expected a ReadableStream, but received a plain value"));
35
+ /**
36
+ * スキーマ情報に基づいて `set` の入力値を検証します。
37
+ *
38
+ * プレーン値はその場で検証し、ストリームはチャンクごとに検証するストリームに変換します。
39
+ *
40
+ * @param info キーに対応するスキーマ情報です。
41
+ * @param value 検証する入力値です。
42
+ * @returns 検証済みの入力値を返します。
43
+ */
44
+ function parseSetValue(info, value) {
45
+ if (isReadableStream(value)) {
46
+ if (info.kind === "plain") {
47
+ // 必ず検証に失敗するため、InvalidInputError が投げられます。
48
+ v.parseInput(PlainValueInputSchema, value);
49
+ }
50
+ // 入力チャンクを検証し、変換後の値を後続のパイプラインへ流します。
51
+ return value.pipeThrough(new TransformStream({
52
+ transform(chunk, controller) {
53
+ controller.enqueue(v.parseInput(info.schema, chunk));
54
+ },
55
+ }));
56
+ }
57
+ if (info.kind === "stream") {
58
+ // 必ず検証に失敗するため、InvalidInputError が投げられます。
59
+ v.parseInput(StreamValueInputSchema, value);
60
+ }
61
+ return v.parseInput(info.schema, value);
62
+ }
63
+ // -------------------------------------------------------------------------------------------------
64
+ //
23
65
  // スキーマ
24
66
  //
25
67
  // -------------------------------------------------------------------------------------------------
26
- const ContextKeySchema = v.string();
27
- const ContextSourceSchema = v.union([
68
+ const VariablesKeySchema = v.string();
69
+ // 配列形式の vars も正当な入力であるため、record スキーマより先に判定する必要があります。
70
+ // record スキーマは配列にもマッチして数値キーのオブジェクトに変換してしまうため、配列形式を先に処理しないと mergeVariables での配列としてのマージが行われません。
71
+ const VariablesSourceSchema = v.union([
72
+ v.array(v.tuple([VariablesKeySchema, v.unknown()])),
28
73
  v.record(v.any(), v.unknown()),
29
- v.array(v.tuple([ContextKeySchema, v.unknown()])),
30
74
  ]);
31
75
  const OpenOptionsSchema = v.object({
32
76
  /**
@@ -34,9 +78,9 @@ const OpenOptionsSchema = v.object({
34
78
  */
35
79
  signal: v.optional(v.instance(AbortSignal)),
36
80
  /**
37
- * 実行時のコンテキスト情報です。
81
+ * 実行時の変数です。
38
82
  */
39
- context: v.optional(ContextSourceSchema),
83
+ vars: v.optional(VariablesSourceSchema),
40
84
  });
41
85
  const OpenArgsSchema = v.tuple([v.optional(OpenOptionsSchema)]);
42
86
  const CloseOptionsSchema = v.object({
@@ -45,16 +89,16 @@ const CloseOptionsSchema = v.object({
45
89
  */
46
90
  signal: v.optional(v.instance(AbortSignal)),
47
91
  /**
48
- * 実行時のコンテキスト情報です。
92
+ * 実行時の変数です。
49
93
  */
50
- context: v.optional(ContextSourceSchema),
94
+ vars: v.optional(VariablesSourceSchema),
51
95
  });
52
96
  const CloseArgsSchema = v.tuple([v.optional(CloseOptionsSchema)]);
53
97
  const SetOptionsSchema = v.object({
54
98
  key: v.string(),
55
99
  value: v.unknown(),
56
100
  signal: v.optional(v.instance(AbortSignal)),
57
- context: v.optional(ContextSourceSchema),
101
+ vars: v.optional(VariablesSourceSchema),
58
102
  });
59
103
  const SetArgsSchema = v.union([
60
104
  v.tuple([SetOptionsSchema]),
@@ -67,7 +111,7 @@ const SetArgsSchema = v.union([
67
111
  const GetOptionsSchema = v.object({
68
112
  key: v.string(),
69
113
  signal: v.optional(v.instance(AbortSignal)),
70
- context: v.optional(ContextSourceSchema),
114
+ vars: v.optional(VariablesSourceSchema),
71
115
  });
72
116
  const GetArgsSchema = v.union([
73
117
  v.tuple([GetOptionsSchema]),
@@ -76,7 +120,7 @@ const GetArgsSchema = v.union([
76
120
  const StreamOptionsSchema = v.object({
77
121
  key: v.string(),
78
122
  signal: v.optional(v.instance(AbortSignal)),
79
- context: v.optional(ContextSourceSchema),
123
+ vars: v.optional(VariablesSourceSchema),
80
124
  });
81
125
  const StreamArgsSchema = v.union([
82
126
  v.tuple([StreamOptionsSchema]),
@@ -85,7 +129,7 @@ const StreamArgsSchema = v.union([
85
129
  const HasOptionsSchema = v.object({
86
130
  key: v.string(),
87
131
  signal: v.optional(v.instance(AbortSignal)),
88
- context: v.optional(ContextSourceSchema),
132
+ vars: v.optional(VariablesSourceSchema),
89
133
  });
90
134
  const HasArgsSchema = v.union([
91
135
  v.tuple([HasOptionsSchema]),
@@ -94,7 +138,7 @@ const HasArgsSchema = v.union([
94
138
  const DeleteOptionsSchema = v.object({
95
139
  key: v.string(),
96
140
  signal: v.optional(v.instance(AbortSignal)),
97
- context: v.optional(ContextSourceSchema),
141
+ vars: v.optional(VariablesSourceSchema),
98
142
  });
99
143
  const DeleteArgsSchema = v.union([
100
144
  v.tuple([DeleteOptionsSchema]),
@@ -106,9 +150,9 @@ const ClearOptionsSchema = v.object({
106
150
  */
107
151
  signal: v.optional(v.instance(AbortSignal)),
108
152
  /**
109
- * 実行時のコンテキスト情報です。
153
+ * 実行時の変数です。
110
154
  */
111
- context: v.optional(ContextSourceSchema),
155
+ vars: v.optional(VariablesSourceSchema),
112
156
  });
113
157
  const ClearArgsSchema = v.tuple([v.optional(ClearOptionsSchema)]);
114
158
  // -------------------------------------------------------------------------------------------------
@@ -121,56 +165,28 @@ const ClearArgsSchema = v.tuple([v.optional(ClearOptionsSchema)]);
121
165
  */
122
166
  const ioLockRegistry = typeof FinalizationRegistry !== "function"
123
167
  ? null
124
- : new FinalizationRegistry((lock) => {
125
- if (!lock.released) {
126
- lock.release();
168
+ : new FinalizationRegistry((held) => {
169
+ if (!held.lock.released) {
170
+ held.lock.release();
127
171
  }
172
+ // valueStream が読み取られないまま GC されたとき、ソースストリームが保持するリソース (S3 レスポンスボディなど) を解放するために破棄します。
173
+ // dispose は valueStream 自身を参照しないため、これを保持しても valueStream のガベージコレクションを妨げません。
174
+ // 失敗しても対処できないので無視します。
175
+ held.dispose().catch((ex) => {
176
+ logger.error `Failed to dispose value stream: ${ex}`;
177
+ });
128
178
  });
129
179
  /**
130
- * UniKvs メインクラスです。
131
- *
132
- * 複数のストレージとトランスフォーマーを統合して KVS 操作を提供します。
133
- *
134
- * @template TKeyValueMapping キーと値のマッピング定義です。
180
+ * [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#client-operations)
135
181
  */
136
182
  export default class UniKvs {
137
- /**
138
- * UniKvs の設定ビルダーを作成します。
139
- *
140
- * @template TKeyValueMapping マッピング定義です。
141
- * @returns 設定ビルダーのインスタンスです。
142
- * @example
143
- * ```typescript
144
- * import { Compression } from "@unikvs/compression";
145
- * import { FileSystem } from "@unikvs/fs.node";
146
- * import { UniKvs, type Value } from "unikvs";
147
- *
148
- * const kvs = UniKvs.config<{
149
- * foo: Value<Uint8Array<ArrayBuffer>>;
150
- * }>()
151
- * .appendTransformer(new Compression("gzip"))
152
- * .appendStorage(new FileSystem(".tmp"))
153
- * .create();
154
- *
155
- * await kvs.open();
156
- *
157
- * await kvs.set("foo", Uint8Array.from([0, 1, 2]));
158
- *
159
- * await kvs.close();
160
- * ```
161
- */
162
- static config() {
163
- return new UniKvsConfig(this);
183
+ static config(options) {
184
+ return new UniKvsConfig(this, options);
164
185
  }
165
186
  /**
166
- * インスタンスを初期化します。
167
- *
168
- * @internal UniKvs の設定ビルダー経由で使用します。
169
- * @param context コンテキストです。
170
- * @param destinations ストレージのリストです。
171
- * @param transformers トランスフォーマーのリストです。
187
+ * [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#client-operations)
172
188
  */
173
- constructor(context, destinations, transformers) {
189
+ constructor(vars, destinations, transformers, valueSchemaResolver = null) {
174
190
  _UniKvs_instances.add(this);
175
191
  /**
176
192
  * 現在の接続状態です。非接続時は null となります。
@@ -178,27 +194,30 @@ export default class UniKvs {
178
194
  _UniKvs_con.set(this, void 0);
179
195
  _UniKvs_acSet.set(this, void 0);
180
196
  /**
181
- * 基本となる実行コンテキスト情報です。
197
+ * 基本となる実行変数情報です。
182
198
  */
183
- _UniKvs_context.set(this, void 0);
199
+ _UniKvs_vars.set(this, void 0);
184
200
  /**
185
- * データの永続化先となるストレージのリストです。
201
+ * データの永続化先となるストレージと前段パイプラインのリストです。
186
202
  */
187
203
  _UniKvs_destinations.set(this, void 0);
188
204
  /**
189
- * データの変換を行うトランスフォーマーのリストです。
205
+ * データの変換を行うトランスフォーマーのリストです。open/close の管理用に全件を保持します。
190
206
  */
191
207
  _UniKvs_transformers.set(this, void 0);
208
+ /**
209
+ * キーに対応する値のスキーマ情報を解決するリゾルバーです。スキーマ未設定時は null となります。
210
+ */
211
+ _UniKvs_valueSchemaResolver.set(this, void 0);
192
212
  __classPrivateFieldSet(this, _UniKvs_con, null, "f");
193
213
  __classPrivateFieldSet(this, _UniKvs_acSet, new Set(), "f");
194
- __classPrivateFieldSet(this, _UniKvs_context, { ...context }, "f");
214
+ __classPrivateFieldSet(this, _UniKvs_vars, { ...vars }, "f");
195
215
  __classPrivateFieldSet(this, _UniKvs_destinations, destinations, "f");
196
216
  __classPrivateFieldSet(this, _UniKvs_transformers, transformers, "f");
217
+ __classPrivateFieldSet(this, _UniKvs_valueSchemaResolver, valueSchemaResolver, "f");
197
218
  }
198
219
  /**
199
- * UniKvs が利用可能であるかを確認します。
200
- *
201
- * @returns 利用可能である場合は true、そうでない場合は false を返します。
220
+ * [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#client-operations)
202
221
  */
203
222
  get isOpen() {
204
223
  return __classPrivateFieldGet(this, _UniKvs_con, "f") !== null;
@@ -208,11 +227,11 @@ export default class UniKvs {
208
227
  throw new UniKvsIsOpenError();
209
228
  }
210
229
  const [options = {}] = v.parseInput(OpenArgsSchema, args);
211
- const { signal: signalOption, context: contextOption } = options;
230
+ const { signal: signalOption, vars: varsOption } = options;
212
231
  const ac = new AbortController();
213
232
  const signal = combineSignals([ac.signal, signalOption]);
214
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
215
- context["unikvs:action"] = "open";
233
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
234
+ vars["unikvs:action"] = "open";
216
235
  signal.throwIfAborted();
217
236
  __classPrivateFieldGet(this, _UniKvs_acSet, "f").add(ac);
218
237
  const dispose = [];
@@ -223,13 +242,13 @@ export default class UniKvs {
223
242
  }
224
243
  const openFns = [];
225
244
  // 各ストレージのオープン処理をリストに追加します。
226
- for (const storage of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
245
+ for (const { storage } of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
227
246
  openFns.push([
228
247
  async () => {
229
- await storage.open(context, signal);
248
+ await storage.open(vars, signal);
230
249
  dispose.push(async () => {
231
250
  try {
232
- await storage.close(context, signal);
251
+ await storage.close(vars, signal);
233
252
  }
234
253
  catch (ex) {
235
254
  logger.error `Failed to close storage: ${ex}`;
@@ -243,10 +262,10 @@ export default class UniKvs {
243
262
  for (const transformer of __classPrivateFieldGet(this, _UniKvs_transformers, "f")) {
244
263
  openFns.push([
245
264
  async () => {
246
- await transformer.open(context, signal);
265
+ await transformer.open(vars, signal);
247
266
  dispose.push(async () => {
248
267
  try {
249
- await transformer.close(context, signal);
268
+ await transformer.close(vars, signal);
250
269
  }
251
270
  catch (ex) {
252
271
  logger.error `Failed to close transformer: ${ex}`;
@@ -267,8 +286,15 @@ export default class UniKvs {
267
286
  }
268
287
  }));
269
288
  if (errors.length > 0) {
289
+ // 中断以外の失敗が混在しない場合は、abort 理由が集約エラーに埋もれないようにそのまま投げます。
290
+ if (signal.aborted && errors.every((error) => error.reason === signal.reason)) {
291
+ throw signal.reason;
292
+ }
270
293
  throw new PluginOperationAggregateError({ action: "open", errors });
271
294
  }
295
+ // すべてのプラグインのオープンが成功した後も、待機中に中断されていないか最終確認します。
296
+ // 中断済みのシグナルを持つ接続を作成すると、isOpen が true でありながら以降のすべての操作が即座に失敗する壊れた状態になります。
297
+ signal.throwIfAborted();
272
298
  __classPrivateFieldSet(this, _UniKvs_con, {
273
299
  ac,
274
300
  io: new Asyncmux(),
@@ -290,9 +316,9 @@ export default class UniKvs {
290
316
  close(...args) {
291
317
  try {
292
318
  const [options = {}] = v.parseInput(CloseArgsSchema, args);
293
- const { signal = AbortSignal.timeout(10e3), context: contextOption } = options;
294
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
295
- context["unikvs:action"] = "close";
319
+ const { signal = AbortSignal.timeout(10e3), vars: varsOption } = options;
320
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
321
+ vars["unikvs:action"] = "close";
296
322
  if (__classPrivateFieldGet(this, _UniKvs_con, "f") === null) {
297
323
  const acArr = [...__classPrivateFieldGet(this, _UniKvs_acSet, "f")];
298
324
  __classPrivateFieldGet(this, _UniKvs_acSet, "f").clear();
@@ -303,7 +329,8 @@ export default class UniKvs {
303
329
  }
304
330
  throw new UniKvsIsNotOpenError();
305
331
  }
306
- const { ac } = __classPrivateFieldGet(this, _UniKvs_con, "f");
332
+ const con = __classPrivateFieldGet(this, _UniKvs_con, "f");
333
+ const { ac } = con;
307
334
  const acArr = [ac, ...__classPrivateFieldGet(this, _UniKvs_acSet, "f")];
308
335
  __classPrivateFieldGet(this, _UniKvs_acSet, "f").clear();
309
336
  for (const ac of acArr) {
@@ -311,13 +338,34 @@ export default class UniKvs {
311
338
  ac.abort(new UniKvsIsNotOpenError());
312
339
  }
313
340
  }
314
- return __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_close).call(this, context, signal, __classPrivateFieldGet(this, _UniKvs_con, "f"));
341
+ return __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_close).call(this, vars, signal, con).catch(async (ex) => {
342
+ // #close が失敗した場合、コネクションの AbortController はすでに abort 済みであり、以降の操作がすべて即座に失敗する壊れた状態になります。
343
+ // そこで接続を破棄して isOpen=false の一貫した状態にし、ベストエフォートでプラグインのクローズ処理を実行します。
344
+ if (__classPrivateFieldGet(this, _UniKvs_con, "f") === con) {
345
+ __classPrivateFieldSet(this, _UniKvs_con, null, "f");
346
+ const disposeSignal = AbortSignal.timeout(10e3);
347
+ await Promise.all([...__classPrivateFieldGet(this, _UniKvs_destinations, "f").map((dest) => dest.storage), ...__classPrivateFieldGet(this, _UniKvs_transformers, "f")].map(async (plugin) => {
348
+ try {
349
+ await plugin.close(vars, disposeSignal);
350
+ }
351
+ catch (reason) {
352
+ logger.error `Failed to close plugin after close failure: ${reason}`;
353
+ }
354
+ }));
355
+ }
356
+ throw ex;
357
+ });
315
358
  }
316
359
  catch (ex) {
317
360
  return Promise.reject(ex);
318
361
  }
319
362
  }
320
- async [(_UniKvs_con = new WeakMap(), _UniKvs_acSet = new WeakMap(), _UniKvs_context = new WeakMap(), _UniKvs_destinations = new WeakMap(), _UniKvs_transformers = new WeakMap(), _UniKvs_instances = new WeakSet(), _UniKvs_close = async function _UniKvs_close(context, signal, con) {
363
+ /**
364
+ * [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#client-operations)
365
+ */
366
+ async [(_UniKvs_con = new WeakMap(), _UniKvs_acSet = new WeakMap(), _UniKvs_vars = new WeakMap(), _UniKvs_destinations = new WeakMap(), _UniKvs_transformers = new WeakMap(), _UniKvs_valueSchemaResolver = new WeakMap(), _UniKvs_instances = new WeakSet(), _UniKvs_resolveValueSchema = function _UniKvs_resolveValueSchema(key) {
367
+ return __classPrivateFieldGet(this, _UniKvs_valueSchemaResolver, "f")?.resolve(key);
368
+ }, _UniKvs_close = async function _UniKvs_close(vars, signal, con) {
321
369
  const lock = await asyncmux(this, signal);
322
370
  try {
323
371
  // ロック待機中に接続状態が変更されていないか再確認します。
@@ -329,10 +377,10 @@ export default class UniKvs {
329
377
  try {
330
378
  const closeFns = [];
331
379
  // ストレージのクローズ処理を登録します。
332
- for (const plugin of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
380
+ for (const { storage } of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
333
381
  closeFns.push([
334
382
  async () => {
335
- await plugin.close(context, signal);
383
+ await storage.close(vars, signal);
336
384
  },
337
385
  "storage",
338
386
  ]);
@@ -341,7 +389,7 @@ export default class UniKvs {
341
389
  for (const plugin of __classPrivateFieldGet(this, _UniKvs_transformers, "f")) {
342
390
  closeFns.push([
343
391
  async () => {
344
- await plugin.close(context, signal);
392
+ await plugin.close(vars, signal);
345
393
  },
346
394
  "transformer",
347
395
  ]);
@@ -381,12 +429,14 @@ export default class UniKvs {
381
429
  throw new UniKvsIsNotOpenError();
382
430
  }
383
431
  const [options] = v.parseInput(SetArgsSchema, args);
384
- const { key, value, signal: signalOption, context: contextOption } = options;
432
+ const { key, signal: signalOption, vars: varsOption } = options;
433
+ const valueSchema = __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_resolveValueSchema).call(this, key);
434
+ const value = valueSchema ? parseSetValue(valueSchema, options.value) : options.value;
385
435
  const { ac, io } = __classPrivateFieldGet(this, _UniKvs_con, "f");
386
436
  const signal = combineSignals([ac.signal, signalOption]);
387
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
388
- context["unikvs:action"] = "set";
389
- context["unikvs:key"] = key;
437
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
438
+ vars["unikvs:action"] = "set";
439
+ vars["unikvs:key"] = key;
390
440
  const lock = await asyncmux(this, signal);
391
441
  try {
392
442
  // ロック待機中に接続状態が変更されていないか再確認します。
@@ -395,28 +445,75 @@ export default class UniKvs {
395
445
  }
396
446
  const errors = [];
397
447
  const errorStorageSet = new Set();
398
- if (value instanceof ReadableStream) {
399
- // 各トランスフォーマーを通してデータをエンコードストリームへ変換します。
400
- let data = value;
401
- for (const transformer of __classPrivateFieldGet(this, _UniKvs_transformers, "f")) {
402
- const e = await transformer.getEncodable(context, signal);
403
- data = data.pipeThrough(e);
448
+ if (isReadableStream(value)) {
449
+ // 各ストレージ専用の前段パイプラインを通すため、tee で分岐しながらエンコードストリームを構築します。
450
+ // 最長の前段パイプラインを基準にし、ストレージの登録順に分岐点を作ります。
451
+ let longest = [];
452
+ for (const dest of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
453
+ if (dest.transformers.length > longest.length) {
454
+ longest = dest.transformers;
455
+ }
456
+ }
457
+ let cur = value;
458
+ const branches = [];
459
+ const built = [];
460
+ try {
461
+ let applied = 0;
462
+ for (let i = 0; i < __classPrivateFieldGet(this, _UniKvs_destinations, "f").length; i++) {
463
+ const dest = __classPrivateFieldGet(this, _UniKvs_destinations, "f")[i];
464
+ while (applied < dest.transformers.length) {
465
+ const e = await longest[applied].getEncodable(vars, signal);
466
+ cur = cur.pipeThrough(e);
467
+ applied++;
468
+ }
469
+ if (i === __classPrivateFieldGet(this, _UniKvs_destinations, "f").length - 1) {
470
+ branches[i] = cur;
471
+ }
472
+ else {
473
+ const [branch, rest] = cur.tee();
474
+ branches[i] = branch;
475
+ built.push(branch);
476
+ cur = rest;
477
+ }
478
+ }
479
+ }
480
+ catch (ex) {
481
+ // チェーンの構築中に失敗した場合、パイプが保持するソースストリームのリソースを解放するためにキャンセルします。
482
+ // キャンセルしないとソースストリームはロックされたままリークします。
483
+ try {
484
+ await cur.cancel(ex);
485
+ }
486
+ catch {
487
+ // キャンセルに失敗しても元の例外の伝播を優先します。
488
+ }
489
+ await Promise.all(built.map(async (branch) => {
490
+ try {
491
+ await branch.cancel(ex);
492
+ }
493
+ catch {
494
+ // キャンセルに失敗しても元の例外の伝播を優先します。
495
+ }
496
+ }));
497
+ throw ex;
404
498
  }
405
499
  const lock = await io.lock({ key, signal });
406
500
  try {
407
- await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (storage, i) => {
501
+ await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (dest, i) => {
502
+ // tee ブランチはキャンセルされるまで健康なブランチの読み取り分のチャンクを保持し続けるため、失敗時に放棄したブランチを確実にキャンセルできるよう参照を保持します。
503
+ const branch = branches[i];
408
504
  try {
409
- // 複数のストレージがある場合は、tee メソッドを使用してストリームを分岐させます。
410
- let r = data;
411
- if (i !== __classPrivateFieldGet(this, _UniKvs_destinations, "f").length - 1) {
412
- [r, data] = data.tee();
413
- }
414
- const w = await storage.getWritable(context, signal, key);
415
- await r.pipeTo(w, { signal });
505
+ const w = await dest.storage.getWritable(vars, signal, key);
506
+ await branch.pipeTo(w, { signal });
416
507
  }
417
508
  catch (reason) {
509
+ try {
510
+ await branch.cancel(reason);
511
+ }
512
+ catch {
513
+ // キャンセルに失敗してもエラー集約を優先します。
514
+ }
418
515
  errors.push({ reason });
419
- errorStorageSet.add(storage);
516
+ errorStorageSet.add(dest);
420
517
  }
421
518
  }));
422
519
  }
@@ -425,20 +522,27 @@ export default class UniKvs {
425
522
  }
426
523
  }
427
524
  else {
428
- // 登録されているトランスフォーマーを順番に適用してデータをエンコードします。
429
- let data = value;
430
- for (const transformer of __classPrivateFieldGet(this, _UniKvs_transformers, "f")) {
431
- data = await transformer.encode(context, signal, data);
525
+ // 各ストレージ専用の前段パイプラインでデータをエンコードします。共有プレフィックスは使い回します。
526
+ let longest = [];
527
+ for (const dest of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
528
+ if (dest.transformers.length > longest.length) {
529
+ longest = dest.transformers;
530
+ }
531
+ }
532
+ const prefix = [value];
533
+ for (const transformer of longest) {
534
+ prefix.push(await transformer.encode(vars, signal, prefix[prefix.length - 1]));
432
535
  }
536
+ const encoded = __classPrivateFieldGet(this, _UniKvs_destinations, "f").map((dest) => prefix[dest.transformers.length]);
433
537
  const lock = await io.lock({ key, signal });
434
538
  try {
435
- await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (storage) => {
539
+ await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (dest, i) => {
436
540
  try {
437
- await storage.write(context, signal, key, data);
541
+ await dest.storage.write(vars, signal, key, encoded[i]);
438
542
  }
439
543
  catch (reason) {
440
544
  errors.push({ reason });
441
- errorStorageSet.add(storage);
545
+ errorStorageSet.add(dest);
442
546
  }
443
547
  }));
444
548
  }
@@ -455,12 +559,12 @@ export default class UniKvs {
455
559
  });
456
560
  {
457
561
  const errors = [];
458
- await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (storage) => {
459
- if (errorStorageSet.has(storage)) {
562
+ await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (dest) => {
563
+ if (errorStorageSet.has(dest)) {
460
564
  return;
461
565
  }
462
566
  try {
463
- await storage.onOtherWriteError(context, signal, key, error);
567
+ await dest.storage.onOtherWriteError(vars, signal, key, error);
464
568
  }
465
569
  catch (ex) {
466
570
  errors.push(ex);
@@ -482,12 +586,13 @@ export default class UniKvs {
482
586
  throw new UniKvsIsNotOpenError();
483
587
  }
484
588
  const [options] = v.parseInput(GetArgsSchema, args);
485
- const { key, signal: signalOption, context: contextOption } = options;
589
+ const { key, signal: signalOption, vars: varsOption } = options;
590
+ const valueSchema = __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_resolveValueSchema).call(this, key);
486
591
  const { ac, io } = __classPrivateFieldGet(this, _UniKvs_con, "f");
487
592
  const signal = combineSignals([ac.signal, signalOption]);
488
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
489
- context["unikvs:action"] = "get";
490
- context["unikvs:key"] = key;
593
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
594
+ vars["unikvs:action"] = "get";
595
+ vars["unikvs:key"] = key;
491
596
  const lock = await asyncmux.readonly(this, signal);
492
597
  try {
493
598
  // ロック待機中に接続状態が変更されていないか再確認します。
@@ -496,27 +601,57 @@ export default class UniKvs {
496
601
  }
497
602
  const NONE = {};
498
603
  let data = NONE;
604
+ let transformers = [];
605
+ const errors = [];
499
606
  const lock = await io.rLock({ key, signal });
500
607
  try {
501
608
  // 各ストレージを巡回し、最初に見つかったデータを取得します。
502
- for (const storage of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
503
- if (await storage.exists(context, signal, key)) {
504
- data = await storage.read(context, signal, key);
609
+ // あるストレージの読み取りに失敗しても、他のストレージからデータを取得できるようにフォールバックします。
610
+ for (const dest of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
611
+ try {
612
+ if (!(await dest.storage.exists(vars, signal, key))) {
613
+ continue;
614
+ }
615
+ data = await dest.storage.read(vars, signal, key);
616
+ transformers = dest.transformers;
505
617
  break;
506
618
  }
619
+ catch (ex) {
620
+ if (signal.aborted) {
621
+ throw ex;
622
+ }
623
+ errors.push({ reason: ex });
624
+ logger.error `Failed to read from a storage: ${ex}`;
625
+ }
507
626
  }
508
627
  }
509
628
  finally {
510
629
  lock.release();
511
630
  }
512
631
  if (data === NONE) {
513
- throw new KeyNotFoundError({ key });
514
- }
515
- // トランスフォーマーを逆順に適用してデータをデコードします。
516
- if (__classPrivateFieldGet(this, _UniKvs_transformers, "f").length > 0) {
517
- for (const transformer of __classPrivateFieldGet(this, _UniKvs_transformers, "f").toReversed()) {
518
- data = await transformer.decode(context, signal, data);
632
+ const args = { key };
633
+ switch (errors.length) {
634
+ case 0:
635
+ break;
636
+ case 1:
637
+ args.cause = errors[0].reason;
638
+ break;
639
+ default:
640
+ args.cause = new PluginOperationAggregateError({
641
+ plugin: "storage",
642
+ action: "read",
643
+ errors,
644
+ });
519
645
  }
646
+ throw new KeyNotFoundError(args);
647
+ }
648
+ // 見つかったストレージ専用の前段パイプラインを逆順に適用してデータをデコードします。
649
+ for (const transformer of transformers.toReversed()) {
650
+ data = await transformer.decode(vars, signal, data);
651
+ }
652
+ // デコード後のデータを検証します。
653
+ if (valueSchema) {
654
+ data = v.parseOutput(valueSchema.schema, data);
520
655
  }
521
656
  return data;
522
657
  }
@@ -529,13 +664,14 @@ export default class UniKvs {
529
664
  throw new UniKvsIsNotOpenError();
530
665
  }
531
666
  const [options] = v.parseInput(StreamArgsSchema, args);
532
- const { key, signal: signalOption, context: contextOption } = options;
667
+ const { key, signal: signalOption, vars: varsOption } = options;
668
+ const valueSchema = __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_resolveValueSchema).call(this, key);
533
669
  const { ac, io } = __classPrivateFieldGet(this, _UniKvs_con, "f");
534
670
  const signal = combineSignals([ac.signal, signalOption]);
535
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
536
- context["unikvs:action"] = "stream";
537
- context["unikvs:key"] = key;
538
- const lock = await asyncmux(this, signal);
671
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
672
+ vars["unikvs:action"] = "stream";
673
+ vars["unikvs:key"] = key;
674
+ const lock = await asyncmux.readonly(this, signal);
539
675
  try {
540
676
  // ロック待機中に接続状態が変更されていないか再確認します。
541
677
  if (__classPrivateFieldGet(this, _UniKvs_con, "f") === null) {
@@ -543,31 +679,61 @@ export default class UniKvs {
543
679
  }
544
680
  const NONE = {};
545
681
  let r = NONE;
682
+ let transformers = [];
683
+ const errors = [];
546
684
  const lock = await io.rLock({ key, signal });
547
685
  try {
548
686
  // 各ストレージを巡回し、最初に見つかったデータを取得します。
549
- for (const storage of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
550
- if (await storage.exists(context, signal, key)) {
551
- r = await storage.getReadable(context, signal, key);
687
+ // あるストレージの読み取りに失敗しても、他のストレージからデータを取得できるようにフォールバックします。
688
+ for (const dest of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
689
+ try {
690
+ if (!(await dest.storage.exists(vars, signal, key))) {
691
+ continue;
692
+ }
693
+ r = await dest.storage.getReadable(vars, signal, key);
694
+ transformers = dest.transformers;
552
695
  break;
553
696
  }
697
+ catch (ex) {
698
+ if (signal.aborted) {
699
+ throw ex;
700
+ }
701
+ errors.push({ reason: ex });
702
+ logger.error `Failed to read from a storage: ${ex}`;
703
+ }
554
704
  }
555
705
  if (r === NONE) {
556
- throw new KeyNotFoundError({ key });
557
- }
558
- // トランスフォーマーを逆順に適用し、デコード用トランスフォームを連結します。
559
- if (__classPrivateFieldGet(this, _UniKvs_transformers, "f").length > 0) {
560
- for (const transformer of __classPrivateFieldGet(this, _UniKvs_transformers, "f").toReversed()) {
561
- const d = await transformer.getDecodable(context, signal);
562
- r = r.pipeThrough(d);
706
+ const args = { key };
707
+ switch (errors.length) {
708
+ case 0:
709
+ break;
710
+ case 1:
711
+ args.cause = errors[0].reason;
712
+ break;
713
+ default:
714
+ args.cause = new PluginOperationAggregateError({
715
+ plugin: "storage",
716
+ action: "read",
717
+ errors,
718
+ });
563
719
  }
720
+ throw new KeyNotFoundError(args);
721
+ }
722
+ // 見つかったストレージ専用の前段パイプラインを逆順に適用し、デコード用トランスフォームを連結します。
723
+ for (const transformer of transformers.toReversed()) {
724
+ const d = await transformer.getDecodable(vars, signal);
725
+ r = r.pipeThrough(d);
726
+ }
727
+ // デコード後のチャンクを検証します。
728
+ if (valueSchema) {
729
+ r = r.pipeThrough(new TransformStream({
730
+ transform(chunk, controller) {
731
+ controller.enqueue(v.parseOutput(valueSchema.schema, chunk));
732
+ },
733
+ }));
564
734
  }
565
735
  if (!ioLockRegistry) {
566
736
  return toValueStream(r, async () => {
567
- try {
568
- await r.cancel();
569
- }
570
- catch { }
571
737
  try {
572
738
  lock.release();
573
739
  }
@@ -580,20 +746,26 @@ export default class UniKvs {
580
746
  ioLockRegistry.unregister(unregisterToken);
581
747
  }
582
748
  catch { }
583
- try {
584
- await r.cancel();
585
- }
586
- catch { }
587
749
  try {
588
750
  lock.release();
589
751
  }
590
752
  catch { }
591
753
  });
592
- // valueStream が GC されるタイミングでストリームが終了していなければロックを自動解放します。
593
- ioLockRegistry.register(valueStream, lock, unregisterToken);
754
+ // valueStream が GC されるタイミングでストリームが終了していなければロックを自動解放するとともに、ソースストリームが保持するリソース (S3 レスポンスボディなど) を解放できるように dispose を記録します。
755
+ ioLockRegistry.register(valueStream, {
756
+ lock,
757
+ dispose: valueStream.dispose,
758
+ }, unregisterToken);
594
759
  return valueStream;
595
760
  }
596
761
  catch (ex) {
762
+ if (r !== NONE) {
763
+ // getReadable 成功後のセットアップ中に失敗した場合、ソースストリームが保持するリソース (S3 レスポンスボディなど) を解放するためにキャンセルします。
764
+ try {
765
+ await r.cancel(ex);
766
+ }
767
+ catch { }
768
+ }
597
769
  lock.release();
598
770
  throw ex;
599
771
  }
@@ -607,13 +779,15 @@ export default class UniKvs {
607
779
  throw new UniKvsIsNotOpenError();
608
780
  }
609
781
  const [options] = v.parseInput(HasArgsSchema, args);
610
- const { key, signal: signalOption, context: contextOption } = options;
782
+ const { key, signal: signalOption, vars: varsOption } = options;
783
+ // キーがキースキーマに一致するかを検証します。
784
+ __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_resolveValueSchema).call(this, key);
611
785
  const { ac, io } = __classPrivateFieldGet(this, _UniKvs_con, "f");
612
786
  const signal = combineSignals([ac.signal, signalOption]);
613
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
614
- context["unikvs:action"] = "has";
615
- context["unikvs:key"] = key;
616
- const lock = await asyncmux(this, signal);
787
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
788
+ vars["unikvs:action"] = "has";
789
+ vars["unikvs:key"] = key;
790
+ const lock = await asyncmux.readonly(this, signal);
617
791
  try {
618
792
  // ロック待機中に接続状態が変更されていないか再確認します。
619
793
  if (__classPrivateFieldGet(this, _UniKvs_con, "f") === null) {
@@ -622,10 +796,37 @@ export default class UniKvs {
622
796
  const lock = await io.rLock({ key, signal });
623
797
  try {
624
798
  // いずれかのストレージに存在すれば true を返します。
625
- for (const storage of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
626
- if (await storage.exists(context, signal, key)) {
627
- return true;
799
+ // あるストレージの存在確認に失敗しても、他のストレージで存在を確認できるようにフォールバックします。
800
+ const errors = [];
801
+ for (const { storage } of __classPrivateFieldGet(this, _UniKvs_destinations, "f")) {
802
+ try {
803
+ if (await storage.exists(vars, signal, key)) {
804
+ return true;
805
+ }
806
+ }
807
+ catch (ex) {
808
+ if (signal.aborted) {
809
+ throw ex;
810
+ }
811
+ errors.push({ reason: ex });
812
+ logger.error `Failed to check existence in a storage: ${ex}`;
813
+ }
814
+ }
815
+ // すべてのストレージで存在を確認できなかった場合は結果が不明のため、get() と同様にエラーとして報告します。
816
+ if (errors.length > 0) {
817
+ const args = { key };
818
+ switch (errors.length) {
819
+ case 1:
820
+ args.cause = errors[0].reason;
821
+ break;
822
+ default:
823
+ args.cause = new PluginOperationAggregateError({
824
+ plugin: "storage",
825
+ action: "read",
826
+ errors,
827
+ });
628
828
  }
829
+ throw new KeyNotFoundError(args);
629
830
  }
630
831
  return false;
631
832
  }
@@ -642,12 +843,14 @@ export default class UniKvs {
642
843
  throw new UniKvsIsNotOpenError();
643
844
  }
644
845
  const [options] = v.parseInput(DeleteArgsSchema, args);
645
- const { key, signal: signalOption, context: contextOption } = options;
846
+ const { key, signal: signalOption, vars: varsOption } = options;
847
+ // キーがキースキーマに一致するかを検証します。
848
+ __classPrivateFieldGet(this, _UniKvs_instances, "m", _UniKvs_resolveValueSchema).call(this, key);
646
849
  const { ac, io } = __classPrivateFieldGet(this, _UniKvs_con, "f");
647
850
  const signal = combineSignals([ac.signal, signalOption]);
648
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
649
- context["unikvs:action"] = "delete";
650
- context["unikvs:key"] = key;
851
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
852
+ vars["unikvs:action"] = "delete";
853
+ vars["unikvs:key"] = key;
651
854
  const lock = await asyncmux(this, signal);
652
855
  try {
653
856
  // ロック待機中に接続状態が変更されていないか再確認します。
@@ -659,10 +862,10 @@ export default class UniKvs {
659
862
  // すべてのストレージから対象データを削除します。
660
863
  // すべての処理を並列に実行し、エラーが発生した場合は集約します。
661
864
  const errors = [];
662
- await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (storage) => {
865
+ await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async ({ storage }) => {
663
866
  try {
664
- if (await storage.exists(context, signal, key)) {
665
- await storage.delete(context, signal, key);
867
+ if (await storage.exists(vars, signal, key)) {
868
+ await storage.delete(vars, signal, key);
666
869
  }
667
870
  }
668
871
  catch (reason) {
@@ -686,11 +889,11 @@ export default class UniKvs {
686
889
  throw new UniKvsIsNotOpenError();
687
890
  }
688
891
  const [options = {}] = v.parseInput(ClearArgsSchema, args);
689
- const { signal: signalOption, context: contextOption } = options;
892
+ const { signal: signalOption, vars: varsOption } = options;
690
893
  const { ac, io } = __classPrivateFieldGet(this, _UniKvs_con, "f");
691
894
  const signal = combineSignals([ac.signal, signalOption]);
692
- const context = mergeContext(__classPrivateFieldGet(this, _UniKvs_context, "f"), contextOption);
693
- context["unikvs:action"] = "clear";
895
+ const vars = mergeVariables(__classPrivateFieldGet(this, _UniKvs_vars, "f"), varsOption);
896
+ vars["unikvs:action"] = "clear";
694
897
  const lock = await asyncmux(this, signal);
695
898
  try {
696
899
  // ロック待機中に接続状態が変更されていないか再確認します。
@@ -702,9 +905,9 @@ export default class UniKvs {
702
905
  // すべてのストレージで一括削除を実行します。
703
906
  // すべての処理を並列に実行し、エラーが発生した場合は集約します。
704
907
  const errors = [];
705
- await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async (storage) => {
908
+ await Promise.all(__classPrivateFieldGet(this, _UniKvs_destinations, "f").map(async ({ storage }) => {
706
909
  try {
707
- await storage.clear(context, signal);
910
+ await storage.clear(vars, signal);
708
911
  }
709
912
  catch (reason) {
710
913
  errors.push({ reason });