unikvs 0.0.4 → 0.0.6
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/src/_storage.d.ts +9 -9
- package/dist/src/_storage.d.ts.map +1 -1
- package/dist/src/_storage.js +13 -5
- package/dist/src/_transformer.d.ts +2 -2
- package/dist/src/_transformer.d.ts.map +1 -1
- package/dist/src/_transformer.js +10 -4
- package/dist/src/_valibot.d.ts +12 -9
- package/dist/src/_valibot.d.ts.map +1 -1
- package/dist/src/_valibot.js +14 -3
- package/dist/src/errors.d.ts +9 -2
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +25 -15
- package/dist/src/unikvs-config.d.ts +5 -5
- package/dist/src/unikvs-config.d.ts.map +1 -1
- package/dist/src/unikvs-config.js +1 -1
- package/dist/src/unikvs.d.ts +53 -30
- package/dist/src/unikvs.d.ts.map +1 -1
- package/dist/src/unikvs.js +185 -152
- package/package.json +20 -18
- package/src/_storage.ts +30 -13
- package/src/_transformer.ts +16 -6
- package/src/_valibot.ts +48 -10
- package/src/errors.ts +31 -3
- package/src/unikvs-config.ts +5 -8
- package/src/unikvs.ts +323 -309
package/src/unikvs.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { Context, IReadableStream,
|
|
1
|
+
import type { Context, IReadableStream, IStorage } from "@unikvs/core";
|
|
2
2
|
import { asyncmux, Asyncmux, type AsyncmuxLock } from "asyncmux";
|
|
3
|
-
import * as v from "valibot";
|
|
4
3
|
|
|
5
4
|
import combineSignals from "./_combine-signals.js";
|
|
6
5
|
import logger from "./_logger.js";
|
|
7
6
|
import mergeContext from "./_merge-context.js";
|
|
8
|
-
import
|
|
7
|
+
import UniKvsStorage from "./_storage.js";
|
|
9
8
|
import toValueStream from "./_to-value-stream.js";
|
|
10
9
|
import UniKvsTransformer from "./_transformer.js";
|
|
11
|
-
import
|
|
10
|
+
import * as v from "./_valibot.js";
|
|
12
11
|
import type { ContextSource } from "./context.types.js";
|
|
13
12
|
import {
|
|
14
13
|
KeyNotFoundError,
|
|
@@ -68,39 +67,149 @@ export type KeyofKeyValueMappingHasStreamValue<TKeyValueMapping extends KeyValue
|
|
|
68
67
|
|
|
69
68
|
// -------------------------------------------------------------------------------------------------
|
|
70
69
|
//
|
|
71
|
-
//
|
|
70
|
+
// スキーマ
|
|
72
71
|
//
|
|
73
72
|
// -------------------------------------------------------------------------------------------------
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const ContextKeySchema = v.string();
|
|
75
|
+
|
|
76
|
+
const ContextSourceSchema = v.union([
|
|
77
|
+
v.record(v.any(), v.unknown()),
|
|
78
|
+
v.array(v.tuple([ContextKeySchema, v.unknown()])),
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
const OpenOptionsSchema = v.object({
|
|
79
82
|
/**
|
|
80
83
|
* 処理の中断を通知するためのシグナルです。
|
|
81
84
|
*/
|
|
82
|
-
|
|
85
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
83
86
|
|
|
84
87
|
/**
|
|
85
88
|
* 実行時のコンテキスト情報です。
|
|
86
89
|
*/
|
|
87
|
-
|
|
88
|
-
};
|
|
90
|
+
context: v.optional(ContextSourceSchema),
|
|
91
|
+
});
|
|
89
92
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
export type CloseOptions = {
|
|
93
|
+
const OpenArgsSchema = v.tuple([v.optional(OpenOptionsSchema)]);
|
|
94
|
+
|
|
95
|
+
const CloseOptionsSchema = v.object({
|
|
94
96
|
/**
|
|
95
97
|
* 処理の中断を通知するためのシグナルです。
|
|
96
98
|
*/
|
|
97
|
-
|
|
99
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
98
100
|
|
|
99
101
|
/**
|
|
100
102
|
* 実行時のコンテキスト情報です。
|
|
101
103
|
*/
|
|
102
|
-
|
|
103
|
-
};
|
|
104
|
+
context: v.optional(ContextSourceSchema),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const CloseArgsSchema = v.tuple([v.optional(CloseOptionsSchema)]);
|
|
108
|
+
|
|
109
|
+
const SetOptionsSchema = v.object({
|
|
110
|
+
key: v.string(),
|
|
111
|
+
value: v.unknown(),
|
|
112
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
113
|
+
context: v.optional(ContextSourceSchema),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const SetArgsSchema = v.union([
|
|
117
|
+
v.tuple([SetOptionsSchema]),
|
|
118
|
+
v.pipe(
|
|
119
|
+
v.tuple([
|
|
120
|
+
SetOptionsSchema.entries.key,
|
|
121
|
+
SetOptionsSchema.entries.value,
|
|
122
|
+
v.optional(v.omit(SetOptionsSchema, ["key", "value"])),
|
|
123
|
+
]),
|
|
124
|
+
v.transform(([key, value, options]) => [{ ...options, key, value }]),
|
|
125
|
+
),
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
const GetOptionsSchema = v.object({
|
|
129
|
+
key: v.string(),
|
|
130
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
131
|
+
context: v.optional(ContextSourceSchema),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const GetArgsSchema = v.union([
|
|
135
|
+
v.tuple([GetOptionsSchema]),
|
|
136
|
+
v.pipe(
|
|
137
|
+
v.tuple([GetOptionsSchema.entries.key, v.optional(v.omit(GetOptionsSchema, ["key"]))]),
|
|
138
|
+
v.transform(([key, options]) => [{ ...options, key }]),
|
|
139
|
+
),
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
const StreamOptionsSchema = v.object({
|
|
143
|
+
key: v.string(),
|
|
144
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
145
|
+
context: v.optional(ContextSourceSchema),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const StreamArgsSchema = v.union([
|
|
149
|
+
v.tuple([StreamOptionsSchema]),
|
|
150
|
+
v.pipe(
|
|
151
|
+
v.tuple([StreamOptionsSchema.entries.key, v.optional(v.omit(StreamOptionsSchema, ["key"]))]),
|
|
152
|
+
v.transform(([key, options]) => [{ ...options, key }]),
|
|
153
|
+
),
|
|
154
|
+
]);
|
|
155
|
+
|
|
156
|
+
const HasOptionsSchema = v.object({
|
|
157
|
+
key: v.string(),
|
|
158
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
159
|
+
context: v.optional(ContextSourceSchema),
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const HasArgsSchema = v.union([
|
|
163
|
+
v.tuple([HasOptionsSchema]),
|
|
164
|
+
v.pipe(
|
|
165
|
+
v.tuple([HasOptionsSchema.entries.key, v.optional(v.omit(HasOptionsSchema, ["key"]))]),
|
|
166
|
+
v.transform(([key, options]) => [{ ...options, key }]),
|
|
167
|
+
),
|
|
168
|
+
]);
|
|
169
|
+
|
|
170
|
+
const DeleteOptionsSchema = v.object({
|
|
171
|
+
key: v.string(),
|
|
172
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
173
|
+
context: v.optional(ContextSourceSchema),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const DeleteArgsSchema = v.union([
|
|
177
|
+
v.tuple([DeleteOptionsSchema]),
|
|
178
|
+
v.pipe(
|
|
179
|
+
v.tuple([DeleteOptionsSchema.entries.key, v.optional(v.omit(DeleteOptionsSchema, ["key"]))]),
|
|
180
|
+
v.transform(([key, options]) => [{ ...options, key }]),
|
|
181
|
+
),
|
|
182
|
+
]);
|
|
183
|
+
|
|
184
|
+
const ClearOptionsSchema = v.object({
|
|
185
|
+
/**
|
|
186
|
+
* 処理の中断を通知するためのシグナルです。
|
|
187
|
+
*/
|
|
188
|
+
signal: v.optional(v.instance(AbortSignal)),
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* 実行時のコンテキスト情報です。
|
|
192
|
+
*/
|
|
193
|
+
context: v.optional(ContextSourceSchema),
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const ClearArgsSchema = v.tuple([v.optional(ClearOptionsSchema)]);
|
|
197
|
+
|
|
198
|
+
// -------------------------------------------------------------------------------------------------
|
|
199
|
+
//
|
|
200
|
+
// 型定義
|
|
201
|
+
//
|
|
202
|
+
// -------------------------------------------------------------------------------------------------
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* オープン操作時のオプションです。
|
|
206
|
+
*/
|
|
207
|
+
export type OpenOptions = v.InferInput<typeof OpenOptionsSchema>;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* クローズ操作時のオプションです。
|
|
211
|
+
*/
|
|
212
|
+
export type CloseOptions = v.InferInput<typeof CloseOptionsSchema>;
|
|
104
213
|
|
|
105
214
|
/**
|
|
106
215
|
* 保存操作時のオプションです。
|
|
@@ -138,7 +247,7 @@ export type SetOptions<
|
|
|
138
247
|
*
|
|
139
248
|
* @template TKey 対象となるキーの型です。
|
|
140
249
|
*/
|
|
141
|
-
export type GetOptions<TKey = Key> = {
|
|
250
|
+
export type GetOptions<TKey = IStorage.Key> = {
|
|
142
251
|
/**
|
|
143
252
|
* 操作対象を識別するためのキーです。
|
|
144
253
|
*/
|
|
@@ -160,7 +269,7 @@ export type GetOptions<TKey = Key> = {
|
|
|
160
269
|
*
|
|
161
270
|
* @template TKey 対象となるキーの型です。
|
|
162
271
|
*/
|
|
163
|
-
export type StreamOptions<TKey = Key> = {
|
|
272
|
+
export type StreamOptions<TKey = IStorage.Key> = {
|
|
164
273
|
/**
|
|
165
274
|
* 操作対象を識別するためのキーです。
|
|
166
275
|
*/
|
|
@@ -182,7 +291,7 @@ export type StreamOptions<TKey = Key> = {
|
|
|
182
291
|
*
|
|
183
292
|
* @template TKey 対象となるキーの型です。
|
|
184
293
|
*/
|
|
185
|
-
export type HasOptions<TKey = Key> = {
|
|
294
|
+
export type HasOptions<TKey = IStorage.Key> = {
|
|
186
295
|
/**
|
|
187
296
|
* 操作対象を識別するためのキーです。
|
|
188
297
|
*/
|
|
@@ -204,7 +313,7 @@ export type HasOptions<TKey = Key> = {
|
|
|
204
313
|
*
|
|
205
314
|
* @template TKey 対象となるキーの型です。
|
|
206
315
|
*/
|
|
207
|
-
export type DeleteOptions<TKey = Key> = {
|
|
316
|
+
export type DeleteOptions<TKey = IStorage.Key> = {
|
|
208
317
|
/**
|
|
209
318
|
* 操作対象を識別するためのキーです。
|
|
210
319
|
*/
|
|
@@ -224,126 +333,7 @@ export type DeleteOptions<TKey = Key> = {
|
|
|
224
333
|
/**
|
|
225
334
|
* 全削除操作時のオプションです。
|
|
226
335
|
*/
|
|
227
|
-
export type ClearOptions =
|
|
228
|
-
/**
|
|
229
|
-
* 処理の中断を通知するためのシグナルです。
|
|
230
|
-
*/
|
|
231
|
-
readonly signal?: AbortSignal | undefined;
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* 実行時のコンテキスト情報です。
|
|
235
|
-
*/
|
|
236
|
-
readonly context?: ContextSource | undefined;
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
// -------------------------------------------------------------------------------------------------
|
|
240
|
-
//
|
|
241
|
-
// スキーマ
|
|
242
|
-
//
|
|
243
|
-
// -------------------------------------------------------------------------------------------------
|
|
244
|
-
|
|
245
|
-
const ContextKeySchema = v.union([v.string(), v.symbol(), v.number()]);
|
|
246
|
-
|
|
247
|
-
const ContextSourceSchema = v.union([
|
|
248
|
-
v.record(v.any(), v.unknown()),
|
|
249
|
-
v.array(v.tuple([ContextKeySchema, v.unknown()])),
|
|
250
|
-
]);
|
|
251
|
-
|
|
252
|
-
const OpenOptionsSchema = v.object({
|
|
253
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
254
|
-
context: v.optional(ContextSourceSchema),
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
const OpenArgsSchema = v.tuple([v.optional(OpenOptionsSchema)]);
|
|
258
|
-
|
|
259
|
-
const CloseOptionsSchema = v.object({
|
|
260
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
261
|
-
context: v.optional(ContextSourceSchema),
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
const CloseArgsSchema = v.tuple([v.optional(CloseOptionsSchema)]);
|
|
265
|
-
|
|
266
|
-
const SetOptionsSchema = v.object({
|
|
267
|
-
key: v.string(),
|
|
268
|
-
value: v.unknown(),
|
|
269
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
270
|
-
context: v.optional(ContextSourceSchema),
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
const SetArgsSchema = v.union([
|
|
274
|
-
v.tuple([SetOptionsSchema]),
|
|
275
|
-
v.pipe(
|
|
276
|
-
v.tuple([
|
|
277
|
-
SetOptionsSchema.entries.key,
|
|
278
|
-
SetOptionsSchema.entries.value,
|
|
279
|
-
v.optional(v.omit(SetOptionsSchema, ["key", "value"])),
|
|
280
|
-
]),
|
|
281
|
-
v.transform(([key, value, options]) => [{ ...options, key, value }]),
|
|
282
|
-
),
|
|
283
|
-
]);
|
|
284
|
-
|
|
285
|
-
const GetOptionsSchema = v.object({
|
|
286
|
-
key: v.string(),
|
|
287
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
288
|
-
context: v.optional(ContextSourceSchema),
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
const GetArgsSchema = v.union([
|
|
292
|
-
v.tuple([GetOptionsSchema]),
|
|
293
|
-
v.pipe(
|
|
294
|
-
v.tuple([GetOptionsSchema.entries.key, v.optional(v.omit(GetOptionsSchema, ["key"]))]),
|
|
295
|
-
v.transform(([key, options]) => [{ ...options, key }]),
|
|
296
|
-
),
|
|
297
|
-
]);
|
|
298
|
-
|
|
299
|
-
const StreamOptionsSchema = v.object({
|
|
300
|
-
key: v.string(),
|
|
301
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
302
|
-
context: v.optional(ContextSourceSchema),
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
const StreamArgsSchema = v.union([
|
|
306
|
-
v.tuple([StreamOptionsSchema]),
|
|
307
|
-
v.pipe(
|
|
308
|
-
v.tuple([StreamOptionsSchema.entries.key, v.optional(v.omit(StreamOptionsSchema, ["key"]))]),
|
|
309
|
-
v.transform(([key, options]) => [{ ...options, key }]),
|
|
310
|
-
),
|
|
311
|
-
]);
|
|
312
|
-
|
|
313
|
-
const HasOptionsSchema = v.object({
|
|
314
|
-
key: v.string(),
|
|
315
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
316
|
-
context: v.optional(ContextSourceSchema),
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
const HasArgsSchema = v.union([
|
|
320
|
-
v.tuple([HasOptionsSchema]),
|
|
321
|
-
v.pipe(
|
|
322
|
-
v.tuple([HasOptionsSchema.entries.key, v.optional(v.omit(HasOptionsSchema, ["key"]))]),
|
|
323
|
-
v.transform(([key, options]) => [{ ...options, key }]),
|
|
324
|
-
),
|
|
325
|
-
]);
|
|
326
|
-
|
|
327
|
-
const DeleteOptionsSchema = v.object({
|
|
328
|
-
key: v.string(),
|
|
329
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
330
|
-
context: v.optional(ContextSourceSchema),
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
const DeleteArgsSchema = v.union([
|
|
334
|
-
v.tuple([DeleteOptionsSchema]),
|
|
335
|
-
v.pipe(
|
|
336
|
-
v.tuple([DeleteOptionsSchema.entries.key, v.optional(v.omit(DeleteOptionsSchema, ["key"]))]),
|
|
337
|
-
v.transform(([key, options]) => [{ ...options, key }]),
|
|
338
|
-
),
|
|
339
|
-
]);
|
|
340
|
-
|
|
341
|
-
const ClearOptionsSchema = v.object({
|
|
342
|
-
signal: v.optional(v.instance(AbortSignal)),
|
|
343
|
-
context: v.optional(ContextSourceSchema),
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
const ClearArgsSchema = v.tuple([v.optional(ClearOptionsSchema)]);
|
|
336
|
+
export type ClearOptions = v.InferInput<typeof ClearOptionsSchema>;
|
|
347
337
|
|
|
348
338
|
// -------------------------------------------------------------------------------------------------
|
|
349
339
|
//
|
|
@@ -359,7 +349,7 @@ const ioLockRegistry: FinalizationRegistry<AsyncmuxLock> | null =
|
|
|
359
349
|
? null
|
|
360
350
|
: new FinalizationRegistry((lock) => {
|
|
361
351
|
try {
|
|
362
|
-
lock.
|
|
352
|
+
lock.release();
|
|
363
353
|
} catch {}
|
|
364
354
|
});
|
|
365
355
|
|
|
@@ -370,12 +360,12 @@ type Connection = {
|
|
|
370
360
|
/**
|
|
371
361
|
* 接続全体を管理する AbortController です。
|
|
372
362
|
*/
|
|
373
|
-
readonly
|
|
363
|
+
readonly ac: AbortController;
|
|
374
364
|
|
|
375
365
|
/**
|
|
376
366
|
* I/O の多重化を制御する Asyncmux インスタンスです。
|
|
377
367
|
*/
|
|
378
|
-
readonly
|
|
368
|
+
readonly io: Asyncmux;
|
|
379
369
|
};
|
|
380
370
|
|
|
381
371
|
/**
|
|
@@ -422,6 +412,8 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
422
412
|
*/
|
|
423
413
|
#con: Connection | null;
|
|
424
414
|
|
|
415
|
+
readonly #acSet: Set<AbortController>;
|
|
416
|
+
|
|
425
417
|
/**
|
|
426
418
|
* 基本となる実行コンテキスト情報です。
|
|
427
419
|
*/
|
|
@@ -451,10 +443,8 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
451
443
|
transformers: readonly UniKvsTransformer[],
|
|
452
444
|
) {
|
|
453
445
|
this.#con = null;
|
|
454
|
-
this.#
|
|
455
|
-
|
|
456
|
-
"unikvs:instance": this,
|
|
457
|
-
};
|
|
446
|
+
this.#acSet = new Set();
|
|
447
|
+
this.#context = { ...context };
|
|
458
448
|
this.#destinations = destinations;
|
|
459
449
|
this.#transformers = transformers;
|
|
460
450
|
}
|
|
@@ -465,7 +455,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
465
455
|
* @returns 利用可能である場合は true、そうでない場合は false を返します。
|
|
466
456
|
*/
|
|
467
457
|
public get isOpen(): boolean {
|
|
468
|
-
return
|
|
458
|
+
return this.#con !== null;
|
|
469
459
|
}
|
|
470
460
|
|
|
471
461
|
/**
|
|
@@ -477,134 +467,114 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
477
467
|
public open(options?: OpenOptions): Promise<void>;
|
|
478
468
|
|
|
479
469
|
public async open(...args: any): Promise<void> {
|
|
480
|
-
if (this.#con) {
|
|
470
|
+
if (this.#con !== null) {
|
|
481
471
|
throw new UniKvsIsOpenError();
|
|
482
472
|
}
|
|
483
473
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
ioMux: new Asyncmux(),
|
|
487
|
-
};
|
|
488
|
-
try {
|
|
489
|
-
const [options = {}] = parse(OpenArgsSchema, args);
|
|
490
|
-
const { signal: signalOption, context: contextOption } = options;
|
|
474
|
+
const [options = {}] = v.parseInput(OpenArgsSchema, args);
|
|
475
|
+
const { signal: signalOption, context: contextOption } = options;
|
|
491
476
|
|
|
492
|
-
|
|
493
|
-
|
|
477
|
+
const ac = new AbortController();
|
|
478
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
494
479
|
|
|
495
|
-
|
|
496
|
-
|
|
480
|
+
const context = mergeContext(this.#context, contextOption);
|
|
481
|
+
context["unikvs:action"] = "open";
|
|
482
|
+
|
|
483
|
+
signal.throwIfAborted();
|
|
484
|
+
|
|
485
|
+
this.#acSet.add(ac);
|
|
486
|
+
|
|
487
|
+
const dispose: (() => Promise<void>)[] = [];
|
|
488
|
+
|
|
489
|
+
const lock = await asyncmux(this, signal);
|
|
490
|
+
try {
|
|
491
|
+
if (this.#con !== null) {
|
|
492
|
+
throw new UniKvsIsOpenError();
|
|
493
|
+
}
|
|
497
494
|
|
|
498
495
|
const openFns: [() => Promise<void>, plugin: "storage" | "transformer"][] = [];
|
|
499
|
-
const dispose: (() => Promise<void>)[] = [];
|
|
500
|
-
const lock = await asyncmux(this, signal);
|
|
501
|
-
try {
|
|
502
|
-
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
503
|
-
if (this.#con.conAc !== conAc) {
|
|
504
|
-
throw new UniKvsIsOpenError();
|
|
505
|
-
}
|
|
506
496
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
497
|
+
// 各ストレージのオープン処理をリストに追加します。
|
|
498
|
+
for (const storage of this.#destinations) {
|
|
499
|
+
openFns.push([
|
|
500
|
+
async () => {
|
|
501
|
+
await storage.open(context, signal);
|
|
512
502
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
503
|
+
dispose.push(async () => {
|
|
504
|
+
try {
|
|
505
|
+
await storage.close(context, signal);
|
|
506
|
+
} catch (ex) {
|
|
507
|
+
logger.error`Failed to close storage: ${ex}`;
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
},
|
|
511
|
+
"storage",
|
|
512
|
+
]);
|
|
513
|
+
}
|
|
524
514
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
515
|
+
// 各トランスフォーマーのオープン処理をリストに追加します。
|
|
516
|
+
for (const transformer of this.#transformers) {
|
|
517
|
+
openFns.push([
|
|
518
|
+
async () => {
|
|
519
|
+
await transformer.open(context, signal);
|
|
530
520
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
521
|
+
dispose.push(async () => {
|
|
522
|
+
try {
|
|
523
|
+
await transformer.close(context, signal);
|
|
524
|
+
} catch (ex) {
|
|
525
|
+
logger.error`Failed to close transformer: ${ex}`;
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
},
|
|
529
|
+
"transformer",
|
|
530
|
+
]);
|
|
531
|
+
}
|
|
542
532
|
|
|
543
|
-
|
|
544
|
-
|
|
533
|
+
// すべての処理を並列に実行し、エラーが発生した場合は集約します。
|
|
534
|
+
const errors: { plugin: "storage" | "transformer"; reason: unknown }[] = [];
|
|
535
|
+
await Promise.all(
|
|
536
|
+
openFns.map(async ([f, plugin]) => {
|
|
537
|
+
try {
|
|
538
|
+
await f();
|
|
539
|
+
} catch (reason) {
|
|
540
|
+
errors.push({ plugin, reason });
|
|
541
|
+
}
|
|
542
|
+
}),
|
|
543
|
+
);
|
|
544
|
+
if (errors.length > 0) {
|
|
545
|
+
throw new PluginOperationAggregateError({ action: "open", errors });
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
this.#con = {
|
|
549
|
+
ac,
|
|
550
|
+
io: new Asyncmux(),
|
|
551
|
+
};
|
|
552
|
+
} catch (ex) {
|
|
553
|
+
if (dispose.length > 0) {
|
|
545
554
|
await Promise.all(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
await f();
|
|
549
|
-
} catch (reason) {
|
|
550
|
-
errors.push({ plugin, reason });
|
|
551
|
-
}
|
|
555
|
+
dispose.map(async (f) => {
|
|
556
|
+
await f();
|
|
552
557
|
}),
|
|
553
558
|
);
|
|
554
|
-
if (errors.length > 0) {
|
|
555
|
-
throw new PluginOperationAggregateError({ action: "open", errors });
|
|
556
|
-
}
|
|
557
|
-
} catch (ex) {
|
|
558
|
-
this.#con = null; // unlock の前に null に戻します。
|
|
559
|
-
|
|
560
|
-
if (dispose.length > 0) {
|
|
561
|
-
await Promise.all(
|
|
562
|
-
dispose.map(async (f) => {
|
|
563
|
-
await f();
|
|
564
|
-
}),
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
throw ex;
|
|
569
|
-
} finally {
|
|
570
|
-
lock.unlock();
|
|
571
559
|
}
|
|
572
|
-
|
|
573
|
-
this.#con = null;
|
|
560
|
+
|
|
574
561
|
throw ex;
|
|
562
|
+
} finally {
|
|
563
|
+
this.#acSet.delete(ac);
|
|
564
|
+
lock.release();
|
|
575
565
|
}
|
|
576
566
|
}
|
|
577
567
|
|
|
578
|
-
|
|
579
|
-
* ストレージをクローズします。
|
|
580
|
-
*
|
|
581
|
-
* @param options クローズ時のオプションです。
|
|
582
|
-
* @returns 完了を通知する Promise です。
|
|
583
|
-
*/
|
|
584
|
-
public close(options?: CloseOptions): Promise<void>;
|
|
585
|
-
|
|
586
|
-
public async close(...args: any): Promise<void> {
|
|
587
|
-
if (!this.#con) {
|
|
588
|
-
throw new UniKvsIsNotOpenError();
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
const [options = {}] = parse(CloseArgsSchema, args);
|
|
592
|
-
const { signal = AbortSignal.timeout(10e3), context: contextOption } = options;
|
|
593
|
-
|
|
594
|
-
const context = mergeContext(this.#context, contextOption);
|
|
595
|
-
context["unikvs:action"] = "close";
|
|
596
|
-
|
|
597
|
-
const { conAc, ioMux } = this.#con;
|
|
598
|
-
conAc.abort(new UniKvsIsNotOpenError()); // 実行中の他の操作をすべて中断させるために signal を発火させます。
|
|
599
|
-
|
|
568
|
+
async #close(context: Context, signal: AbortSignal, con: Connection): Promise<void> {
|
|
600
569
|
const lock = await asyncmux(this, signal);
|
|
601
570
|
try {
|
|
602
571
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
603
|
-
if (
|
|
572
|
+
if (this.#con !== con) {
|
|
604
573
|
throw new UniKvsIsNotOpenError();
|
|
605
574
|
}
|
|
606
575
|
|
|
607
|
-
const
|
|
576
|
+
const { io } = this.#con;
|
|
577
|
+
const lock = await io.lock({ signal });
|
|
608
578
|
try {
|
|
609
579
|
const closeFns: [() => Promise<void>, plugin: "storage" | "transformer"][] = [];
|
|
610
580
|
|
|
@@ -643,11 +613,55 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
643
613
|
throw new PluginOperationAggregateError({ action: "close", errors });
|
|
644
614
|
}
|
|
645
615
|
} finally {
|
|
646
|
-
lock.
|
|
616
|
+
lock.release();
|
|
647
617
|
}
|
|
648
|
-
|
|
618
|
+
|
|
649
619
|
this.#con = null;
|
|
650
|
-
|
|
620
|
+
} finally {
|
|
621
|
+
lock.release();
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* ストレージをクローズします。
|
|
627
|
+
*
|
|
628
|
+
* @param options クローズ時のオプションです。
|
|
629
|
+
* @returns 完了を通知する Promise です。
|
|
630
|
+
*/
|
|
631
|
+
public close(options?: CloseOptions): Promise<void>;
|
|
632
|
+
|
|
633
|
+
public close(...args: any): Promise<void> {
|
|
634
|
+
try {
|
|
635
|
+
const [options = {}] = v.parseInput(CloseArgsSchema, args);
|
|
636
|
+
const { signal = AbortSignal.timeout(10e3), context: contextOption } = options;
|
|
637
|
+
|
|
638
|
+
const context = mergeContext(this.#context, contextOption);
|
|
639
|
+
context["unikvs:action"] = "close";
|
|
640
|
+
|
|
641
|
+
if (this.#con === null) {
|
|
642
|
+
const acArr = [...this.#acSet];
|
|
643
|
+
this.#acSet.clear();
|
|
644
|
+
for (const ac of acArr) {
|
|
645
|
+
if (!ac.signal.aborted) {
|
|
646
|
+
ac.abort(new UniKvsIsNotOpenError());
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
throw new UniKvsIsNotOpenError();
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
const { ac } = this.#con;
|
|
654
|
+
const acArr = [ac, ...this.#acSet];
|
|
655
|
+
this.#acSet.clear();
|
|
656
|
+
for (const ac of acArr) {
|
|
657
|
+
if (!ac.signal.aborted) {
|
|
658
|
+
ac.abort(new UniKvsIsNotOpenError());
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
return this.#close(context, signal, this.#con);
|
|
663
|
+
} catch (ex) {
|
|
664
|
+
return Promise.reject(ex);
|
|
651
665
|
}
|
|
652
666
|
}
|
|
653
667
|
|
|
@@ -688,15 +702,15 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
688
702
|
): Promise<void>;
|
|
689
703
|
|
|
690
704
|
public async set(...args: any): Promise<void> {
|
|
691
|
-
if (
|
|
705
|
+
if (this.#con === null) {
|
|
692
706
|
throw new UniKvsIsNotOpenError();
|
|
693
707
|
}
|
|
694
708
|
|
|
695
|
-
const [options] =
|
|
709
|
+
const [options] = v.parseInput(SetArgsSchema, args);
|
|
696
710
|
const { key, value, signal: signalOption, context: contextOption } = options;
|
|
697
711
|
|
|
698
|
-
const {
|
|
699
|
-
const signal = combineSignals([
|
|
712
|
+
const { ac, io } = this.#con;
|
|
713
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
700
714
|
|
|
701
715
|
const context = mergeContext(this.#context, contextOption);
|
|
702
716
|
context["unikvs:action"] = "set";
|
|
@@ -705,7 +719,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
705
719
|
const lock = await asyncmux(this, signal);
|
|
706
720
|
try {
|
|
707
721
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
708
|
-
if (
|
|
722
|
+
if (this.#con === null) {
|
|
709
723
|
throw new UniKvsIsNotOpenError();
|
|
710
724
|
}
|
|
711
725
|
|
|
@@ -719,7 +733,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
719
733
|
data = data.pipeThrough(e);
|
|
720
734
|
}
|
|
721
735
|
|
|
722
|
-
const lock = await
|
|
736
|
+
const lock = await io.lock({ key, signal });
|
|
723
737
|
try {
|
|
724
738
|
await Promise.all(
|
|
725
739
|
this.#destinations.map(async (storage, i) => {
|
|
@@ -739,7 +753,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
739
753
|
}),
|
|
740
754
|
);
|
|
741
755
|
} finally {
|
|
742
|
-
lock.
|
|
756
|
+
lock.release();
|
|
743
757
|
}
|
|
744
758
|
} else {
|
|
745
759
|
// 登録されているトランスフォーマーを順番に適用してデータをエンコードします。
|
|
@@ -748,7 +762,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
748
762
|
data = await transformer.encode(context, signal, data);
|
|
749
763
|
}
|
|
750
764
|
|
|
751
|
-
const lock = await
|
|
765
|
+
const lock = await io.lock({ key, signal });
|
|
752
766
|
try {
|
|
753
767
|
await Promise.all(
|
|
754
768
|
this.#destinations.map(async (storage) => {
|
|
@@ -761,7 +775,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
761
775
|
}),
|
|
762
776
|
);
|
|
763
777
|
} finally {
|
|
764
|
-
lock.
|
|
778
|
+
lock.release();
|
|
765
779
|
}
|
|
766
780
|
}
|
|
767
781
|
|
|
@@ -795,7 +809,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
795
809
|
throw error;
|
|
796
810
|
}
|
|
797
811
|
} finally {
|
|
798
|
-
lock.
|
|
812
|
+
lock.release();
|
|
799
813
|
}
|
|
800
814
|
}
|
|
801
815
|
|
|
@@ -824,15 +838,15 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
824
838
|
): Promise<$InferPlainValueData<TKeyValueMapping[TKey]>>;
|
|
825
839
|
|
|
826
840
|
public async get(...args: any): Promise<unknown> {
|
|
827
|
-
if (
|
|
841
|
+
if (this.#con === null) {
|
|
828
842
|
throw new UniKvsIsNotOpenError();
|
|
829
843
|
}
|
|
830
844
|
|
|
831
|
-
const [options] =
|
|
845
|
+
const [options] = v.parseInput(GetArgsSchema, args);
|
|
832
846
|
const { key, signal: signalOption, context: contextOption } = options;
|
|
833
847
|
|
|
834
|
-
const {
|
|
835
|
-
const signal = combineSignals([
|
|
848
|
+
const { ac, io } = this.#con;
|
|
849
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
836
850
|
|
|
837
851
|
const context = mergeContext(this.#context, contextOption);
|
|
838
852
|
context["unikvs:action"] = "get";
|
|
@@ -841,14 +855,14 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
841
855
|
const lock = await asyncmux.readonly(this, signal);
|
|
842
856
|
try {
|
|
843
857
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
844
|
-
if (
|
|
858
|
+
if (this.#con === null) {
|
|
845
859
|
throw new UniKvsIsNotOpenError();
|
|
846
860
|
}
|
|
847
861
|
|
|
848
862
|
const NONE = {};
|
|
849
|
-
let data = NONE;
|
|
863
|
+
let data: any = NONE;
|
|
850
864
|
|
|
851
|
-
const lock = await
|
|
865
|
+
const lock = await io.rLock({ key, signal });
|
|
852
866
|
try {
|
|
853
867
|
// 各ストレージを巡回し、最初に見つかったデータを取得します。
|
|
854
868
|
for (const storage of this.#destinations) {
|
|
@@ -858,7 +872,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
858
872
|
}
|
|
859
873
|
}
|
|
860
874
|
} finally {
|
|
861
|
-
lock.
|
|
875
|
+
lock.release();
|
|
862
876
|
}
|
|
863
877
|
|
|
864
878
|
if (data === NONE) {
|
|
@@ -874,7 +888,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
874
888
|
|
|
875
889
|
return data;
|
|
876
890
|
} finally {
|
|
877
|
-
lock.
|
|
891
|
+
lock.release();
|
|
878
892
|
}
|
|
879
893
|
}
|
|
880
894
|
|
|
@@ -903,15 +917,15 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
903
917
|
): Promise<ValueStream<$InferStreamValueChunkData<TKeyValueMapping[TKey]>>>;
|
|
904
918
|
|
|
905
919
|
public async stream(...args: any): Promise<ValueStream> {
|
|
906
|
-
if (
|
|
920
|
+
if (this.#con === null) {
|
|
907
921
|
throw new UniKvsIsNotOpenError();
|
|
908
922
|
}
|
|
909
923
|
|
|
910
|
-
const [options] =
|
|
924
|
+
const [options] = v.parseInput(StreamArgsSchema, args);
|
|
911
925
|
const { key, signal: signalOption, context: contextOption } = options;
|
|
912
926
|
|
|
913
|
-
const {
|
|
914
|
-
const signal = combineSignals([
|
|
927
|
+
const { ac, io } = this.#con;
|
|
928
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
915
929
|
|
|
916
930
|
const context = mergeContext(this.#context, contextOption);
|
|
917
931
|
context["unikvs:action"] = "stream";
|
|
@@ -920,14 +934,14 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
920
934
|
const lock = await asyncmux(this, signal);
|
|
921
935
|
try {
|
|
922
936
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
923
|
-
if (
|
|
937
|
+
if (this.#con === null) {
|
|
924
938
|
throw new UniKvsIsNotOpenError();
|
|
925
939
|
}
|
|
926
940
|
|
|
927
941
|
const NONE: any = {};
|
|
928
942
|
let r: IReadableStream = NONE;
|
|
929
943
|
|
|
930
|
-
const lock = await
|
|
944
|
+
const lock = await io.rLock({ key, signal });
|
|
931
945
|
try {
|
|
932
946
|
// 各ストレージを巡回し、最初に見つかったデータを取得します。
|
|
933
947
|
for (const storage of this.#destinations) {
|
|
@@ -955,7 +969,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
955
969
|
await r.cancel();
|
|
956
970
|
} catch {}
|
|
957
971
|
try {
|
|
958
|
-
lock.
|
|
972
|
+
lock.release();
|
|
959
973
|
} catch {}
|
|
960
974
|
});
|
|
961
975
|
}
|
|
@@ -969,7 +983,7 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
969
983
|
await r.cancel();
|
|
970
984
|
} catch {}
|
|
971
985
|
try {
|
|
972
|
-
lock.
|
|
986
|
+
lock.release();
|
|
973
987
|
} catch {}
|
|
974
988
|
});
|
|
975
989
|
|
|
@@ -978,11 +992,11 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
978
992
|
|
|
979
993
|
return valueStream;
|
|
980
994
|
} catch (ex) {
|
|
981
|
-
lock.
|
|
995
|
+
lock.release();
|
|
982
996
|
throw ex;
|
|
983
997
|
}
|
|
984
998
|
} finally {
|
|
985
|
-
lock.
|
|
999
|
+
lock.release();
|
|
986
1000
|
}
|
|
987
1001
|
}
|
|
988
1002
|
|
|
@@ -1007,15 +1021,15 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1007
1021
|
public has(options: HasOptions<KeyofKeyValueMapping<TKeyValueMapping>>): Promise<boolean>;
|
|
1008
1022
|
|
|
1009
1023
|
public async has(...args: any): Promise<boolean> {
|
|
1010
|
-
if (
|
|
1024
|
+
if (this.#con === null) {
|
|
1011
1025
|
throw new UniKvsIsNotOpenError();
|
|
1012
1026
|
}
|
|
1013
1027
|
|
|
1014
|
-
const [options] =
|
|
1028
|
+
const [options] = v.parseInput(HasArgsSchema, args);
|
|
1015
1029
|
const { key, signal: signalOption, context: contextOption } = options;
|
|
1016
1030
|
|
|
1017
|
-
const {
|
|
1018
|
-
const signal = combineSignals([
|
|
1031
|
+
const { ac, io } = this.#con;
|
|
1032
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
1019
1033
|
|
|
1020
1034
|
const context = mergeContext(this.#context, contextOption);
|
|
1021
1035
|
context["unikvs:action"] = "has";
|
|
@@ -1024,11 +1038,11 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1024
1038
|
const lock = await asyncmux(this, signal);
|
|
1025
1039
|
try {
|
|
1026
1040
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
1027
|
-
if (
|
|
1041
|
+
if (this.#con === null) {
|
|
1028
1042
|
throw new UniKvsIsNotOpenError();
|
|
1029
1043
|
}
|
|
1030
1044
|
|
|
1031
|
-
const lock = await
|
|
1045
|
+
const lock = await io.rLock({ key, signal });
|
|
1032
1046
|
try {
|
|
1033
1047
|
// いずれかのストレージに存在すれば true を返します。
|
|
1034
1048
|
for (const storage of this.#destinations) {
|
|
@@ -1039,10 +1053,10 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1039
1053
|
|
|
1040
1054
|
return false;
|
|
1041
1055
|
} finally {
|
|
1042
|
-
lock.
|
|
1056
|
+
lock.release();
|
|
1043
1057
|
}
|
|
1044
1058
|
} finally {
|
|
1045
|
-
lock.
|
|
1059
|
+
lock.release();
|
|
1046
1060
|
}
|
|
1047
1061
|
}
|
|
1048
1062
|
|
|
@@ -1067,15 +1081,15 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1067
1081
|
public delete(options: DeleteOptions<KeyofKeyValueMapping<TKeyValueMapping>>): Promise<void>;
|
|
1068
1082
|
|
|
1069
1083
|
public async delete(...args: any): Promise<void> {
|
|
1070
|
-
if (
|
|
1084
|
+
if (this.#con === null) {
|
|
1071
1085
|
throw new UniKvsIsNotOpenError();
|
|
1072
1086
|
}
|
|
1073
1087
|
|
|
1074
|
-
const [options] =
|
|
1088
|
+
const [options] = v.parseInput(DeleteArgsSchema, args);
|
|
1075
1089
|
const { key, signal: signalOption, context: contextOption } = options;
|
|
1076
1090
|
|
|
1077
|
-
const {
|
|
1078
|
-
const signal = combineSignals([
|
|
1091
|
+
const { ac, io } = this.#con;
|
|
1092
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
1079
1093
|
|
|
1080
1094
|
const context = mergeContext(this.#context, contextOption);
|
|
1081
1095
|
context["unikvs:action"] = "delete";
|
|
@@ -1084,11 +1098,11 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1084
1098
|
const lock = await asyncmux(this, signal);
|
|
1085
1099
|
try {
|
|
1086
1100
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
1087
|
-
if (
|
|
1101
|
+
if (this.#con === null) {
|
|
1088
1102
|
throw new UniKvsIsNotOpenError();
|
|
1089
1103
|
}
|
|
1090
1104
|
|
|
1091
|
-
const lock = await
|
|
1105
|
+
const lock = await io.lock({ key, signal });
|
|
1092
1106
|
try {
|
|
1093
1107
|
// すべてのストレージから対象データを削除します。
|
|
1094
1108
|
// すべての処理を並列に実行し、エラーが発生した場合は集約します。
|
|
@@ -1108,10 +1122,10 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1108
1122
|
throw new PluginOperationAggregateError({ plugin: "storage", action: "delete", errors });
|
|
1109
1123
|
}
|
|
1110
1124
|
} finally {
|
|
1111
|
-
lock.
|
|
1125
|
+
lock.release();
|
|
1112
1126
|
}
|
|
1113
1127
|
} finally {
|
|
1114
|
-
lock.
|
|
1128
|
+
lock.release();
|
|
1115
1129
|
}
|
|
1116
1130
|
}
|
|
1117
1131
|
|
|
@@ -1124,15 +1138,15 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1124
1138
|
public async clear(options?: ClearOptions): Promise<void>;
|
|
1125
1139
|
|
|
1126
1140
|
public async clear(...args: any): Promise<void> {
|
|
1127
|
-
if (
|
|
1141
|
+
if (this.#con === null) {
|
|
1128
1142
|
throw new UniKvsIsNotOpenError();
|
|
1129
1143
|
}
|
|
1130
1144
|
|
|
1131
|
-
const [options = {}] =
|
|
1145
|
+
const [options = {}] = v.parseInput(ClearArgsSchema, args);
|
|
1132
1146
|
const { signal: signalOption, context: contextOption } = options;
|
|
1133
1147
|
|
|
1134
|
-
const {
|
|
1135
|
-
const signal = combineSignals([
|
|
1148
|
+
const { ac, io } = this.#con;
|
|
1149
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
1136
1150
|
|
|
1137
1151
|
const context = mergeContext(this.#context, contextOption);
|
|
1138
1152
|
context["unikvs:action"] = "clear";
|
|
@@ -1140,11 +1154,11 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1140
1154
|
const lock = await asyncmux(this, signal);
|
|
1141
1155
|
try {
|
|
1142
1156
|
// ロック待機中に接続状態が変更されていないか再確認します。
|
|
1143
|
-
if (
|
|
1157
|
+
if (this.#con === null) {
|
|
1144
1158
|
throw new UniKvsIsNotOpenError();
|
|
1145
1159
|
}
|
|
1146
1160
|
|
|
1147
|
-
const lock = await
|
|
1161
|
+
const lock = await io.lock({ signal });
|
|
1148
1162
|
try {
|
|
1149
1163
|
// すべてのストレージで一括削除を実行します。
|
|
1150
1164
|
// すべての処理を並列に実行し、エラーが発生した場合は集約します。
|
|
@@ -1162,10 +1176,10 @@ export default class UniKvs<TKeyValueMapping extends KeyValueMapping = KeyValueM
|
|
|
1162
1176
|
throw new PluginOperationAggregateError({ plugin: "storage", action: "clear", errors });
|
|
1163
1177
|
}
|
|
1164
1178
|
} finally {
|
|
1165
|
-
lock.
|
|
1179
|
+
lock.release();
|
|
1166
1180
|
}
|
|
1167
1181
|
} finally {
|
|
1168
|
-
lock.
|
|
1182
|
+
lock.release();
|
|
1169
1183
|
}
|
|
1170
1184
|
}
|
|
1171
1185
|
}
|