unikvs 0.0.10 → 0.0.13
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 +3 -0
- package/dist/index.d.ts +1553 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4032 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -34
- package/src/_contexts.ts +1089 -0
- package/src/_logger.ts +5 -3
- package/src/_middleware.ts +207 -0
- package/src/_pipeline-graph.helpers.ts +183 -0
- package/src/_pipeline-graph.ts +1307 -0
- package/src/_pipeline-graph.types.ts +303 -0
- package/src/_pipeline-leaf-resolver.ts +70 -0
- package/src/_plugin-lifecycle.ts +201 -0
- package/src/_storage.ts +173 -96
- package/src/_streams.schemas.ts +21 -0
- package/src/_streams.ts +73 -0
- package/src/_to-value-stream.ts +22 -11
- package/src/_types.ts +237 -0
- package/src/_unikvs-branch.ts +94 -0
- package/src/_unikvs.schemas.ts +451 -0
- package/src/_valibot.ts +17 -3
- package/src/_value-schemas.ts +192 -0
- package/src/_value-validation.ts +57 -0
- package/src/errors.ts +446 -252
- package/src/index.ts +46 -26
- package/src/types.ts +13 -0
- package/src/unikvs-branch.ts +445 -0
- package/src/unikvs-builder.ts +706 -0
- package/src/unikvs.ts +1456 -971
- package/src/unikvs.types.ts +194 -0
- package/src/value-schemas.ts +98 -0
- package/dist/src/_logger.d.ts +0 -3
- package/dist/src/_logger.d.ts.map +0 -1
- package/dist/src/_logger.js +0 -3
- package/dist/src/_merge-context.d.ts +0 -13
- package/dist/src/_merge-context.d.ts.map +0 -1
- package/dist/src/_merge-context.js +0 -12
- package/dist/src/_storage.d.ts +0 -18
- package/dist/src/_storage.d.ts.map +0 -1
- package/dist/src/_storage.js +0 -94
- package/dist/src/_to-value-stream.d.ts +0 -12
- package/dist/src/_to-value-stream.d.ts.map +0 -1
- package/dist/src/_to-value-stream.js +0 -102
- package/dist/src/_transformer.d.ts +0 -13
- package/dist/src/_transformer.d.ts.map +0 -1
- package/dist/src/_transformer.js +0 -60
- package/dist/src/_valibot.d.ts +0 -15
- package/dist/src/_valibot.d.ts.map +0 -1
- package/dist/src/_valibot.js +0 -23
- package/dist/src/context.types.d.ts +0 -17
- package/dist/src/context.types.d.ts.map +0 -1
- package/dist/src/context.types.js +0 -1
- package/dist/src/errors.d.ts +0 -340
- package/dist/src/errors.d.ts.map +0 -1
- package/dist/src/errors.js +0 -250
- package/dist/src/index.d.ts +0 -10
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -3
- package/dist/src/unikvs-config.d.ts +0 -255
- package/dist/src/unikvs-config.d.ts.map +0 -1
- package/dist/src/unikvs-config.js +0 -105
- package/dist/src/unikvs.d.ts +0 -354
- package/dist/src/unikvs.d.ts.map +0 -1
- package/dist/src/unikvs.js +0 -867
- package/dist/src/utils.types.d.ts +0 -7
- package/dist/src/utils.types.d.ts.map +0 -1
- package/dist/src/utils.types.js +0 -1
- package/dist/src/value-stream.types.d.ts +0 -16
- package/dist/src/value-stream.types.d.ts.map +0 -1
- package/dist/src/value-stream.types.js +0 -1
- package/src/_merge-context.ts +0 -19
- package/src/_transformer.ts +0 -89
- package/src/context.types.ts +0 -19
- package/src/unikvs-config.ts +0 -426
- package/src/utils.types.ts +0 -6
- package/src/value-stream.types.ts +0 -19
package/dist/index.js
ADDED
|
@@ -0,0 +1,4032 @@
|
|
|
1
|
+
import { ErrorBase, InvalidUsageErrorBase, KeyNotFoundError, ReadonlyVariableError, RepairNotAllowedError, setErrorMessage } from "@unikvs/core";
|
|
2
|
+
import { Asyncmux, asyncmux } from "asyncmux";
|
|
3
|
+
import { callAsyncableFnOnce, callFnOnce } from "call-fn-once";
|
|
4
|
+
import { tryCaptureStackTrace } from "try-capture-stack-trace";
|
|
5
|
+
import { boolean, check, custom, instance, omit, optional, pipe, safeParse, safeParse as safeParse$1, string, union, unknown } from "valibot";
|
|
6
|
+
import { array, object, record, transform, tuple } from "@tai-kun/valibot-extra-lab";
|
|
7
|
+
import { getLogger } from "@logtape/logtape";
|
|
8
|
+
import { combineSignals, throwIfAborted } from "abort-signal-utils";
|
|
9
|
+
//#region ../src/errors.ts
|
|
10
|
+
var _InvalidInputError;
|
|
11
|
+
var _InvalidOutputError;
|
|
12
|
+
var _UniKvsIsOpenError;
|
|
13
|
+
var _UniKvsIsNotOpenError;
|
|
14
|
+
var _StorageIsNotOpenError;
|
|
15
|
+
var _WritableStreamNotSupportedError;
|
|
16
|
+
var _ReadableStreamNotSupportedError;
|
|
17
|
+
var _MultipartWriteNotSupportedError;
|
|
18
|
+
var _MiddlewareIsNotOpenError;
|
|
19
|
+
var _MiddlewareDestinationMissingError;
|
|
20
|
+
var _MiddlewareDestinationFrozenError;
|
|
21
|
+
var _MiddlewareNextNotCalledError;
|
|
22
|
+
var _MiddlewareNextNotAwaitedError;
|
|
23
|
+
var _MiddlewareNextCalledMultipleTimesError;
|
|
24
|
+
var _StreamEncodingNotSupportedError;
|
|
25
|
+
var _StreamDecodingNotSupportedError;
|
|
26
|
+
var _PluginOperationAggregateError;
|
|
27
|
+
var _MissingStorageError;
|
|
28
|
+
/**
|
|
29
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
30
|
+
*/
|
|
31
|
+
var InvalidInputError = class extends InvalidUsageErrorBase {
|
|
32
|
+
constructor(args) {
|
|
33
|
+
const { value: input, issues, ...options } = args;
|
|
34
|
+
super({
|
|
35
|
+
input,
|
|
36
|
+
issues
|
|
37
|
+
}, ({ issues: messageIssues }) => messageIssues.map((i) => i.message).join(": "), options);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
_InvalidInputError = InvalidInputError;
|
|
41
|
+
_InvalidInputError.prototype.name = "UniKvsInvalidInputError";
|
|
42
|
+
/**
|
|
43
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
44
|
+
*/
|
|
45
|
+
var InvalidOutputError = class extends InvalidUsageErrorBase {
|
|
46
|
+
constructor(args) {
|
|
47
|
+
const { value: output, issues, ...options } = args;
|
|
48
|
+
super({
|
|
49
|
+
issues,
|
|
50
|
+
output
|
|
51
|
+
}, ({ issues: messageIssues }) => messageIssues.map((i) => i.message).join(": "), options);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
_InvalidOutputError = InvalidOutputError;
|
|
55
|
+
_InvalidOutputError.prototype.name = "UniKvsInvalidOutputError";
|
|
56
|
+
/**
|
|
57
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
58
|
+
*/
|
|
59
|
+
var UniKvsIsOpenError = class extends ErrorBase {
|
|
60
|
+
constructor(options) {
|
|
61
|
+
super("UniKvs is open", options);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
_UniKvsIsOpenError = UniKvsIsOpenError;
|
|
65
|
+
_UniKvsIsOpenError.prototype.name = "UniKvsIsOpenError";
|
|
66
|
+
setErrorMessage(UniKvsIsOpenError, "UniKvs は開いています", "ja");
|
|
67
|
+
/**
|
|
68
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
69
|
+
*/
|
|
70
|
+
var UniKvsIsNotOpenError = class extends ErrorBase {
|
|
71
|
+
constructor(options) {
|
|
72
|
+
super("UniKvs is not open", options);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
_UniKvsIsNotOpenError = UniKvsIsNotOpenError;
|
|
76
|
+
_UniKvsIsNotOpenError.prototype.name = "UniKvsIsNotOpenError";
|
|
77
|
+
setErrorMessage(UniKvsIsNotOpenError, "UniKvs は開いていません", "ja");
|
|
78
|
+
/**
|
|
79
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
80
|
+
*/
|
|
81
|
+
var StorageIsNotOpenError = class extends ErrorBase {
|
|
82
|
+
constructor(args) {
|
|
83
|
+
const { name, ...options } = args;
|
|
84
|
+
super({ name }, ({ name: messageName }) => `Storage "${messageName}" is not open`, options);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
_StorageIsNotOpenError = StorageIsNotOpenError;
|
|
88
|
+
_StorageIsNotOpenError.prototype.name = "UniKvsStorageIsNotOpenError";
|
|
89
|
+
setErrorMessage(StorageIsNotOpenError, ({ name }) => `ストレージ "${name}" は開いていません`, "ja");
|
|
90
|
+
/**
|
|
91
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
92
|
+
*/
|
|
93
|
+
var WritableStreamNotSupportedError = class extends ErrorBase {
|
|
94
|
+
constructor(args) {
|
|
95
|
+
const { name, ...options } = args;
|
|
96
|
+
super({ name }, ({ name: messageName }) => `Storage "${messageName}" does not support writable stream`, options);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
_WritableStreamNotSupportedError = WritableStreamNotSupportedError;
|
|
100
|
+
_WritableStreamNotSupportedError.prototype.name = "UniKvsWritableStreamNotSupportedError";
|
|
101
|
+
setErrorMessage(WritableStreamNotSupportedError, ({ name }) => `ストレージ "${name}" は書き込み可能なストリームをサポートしていません`, "ja");
|
|
102
|
+
/**
|
|
103
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
104
|
+
*/
|
|
105
|
+
var ReadableStreamNotSupportedError = class extends ErrorBase {
|
|
106
|
+
constructor(args) {
|
|
107
|
+
const { name, ...options } = args;
|
|
108
|
+
super({ name }, ({ name: messageName }) => `Storage "${messageName}" does not support readable stream`, options);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
_ReadableStreamNotSupportedError = ReadableStreamNotSupportedError;
|
|
112
|
+
_ReadableStreamNotSupportedError.prototype.name = "UniKvsReadableStreamNotSupportedError";
|
|
113
|
+
setErrorMessage(ReadableStreamNotSupportedError, ({ name }) => `ストレージ "${name}" は読み取り可能なストリームをサポートしていません`, "ja");
|
|
114
|
+
/**
|
|
115
|
+
* ストレージがマルチパート書き込みをサポートしていない場合に投げられるエラーです。
|
|
116
|
+
*/
|
|
117
|
+
var MultipartWriteNotSupportedError = class extends ErrorBase {
|
|
118
|
+
constructor(args) {
|
|
119
|
+
const { name, ...options } = args;
|
|
120
|
+
super({ name }, ({ name: messageName }) => `Storage "${messageName}" does not support multipart-write`, options);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
_MultipartWriteNotSupportedError = MultipartWriteNotSupportedError;
|
|
124
|
+
_MultipartWriteNotSupportedError.prototype.name = "UniKvsMultipartWriteNotSupportedError";
|
|
125
|
+
setErrorMessage(MultipartWriteNotSupportedError, ({ name }) => `ストレージ "${name}" はマルチパート書き込みをサポートしていません`, "ja");
|
|
126
|
+
/**
|
|
127
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
128
|
+
*/
|
|
129
|
+
var MiddlewareIsNotOpenError = class extends ErrorBase {
|
|
130
|
+
constructor(args) {
|
|
131
|
+
const { name, ...options } = args;
|
|
132
|
+
super({ name }, ({ name: messageName }) => `Middleware "${messageName}" is not open`, options);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
_MiddlewareIsNotOpenError = MiddlewareIsNotOpenError;
|
|
136
|
+
_MiddlewareIsNotOpenError.prototype.name = "UniKvsMiddlewareIsNotOpenError";
|
|
137
|
+
setErrorMessage(MiddlewareIsNotOpenError, ({ name }) => `ミドルウェア "${name}" は開いていません`, "ja");
|
|
138
|
+
/**
|
|
139
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
140
|
+
*/
|
|
141
|
+
var MiddlewareDestinationMissingError = class extends ErrorBase {
|
|
142
|
+
constructor(args) {
|
|
143
|
+
const { name, operation, ...options } = args;
|
|
144
|
+
super({
|
|
145
|
+
name,
|
|
146
|
+
operation
|
|
147
|
+
}, ({ name: messageName, operation: messageOperation }) => `Middleware "${messageName}" did not set destination for ${messageOperation}.`, options);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
_MiddlewareDestinationMissingError = MiddlewareDestinationMissingError;
|
|
151
|
+
_MiddlewareDestinationMissingError.prototype.name = "UniKvsMiddlewareDestinationMissingError";
|
|
152
|
+
setErrorMessage(MiddlewareDestinationMissingError, ({ name, operation }) => `ミドルウェア "${name}" は ${operation} の destination を設定しませんでした。`, "ja");
|
|
153
|
+
/**
|
|
154
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
155
|
+
*/
|
|
156
|
+
var MiddlewareDestinationFrozenError = class extends ErrorBase {
|
|
157
|
+
constructor(args) {
|
|
158
|
+
const { key, action, ...options } = args;
|
|
159
|
+
super({
|
|
160
|
+
key,
|
|
161
|
+
action
|
|
162
|
+
}, ({ key: messageKey, action: messageAction }) => `Cannot set destination after next() was called for ${messageAction} operation on key ${JSON.stringify(messageKey)}.`, options);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
_MiddlewareDestinationFrozenError = MiddlewareDestinationFrozenError;
|
|
166
|
+
_MiddlewareDestinationFrozenError.prototype.name = "UniKvsMiddlewareDestinationFrozenError";
|
|
167
|
+
setErrorMessage(MiddlewareDestinationFrozenError, ({ key: messageKey, action: messageAction }) => `next() を呼び出した後に destination を設定できません(${messageAction} 操作、キー ${JSON.stringify(messageKey)})。`, "ja");
|
|
168
|
+
/**
|
|
169
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
170
|
+
*/
|
|
171
|
+
var MiddlewareNextNotCalledError = class extends ErrorBase {
|
|
172
|
+
constructor(args) {
|
|
173
|
+
const { name, operation, ...options } = args;
|
|
174
|
+
super({
|
|
175
|
+
name,
|
|
176
|
+
operation
|
|
177
|
+
}, ({ name: messageName, operation: messageOperation }) => `Middleware "${messageName}" did not call next() for ${messageOperation}.`, options);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
_MiddlewareNextNotCalledError = MiddlewareNextNotCalledError;
|
|
181
|
+
_MiddlewareNextNotCalledError.prototype.name = "UniKvsMiddlewareNextNotCalledError";
|
|
182
|
+
setErrorMessage(MiddlewareNextNotCalledError, ({ name, operation }) => `ミドルウェア "${name}" は ${operation} で next() を呼びませんでした。`, "ja");
|
|
183
|
+
/**
|
|
184
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
185
|
+
*/
|
|
186
|
+
var MiddlewareNextNotAwaitedError = class extends ErrorBase {
|
|
187
|
+
constructor(args) {
|
|
188
|
+
const { name, operation, ...options } = args;
|
|
189
|
+
super({
|
|
190
|
+
name,
|
|
191
|
+
operation
|
|
192
|
+
}, ({ name: messageName, operation: messageOperation }) => `Middleware "${messageName}" did not await next() for ${messageOperation}.`, options);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
_MiddlewareNextNotAwaitedError = MiddlewareNextNotAwaitedError;
|
|
196
|
+
_MiddlewareNextNotAwaitedError.prototype.name = "UniKvsMiddlewareNextNotAwaitedError";
|
|
197
|
+
setErrorMessage(MiddlewareNextNotAwaitedError, ({ name, operation }) => `ミドルウェア "${name}" は ${operation} で next() を await しませんでした。`, "ja");
|
|
198
|
+
/**
|
|
199
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
200
|
+
*/
|
|
201
|
+
var MiddlewareNextCalledMultipleTimesError = class extends ErrorBase {
|
|
202
|
+
constructor(args) {
|
|
203
|
+
const { name, operation, ...options } = args;
|
|
204
|
+
super({
|
|
205
|
+
name,
|
|
206
|
+
operation
|
|
207
|
+
}, ({ name: messageName, operation: messageOperation }) => `Middleware "${messageName}" called next() multiple times for ${messageOperation}.`, options);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
_MiddlewareNextCalledMultipleTimesError = MiddlewareNextCalledMultipleTimesError;
|
|
211
|
+
_MiddlewareNextCalledMultipleTimesError.prototype.name = "UniKvsMiddlewareNextCalledMultipleTimesError";
|
|
212
|
+
setErrorMessage(MiddlewareNextCalledMultipleTimesError, ({ name, operation }) => `ミドルウェア "${name}" は ${operation} で next() を複数回呼びました。`, "ja");
|
|
213
|
+
/**
|
|
214
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
215
|
+
*/
|
|
216
|
+
var StreamEncodingNotSupportedError = class extends ErrorBase {
|
|
217
|
+
constructor(args) {
|
|
218
|
+
const { name, ...options } = args;
|
|
219
|
+
super({ name }, ({ name: messageName }) => `Middleware "${messageName}" does not support stream encoding.`, options);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
_StreamEncodingNotSupportedError = StreamEncodingNotSupportedError;
|
|
223
|
+
_StreamEncodingNotSupportedError.prototype.name = "UniKvsStreamEncodingNotSupportedError";
|
|
224
|
+
setErrorMessage(StreamEncodingNotSupportedError, ({ name }) => `ミドルウェア "${name}" はストリームのエンコードをサポートしていません。`, "ja");
|
|
225
|
+
/**
|
|
226
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
227
|
+
*/
|
|
228
|
+
var StreamDecodingNotSupportedError = class extends ErrorBase {
|
|
229
|
+
constructor(args) {
|
|
230
|
+
const { name, ...options } = args;
|
|
231
|
+
super({ name }, ({ name: messageName }) => `Middleware "${messageName}" does not support decodable stream`, options);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
_StreamDecodingNotSupportedError = StreamDecodingNotSupportedError;
|
|
235
|
+
_StreamDecodingNotSupportedError.prototype.name = "UniKvsStreamDecodingNotSupportedError";
|
|
236
|
+
setErrorMessage(StreamDecodingNotSupportedError, ({ name }) => `ミドルウェア "${name}" はデコード可能なストリームをサポートしていません`, "ja");
|
|
237
|
+
/**
|
|
238
|
+
* プラグイン種別を正規化します。
|
|
239
|
+
*
|
|
240
|
+
* @param plugin 種別名です。
|
|
241
|
+
*
|
|
242
|
+
* @returns 正規化された種別を返します。
|
|
243
|
+
*/
|
|
244
|
+
function normalizePlugin(plugin) {
|
|
245
|
+
return plugin;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
249
|
+
*/
|
|
250
|
+
var PluginOperationAggregateError = class extends ErrorBase {
|
|
251
|
+
constructor(args) {
|
|
252
|
+
const { action, errors, plugin, ...options } = args;
|
|
253
|
+
const normalizedErrors = errors.map((error) => ({
|
|
254
|
+
plugin: normalizePlugin(error.plugin ?? plugin ?? ""),
|
|
255
|
+
...error.name !== void 0 ? { name: error.name } : {},
|
|
256
|
+
...error.index !== void 0 ? { index: error.index } : {},
|
|
257
|
+
reason: error.reason
|
|
258
|
+
}));
|
|
259
|
+
const plugins = [...new Set(normalizedErrors.map((error) => error.plugin))];
|
|
260
|
+
const [onlyPlugin] = plugins;
|
|
261
|
+
const meta = {
|
|
262
|
+
action,
|
|
263
|
+
errors: normalizedErrors,
|
|
264
|
+
plugin: plugins.length === 1 && onlyPlugin !== void 0 ? onlyPlugin : "plugin"
|
|
265
|
+
};
|
|
266
|
+
super(meta, ({ action: messageAction, errors: messageErrors, plugin: messagePlugin }) => `${messageErrors.length} ${messagePlugin}(s) fail ${messageAction} operation`, options);
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
_PluginOperationAggregateError = PluginOperationAggregateError;
|
|
270
|
+
_PluginOperationAggregateError.prototype.name = "UniKvsPluginOperationAggregateError";
|
|
271
|
+
setErrorMessage(PluginOperationAggregateError, ({ action, errors, plugin }) => `${errors.length} 個の${{
|
|
272
|
+
plugin: "プラグイン",
|
|
273
|
+
storage: "ストレージ",
|
|
274
|
+
middleware: "ミドルウェア"
|
|
275
|
+
}[plugin]}が ${action} 操作に失敗`, "ja");
|
|
276
|
+
/**
|
|
277
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#errors)
|
|
278
|
+
*/
|
|
279
|
+
var MissingStorageError = class extends ErrorBase {
|
|
280
|
+
constructor(options) {
|
|
281
|
+
super("At least one storage is required to use UniKvs", options);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
_MissingStorageError = MissingStorageError;
|
|
285
|
+
_MissingStorageError.prototype.name = "UniKvsMissingStorageError";
|
|
286
|
+
setErrorMessage(MissingStorageError, "UniKvs を使用するためには最低 1 つのストレージが必要です", "ja");
|
|
287
|
+
//#endregion
|
|
288
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/checkPrivateRedeclaration.js
|
|
289
|
+
function _checkPrivateRedeclaration(e, t) {
|
|
290
|
+
if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
291
|
+
}
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/classPrivateFieldInitSpec.js
|
|
294
|
+
function _classPrivateFieldInitSpec(e, t, a) {
|
|
295
|
+
_checkPrivateRedeclaration(e, t), t.set(e, a);
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/assertClassBrand.js
|
|
299
|
+
function _assertClassBrand(e, t, n) {
|
|
300
|
+
if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
|
|
301
|
+
throw new TypeError("Private element is not present on this object");
|
|
302
|
+
}
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/classPrivateFieldSet2.js
|
|
305
|
+
function _classPrivateFieldSet2(s, a, r) {
|
|
306
|
+
return s.set(_assertClassBrand(s, a), r), r;
|
|
307
|
+
}
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/classPrivateFieldGet2.js
|
|
310
|
+
function _classPrivateFieldGet2(s, a) {
|
|
311
|
+
return s.get(_assertClassBrand(s, a));
|
|
312
|
+
}
|
|
313
|
+
//#endregion
|
|
314
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/classPrivateMethodInitSpec.js
|
|
315
|
+
function _classPrivateMethodInitSpec(e, a) {
|
|
316
|
+
_checkPrivateRedeclaration(e, a), a.add(e);
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region ../src/_plugin-lifecycle.ts
|
|
320
|
+
var _plugin = /* @__PURE__ */ new WeakMap();
|
|
321
|
+
var _references = /* @__PURE__ */ new WeakMap();
|
|
322
|
+
var _closeFailed = /* @__PURE__ */ new WeakMap();
|
|
323
|
+
var _PluginLifecycle_brand = /* @__PURE__ */ new WeakSet();
|
|
324
|
+
/**
|
|
325
|
+
* 共有プラグインの参照カウントと実 `close` の再試行を管理します。
|
|
326
|
+
*
|
|
327
|
+
* 同じプラグインを共有する利用者のうち、最初の `open` だけが実際に開き、最後の `close` だけが実際に閉じます。
|
|
328
|
+
* 実 `close` に失敗したときは所有権を残し、次の `close` で再試行できるようにします。
|
|
329
|
+
*
|
|
330
|
+
* @template TOpenContext オープンコンテキストの型です。
|
|
331
|
+
* @template TCloseContext クローズコンテキストの型です。
|
|
332
|
+
*/
|
|
333
|
+
var PluginLifecycle = class {
|
|
334
|
+
constructor(plugin) {
|
|
335
|
+
_classPrivateMethodInitSpec(this, _PluginLifecycle_brand);
|
|
336
|
+
_classPrivateFieldInitSpec(this, _plugin, void 0);
|
|
337
|
+
_classPrivateFieldInitSpec(this, _references, void 0);
|
|
338
|
+
_classPrivateFieldInitSpec(this, _closeFailed, void 0);
|
|
339
|
+
_classPrivateFieldSet2(_plugin, this, plugin);
|
|
340
|
+
_classPrivateFieldSet2(_references, this, 0);
|
|
341
|
+
_classPrivateFieldSet2(_closeFailed, this, false);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* プラグインを開きます。
|
|
345
|
+
*
|
|
346
|
+
* 同じプラグインを共有する利用者のうち、最初の 1 回だけ実際の `open` を呼びます。
|
|
347
|
+
* この管理対象外で既に開かれているプラグインは open/close の対象外にします。
|
|
348
|
+
* 参照が残っていても実体が閉じられているときは、既存の参照を失わずに実 open へフォールバックします。
|
|
349
|
+
* `close` を持たないプラグインは閉じられないため、参照を数えません。
|
|
350
|
+
*
|
|
351
|
+
* @param c オープンコンテキストです。
|
|
352
|
+
*/
|
|
353
|
+
async open(c) {
|
|
354
|
+
if (_classPrivateFieldGet2(_plugin, this).open === void 0) return;
|
|
355
|
+
if (_classPrivateFieldGet2(_plugin, this).close === void 0) {
|
|
356
|
+
if (_classPrivateFieldGet2(_plugin, this).isOpen) return;
|
|
357
|
+
await _classPrivateFieldGet2(_plugin, this).open(c);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (_classPrivateFieldGet2(_plugin, this).isOpen && _classPrivateFieldGet2(_references, this) === 0 && !_classPrivateFieldGet2(_closeFailed, this)) return;
|
|
361
|
+
if (_classPrivateFieldGet2(_references, this) > 0 || _classPrivateFieldGet2(_closeFailed, this)) {
|
|
362
|
+
if (_classPrivateFieldGet2(_plugin, this).isOpen) {
|
|
363
|
+
_classPrivateFieldSet2(_references, this, _classPrivateFieldGet2(_references, this) + 1);
|
|
364
|
+
_classPrivateFieldSet2(_closeFailed, this, false);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
await _classPrivateFieldGet2(_plugin, this).open(c);
|
|
368
|
+
_classPrivateFieldSet2(_references, this, _classPrivateFieldGet2(_references, this) + 1);
|
|
369
|
+
_classPrivateFieldSet2(_closeFailed, this, false);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
await _classPrivateFieldGet2(_plugin, this).open(c);
|
|
373
|
+
_classPrivateFieldSet2(_references, this, _classPrivateFieldGet2(_references, this) + 1);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* プラグインを閉じます。
|
|
377
|
+
*
|
|
378
|
+
* 同じプラグインを共有する利用者のうち、最後の 1 回だけ実際の `close` を呼びます。
|
|
379
|
+
* 各呼び出しで参照を 1 つ減らし、実 `close` は全参照が解放されたときにだけ呼びます。
|
|
380
|
+
* 実 `close` に失敗したときは所有権を残し、次の `close` で再試行できるようにします。
|
|
381
|
+
* `close` を持たないプラグインは open で参照を数えないため、ここでは何もしません。
|
|
382
|
+
* 実 `close` へ渡すコンテキストは最後に閉じる利用者のものであり、最初に開いた利用者の vars/signal は保持しません。
|
|
383
|
+
*
|
|
384
|
+
* @param c クローズコンテキストです。
|
|
385
|
+
*/
|
|
386
|
+
async close(c) {
|
|
387
|
+
if (_classPrivateFieldGet2(_plugin, this).close === void 0) return;
|
|
388
|
+
if (_classPrivateFieldGet2(_references, this) === 0 && !_classPrivateFieldGet2(_closeFailed, this)) return;
|
|
389
|
+
if (_classPrivateFieldGet2(_references, this) > 0) _classPrivateFieldSet2(_references, this, _classPrivateFieldGet2(_references, this) - 1);
|
|
390
|
+
if (_classPrivateFieldGet2(_references, this) > 0) return;
|
|
391
|
+
if (!_classPrivateFieldGet2(_plugin, this).isOpen) {
|
|
392
|
+
_classPrivateFieldSet2(_closeFailed, this, false);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
await _assertClassBrand(_PluginLifecycle_brand, this, _closeReal).call(this, c);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* 失敗した実 `close` だけを再試行します。
|
|
399
|
+
*
|
|
400
|
+
* 通常の `close` と違い参照を減らしません。close 失敗後に新しい `open` が所有権を引き継いでいる場合は何もしません。
|
|
401
|
+
* 実体が既に閉じられているときは失敗状態だけを解消します。
|
|
402
|
+
*
|
|
403
|
+
* @param c クローズコンテキストです。
|
|
404
|
+
*/
|
|
405
|
+
async retryClose(c) {
|
|
406
|
+
if (_classPrivateFieldGet2(_plugin, this).close === void 0) return;
|
|
407
|
+
if (!_classPrivateFieldGet2(_closeFailed, this) || _classPrivateFieldGet2(_references, this) > 0) return;
|
|
408
|
+
if (!_classPrivateFieldGet2(_plugin, this).isOpen) {
|
|
409
|
+
_classPrivateFieldSet2(_closeFailed, this, false);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
await _assertClassBrand(_PluginLifecycle_brand, this, _closeReal).call(this, c);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
/**
|
|
416
|
+
* 実 `close` を実行し、失敗したかどうかを記録します。
|
|
417
|
+
*
|
|
418
|
+
* @param c クローズコンテキストです。
|
|
419
|
+
*/
|
|
420
|
+
async function _closeReal(c) {
|
|
421
|
+
if (_classPrivateFieldGet2(_plugin, this).close === void 0) return;
|
|
422
|
+
try {
|
|
423
|
+
await _classPrivateFieldGet2(_plugin, this).close(c);
|
|
424
|
+
_classPrivateFieldSet2(_closeFailed, this, false);
|
|
425
|
+
} catch (ex) {
|
|
426
|
+
_classPrivateFieldSet2(_closeFailed, this, true);
|
|
427
|
+
throw ex;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
//#endregion
|
|
431
|
+
//#region ../src/_middleware.ts
|
|
432
|
+
var _UniKvsMiddleware;
|
|
433
|
+
let _initProto$1;
|
|
434
|
+
function _applyDecs$1(e, t, n, r, o, i) {
|
|
435
|
+
var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length;
|
|
436
|
+
function g(t, n, r) {
|
|
437
|
+
return function(o, i) {
|
|
438
|
+
n && (i = o, o = e);
|
|
439
|
+
for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []);
|
|
440
|
+
return r ? i : o;
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function b(e, t, n, r) {
|
|
444
|
+
if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined"));
|
|
445
|
+
return e;
|
|
446
|
+
}
|
|
447
|
+
function applyDec(e, t, n, r, o, i, u, s, f, l, p) {
|
|
448
|
+
function d(e) {
|
|
449
|
+
if (!p(e)) throw new TypeError("Attempted to access private element on non-instance");
|
|
450
|
+
}
|
|
451
|
+
var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o;
|
|
452
|
+
function I(t, n, r) {
|
|
453
|
+
return function(o, i) {
|
|
454
|
+
return n && (i = o, o = e), r && r(o), P[t].call(o, i);
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
if (!w) {
|
|
458
|
+
var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value";
|
|
459
|
+
if (f ? (l || D ? P = {
|
|
460
|
+
get: _setFunctionName$1(function() {
|
|
461
|
+
return v(this);
|
|
462
|
+
}, r, "get"),
|
|
463
|
+
set: function(e) {
|
|
464
|
+
t[4](this, e);
|
|
465
|
+
}
|
|
466
|
+
} : P[F] = v, l || _setFunctionName$1(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) {
|
|
467
|
+
if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet");
|
|
468
|
+
y[+s][r] = o < 3 ? 1 : o;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) {
|
|
472
|
+
var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = {
|
|
473
|
+
kind: [
|
|
474
|
+
"field",
|
|
475
|
+
"accessor",
|
|
476
|
+
"method",
|
|
477
|
+
"getter",
|
|
478
|
+
"setter",
|
|
479
|
+
"class"
|
|
480
|
+
][o],
|
|
481
|
+
name: r,
|
|
482
|
+
metadata: a,
|
|
483
|
+
addInitializer: function(e, t) {
|
|
484
|
+
if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished");
|
|
485
|
+
b(t, "An initializer", "be", !0), i.push(t);
|
|
486
|
+
}.bind(null, A)
|
|
487
|
+
};
|
|
488
|
+
if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);
|
|
489
|
+
else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function(e) {
|
|
490
|
+
return r in e;
|
|
491
|
+
} }, j || (c.get = f ? E ? function(e) {
|
|
492
|
+
return d(e), P.value;
|
|
493
|
+
} : I("get", 0, d) : function(e) {
|
|
494
|
+
return e[r];
|
|
495
|
+
}), E || S || (c.set = f ? I("set", 0, d) : function(e, t) {
|
|
496
|
+
e[r] = t;
|
|
497
|
+
}), N = T.call(z, D ? {
|
|
498
|
+
get: P.get,
|
|
499
|
+
set: P.set
|
|
500
|
+
} : P[F], H), A.v = 1, D) {
|
|
501
|
+
if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);
|
|
502
|
+
else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined");
|
|
503
|
+
} else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N);
|
|
504
|
+
}
|
|
505
|
+
return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N;
|
|
506
|
+
}
|
|
507
|
+
function w(e) {
|
|
508
|
+
return m(e, d, {
|
|
509
|
+
configurable: !0,
|
|
510
|
+
enumerable: !0,
|
|
511
|
+
value: a
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function(e) {
|
|
515
|
+
e && f.push(g(e));
|
|
516
|
+
}, p = function(t, r) {
|
|
517
|
+
for (var i = 0; i < n.length; i++) {
|
|
518
|
+
var a = n[i], c = a[1], l = 7 & c;
|
|
519
|
+
if ((8 & c) == t && !l == r) {
|
|
520
|
+
var p = a[2], d = !!a[3], m = 16 & c;
|
|
521
|
+
applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey$1(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function(t) {
|
|
522
|
+
return _checkInRHS$1(t) === e;
|
|
523
|
+
} : o);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), {
|
|
527
|
+
e: c,
|
|
528
|
+
get c() {
|
|
529
|
+
var n = [];
|
|
530
|
+
return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)];
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function _toPropertyKey$1(t) {
|
|
535
|
+
var i = _toPrimitive$1(t, "string");
|
|
536
|
+
return "symbol" == typeof i ? i : i + "";
|
|
537
|
+
}
|
|
538
|
+
function _toPrimitive$1(t, e) {
|
|
539
|
+
if ("object" != typeof t || !t) return t;
|
|
540
|
+
var r;
|
|
541
|
+
if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) {
|
|
542
|
+
var i = r.call(t, e || "default");
|
|
543
|
+
if ("object" != typeof i) return i;
|
|
544
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
545
|
+
}
|
|
546
|
+
return ("string" === e ? String : Number)(t);
|
|
547
|
+
}
|
|
548
|
+
function _setFunctionName$1(e, t, n) {
|
|
549
|
+
"symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
|
|
550
|
+
try {
|
|
551
|
+
Object.defineProperty(e, "name", {
|
|
552
|
+
configurable: !0,
|
|
553
|
+
value: n ? n + " " + t : t
|
|
554
|
+
});
|
|
555
|
+
} catch (e) {}
|
|
556
|
+
return e;
|
|
557
|
+
}
|
|
558
|
+
function _checkInRHS$1(e) {
|
|
559
|
+
if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
|
|
560
|
+
return e;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* 同じオブジェクトに対して同じ `UniKvsMiddleware` インスタンスを返すためのメモです。
|
|
564
|
+
*/
|
|
565
|
+
const instances$1 = /* #__PURE__ */ new WeakMap();
|
|
566
|
+
var _mw = /* @__PURE__ */ new WeakMap();
|
|
567
|
+
var _lifecycle$1 = /* @__PURE__ */ new WeakMap();
|
|
568
|
+
/**
|
|
569
|
+
* `IMiddleware` を `UniKvs` 内部から扱うためのラッパーです。
|
|
570
|
+
*
|
|
571
|
+
* ミドルウェアを安全に使うための検証などの処理が集約されています。
|
|
572
|
+
*/
|
|
573
|
+
var UniKvsMiddleware = class UniKvsMiddleware {
|
|
574
|
+
constructor(middleware) {
|
|
575
|
+
_classPrivateFieldInitSpec(this, _mw, void _initProto$1(this));
|
|
576
|
+
_classPrivateFieldInitSpec(this, _lifecycle$1, void 0);
|
|
577
|
+
_classPrivateFieldSet2(_mw, this, middleware);
|
|
578
|
+
_classPrivateFieldSet2(_lifecycle$1, this, new PluginLifecycle(middleware));
|
|
579
|
+
this.name = middleware.name;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* `IMiddleware` から `UniKvs` 内部から扱うためのミドルウェアを作成します。
|
|
583
|
+
*
|
|
584
|
+
* @param middleware 元となるミドルウェアです。
|
|
585
|
+
*
|
|
586
|
+
* @returns 検証などの機能が集約されたミドルウェアです。
|
|
587
|
+
*/
|
|
588
|
+
static from(middleware) {
|
|
589
|
+
return callFnOnce(instances$1, middleware, () => new UniKvsMiddleware(middleware));
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* ミドルウェアを開きます。
|
|
593
|
+
*
|
|
594
|
+
* @param c オープンコンテキストです。
|
|
595
|
+
*/
|
|
596
|
+
async open(c) {
|
|
597
|
+
await _classPrivateFieldGet2(_lifecycle$1, this).open(c);
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* ミドルウェアを閉じます。
|
|
601
|
+
*
|
|
602
|
+
* @param c クローズコンテキストです。
|
|
603
|
+
*/
|
|
604
|
+
async close(c) {
|
|
605
|
+
await _classPrivateFieldGet2(_lifecycle$1, this).close(c);
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* 失敗した実 `close` だけを再試行します。
|
|
609
|
+
*
|
|
610
|
+
* @param c クローズコンテキストです。
|
|
611
|
+
*/
|
|
612
|
+
async retryClose(c) {
|
|
613
|
+
await _classPrivateFieldGet2(_lifecycle$1, this).retryClose(c);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* キーを写像します。
|
|
617
|
+
*
|
|
618
|
+
* @param c キー写像コンテキストです。
|
|
619
|
+
*
|
|
620
|
+
* @returns 写像後のキーを返します。
|
|
621
|
+
*/
|
|
622
|
+
mapKey(c) {
|
|
623
|
+
if (!_classPrivateFieldGet2(_mw, this).isOpen) throw new MiddlewareIsNotOpenError({ name: this.name });
|
|
624
|
+
if (_classPrivateFieldGet2(_mw, this).mapKey === void 0) return c.key;
|
|
625
|
+
return _classPrivateFieldGet2(_mw, this).mapKey(c);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* 任意の操作に割り込みます。
|
|
629
|
+
*
|
|
630
|
+
* @param c 操作コンテキストです。
|
|
631
|
+
* @param next 後段の処理です。
|
|
632
|
+
*/
|
|
633
|
+
async use(c, next) {
|
|
634
|
+
if (!_classPrivateFieldGet2(_mw, this).isOpen) throw new MiddlewareIsNotOpenError({ name: this.name });
|
|
635
|
+
if (_classPrivateFieldGet2(_mw, this).use === void 0) await next();
|
|
636
|
+
else await _classPrivateFieldGet2(_mw, this).use(c, next);
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* データをエンコードします。
|
|
640
|
+
*
|
|
641
|
+
* @param c エンコードコンテキストです。
|
|
642
|
+
* @param next 後段の処理です。
|
|
643
|
+
*/
|
|
644
|
+
async encode(c, next) {
|
|
645
|
+
if (!_classPrivateFieldGet2(_mw, this).isOpen) throw new MiddlewareIsNotOpenError({ name: this.name });
|
|
646
|
+
if (_classPrivateFieldGet2(_mw, this).encode === void 0) {
|
|
647
|
+
c.destination = c.source;
|
|
648
|
+
await next();
|
|
649
|
+
} else await _classPrivateFieldGet2(_mw, this).encode(c, next);
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* データをデコードします。
|
|
653
|
+
*
|
|
654
|
+
* @param c デコードコンテキストです。
|
|
655
|
+
* @param next 後段の処理です。
|
|
656
|
+
*/
|
|
657
|
+
async decode(c, next) {
|
|
658
|
+
if (!_classPrivateFieldGet2(_mw, this).isOpen) throw new MiddlewareIsNotOpenError({ name: this.name });
|
|
659
|
+
if (_classPrivateFieldGet2(_mw, this).decode === void 0) {
|
|
660
|
+
c.destination = c.source;
|
|
661
|
+
await next();
|
|
662
|
+
} else await _classPrivateFieldGet2(_mw, this).decode(c, next);
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* ストリームをエンコードします。
|
|
666
|
+
*
|
|
667
|
+
* @param c エンコードストリームコンテキストです。
|
|
668
|
+
* @param next 後段の処理です。
|
|
669
|
+
*/
|
|
670
|
+
async encodeStream(c, next) {
|
|
671
|
+
if (!_classPrivateFieldGet2(_mw, this).isOpen) throw new MiddlewareIsNotOpenError({ name: this.name });
|
|
672
|
+
if (_classPrivateFieldGet2(_mw, this).encodeStream === void 0) throw new StreamEncodingNotSupportedError({ name: this.name });
|
|
673
|
+
await _classPrivateFieldGet2(_mw, this).encodeStream(c, next);
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* ストリームをデコードします。
|
|
677
|
+
*
|
|
678
|
+
* @param c デコードストリームコンテキストです。
|
|
679
|
+
* @param next 後段の処理です。
|
|
680
|
+
*/
|
|
681
|
+
async decodeStream(c, next) {
|
|
682
|
+
if (!_classPrivateFieldGet2(_mw, this).isOpen) throw new MiddlewareIsNotOpenError({ name: this.name });
|
|
683
|
+
if (_classPrivateFieldGet2(_mw, this).decodeStream === void 0) throw new StreamDecodingNotSupportedError({ name: this.name });
|
|
684
|
+
await _classPrivateFieldGet2(_mw, this).decodeStream(c, next);
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
_UniKvsMiddleware = UniKvsMiddleware;
|
|
688
|
+
[_initProto$1] = _applyDecs$1(_UniKvsMiddleware, [], [
|
|
689
|
+
[
|
|
690
|
+
asyncmux,
|
|
691
|
+
2,
|
|
692
|
+
"open"
|
|
693
|
+
],
|
|
694
|
+
[
|
|
695
|
+
asyncmux,
|
|
696
|
+
2,
|
|
697
|
+
"close"
|
|
698
|
+
],
|
|
699
|
+
[
|
|
700
|
+
asyncmux,
|
|
701
|
+
2,
|
|
702
|
+
"retryClose"
|
|
703
|
+
]
|
|
704
|
+
]).e;
|
|
705
|
+
//#endregion
|
|
706
|
+
//#region ../src/_streams.ts
|
|
707
|
+
/**
|
|
708
|
+
* 値が `ReadableStream` のインターフェースを満たすかどうかを判定します。
|
|
709
|
+
*
|
|
710
|
+
* ランタイムによっては `ReadableStream` クラスを継承せずに同じインターフェースを備えたオブジェクトが存在するため、`instanceof` ではなく必要なメソッドの有無で判定します。
|
|
711
|
+
*
|
|
712
|
+
* @param input 判定する値です。
|
|
713
|
+
*
|
|
714
|
+
* @returns `ReadableStream` のインターフェースを満たす場合は `true` を返します。
|
|
715
|
+
*/
|
|
716
|
+
function isReadableStream(input) {
|
|
717
|
+
if (typeof input !== "object" || input === null) return false;
|
|
718
|
+
const stream = input;
|
|
719
|
+
return typeof stream.tee === "function" && typeof stream.cancel === "function" && typeof stream.pipeTo === "function" && typeof stream.getReader === "function" && typeof stream.pipeThrough === "function";
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* 値が `WritableStream` のインターフェースを満たすかどうかを判定します。
|
|
723
|
+
*
|
|
724
|
+
* ランタイムによっては `WritableStream` クラスを継承せずに同じインターフェースを備えたオブジェクトが存在するため、`instanceof` ではなく必要なメソッドの有無で判定します。
|
|
725
|
+
*
|
|
726
|
+
* @param input 判定する値です。
|
|
727
|
+
*
|
|
728
|
+
* @returns `WritableStream` のインターフェースを満たす場合は `true` を返します。
|
|
729
|
+
*/
|
|
730
|
+
function isWritableStream(input) {
|
|
731
|
+
if (typeof input !== "object" || input === null) return false;
|
|
732
|
+
const stream = input;
|
|
733
|
+
return typeof stream.abort === "function" && typeof stream.close === "function" && typeof stream.getWriter === "function";
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* ストリームの重複を除いてキャンセルします。
|
|
737
|
+
*
|
|
738
|
+
* 個々のキャンセルに失敗しても無視し、元の例外を優先して伝えます。
|
|
739
|
+
*
|
|
740
|
+
* @param streams キャンセルするストリームです。
|
|
741
|
+
* @param reason キャンセル理由です。
|
|
742
|
+
*/
|
|
743
|
+
async function cancelStreams(streams, reason) {
|
|
744
|
+
await Promise.all([...new Set(streams)].map(async (stream) => {
|
|
745
|
+
try {
|
|
746
|
+
await stream.cancel(reason);
|
|
747
|
+
} catch {}
|
|
748
|
+
}));
|
|
749
|
+
}
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region ../src/_valibot.ts
|
|
752
|
+
function parseInput(schema, value, Error = InvalidInputError) {
|
|
753
|
+
const result = safeParse(schema, value);
|
|
754
|
+
if (result.success) return result.output;
|
|
755
|
+
const error = new Error({
|
|
756
|
+
value,
|
|
757
|
+
issues: result.issues
|
|
758
|
+
});
|
|
759
|
+
tryCaptureStackTrace(error, parseInput);
|
|
760
|
+
throw error;
|
|
761
|
+
}
|
|
762
|
+
function parseOutput(schema, value, Error = InvalidOutputError) {
|
|
763
|
+
const result = safeParse(schema, value);
|
|
764
|
+
if (result.success) return result.output;
|
|
765
|
+
const error = new Error({
|
|
766
|
+
value,
|
|
767
|
+
issues: result.issues
|
|
768
|
+
});
|
|
769
|
+
tryCaptureStackTrace(error, parseOutput);
|
|
770
|
+
throw error;
|
|
771
|
+
}
|
|
772
|
+
//#endregion
|
|
773
|
+
//#region ../src/_streams.schemas.ts
|
|
774
|
+
/**
|
|
775
|
+
* `ReadableStream` のインターフェースを満たすかを検証するためのスキーマです。
|
|
776
|
+
*/
|
|
777
|
+
const ReadableStreamSchema = custom(isReadableStream, "Expected a ReadableStream");
|
|
778
|
+
/**
|
|
779
|
+
* `WritableStream` のインターフェースを満たすかを検証するためのスキーマです。
|
|
780
|
+
*/
|
|
781
|
+
const WritableStreamSchema = custom(isWritableStream, "Expected a WritableStream");
|
|
782
|
+
//#endregion
|
|
783
|
+
//#region ../src/_storage.ts
|
|
784
|
+
var _UniKvsStorage;
|
|
785
|
+
let _initProto;
|
|
786
|
+
function _applyDecs(e, t, n, r, o, i) {
|
|
787
|
+
var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length;
|
|
788
|
+
function g(t, n, r) {
|
|
789
|
+
return function(o, i) {
|
|
790
|
+
n && (i = o, o = e);
|
|
791
|
+
for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []);
|
|
792
|
+
return r ? i : o;
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
function b(e, t, n, r) {
|
|
796
|
+
if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined"));
|
|
797
|
+
return e;
|
|
798
|
+
}
|
|
799
|
+
function applyDec(e, t, n, r, o, i, u, s, f, l, p) {
|
|
800
|
+
function d(e) {
|
|
801
|
+
if (!p(e)) throw new TypeError("Attempted to access private element on non-instance");
|
|
802
|
+
}
|
|
803
|
+
var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o;
|
|
804
|
+
function I(t, n, r) {
|
|
805
|
+
return function(o, i) {
|
|
806
|
+
return n && (i = o, o = e), r && r(o), P[t].call(o, i);
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
if (!w) {
|
|
810
|
+
var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value";
|
|
811
|
+
if (f ? (l || D ? P = {
|
|
812
|
+
get: _setFunctionName(function() {
|
|
813
|
+
return v(this);
|
|
814
|
+
}, r, "get"),
|
|
815
|
+
set: function(e) {
|
|
816
|
+
t[4](this, e);
|
|
817
|
+
}
|
|
818
|
+
} : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) {
|
|
819
|
+
if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet");
|
|
820
|
+
y[+s][r] = o < 3 ? 1 : o;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) {
|
|
824
|
+
var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = {
|
|
825
|
+
kind: [
|
|
826
|
+
"field",
|
|
827
|
+
"accessor",
|
|
828
|
+
"method",
|
|
829
|
+
"getter",
|
|
830
|
+
"setter",
|
|
831
|
+
"class"
|
|
832
|
+
][o],
|
|
833
|
+
name: r,
|
|
834
|
+
metadata: a,
|
|
835
|
+
addInitializer: function(e, t) {
|
|
836
|
+
if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished");
|
|
837
|
+
b(t, "An initializer", "be", !0), i.push(t);
|
|
838
|
+
}.bind(null, A)
|
|
839
|
+
};
|
|
840
|
+
if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);
|
|
841
|
+
else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function(e) {
|
|
842
|
+
return r in e;
|
|
843
|
+
} }, j || (c.get = f ? E ? function(e) {
|
|
844
|
+
return d(e), P.value;
|
|
845
|
+
} : I("get", 0, d) : function(e) {
|
|
846
|
+
return e[r];
|
|
847
|
+
}), E || S || (c.set = f ? I("set", 0, d) : function(e, t) {
|
|
848
|
+
e[r] = t;
|
|
849
|
+
}), N = T.call(z, D ? {
|
|
850
|
+
get: P.get,
|
|
851
|
+
set: P.set
|
|
852
|
+
} : P[F], H), A.v = 1, D) {
|
|
853
|
+
if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);
|
|
854
|
+
else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined");
|
|
855
|
+
} else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N);
|
|
856
|
+
}
|
|
857
|
+
return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N;
|
|
858
|
+
}
|
|
859
|
+
function w(e) {
|
|
860
|
+
return m(e, d, {
|
|
861
|
+
configurable: !0,
|
|
862
|
+
enumerable: !0,
|
|
863
|
+
value: a
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function(e) {
|
|
867
|
+
e && f.push(g(e));
|
|
868
|
+
}, p = function(t, r) {
|
|
869
|
+
for (var i = 0; i < n.length; i++) {
|
|
870
|
+
var a = n[i], c = a[1], l = 7 & c;
|
|
871
|
+
if ((8 & c) == t && !l == r) {
|
|
872
|
+
var p = a[2], d = !!a[3], m = 16 & c;
|
|
873
|
+
applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function(t) {
|
|
874
|
+
return _checkInRHS(t) === e;
|
|
875
|
+
} : o);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), {
|
|
879
|
+
e: c,
|
|
880
|
+
get c() {
|
|
881
|
+
var n = [];
|
|
882
|
+
return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)];
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
function _toPropertyKey(t) {
|
|
887
|
+
var i = _toPrimitive(t, "string");
|
|
888
|
+
return "symbol" == typeof i ? i : i + "";
|
|
889
|
+
}
|
|
890
|
+
function _toPrimitive(t, e) {
|
|
891
|
+
if ("object" != typeof t || !t) return t;
|
|
892
|
+
var r;
|
|
893
|
+
if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) {
|
|
894
|
+
var i = r.call(t, e || "default");
|
|
895
|
+
if ("object" != typeof i) return i;
|
|
896
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
897
|
+
}
|
|
898
|
+
return ("string" === e ? String : Number)(t);
|
|
899
|
+
}
|
|
900
|
+
function _setFunctionName(e, t, n) {
|
|
901
|
+
"symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
|
|
902
|
+
try {
|
|
903
|
+
Object.defineProperty(e, "name", {
|
|
904
|
+
configurable: !0,
|
|
905
|
+
value: n ? n + " " + t : t
|
|
906
|
+
});
|
|
907
|
+
} catch (e) {}
|
|
908
|
+
return e;
|
|
909
|
+
}
|
|
910
|
+
function _checkInRHS(e) {
|
|
911
|
+
if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
|
|
912
|
+
return e;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* 同じオブジェクトに対して同じ `UniKvsStorage` インスタンスを返すためのメモです。
|
|
916
|
+
*/
|
|
917
|
+
const instances = /* #__PURE__ */ new WeakMap();
|
|
918
|
+
var _io = /* @__PURE__ */ new WeakMap();
|
|
919
|
+
var _lifecycle = /* @__PURE__ */ new WeakMap();
|
|
920
|
+
/**
|
|
921
|
+
* `IStorage` を `UniKvs` 内部から扱うためのラッパーです。
|
|
922
|
+
*
|
|
923
|
+
* ストレージを安全に使うための検証などの処理が集約されています。
|
|
924
|
+
*/
|
|
925
|
+
var UniKvsStorage = class UniKvsStorage {
|
|
926
|
+
constructor(storage) {
|
|
927
|
+
_classPrivateFieldInitSpec(this, _io, void _initProto(this));
|
|
928
|
+
_classPrivateFieldInitSpec(this, _lifecycle, void 0);
|
|
929
|
+
_classPrivateFieldSet2(_io, this, storage);
|
|
930
|
+
_classPrivateFieldSet2(_lifecycle, this, new PluginLifecycle(storage));
|
|
931
|
+
this.name = storage.name;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* `IStorage` から `UniKvs` 内部から扱うためのストレージを作成します。
|
|
935
|
+
*
|
|
936
|
+
* @param storage 元となるストレージです。
|
|
937
|
+
*
|
|
938
|
+
* @returns 検証などの機能が集約されたストレージです。
|
|
939
|
+
*/
|
|
940
|
+
static from(storage) {
|
|
941
|
+
return callFnOnce(instances, storage, () => new UniKvsStorage(storage));
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* ストレージを開きます。
|
|
945
|
+
*
|
|
946
|
+
* @param c オープンコンテキストです。
|
|
947
|
+
*/
|
|
948
|
+
async open(c) {
|
|
949
|
+
await _classPrivateFieldGet2(_lifecycle, this).open(c);
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* ストレージを閉じます。
|
|
953
|
+
*
|
|
954
|
+
* @param c クローズコンテキストです。
|
|
955
|
+
*/
|
|
956
|
+
async close(c) {
|
|
957
|
+
await _classPrivateFieldGet2(_lifecycle, this).close(c);
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* 失敗した実 `close` だけを再試行します。
|
|
961
|
+
*
|
|
962
|
+
* @param c クローズコンテキストです。
|
|
963
|
+
*/
|
|
964
|
+
async retryClose(c) {
|
|
965
|
+
await _classPrivateFieldGet2(_lifecycle, this).retryClose(c);
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* データを書き込みます。
|
|
969
|
+
*
|
|
970
|
+
* @param c 書き込みコンテキストです。
|
|
971
|
+
* @param data 書き込むデータです。
|
|
972
|
+
*/
|
|
973
|
+
async write(c, data) {
|
|
974
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
975
|
+
await _classPrivateFieldGet2(_io, this).write(c, data);
|
|
976
|
+
}
|
|
977
|
+
/**
|
|
978
|
+
* データを読み取ります。
|
|
979
|
+
*
|
|
980
|
+
* @param c 読み取りコンテキストです。
|
|
981
|
+
*
|
|
982
|
+
* @returns 読み取ったデータを返します。
|
|
983
|
+
*/
|
|
984
|
+
async read(c) {
|
|
985
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
986
|
+
return await _classPrivateFieldGet2(_io, this).read(c);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* データの存在を確認します。
|
|
990
|
+
*
|
|
991
|
+
* @param c 存在確認コンテキストです。
|
|
992
|
+
*
|
|
993
|
+
* @returns 存在する場合は `true` を返します。
|
|
994
|
+
*/
|
|
995
|
+
async exists(c) {
|
|
996
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
997
|
+
return await _classPrivateFieldGet2(_io, this).exists(c);
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* データを削除します。
|
|
1001
|
+
*
|
|
1002
|
+
* @param c 削除コンテキストです。
|
|
1003
|
+
*/
|
|
1004
|
+
async delete(c) {
|
|
1005
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
1006
|
+
await _classPrivateFieldGet2(_io, this).delete(c);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* データをすべて削除します。
|
|
1010
|
+
*
|
|
1011
|
+
* @param c クリアコンテキストです。
|
|
1012
|
+
*/
|
|
1013
|
+
async clear(c) {
|
|
1014
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
1015
|
+
await _classPrivateFieldGet2(_io, this).clear(c);
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* 読み取り用のストリームを取得します。
|
|
1019
|
+
*
|
|
1020
|
+
* @param c ストリーム取得コンテキストです。
|
|
1021
|
+
*
|
|
1022
|
+
* @returns 読み取り用のストリームを返します。
|
|
1023
|
+
*/
|
|
1024
|
+
async getReadable(c) {
|
|
1025
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
1026
|
+
if (_classPrivateFieldGet2(_io, this).getReadable === void 0) throw new ReadableStreamNotSupportedError({ name: this.name });
|
|
1027
|
+
const output = await _classPrivateFieldGet2(_io, this).getReadable(c);
|
|
1028
|
+
return parseOutput(ReadableStreamSchema, output);
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* 書き込み用のストリームを取得します。
|
|
1032
|
+
*
|
|
1033
|
+
* @param c ストリーム取得コンテキストです。
|
|
1034
|
+
*
|
|
1035
|
+
* @returns 書き込み用のストリームを返します。
|
|
1036
|
+
*/
|
|
1037
|
+
async getWritable(c) {
|
|
1038
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
1039
|
+
if (_classPrivateFieldGet2(_io, this).getWritable === void 0) throw new WritableStreamNotSupportedError({ name: this.name });
|
|
1040
|
+
const output = await _classPrivateFieldGet2(_io, this).getWritable(c);
|
|
1041
|
+
return parseOutput(WritableStreamSchema, output);
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* 他のストレージへの書き込み失敗を通知します。
|
|
1045
|
+
*
|
|
1046
|
+
* @param c 書き込み失敗通知コンテキストです。
|
|
1047
|
+
* @param err 集約エラーです。
|
|
1048
|
+
*/
|
|
1049
|
+
async onOtherWriteError(c, err) {
|
|
1050
|
+
if (!_classPrivateFieldGet2(_io, this).isOpen) throw new StorageIsNotOpenError({ name: this.name });
|
|
1051
|
+
if (_classPrivateFieldGet2(_io, this).onOtherWriteError === void 0) return;
|
|
1052
|
+
await _classPrivateFieldGet2(_io, this).onOtherWriteError(c, [{
|
|
1053
|
+
errors: err.meta.errors.map((error) => ({
|
|
1054
|
+
plugin: "storage",
|
|
1055
|
+
reason: error.reason
|
|
1056
|
+
})),
|
|
1057
|
+
plugin: "storage"
|
|
1058
|
+
}]);
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
_UniKvsStorage = UniKvsStorage;
|
|
1062
|
+
[_initProto] = _applyDecs(_UniKvsStorage, [], [
|
|
1063
|
+
[
|
|
1064
|
+
asyncmux,
|
|
1065
|
+
2,
|
|
1066
|
+
"open"
|
|
1067
|
+
],
|
|
1068
|
+
[
|
|
1069
|
+
asyncmux,
|
|
1070
|
+
2,
|
|
1071
|
+
"close"
|
|
1072
|
+
],
|
|
1073
|
+
[
|
|
1074
|
+
asyncmux,
|
|
1075
|
+
2,
|
|
1076
|
+
"retryClose"
|
|
1077
|
+
]
|
|
1078
|
+
]).e;
|
|
1079
|
+
//#endregion
|
|
1080
|
+
//#region ../src/_unikvs-branch.ts
|
|
1081
|
+
/**
|
|
1082
|
+
* インスタンスと内部状態の対応表です。
|
|
1083
|
+
* コンパイラーによる `#` フィールドのダウンレベルと同様に、`WeakMap` をブランド兼ストレージとして使います。
|
|
1084
|
+
*/
|
|
1085
|
+
const branchStates = /* #__PURE__ */ new WeakMap();
|
|
1086
|
+
/**
|
|
1087
|
+
* 分岐先のスナップショットを返します。
|
|
1088
|
+
*
|
|
1089
|
+
* 親の `fork` で接頭辞付加するために使用します。
|
|
1090
|
+
* `new Branch()` で作成された分岐以外の値が渡されたときは例外を投げます。
|
|
1091
|
+
* 外部からは使用しません。
|
|
1092
|
+
*
|
|
1093
|
+
* @param branch スナップショットを取得する分岐です。
|
|
1094
|
+
*
|
|
1095
|
+
* @returns 分岐先のコピーを返します。
|
|
1096
|
+
*/
|
|
1097
|
+
function getBranchDestinationsForFork(branch) {
|
|
1098
|
+
const state = branchStates.get(branch);
|
|
1099
|
+
if (!state) throw new TypeError("fork() expects a branch created by new Branch().");
|
|
1100
|
+
return state.destinations.map((dest) => ({
|
|
1101
|
+
storage: dest.storage,
|
|
1102
|
+
middlewares: [...dest.middlewares]
|
|
1103
|
+
}));
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* 分岐先を親の接頭辞付きで追加します。
|
|
1107
|
+
*
|
|
1108
|
+
* @param destinations 追加先の分岐先列です。
|
|
1109
|
+
* @param prefix 親のミドルウェア列です。
|
|
1110
|
+
* @param branch 追加する分岐です。
|
|
1111
|
+
*/
|
|
1112
|
+
function appendForkDestinations(destinations, prefix, branch) {
|
|
1113
|
+
const prefixSnapshot = [...prefix];
|
|
1114
|
+
for (const dest of getBranchDestinationsForFork(branch)) destinations.push({
|
|
1115
|
+
storage: dest.storage,
|
|
1116
|
+
middlewares: [...prefixSnapshot, ...dest.middlewares]
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
//#endregion
|
|
1120
|
+
//#region ../src/unikvs-branch.ts
|
|
1121
|
+
var _UniKvsBranch_brand = /* @__PURE__ */ new WeakSet();
|
|
1122
|
+
/**
|
|
1123
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#builder)
|
|
1124
|
+
*/
|
|
1125
|
+
var UniKvsBranch = class {
|
|
1126
|
+
constructor() {
|
|
1127
|
+
_classPrivateMethodInitSpec(this, _UniKvsBranch_brand);
|
|
1128
|
+
branchStates.set(this, {
|
|
1129
|
+
middlewares: [],
|
|
1130
|
+
destinations: []
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
fork(branch) {
|
|
1134
|
+
const state = _assertClassBrand(_UniKvsBranch_brand, this, _branchState).call(this);
|
|
1135
|
+
appendForkDestinations(state.destinations, state.middlewares, branch);
|
|
1136
|
+
return this;
|
|
1137
|
+
}
|
|
1138
|
+
use(middleware) {
|
|
1139
|
+
_assertClassBrand(_UniKvsBranch_brand, this, _branchState).call(this).middlewares.push(UniKvsMiddleware.from(middleware));
|
|
1140
|
+
return this;
|
|
1141
|
+
}
|
|
1142
|
+
persist(storage) {
|
|
1143
|
+
const state = _assertClassBrand(_UniKvsBranch_brand, this, _branchState).call(this);
|
|
1144
|
+
state.destinations.push({
|
|
1145
|
+
storage: UniKvsStorage.from(storage),
|
|
1146
|
+
middlewares: [...state.middlewares]
|
|
1147
|
+
});
|
|
1148
|
+
return this;
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
/**
|
|
1152
|
+
* この分岐の構築状態を取得します。
|
|
1153
|
+
*
|
|
1154
|
+
* @returns 構築状態を返します。
|
|
1155
|
+
*/
|
|
1156
|
+
function _branchState() {
|
|
1157
|
+
const state = branchStates.get(this);
|
|
1158
|
+
if (state === void 0) throw new Error("分岐の構築状態が見つかりません。");
|
|
1159
|
+
return state;
|
|
1160
|
+
}
|
|
1161
|
+
//#endregion
|
|
1162
|
+
//#region ../src/_contexts.ts
|
|
1163
|
+
/**
|
|
1164
|
+
* 実行時変数の初期値をエントリー列に正規化します。
|
|
1165
|
+
*
|
|
1166
|
+
* レコードは `Object.entries` で展開します。
|
|
1167
|
+
* 反復子はそのまま返します。
|
|
1168
|
+
*
|
|
1169
|
+
* @param vars 初期値です。
|
|
1170
|
+
*
|
|
1171
|
+
* @returns エントリー列を返します。
|
|
1172
|
+
*/
|
|
1173
|
+
function normalizeVariablesInit(vars) {
|
|
1174
|
+
if (!vars) return [];
|
|
1175
|
+
if (Symbol.iterator in vars) return vars;
|
|
1176
|
+
return Object.entries(vars);
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* 新しい空の変数ストアを作成します。
|
|
1180
|
+
*
|
|
1181
|
+
* @param vars 初期値です。
|
|
1182
|
+
*
|
|
1183
|
+
* @returns 空ストアを返します。
|
|
1184
|
+
*/
|
|
1185
|
+
function createVariablesStore(vars = []) {
|
|
1186
|
+
return {
|
|
1187
|
+
data: new Map(vars),
|
|
1188
|
+
readonly: /* @__PURE__ */ new Set()
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
var _data = /* @__PURE__ */ new WeakMap();
|
|
1192
|
+
var _readonly = /* @__PURE__ */ new WeakMap();
|
|
1193
|
+
/**
|
|
1194
|
+
* 実行時変数を保持する基底コンテキストです。
|
|
1195
|
+
*/
|
|
1196
|
+
var PipelineContext = class {
|
|
1197
|
+
/**
|
|
1198
|
+
* コンテキストを作成します。
|
|
1199
|
+
*
|
|
1200
|
+
* @param init 初期値です。
|
|
1201
|
+
*/
|
|
1202
|
+
constructor(init) {
|
|
1203
|
+
_classPrivateFieldInitSpec(this, _data, void 0);
|
|
1204
|
+
_classPrivateFieldInitSpec(this, _readonly, void 0);
|
|
1205
|
+
const { store } = init;
|
|
1206
|
+
if (store) {
|
|
1207
|
+
_classPrivateFieldSet2(_data, this, store.data);
|
|
1208
|
+
_classPrivateFieldSet2(_readonly, this, store.readonly);
|
|
1209
|
+
} else {
|
|
1210
|
+
_classPrivateFieldSet2(_data, this, /* @__PURE__ */ new Map());
|
|
1211
|
+
_classPrivateFieldSet2(_readonly, this, /* @__PURE__ */ new Set());
|
|
1212
|
+
}
|
|
1213
|
+
const vars = normalizeVariablesInit(init.vars);
|
|
1214
|
+
for (const [name, value] of vars) _classPrivateFieldGet2(_data, this).set(name, value);
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* 変数の値を読み取ります。
|
|
1218
|
+
*
|
|
1219
|
+
* @param name 変数名です。
|
|
1220
|
+
*
|
|
1221
|
+
* @returns 変数の値を返します。
|
|
1222
|
+
*/
|
|
1223
|
+
get(name) {
|
|
1224
|
+
return _classPrivateFieldGet2(_data, this).get(name);
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* 変数の値を書き込みます。
|
|
1228
|
+
*
|
|
1229
|
+
* @param name 変数名です。
|
|
1230
|
+
* @param value 設定する値です。
|
|
1231
|
+
*
|
|
1232
|
+
* @returns 自身を返します。
|
|
1233
|
+
*/
|
|
1234
|
+
set(name, value) {
|
|
1235
|
+
if (_classPrivateFieldGet2(_readonly, this).has(name)) throw new ReadonlyVariableError({ name });
|
|
1236
|
+
_classPrivateFieldGet2(_data, this).set(name, value);
|
|
1237
|
+
return this;
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* 変数の値を設定し、読み取り専用にします。
|
|
1241
|
+
*
|
|
1242
|
+
* @param name 変数名です。
|
|
1243
|
+
* @param value 設定する値です。
|
|
1244
|
+
*
|
|
1245
|
+
* @returns 自身を返します。
|
|
1246
|
+
*/
|
|
1247
|
+
setReadonly(name, value) {
|
|
1248
|
+
if (_classPrivateFieldGet2(_readonly, this).has(name)) throw new ReadonlyVariableError({ name });
|
|
1249
|
+
_classPrivateFieldGet2(_data, this).set(name, value);
|
|
1250
|
+
_classPrivateFieldGet2(_readonly, this).add(name);
|
|
1251
|
+
return this;
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
var MapKeyContext = class extends PipelineContext {
|
|
1255
|
+
/**
|
|
1256
|
+
* コンテキストを作成します。
|
|
1257
|
+
*
|
|
1258
|
+
* @param init 初期値です。
|
|
1259
|
+
*/
|
|
1260
|
+
constructor(init) {
|
|
1261
|
+
const { key, vars, store } = init;
|
|
1262
|
+
super({
|
|
1263
|
+
vars,
|
|
1264
|
+
store
|
|
1265
|
+
});
|
|
1266
|
+
this.key = key;
|
|
1267
|
+
}
|
|
1268
|
+
};
|
|
1269
|
+
var ActionContext = class extends PipelineContext {
|
|
1270
|
+
/**
|
|
1271
|
+
* コンテキストを作成します。
|
|
1272
|
+
*
|
|
1273
|
+
* @param init 初期値です。
|
|
1274
|
+
*/
|
|
1275
|
+
constructor(init) {
|
|
1276
|
+
const { vars, store, action, signal } = init;
|
|
1277
|
+
super({
|
|
1278
|
+
vars,
|
|
1279
|
+
store
|
|
1280
|
+
});
|
|
1281
|
+
this.action = action;
|
|
1282
|
+
this.signal = signal;
|
|
1283
|
+
}
|
|
1284
|
+
};
|
|
1285
|
+
var LifecycleContext = class extends ActionContext {};
|
|
1286
|
+
/**
|
|
1287
|
+
* 開始処理のコンテキストです。
|
|
1288
|
+
*/
|
|
1289
|
+
var OpenContext = class extends LifecycleContext {
|
|
1290
|
+
/**
|
|
1291
|
+
* コンテキストを作成します。
|
|
1292
|
+
*
|
|
1293
|
+
* @param init 初期値です。
|
|
1294
|
+
*/
|
|
1295
|
+
constructor(init) {
|
|
1296
|
+
super({
|
|
1297
|
+
...init,
|
|
1298
|
+
action: "open"
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
/**
|
|
1303
|
+
* 終了処理のコンテキストです。
|
|
1304
|
+
*/
|
|
1305
|
+
var CloseContext = class extends LifecycleContext {
|
|
1306
|
+
/**
|
|
1307
|
+
* コンテキストを作成します。
|
|
1308
|
+
*
|
|
1309
|
+
* @param init 初期値です。
|
|
1310
|
+
*/
|
|
1311
|
+
constructor(init) {
|
|
1312
|
+
super({
|
|
1313
|
+
...init,
|
|
1314
|
+
action: "close"
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
var KeyedActionContext = class extends ActionContext {
|
|
1319
|
+
/**
|
|
1320
|
+
* コンテキストを作成します。
|
|
1321
|
+
*
|
|
1322
|
+
* @param init 初期値です。
|
|
1323
|
+
*/
|
|
1324
|
+
constructor(init) {
|
|
1325
|
+
const { key, ...superInit } = init;
|
|
1326
|
+
super(superInit);
|
|
1327
|
+
this.key = key;
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
/**
|
|
1331
|
+
* 書き込み処理のコンテキストです。
|
|
1332
|
+
*/
|
|
1333
|
+
var SetContext = class extends KeyedActionContext {
|
|
1334
|
+
/**
|
|
1335
|
+
* コンテキストを作成します。
|
|
1336
|
+
*
|
|
1337
|
+
* @param init 初期値です。
|
|
1338
|
+
*/
|
|
1339
|
+
constructor(init) {
|
|
1340
|
+
super({
|
|
1341
|
+
...init,
|
|
1342
|
+
action: "set"
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
/**
|
|
1347
|
+
* 読み取り処理のコンテキストです。
|
|
1348
|
+
*/
|
|
1349
|
+
var GetContext = class extends KeyedActionContext {
|
|
1350
|
+
/**
|
|
1351
|
+
* コンテキストを作成します。
|
|
1352
|
+
*
|
|
1353
|
+
* @param init 初期値です。
|
|
1354
|
+
*/
|
|
1355
|
+
constructor(init) {
|
|
1356
|
+
const { repair = {
|
|
1357
|
+
enabled: false,
|
|
1358
|
+
targets: []
|
|
1359
|
+
}, ...superInit } = init;
|
|
1360
|
+
super({
|
|
1361
|
+
...superInit,
|
|
1362
|
+
action: "get"
|
|
1363
|
+
});
|
|
1364
|
+
this.repair = repair;
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
/**
|
|
1368
|
+
* ストリーム処理のコンテキストです。
|
|
1369
|
+
*/
|
|
1370
|
+
var StreamContext = class extends KeyedActionContext {
|
|
1371
|
+
/**
|
|
1372
|
+
* コンテキストを作成します。
|
|
1373
|
+
*
|
|
1374
|
+
* @param init 初期値です。
|
|
1375
|
+
*/
|
|
1376
|
+
constructor(init) {
|
|
1377
|
+
const { repair = {
|
|
1378
|
+
enabled: false,
|
|
1379
|
+
targets: []
|
|
1380
|
+
}, ...superInit } = init;
|
|
1381
|
+
super({
|
|
1382
|
+
...superInit,
|
|
1383
|
+
action: "stream"
|
|
1384
|
+
});
|
|
1385
|
+
this.repair = repair;
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
/**
|
|
1389
|
+
* 存在確認のコンテキストです。
|
|
1390
|
+
*/
|
|
1391
|
+
var HasContext = class extends KeyedActionContext {
|
|
1392
|
+
/**
|
|
1393
|
+
* コンテキストを作成します。
|
|
1394
|
+
*
|
|
1395
|
+
* @param init 初期値です。
|
|
1396
|
+
*/
|
|
1397
|
+
constructor(init) {
|
|
1398
|
+
super({
|
|
1399
|
+
...init,
|
|
1400
|
+
action: "has"
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
/**
|
|
1405
|
+
* 削除処理のコンテキストです。
|
|
1406
|
+
*/
|
|
1407
|
+
var DeleteContext = class extends KeyedActionContext {
|
|
1408
|
+
/**
|
|
1409
|
+
* コンテキストを作成します。
|
|
1410
|
+
*
|
|
1411
|
+
* @param init 初期値です。
|
|
1412
|
+
*/
|
|
1413
|
+
constructor(init) {
|
|
1414
|
+
super({
|
|
1415
|
+
...init,
|
|
1416
|
+
action: "delete"
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
/**
|
|
1421
|
+
* 全削除のコンテキストです。
|
|
1422
|
+
*/
|
|
1423
|
+
var ClearContext = class extends ActionContext {
|
|
1424
|
+
/**
|
|
1425
|
+
* コンテキストを作成します。
|
|
1426
|
+
*
|
|
1427
|
+
* @param init 初期値です。
|
|
1428
|
+
*/
|
|
1429
|
+
constructor(init) {
|
|
1430
|
+
super({
|
|
1431
|
+
...init,
|
|
1432
|
+
action: "clear"
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
/**
|
|
1437
|
+
* 値変換の基底コンテキストです。
|
|
1438
|
+
*/
|
|
1439
|
+
var TransformContext = class extends KeyedActionContext {
|
|
1440
|
+
/**
|
|
1441
|
+
* コンテキストを作成します。
|
|
1442
|
+
*
|
|
1443
|
+
* @param init 初期値です。
|
|
1444
|
+
*/
|
|
1445
|
+
constructor(init) {
|
|
1446
|
+
const { source, ...superInit } = init;
|
|
1447
|
+
super(superInit);
|
|
1448
|
+
this.source = source;
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
/**
|
|
1452
|
+
* データ変換の基底コンテキストです。
|
|
1453
|
+
*/
|
|
1454
|
+
var TransformDataContext = class extends TransformContext {};
|
|
1455
|
+
/**
|
|
1456
|
+
* 符号化のコンテキストです。
|
|
1457
|
+
*/
|
|
1458
|
+
var EncodeContext = class extends TransformDataContext {
|
|
1459
|
+
/**
|
|
1460
|
+
* コンテキストを作成します。
|
|
1461
|
+
*
|
|
1462
|
+
* @param init 初期値です。
|
|
1463
|
+
*/
|
|
1464
|
+
constructor(init) {
|
|
1465
|
+
super({
|
|
1466
|
+
...init,
|
|
1467
|
+
action: "set"
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
/**
|
|
1472
|
+
* 復号のコンテキストです。
|
|
1473
|
+
*/
|
|
1474
|
+
var DecodeContext = class extends TransformDataContext {
|
|
1475
|
+
/**
|
|
1476
|
+
* コンテキストを作成します。
|
|
1477
|
+
*
|
|
1478
|
+
* @param init 初期値です。
|
|
1479
|
+
*/
|
|
1480
|
+
constructor(init) {
|
|
1481
|
+
super({
|
|
1482
|
+
...init,
|
|
1483
|
+
action: "get"
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
};
|
|
1487
|
+
/**
|
|
1488
|
+
* ストリーム変換の基底コンテキストです。
|
|
1489
|
+
*/
|
|
1490
|
+
var TransformStreamContext = class extends TransformContext {};
|
|
1491
|
+
/**
|
|
1492
|
+
* ストリーム符号化のコンテキストです。
|
|
1493
|
+
*/
|
|
1494
|
+
var EncodeStreamContext = class extends TransformStreamContext {
|
|
1495
|
+
/**
|
|
1496
|
+
* コンテキストを作成します。
|
|
1497
|
+
*
|
|
1498
|
+
* @param init 初期値です。
|
|
1499
|
+
*/
|
|
1500
|
+
constructor(init) {
|
|
1501
|
+
super({
|
|
1502
|
+
...init,
|
|
1503
|
+
action: "set"
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
/**
|
|
1508
|
+
* ストリーム復号のコンテキストです。
|
|
1509
|
+
*/
|
|
1510
|
+
var DecodeStreamContext = class extends TransformStreamContext {
|
|
1511
|
+
/**
|
|
1512
|
+
* コンテキストを作成します。
|
|
1513
|
+
*
|
|
1514
|
+
* @param init 初期値です。
|
|
1515
|
+
*/
|
|
1516
|
+
constructor(init) {
|
|
1517
|
+
super({
|
|
1518
|
+
...init,
|
|
1519
|
+
action: "stream"
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1523
|
+
//#endregion
|
|
1524
|
+
//#region ../src/_logger.ts
|
|
1525
|
+
const logger = getLogger("unikvs");
|
|
1526
|
+
const repairLogger = getLogger(["@unikvs/*", "@unikvs/allow-repair"]);
|
|
1527
|
+
//#endregion
|
|
1528
|
+
//#region ../src/_pipeline-graph.helpers.ts
|
|
1529
|
+
/**
|
|
1530
|
+
* 対象判定に通る葉だけを登録順に絞ります。
|
|
1531
|
+
*
|
|
1532
|
+
* 全葉が対象なら複製せず `node.allLeaves` を返します。
|
|
1533
|
+
*
|
|
1534
|
+
* @param node 対象の節です。
|
|
1535
|
+
* @param isActive 書き込み対象とする葉を判定します。
|
|
1536
|
+
*
|
|
1537
|
+
* @returns 対象の葉を登録順に返します。
|
|
1538
|
+
*/
|
|
1539
|
+
function activeLeavesOf(node, isActive) {
|
|
1540
|
+
const active = node.allLeaves.filter(isActive);
|
|
1541
|
+
if (active.length === node.allLeaves.length) return node.allLeaves;
|
|
1542
|
+
return active;
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* 葉と節を登録順に並べた静的な項目列を作成します。
|
|
1546
|
+
*
|
|
1547
|
+
* 各操作の走査はこの並びをそのまま読みます。
|
|
1548
|
+
* 並べ替え用の順序は項目に保持せず、作成時のローカル変数で解決します。
|
|
1549
|
+
*
|
|
1550
|
+
* @param leaves この節で終端する葉です。
|
|
1551
|
+
* @param children 子の節です。
|
|
1552
|
+
*
|
|
1553
|
+
* @returns 登録順に並べた項目列を返します。
|
|
1554
|
+
*/
|
|
1555
|
+
function createEntries(leaves, children) {
|
|
1556
|
+
return [...leaves.map((leaf) => ({
|
|
1557
|
+
entry: {
|
|
1558
|
+
kind: "leaf",
|
|
1559
|
+
leaf
|
|
1560
|
+
},
|
|
1561
|
+
order: leaf.index
|
|
1562
|
+
})), ...children.map((child) => {
|
|
1563
|
+
const [firstLeaf] = child.allLeaves;
|
|
1564
|
+
if (firstLeaf === void 0) throw new Error("子節に葉が存在しません。");
|
|
1565
|
+
return {
|
|
1566
|
+
entry: {
|
|
1567
|
+
kind: "node",
|
|
1568
|
+
node: child
|
|
1569
|
+
},
|
|
1570
|
+
order: firstLeaf.index
|
|
1571
|
+
};
|
|
1572
|
+
})].toSorted((a, b) => a.order - b.order).map((item) => item.entry);
|
|
1573
|
+
}
|
|
1574
|
+
/**
|
|
1575
|
+
* 変換後のデータが設定されていることを検証し、変換後のデータを返します。
|
|
1576
|
+
*
|
|
1577
|
+
* ミドルウェアが `destination` を設定しなかったときに投げます。
|
|
1578
|
+
*
|
|
1579
|
+
* @param middleware 対象のミドルウェアです。
|
|
1580
|
+
* @param ctx 検証するコンテキストです。
|
|
1581
|
+
* @param operation エラーに付与する操作名です。
|
|
1582
|
+
*
|
|
1583
|
+
* @returns 変換後のデータを返します。
|
|
1584
|
+
*/
|
|
1585
|
+
function requireDestination(middleware, ctx, operation) {
|
|
1586
|
+
if ("destination" in ctx) return ctx.destination;
|
|
1587
|
+
throw new MiddlewareDestinationMissingError({
|
|
1588
|
+
name: middleware.name,
|
|
1589
|
+
operation
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* 変換後のストリームが設定されていることを検証し、型を検証したストリームを返します。
|
|
1594
|
+
*
|
|
1595
|
+
* ミドルウェアが `destination` を設定しなかったときに投げます。
|
|
1596
|
+
* ストリームの場合は存在確認に加えて `ReadableStream` の型も検証します。
|
|
1597
|
+
*
|
|
1598
|
+
* @param middleware 対象のミドルウェアです。
|
|
1599
|
+
* @param ctx 検証するコンテキストです。
|
|
1600
|
+
* @param operation エラーに付与する操作名です。
|
|
1601
|
+
*
|
|
1602
|
+
* @returns 変換後のストリームを返します。
|
|
1603
|
+
*/
|
|
1604
|
+
function requireStreamDestination(middleware, ctx, operation) {
|
|
1605
|
+
const destination = requireDestination(middleware, ctx, operation);
|
|
1606
|
+
return parseOutput(ReadableStreamSchema, destination);
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* コンテキストの `destination` を凍結します。
|
|
1610
|
+
*
|
|
1611
|
+
* パイプラインの `next` から同期的に呼び出します。
|
|
1612
|
+
* 凍結後の読み取りはできますが、書き込むと `MiddlewareDestinationFrozenError` を投げます。
|
|
1613
|
+
*
|
|
1614
|
+
* @param ctx 凍結するコンテキストです。
|
|
1615
|
+
*/
|
|
1616
|
+
function freezeDestination(ctx) {
|
|
1617
|
+
const { destination } = ctx;
|
|
1618
|
+
Object.defineProperty(ctx, "destination", {
|
|
1619
|
+
get() {
|
|
1620
|
+
return destination;
|
|
1621
|
+
},
|
|
1622
|
+
set() {
|
|
1623
|
+
throw new MiddlewareDestinationFrozenError({
|
|
1624
|
+
key: ctx.key,
|
|
1625
|
+
action: ctx.action
|
|
1626
|
+
});
|
|
1627
|
+
},
|
|
1628
|
+
enumerable: true,
|
|
1629
|
+
configurable: true
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* 単一ミドルウェアの `mapKey` を実行します。
|
|
1634
|
+
*
|
|
1635
|
+
* 共有ストアを参照するため、カスタム変数の下流変更が写像にも見えます。
|
|
1636
|
+
*
|
|
1637
|
+
* @param middleware 対象のミドルウェアです。
|
|
1638
|
+
* @param key 写像前のキーです。
|
|
1639
|
+
* @param scope 操作共通の実行時情報です。
|
|
1640
|
+
*
|
|
1641
|
+
* @returns 写像後のキーを返します。
|
|
1642
|
+
*/
|
|
1643
|
+
function applyMapKey(middleware, key, scope) {
|
|
1644
|
+
const c = new MapKeyContext({
|
|
1645
|
+
key,
|
|
1646
|
+
store: scope.store
|
|
1647
|
+
});
|
|
1648
|
+
return middleware.mapKey(c);
|
|
1649
|
+
}
|
|
1650
|
+
//#endregion
|
|
1651
|
+
//#region ../src/_pipeline-leaf-resolver.ts
|
|
1652
|
+
var _rootKey = /* @__PURE__ */ new WeakMap();
|
|
1653
|
+
var _scope = /* @__PURE__ */ new WeakMap();
|
|
1654
|
+
var _nodeCache = /* @__PURE__ */ new WeakMap();
|
|
1655
|
+
/**
|
|
1656
|
+
* 単一操作のスコープで葉の写像キーを解決します。
|
|
1657
|
+
*
|
|
1658
|
+
* 新 `mapKey` は同期的であり、中断シグナルも受け付けないため、共有節の写像は操作内で 1 回だけ実行され、結果を使い回します。
|
|
1659
|
+
* 並行解決でも `Map` キャッシュにより重複しません (`resolve` 自体が同期的であるため、競合しません)。
|
|
1660
|
+
*/
|
|
1661
|
+
var LeafResolver = class {
|
|
1662
|
+
/**
|
|
1663
|
+
* 通常は `PipelineGraph.createResolver` から生成します。
|
|
1664
|
+
*
|
|
1665
|
+
* @param scope 操作共通の実行時情報です。
|
|
1666
|
+
*/
|
|
1667
|
+
constructor(scope) {
|
|
1668
|
+
_classPrivateFieldInitSpec(this, _rootKey, void 0);
|
|
1669
|
+
_classPrivateFieldInitSpec(this, _scope, void 0);
|
|
1670
|
+
_classPrivateFieldInitSpec(this, _nodeCache, void 0);
|
|
1671
|
+
_classPrivateFieldSet2(_rootKey, this, scope.key);
|
|
1672
|
+
_classPrivateFieldSet2(_scope, this, scope);
|
|
1673
|
+
_classPrivateFieldSet2(_nodeCache, this, /* @__PURE__ */ new Map());
|
|
1674
|
+
}
|
|
1675
|
+
/**
|
|
1676
|
+
* 葉の写像キーを解決します。
|
|
1677
|
+
*
|
|
1678
|
+
* @param leaf 解決する葉です。
|
|
1679
|
+
*
|
|
1680
|
+
* @returns 解決済みの葉を返します。
|
|
1681
|
+
*/
|
|
1682
|
+
resolve(leaf) {
|
|
1683
|
+
let key = _classPrivateFieldGet2(_rootKey, this);
|
|
1684
|
+
for (const node of leaf.path) {
|
|
1685
|
+
const cached = _classPrivateFieldGet2(_nodeCache, this).get(node);
|
|
1686
|
+
if (cached !== void 0) {
|
|
1687
|
+
key = cached;
|
|
1688
|
+
continue;
|
|
1689
|
+
}
|
|
1690
|
+
const mapped = applyMapKey(node.middleware, key, _classPrivateFieldGet2(_scope, this));
|
|
1691
|
+
_classPrivateFieldGet2(_nodeCache, this).set(node, mapped);
|
|
1692
|
+
key = mapped;
|
|
1693
|
+
}
|
|
1694
|
+
return {
|
|
1695
|
+
key,
|
|
1696
|
+
leaf
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
};
|
|
1700
|
+
//#endregion
|
|
1701
|
+
//#region ../src/_pipeline-graph.ts
|
|
1702
|
+
let _Symbol$iterator;
|
|
1703
|
+
/**
|
|
1704
|
+
* 節を前順で列挙するための再帰ヘルパーです。
|
|
1705
|
+
*
|
|
1706
|
+
* @param node 列挙を開始する節です。
|
|
1707
|
+
*
|
|
1708
|
+
* @yields 前順の節です。
|
|
1709
|
+
*/
|
|
1710
|
+
function* visit(node) {
|
|
1711
|
+
yield node;
|
|
1712
|
+
for (const entry of node.entries) if (entry.kind === "node") yield* visit(entry.node);
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* 直通区間をまとめて葉名簿と全葉を確定します。
|
|
1716
|
+
*
|
|
1717
|
+
* @param node 確定する節です。
|
|
1718
|
+
*/
|
|
1719
|
+
function finalize(node) {
|
|
1720
|
+
if (node.leaves.length === 0 && node.children.length === 1) {
|
|
1721
|
+
const [child] = node.children;
|
|
1722
|
+
if (child === void 0) throw new Error("直通区間の子節が存在しません。");
|
|
1723
|
+
finalize(child);
|
|
1724
|
+
node.entries = [{
|
|
1725
|
+
kind: "node",
|
|
1726
|
+
node: child
|
|
1727
|
+
}];
|
|
1728
|
+
node.allLeaves = child.allLeaves;
|
|
1729
|
+
node.leafNames = child.leafNames;
|
|
1730
|
+
} else {
|
|
1731
|
+
const leaves = [...node.leaves];
|
|
1732
|
+
for (const child of node.children) {
|
|
1733
|
+
finalize(child);
|
|
1734
|
+
leaves.push(...child.allLeaves);
|
|
1735
|
+
}
|
|
1736
|
+
leaves.sort((a, b) => a.index - b.index);
|
|
1737
|
+
const [singleLeaf] = leaves;
|
|
1738
|
+
node.entries = createEntries(node.leaves, node.children);
|
|
1739
|
+
node.allLeaves = leaves;
|
|
1740
|
+
if (leaves.length === 1 && singleLeaf !== void 0) node.leafNames = singleLeaf.nameNames;
|
|
1741
|
+
else node.leafNames = Object.freeze(leaves.map((leaf) => leaf.name));
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
var _leaves = /* @__PURE__ */ new WeakMap();
|
|
1745
|
+
var _entries$1 = /* @__PURE__ */ new WeakMap();
|
|
1746
|
+
var _middlewares$1 = /* @__PURE__ */ new WeakMap();
|
|
1747
|
+
var _isSingleLeaf = /* @__PURE__ */ new WeakMap();
|
|
1748
|
+
_Symbol$iterator = Symbol.iterator;
|
|
1749
|
+
/**
|
|
1750
|
+
* コンパイル済みのパイプライン・グラフです。
|
|
1751
|
+
*
|
|
1752
|
+
* 宛先の変換チェーンをミドルウェアのインスタンス同一性で共有する根付き木として保持し、操作ごとの走査・エンコード・書き戻し・ストリーム構築を提供します。
|
|
1753
|
+
*
|
|
1754
|
+
* 不変条件 :
|
|
1755
|
+
* - 葉(`leaves`)と各節の項目(`entries`)は宛先の登録順です。
|
|
1756
|
+
* - 名簿(`leafNames` / `nameNames`)は凍結された配列で、直通区間では参照を共有します。
|
|
1757
|
+
* - 共有節は 1 操作内で 1 回だけ `encode`/`encodeStream`/`mapKey` を実行します。分岐点ではプレーン値のエンコード結果を共有し、ストリームは tee で分岐します。
|
|
1758
|
+
* - 書き戻しの拒否は、走査中と書き込み中の 2 経路で分類します。いずれも即時に確定します。
|
|
1759
|
+
*/
|
|
1760
|
+
var PipelineGraph = class PipelineGraph {
|
|
1761
|
+
constructor(leaves, entries, middlewares) {
|
|
1762
|
+
_classPrivateFieldInitSpec(this, _leaves, void 0);
|
|
1763
|
+
_classPrivateFieldInitSpec(this, _entries$1, void 0);
|
|
1764
|
+
_classPrivateFieldInitSpec(this, _middlewares$1, void 0);
|
|
1765
|
+
_classPrivateFieldInitSpec(this, _isSingleLeaf, void 0);
|
|
1766
|
+
_classPrivateFieldSet2(_leaves, this, leaves);
|
|
1767
|
+
_classPrivateFieldSet2(_entries$1, this, entries);
|
|
1768
|
+
_classPrivateFieldSet2(_middlewares$1, this, middlewares);
|
|
1769
|
+
_classPrivateFieldSet2(_isSingleLeaf, this, leaves.length === 1);
|
|
1770
|
+
}
|
|
1771
|
+
/**
|
|
1772
|
+
* 宛先定義の列を trie にコンパイルします。
|
|
1773
|
+
*
|
|
1774
|
+
* ミドルウェアはインスタンス同一性で共有します。同一インスタンスが複数の節に現れても、`open`/`close`/`use` の対象には初出の 1 件だけを保持します。
|
|
1775
|
+
*
|
|
1776
|
+
* @param destinations コンパイルする宛先定義です。
|
|
1777
|
+
*
|
|
1778
|
+
* @returns コンパイル済みのパイプライン・グラフを返します。
|
|
1779
|
+
*/
|
|
1780
|
+
static compile(destinations) {
|
|
1781
|
+
const rootLeaves = [];
|
|
1782
|
+
const rootChildren = [];
|
|
1783
|
+
const allLeaves = [];
|
|
1784
|
+
const middlewares = [];
|
|
1785
|
+
const seenMiddlewares = /* @__PURE__ */ new Set();
|
|
1786
|
+
for (const dest of destinations) {
|
|
1787
|
+
const index = allLeaves.length;
|
|
1788
|
+
const name = dest.storage.name;
|
|
1789
|
+
const path = [];
|
|
1790
|
+
let parent = null;
|
|
1791
|
+
let canRepair = false;
|
|
1792
|
+
let siblings = rootChildren;
|
|
1793
|
+
for (const middleware of dest.middlewares) {
|
|
1794
|
+
let node = siblings.find((candidate) => candidate.middleware === middleware);
|
|
1795
|
+
if (node === void 0) {
|
|
1796
|
+
node = {
|
|
1797
|
+
leaves: [],
|
|
1798
|
+
entries: [],
|
|
1799
|
+
children: [],
|
|
1800
|
+
allLeaves: [],
|
|
1801
|
+
leafNames: [],
|
|
1802
|
+
middleware
|
|
1803
|
+
};
|
|
1804
|
+
siblings.push(node);
|
|
1805
|
+
if (!seenMiddlewares.has(middleware)) {
|
|
1806
|
+
seenMiddlewares.add(middleware);
|
|
1807
|
+
middlewares.push(middleware);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
if (middleware.name === "AllowRepair") canRepair = true;
|
|
1811
|
+
path.push(node);
|
|
1812
|
+
parent = node;
|
|
1813
|
+
siblings = node.children;
|
|
1814
|
+
}
|
|
1815
|
+
const leaf = {
|
|
1816
|
+
name,
|
|
1817
|
+
path,
|
|
1818
|
+
index,
|
|
1819
|
+
storage: dest.storage,
|
|
1820
|
+
canRepair,
|
|
1821
|
+
nameNames: Object.freeze([name])
|
|
1822
|
+
};
|
|
1823
|
+
if (parent === null) rootLeaves.push(leaf);
|
|
1824
|
+
else parent.leaves.push(leaf);
|
|
1825
|
+
allLeaves.push(leaf);
|
|
1826
|
+
}
|
|
1827
|
+
for (const child of rootChildren) finalize(child);
|
|
1828
|
+
let rootEntries;
|
|
1829
|
+
let rootAllLeaves;
|
|
1830
|
+
if (rootLeaves.length === 0 && rootChildren.length === 1) {
|
|
1831
|
+
const [child] = rootChildren;
|
|
1832
|
+
if (child === void 0) throw new Error("根直下の子節が存在しません。");
|
|
1833
|
+
rootEntries = [{
|
|
1834
|
+
kind: "node",
|
|
1835
|
+
node: child
|
|
1836
|
+
}];
|
|
1837
|
+
rootAllLeaves = child.allLeaves;
|
|
1838
|
+
} else {
|
|
1839
|
+
const collected = [...rootLeaves];
|
|
1840
|
+
for (const child of rootChildren) collected.push(...child.allLeaves);
|
|
1841
|
+
rootEntries = createEntries(rootLeaves, rootChildren);
|
|
1842
|
+
rootAllLeaves = collected.toSorted((a, b) => a.index - b.index);
|
|
1843
|
+
}
|
|
1844
|
+
return new PipelineGraph(rootAllLeaves, rootEntries, middlewares);
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* 全葉です。登録順に保持します。
|
|
1848
|
+
*/
|
|
1849
|
+
get leaves() {
|
|
1850
|
+
return _classPrivateFieldGet2(_leaves, this);
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* `open`/`close`/`use` の対象となるミドルウェアです。
|
|
1854
|
+
* 初出順・重複なしです。
|
|
1855
|
+
*/
|
|
1856
|
+
get middlewares() {
|
|
1857
|
+
return _classPrivateFieldGet2(_middlewares$1, this);
|
|
1858
|
+
}
|
|
1859
|
+
/**
|
|
1860
|
+
* 全葉数が 1 件かどうかです。
|
|
1861
|
+
*/
|
|
1862
|
+
get isSingleLeaf() {
|
|
1863
|
+
return _classPrivateFieldGet2(_isSingleLeaf, this);
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* 葉数です。
|
|
1867
|
+
*/
|
|
1868
|
+
get size() {
|
|
1869
|
+
return _classPrivateFieldGet2(_leaves, this).length;
|
|
1870
|
+
}
|
|
1871
|
+
/**
|
|
1872
|
+
* 葉を登録順に列挙します。
|
|
1873
|
+
*/
|
|
1874
|
+
[_Symbol$iterator]() {
|
|
1875
|
+
return _classPrivateFieldGet2(_leaves, this)[Symbol.iterator]();
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* 節を根から前順 (親が子より前、兄弟は登録順) に列挙します。
|
|
1879
|
+
*
|
|
1880
|
+
* 構造の確認・保守用です。操作の走査には使用しません。
|
|
1881
|
+
*
|
|
1882
|
+
* @yields 前順の節です。
|
|
1883
|
+
*/
|
|
1884
|
+
*nodes() {
|
|
1885
|
+
for (const entry of _classPrivateFieldGet2(_entries$1, this)) if (entry.kind === "node") yield* visit(entry.node);
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* 単一操作のスコープでキー写像をメモ化するリゾルバーを生成します。
|
|
1889
|
+
*
|
|
1890
|
+
* 新 `mapKey` は同期的であるため、リゾルバーも同期的です。共有節の写像は操作内で 1 回だけ実行されます。
|
|
1891
|
+
*
|
|
1892
|
+
* @param key 根のキー (論理キー) です。
|
|
1893
|
+
* @param vars 根の実行時変数です。
|
|
1894
|
+
*
|
|
1895
|
+
* @returns 葉リゾルバーを返します。
|
|
1896
|
+
*/
|
|
1897
|
+
createResolver(scope) {
|
|
1898
|
+
return new LeafResolver(scope);
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* 葉の経路のミドルウェアを逆順に適用してデータをデコードします。
|
|
1902
|
+
*
|
|
1903
|
+
* 各段の前後で中断を確認します。
|
|
1904
|
+
*
|
|
1905
|
+
* @param leaf デコード元の葉です。
|
|
1906
|
+
* @param scope 操作共通の実行時情報です。`key` は論理キーです。
|
|
1907
|
+
* @param data デコードするデータです。
|
|
1908
|
+
*
|
|
1909
|
+
* @returns デコード済みのデータを返します。
|
|
1910
|
+
*/
|
|
1911
|
+
async decode(leaf, scope, data) {
|
|
1912
|
+
const reversed = leaf.path.toReversed();
|
|
1913
|
+
async function run(index, input) {
|
|
1914
|
+
const maybeNode = reversed[index];
|
|
1915
|
+
if (maybeNode === void 0) return input;
|
|
1916
|
+
const node = maybeNode;
|
|
1917
|
+
const ctx = new DecodeContext({
|
|
1918
|
+
key: scope.key,
|
|
1919
|
+
store: scope.store,
|
|
1920
|
+
signal: scope.signal,
|
|
1921
|
+
source: input
|
|
1922
|
+
});
|
|
1923
|
+
let downstreamResult;
|
|
1924
|
+
let hasDownstream = false;
|
|
1925
|
+
let nextCalled = false;
|
|
1926
|
+
let nextSettled = false;
|
|
1927
|
+
function next() {
|
|
1928
|
+
if (nextCalled) return Promise.reject(new MiddlewareNextCalledMultipleTimesError({
|
|
1929
|
+
name: node.middleware.name,
|
|
1930
|
+
operation: "decode"
|
|
1931
|
+
}));
|
|
1932
|
+
nextCalled = true;
|
|
1933
|
+
let decoded;
|
|
1934
|
+
try {
|
|
1935
|
+
decoded = requireDestination(node.middleware, ctx, "decode");
|
|
1936
|
+
freezeDestination(ctx);
|
|
1937
|
+
} catch (ex) {
|
|
1938
|
+
return Promise.reject(ex);
|
|
1939
|
+
}
|
|
1940
|
+
return Promise.try(async () => {
|
|
1941
|
+
try {
|
|
1942
|
+
downstreamResult = await run(index + 1, decoded);
|
|
1943
|
+
hasDownstream = true;
|
|
1944
|
+
} finally {
|
|
1945
|
+
nextSettled = true;
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
await node.middleware.decode(ctx, next);
|
|
1950
|
+
scope.signal.throwIfAborted();
|
|
1951
|
+
if (!nextCalled) throw new MiddlewareNextNotCalledError({
|
|
1952
|
+
name: node.middleware.name,
|
|
1953
|
+
operation: "decode"
|
|
1954
|
+
});
|
|
1955
|
+
if (!nextSettled) throw new MiddlewareNextNotAwaitedError({
|
|
1956
|
+
name: node.middleware.name,
|
|
1957
|
+
operation: "decode"
|
|
1958
|
+
});
|
|
1959
|
+
const destination = requireDestination(node.middleware, ctx, "decode");
|
|
1960
|
+
if (hasDownstream) return downstreamResult;
|
|
1961
|
+
return destination;
|
|
1962
|
+
}
|
|
1963
|
+
return run(0, data);
|
|
1964
|
+
}
|
|
1965
|
+
/**
|
|
1966
|
+
* 葉の経路のミドルウェアを逆順に `pipeThrough` してストリームをデコードします。
|
|
1967
|
+
*
|
|
1968
|
+
* @param leaf デコード元の葉です。
|
|
1969
|
+
* @param scope 操作共通の実行時情報です。`key` は論理キーです。
|
|
1970
|
+
* @param source 入力ストリームです。
|
|
1971
|
+
*
|
|
1972
|
+
* @returns デコード済みのストリームを返します。
|
|
1973
|
+
*/
|
|
1974
|
+
async decodeStream(leaf, scope, source) {
|
|
1975
|
+
const pipes = [];
|
|
1976
|
+
try {
|
|
1977
|
+
const reversed = leaf.path.toReversed();
|
|
1978
|
+
async function run(index, input) {
|
|
1979
|
+
const maybeNode = reversed[index];
|
|
1980
|
+
if (maybeNode === void 0) return input;
|
|
1981
|
+
const node = maybeNode;
|
|
1982
|
+
const ctx = new DecodeStreamContext({
|
|
1983
|
+
key: scope.key,
|
|
1984
|
+
store: scope.store,
|
|
1985
|
+
signal: scope.signal,
|
|
1986
|
+
source: input
|
|
1987
|
+
});
|
|
1988
|
+
let downstreamResult;
|
|
1989
|
+
let nextCalled = false;
|
|
1990
|
+
let nextSettled = false;
|
|
1991
|
+
function next() {
|
|
1992
|
+
if (nextCalled) return Promise.reject(new MiddlewareNextCalledMultipleTimesError({
|
|
1993
|
+
name: node.middleware.name,
|
|
1994
|
+
operation: "decode"
|
|
1995
|
+
}));
|
|
1996
|
+
nextCalled = true;
|
|
1997
|
+
let decoded;
|
|
1998
|
+
try {
|
|
1999
|
+
decoded = requireStreamDestination(node.middleware, ctx, "decode");
|
|
2000
|
+
freezeDestination(ctx);
|
|
2001
|
+
} catch (ex) {
|
|
2002
|
+
return Promise.reject(ex);
|
|
2003
|
+
}
|
|
2004
|
+
return Promise.try(async () => {
|
|
2005
|
+
try {
|
|
2006
|
+
downstreamResult = await run(index + 1, decoded);
|
|
2007
|
+
} finally {
|
|
2008
|
+
nextSettled = true;
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
try {
|
|
2013
|
+
await node.middleware.decodeStream(ctx, next);
|
|
2014
|
+
scope.signal.throwIfAborted();
|
|
2015
|
+
if (!nextCalled) throw new MiddlewareNextNotCalledError({
|
|
2016
|
+
name: node.middleware.name,
|
|
2017
|
+
operation: "decode"
|
|
2018
|
+
});
|
|
2019
|
+
if (!nextSettled) throw new MiddlewareNextNotAwaitedError({
|
|
2020
|
+
name: node.middleware.name,
|
|
2021
|
+
operation: "decode"
|
|
2022
|
+
});
|
|
2023
|
+
const output = requireStreamDestination(node.middleware, ctx, "decode");
|
|
2024
|
+
pipes.push(output);
|
|
2025
|
+
if (downstreamResult !== void 0) return downstreamResult;
|
|
2026
|
+
return output;
|
|
2027
|
+
} catch (ex) {
|
|
2028
|
+
if (ctx.destination !== void 0) pipes.push(ctx.destination);
|
|
2029
|
+
throw ex;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
return await run(0, source);
|
|
2033
|
+
} catch (ex) {
|
|
2034
|
+
await cancelStreams(pipes, ex);
|
|
2035
|
+
throw ex;
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
/**
|
|
2039
|
+
* 共有節を 1 回だけ実行しながら、全葉向けのプレーン値をエンコードします。
|
|
2040
|
+
*
|
|
2041
|
+
* エンコード中の失敗は生の例外として投げます。
|
|
2042
|
+
*
|
|
2043
|
+
* @param scope 操作共通の実行時情報です。`key` は論理キーです。
|
|
2044
|
+
* @param data エンコードするデータです。
|
|
2045
|
+
*
|
|
2046
|
+
* @returns 登録順のエンコード結果を返します。
|
|
2047
|
+
*/
|
|
2048
|
+
async encode(scope, data) {
|
|
2049
|
+
const targets = [];
|
|
2050
|
+
async function walk(node, input, parentKey) {
|
|
2051
|
+
scope.signal.throwIfAborted();
|
|
2052
|
+
const ctx = new EncodeContext({
|
|
2053
|
+
key: scope.key,
|
|
2054
|
+
store: scope.store,
|
|
2055
|
+
signal: scope.signal,
|
|
2056
|
+
source: input
|
|
2057
|
+
});
|
|
2058
|
+
let nodeKey = parentKey;
|
|
2059
|
+
let nextCalled = false;
|
|
2060
|
+
let nextSettled = false;
|
|
2061
|
+
function next() {
|
|
2062
|
+
if (nextCalled) return Promise.reject(new MiddlewareNextCalledMultipleTimesError({
|
|
2063
|
+
name: node.middleware.name,
|
|
2064
|
+
operation: "encode"
|
|
2065
|
+
}));
|
|
2066
|
+
nextCalled = true;
|
|
2067
|
+
let encoded;
|
|
2068
|
+
try {
|
|
2069
|
+
encoded = requireDestination(node.middleware, ctx, "encode");
|
|
2070
|
+
freezeDestination(ctx);
|
|
2071
|
+
} catch (ex) {
|
|
2072
|
+
return Promise.reject(ex);
|
|
2073
|
+
}
|
|
2074
|
+
return Promise.try(async () => {
|
|
2075
|
+
try {
|
|
2076
|
+
nodeKey = applyMapKey(node.middleware, parentKey, scope);
|
|
2077
|
+
for (const entry of node.entries) if (entry.kind === "node") await walk(entry.node, encoded, nodeKey);
|
|
2078
|
+
else targets.push({
|
|
2079
|
+
key: nodeKey,
|
|
2080
|
+
data: encoded,
|
|
2081
|
+
leaf: entry.leaf
|
|
2082
|
+
});
|
|
2083
|
+
} finally {
|
|
2084
|
+
nextSettled = true;
|
|
2085
|
+
}
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
await node.middleware.encode(ctx, next);
|
|
2089
|
+
scope.signal.throwIfAborted();
|
|
2090
|
+
if (!nextCalled) throw new MiddlewareNextNotCalledError({
|
|
2091
|
+
name: node.middleware.name,
|
|
2092
|
+
operation: "encode"
|
|
2093
|
+
});
|
|
2094
|
+
if (!nextSettled) throw new MiddlewareNextNotAwaitedError({
|
|
2095
|
+
name: node.middleware.name,
|
|
2096
|
+
operation: "encode"
|
|
2097
|
+
});
|
|
2098
|
+
}
|
|
2099
|
+
for (const entry of _classPrivateFieldGet2(_entries$1, this)) if (entry.kind === "node") await walk(entry.node, data, scope.key);
|
|
2100
|
+
else targets.push({
|
|
2101
|
+
key: scope.key,
|
|
2102
|
+
data,
|
|
2103
|
+
leaf: entry.leaf
|
|
2104
|
+
});
|
|
2105
|
+
targets.sort((a, b) => a.leaf.index - b.leaf.index);
|
|
2106
|
+
return targets;
|
|
2107
|
+
}
|
|
2108
|
+
/**
|
|
2109
|
+
* 書き戻し対象の葉へ、共有節を 1 回だけ実行しながら再エンコードして書き込みます。
|
|
2110
|
+
*
|
|
2111
|
+
* 葉への書き込みは並列に開始し、対象単位の拒否は記録だけして他の対象の開始を止めません。
|
|
2112
|
+
* 走査中に確定した拒否は即座に投げます。書き込み中に判明した拒否も、応答のない他の書き込みを待たずに確定させます。
|
|
2113
|
+
* 拒否がなければ全タスクの終了を待ちます。
|
|
2114
|
+
*
|
|
2115
|
+
* @param scope 操作共通の実行時情報です。`key` は論理キーです。
|
|
2116
|
+
* @param targets 書き戻し対象の葉です。登録順に渡します。
|
|
2117
|
+
* @param throwOnRepairDenied 書き戻し拒否をエラーとして投げるかどうかです。
|
|
2118
|
+
* @param data デコード済みの原データです。
|
|
2119
|
+
* @param write 葉への書き込み処理です。
|
|
2120
|
+
*/
|
|
2121
|
+
async repair(scope, targets, throwOnRepairDenied, data, write) {
|
|
2122
|
+
if (targets.length === 0) return;
|
|
2123
|
+
const targetSet = new Set(targets);
|
|
2124
|
+
const isTarget = (leaf) => targetSet.has(leaf);
|
|
2125
|
+
const writeTasks = [];
|
|
2126
|
+
let traversalDenial = null;
|
|
2127
|
+
const writeDenials = [];
|
|
2128
|
+
const writeDenialSignal = Promise.withResolvers();
|
|
2129
|
+
const writeLeaf = (leaf, input, writeKey) => {
|
|
2130
|
+
writeTasks.push((async () => {
|
|
2131
|
+
try {
|
|
2132
|
+
await write(leaf, writeKey, input);
|
|
2133
|
+
} catch (ex) {
|
|
2134
|
+
if (scope.signal.aborted) return;
|
|
2135
|
+
if (ex instanceof RepairNotAllowedError) {
|
|
2136
|
+
repairLogger.warn`Failed to repair a storage: ${ex}`;
|
|
2137
|
+
if (throwOnRepairDenied) {
|
|
2138
|
+
writeDenials.push(new RepairNotAllowedError({
|
|
2139
|
+
cause: ex,
|
|
2140
|
+
names: [leaf.name]
|
|
2141
|
+
}));
|
|
2142
|
+
writeDenialSignal.resolve();
|
|
2143
|
+
}
|
|
2144
|
+
return;
|
|
2145
|
+
}
|
|
2146
|
+
logger.error`Failed to repair a storage: ${ex}`;
|
|
2147
|
+
}
|
|
2148
|
+
})());
|
|
2149
|
+
};
|
|
2150
|
+
const recordTraversalDenial = (denied) => {
|
|
2151
|
+
traversalDenial ?? (traversalDenial = denied);
|
|
2152
|
+
};
|
|
2153
|
+
const skipDenied = (leaf) => {
|
|
2154
|
+
if (scope.signal.aborted) return;
|
|
2155
|
+
repairLogger.warn`Skipped repair for a storage without AllowRepair: ${leaf.name}`;
|
|
2156
|
+
if (throwOnRepairDenied) recordTraversalDenial(new RepairNotAllowedError({ names: [leaf.name] }));
|
|
2157
|
+
};
|
|
2158
|
+
const walk = async (node, input, parentKey) => {
|
|
2159
|
+
const activeLeaves = activeLeavesOf(node, isTarget);
|
|
2160
|
+
const [firstLeaf] = activeLeaves;
|
|
2161
|
+
if (firstLeaf === void 0) return;
|
|
2162
|
+
const shared = activeLeaves.length >= 2;
|
|
2163
|
+
if (!(shared || firstLeaf.canRepair)) {
|
|
2164
|
+
scope.signal.throwIfAborted();
|
|
2165
|
+
for (const entry of node.entries) if (entry.kind === "node") await walk(entry.node, input, parentKey);
|
|
2166
|
+
else {
|
|
2167
|
+
if (!isTarget(entry.leaf)) continue;
|
|
2168
|
+
if (!entry.leaf.canRepair) {
|
|
2169
|
+
skipDenied(entry.leaf);
|
|
2170
|
+
continue;
|
|
2171
|
+
}
|
|
2172
|
+
writeLeaf(entry.leaf, input, parentKey);
|
|
2173
|
+
}
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
scope.signal.throwIfAborted();
|
|
2177
|
+
const ctx = new EncodeContext({
|
|
2178
|
+
key: scope.key,
|
|
2179
|
+
store: scope.store,
|
|
2180
|
+
signal: scope.signal,
|
|
2181
|
+
source: input
|
|
2182
|
+
});
|
|
2183
|
+
let nodeKey = parentKey;
|
|
2184
|
+
let nextCalled = false;
|
|
2185
|
+
let nextSettled = false;
|
|
2186
|
+
let downstreamStarted = false;
|
|
2187
|
+
function next() {
|
|
2188
|
+
if (nextCalled) return Promise.reject(new MiddlewareNextCalledMultipleTimesError({
|
|
2189
|
+
name: node.middleware.name,
|
|
2190
|
+
operation: "encode"
|
|
2191
|
+
}));
|
|
2192
|
+
nextCalled = true;
|
|
2193
|
+
let encoded;
|
|
2194
|
+
try {
|
|
2195
|
+
encoded = requireDestination(node.middleware, ctx, "encode");
|
|
2196
|
+
freezeDestination(ctx);
|
|
2197
|
+
} catch (ex) {
|
|
2198
|
+
return Promise.reject(ex);
|
|
2199
|
+
}
|
|
2200
|
+
return Promise.try(async () => {
|
|
2201
|
+
try {
|
|
2202
|
+
nodeKey = applyMapKey(node.middleware, parentKey, scope);
|
|
2203
|
+
scope.signal.throwIfAborted();
|
|
2204
|
+
downstreamStarted = true;
|
|
2205
|
+
for (const entry of node.entries) if (entry.kind === "node") await walk(entry.node, encoded, nodeKey);
|
|
2206
|
+
else {
|
|
2207
|
+
if (!isTarget(entry.leaf)) continue;
|
|
2208
|
+
if (!entry.leaf.canRepair) {
|
|
2209
|
+
skipDenied(entry.leaf);
|
|
2210
|
+
continue;
|
|
2211
|
+
}
|
|
2212
|
+
writeLeaf(entry.leaf, encoded, nodeKey);
|
|
2213
|
+
}
|
|
2214
|
+
} finally {
|
|
2215
|
+
nextSettled = true;
|
|
2216
|
+
}
|
|
2217
|
+
});
|
|
2218
|
+
}
|
|
2219
|
+
try {
|
|
2220
|
+
await node.middleware.encode(ctx, next);
|
|
2221
|
+
scope.signal.throwIfAborted();
|
|
2222
|
+
if (!nextCalled) throw new MiddlewareNextNotCalledError({
|
|
2223
|
+
name: node.middleware.name,
|
|
2224
|
+
operation: "encode"
|
|
2225
|
+
});
|
|
2226
|
+
if (!nextSettled) throw new MiddlewareNextNotAwaitedError({
|
|
2227
|
+
name: node.middleware.name,
|
|
2228
|
+
operation: "encode"
|
|
2229
|
+
});
|
|
2230
|
+
} catch (ex) {
|
|
2231
|
+
if (scope.signal.aborted) {
|
|
2232
|
+
if (shared) throw ex;
|
|
2233
|
+
return;
|
|
2234
|
+
}
|
|
2235
|
+
if (ex instanceof MiddlewareNextNotCalledError || ex instanceof MiddlewareNextNotAwaitedError || ex instanceof MiddlewareNextCalledMultipleTimesError || ex instanceof MiddlewareDestinationMissingError || ex instanceof MiddlewareDestinationFrozenError) throw ex;
|
|
2236
|
+
if (downstreamStarted) {
|
|
2237
|
+
if (ex instanceof RepairNotAllowedError) {
|
|
2238
|
+
if (throwOnRepairDenied) throw ex;
|
|
2239
|
+
repairLogger.warn`Failed to repair a storage: ${ex}`;
|
|
2240
|
+
return;
|
|
2241
|
+
}
|
|
2242
|
+
logger.error`Failed to repair a storage: ${ex}`;
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2245
|
+
if (ex instanceof RepairNotAllowedError) {
|
|
2246
|
+
repairLogger.warn`Failed to repair a storage: ${ex}`;
|
|
2247
|
+
if (throwOnRepairDenied) {
|
|
2248
|
+
const denied = new RepairNotAllowedError({
|
|
2249
|
+
cause: ex,
|
|
2250
|
+
names: activeLeaves.map((leaf) => leaf.name)
|
|
2251
|
+
});
|
|
2252
|
+
if (shared) throw denied;
|
|
2253
|
+
recordTraversalDenial(denied);
|
|
2254
|
+
}
|
|
2255
|
+
} else logger.error`Failed to repair a storage: ${ex}`;
|
|
2256
|
+
}
|
|
2257
|
+
};
|
|
2258
|
+
for (const entry of _classPrivateFieldGet2(_entries$1, this)) if (entry.kind === "node") await walk(entry.node, data, scope.key);
|
|
2259
|
+
else {
|
|
2260
|
+
if (!isTarget(entry.leaf)) continue;
|
|
2261
|
+
if (!entry.leaf.canRepair) {
|
|
2262
|
+
skipDenied(entry.leaf);
|
|
2263
|
+
continue;
|
|
2264
|
+
}
|
|
2265
|
+
writeLeaf(entry.leaf, data, scope.key);
|
|
2266
|
+
}
|
|
2267
|
+
if (traversalDenial !== null) throw traversalDenial;
|
|
2268
|
+
await Promise.race([Promise.allSettled(writeTasks), writeDenialSignal.promise]);
|
|
2269
|
+
const [firstDenial] = writeDenials;
|
|
2270
|
+
if (firstDenial !== void 0) throw firstDenial;
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* 共有節を 1 回だけ実行しながらストリームエンコード木を構築します。
|
|
2274
|
+
*
|
|
2275
|
+
* 新 Middleware の `encodeStream` は `c.source.pipeThrough(...)` で変換し `c.destination` に設定します。
|
|
2276
|
+
* 共有節の実行は 1 回だけであり、分岐点では tee で入力を分けます。
|
|
2277
|
+
* 計画段階の失敗は何も構築せずに伝播するため、呼び出し側が `streams` のソースをキャンセルします。
|
|
2278
|
+
* tee とパイプの構築後の失敗は、`streams` に収集したストリーム (分割した読み取り側を含む) を内部でキャンセルしてから伝播します。
|
|
2279
|
+
* 呼び出し側はどちらの失敗でも `streams` をキャンセルできます。
|
|
2280
|
+
*
|
|
2281
|
+
* @param scope 操作共通の実行時情報です。`key` は論理キーです。
|
|
2282
|
+
* @param source 入力ストリームです。
|
|
2283
|
+
* @param streams 構築したストリームを収集する集合です。呼び出し側がソースを事前に追加します。
|
|
2284
|
+
* @param options 構築オプションです。
|
|
2285
|
+
*
|
|
2286
|
+
* @returns 構築結果を返します。
|
|
2287
|
+
*/
|
|
2288
|
+
async buildEncodeTree(scope, source, streams, options = {}) {
|
|
2289
|
+
const { isActive, onNodeError } = options;
|
|
2290
|
+
const targets = [];
|
|
2291
|
+
let readStream = source;
|
|
2292
|
+
const walk = async (node, input, parentKey) => {
|
|
2293
|
+
const activeLeaves = isActive === void 0 ? node.allLeaves : activeLeavesOf(node, isActive);
|
|
2294
|
+
if (activeLeaves.length === 0) return null;
|
|
2295
|
+
scope.signal.throwIfAborted();
|
|
2296
|
+
const ctx = new EncodeStreamContext({
|
|
2297
|
+
key: scope.key,
|
|
2298
|
+
store: scope.store,
|
|
2299
|
+
signal: scope.signal,
|
|
2300
|
+
source: input
|
|
2301
|
+
});
|
|
2302
|
+
let nodeKey = parentKey;
|
|
2303
|
+
let output;
|
|
2304
|
+
let nextCalled = false;
|
|
2305
|
+
let nextSettled = false;
|
|
2306
|
+
let downstreamStarted = false;
|
|
2307
|
+
let downstreamError;
|
|
2308
|
+
let hasDownstreamError = false;
|
|
2309
|
+
let emptyBranches = false;
|
|
2310
|
+
function next() {
|
|
2311
|
+
if (nextCalled) return Promise.reject(new MiddlewareNextCalledMultipleTimesError({
|
|
2312
|
+
name: node.middleware.name,
|
|
2313
|
+
operation: "encode"
|
|
2314
|
+
}));
|
|
2315
|
+
nextCalled = true;
|
|
2316
|
+
let encoded;
|
|
2317
|
+
try {
|
|
2318
|
+
encoded = requireStreamDestination(node.middleware, ctx, "encode");
|
|
2319
|
+
freezeDestination(ctx);
|
|
2320
|
+
} catch (ex) {
|
|
2321
|
+
return Promise.reject(ex);
|
|
2322
|
+
}
|
|
2323
|
+
return Promise.try(async () => {
|
|
2324
|
+
try {
|
|
2325
|
+
output = encoded;
|
|
2326
|
+
streams.add(output);
|
|
2327
|
+
nodeKey = applyMapKey(node.middleware, parentKey, scope);
|
|
2328
|
+
scope.signal.throwIfAborted();
|
|
2329
|
+
downstreamStarted = true;
|
|
2330
|
+
const branchEntries = node.entries.filter((entry) => {
|
|
2331
|
+
if (entry.kind === "leaf") return isActive === void 0 || isActive(entry.leaf);
|
|
2332
|
+
const leaves = entry.node.allLeaves;
|
|
2333
|
+
return isActive === void 0 || leaves.some(isActive);
|
|
2334
|
+
});
|
|
2335
|
+
if (branchEntries.length === 0) {
|
|
2336
|
+
emptyBranches = true;
|
|
2337
|
+
return;
|
|
2338
|
+
}
|
|
2339
|
+
const assigned = [];
|
|
2340
|
+
let current = output;
|
|
2341
|
+
for (let i = 0; i < branchEntries.length; i++) if (i < branchEntries.length - 1) {
|
|
2342
|
+
const [branch, rest] = current.tee();
|
|
2343
|
+
streams.add(branch);
|
|
2344
|
+
streams.add(rest);
|
|
2345
|
+
assigned.push(branch);
|
|
2346
|
+
current = rest;
|
|
2347
|
+
} else assigned.push(current);
|
|
2348
|
+
for (let i = 0; i < branchEntries.length; i++) {
|
|
2349
|
+
const entry = branchEntries[i];
|
|
2350
|
+
const stream = assigned[i];
|
|
2351
|
+
if (entry === void 0 || stream === void 0) throw new Error("分岐の項目またはストリームが存在しません。");
|
|
2352
|
+
if (entry.kind === "leaf") targets.push({
|
|
2353
|
+
key: nodeKey,
|
|
2354
|
+
leaf: entry.leaf,
|
|
2355
|
+
stream
|
|
2356
|
+
});
|
|
2357
|
+
else if (await walk(entry.node, stream, nodeKey) === null) Promise.try(() => stream.cancel(/* @__PURE__ */ new Error("Skipped branch"))).catch(() => {});
|
|
2358
|
+
}
|
|
2359
|
+
} catch (ex) {
|
|
2360
|
+
downstreamError = ex;
|
|
2361
|
+
hasDownstreamError = true;
|
|
2362
|
+
throw ex;
|
|
2363
|
+
} finally {
|
|
2364
|
+
nextSettled = true;
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
try {
|
|
2369
|
+
await node.middleware.encodeStream(ctx, next);
|
|
2370
|
+
scope.signal.throwIfAborted();
|
|
2371
|
+
if (!nextCalled) throw new MiddlewareNextNotCalledError({
|
|
2372
|
+
name: node.middleware.name,
|
|
2373
|
+
operation: "encode"
|
|
2374
|
+
});
|
|
2375
|
+
if (!nextSettled) throw new MiddlewareNextNotAwaitedError({
|
|
2376
|
+
name: node.middleware.name,
|
|
2377
|
+
operation: "encode"
|
|
2378
|
+
});
|
|
2379
|
+
} catch (ex) {
|
|
2380
|
+
if (ctx.destination !== void 0) streams.add(ctx.destination);
|
|
2381
|
+
if (scope.signal.aborted) throw ex;
|
|
2382
|
+
if (ex instanceof MiddlewareNextNotCalledError || ex instanceof MiddlewareNextNotAwaitedError || ex instanceof MiddlewareNextCalledMultipleTimesError || ex instanceof MiddlewareDestinationMissingError || ex instanceof MiddlewareDestinationFrozenError) throw ex;
|
|
2383
|
+
if (downstreamStarted) {
|
|
2384
|
+
if (hasDownstreamError && ex === downstreamError) throw ex;
|
|
2385
|
+
if (onNodeError !== void 0) {
|
|
2386
|
+
if (ex instanceof RepairNotAllowedError) {
|
|
2387
|
+
if (onNodeError(ex, activeLeaves)) return output === void 0 ? null : {
|
|
2388
|
+
key: nodeKey,
|
|
2389
|
+
output
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
logger.error`Failed to repair a storage: ${ex}`;
|
|
2393
|
+
return output === void 0 ? null : {
|
|
2394
|
+
key: nodeKey,
|
|
2395
|
+
output
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
throw ex;
|
|
2399
|
+
}
|
|
2400
|
+
if (onNodeError !== void 0 && onNodeError(ex, activeLeaves)) {
|
|
2401
|
+
const abandoned = output ?? ctx.destination;
|
|
2402
|
+
if (abandoned !== void 0) Promise.try(() => abandoned.cancel(ex)).catch(() => {});
|
|
2403
|
+
return null;
|
|
2404
|
+
}
|
|
2405
|
+
throw ex;
|
|
2406
|
+
}
|
|
2407
|
+
if (emptyBranches || output === void 0) return null;
|
|
2408
|
+
return {
|
|
2409
|
+
key: nodeKey,
|
|
2410
|
+
output
|
|
2411
|
+
};
|
|
2412
|
+
};
|
|
2413
|
+
try {
|
|
2414
|
+
let rootInput = source;
|
|
2415
|
+
if (options.splitRead === true) {
|
|
2416
|
+
const [repairInput, read] = source.tee();
|
|
2417
|
+
streams.add(repairInput);
|
|
2418
|
+
streams.add(read);
|
|
2419
|
+
rootInput = repairInput;
|
|
2420
|
+
readStream = read;
|
|
2421
|
+
}
|
|
2422
|
+
if (_classPrivateFieldGet2(_leaves, this).filter((leaf) => isActive === void 0 || isActive(leaf)).length === 0 && _classPrivateFieldGet2(_entries$1, this).length === 0) return {
|
|
2423
|
+
targets,
|
|
2424
|
+
readStream
|
|
2425
|
+
};
|
|
2426
|
+
const rootBranchEntries = _classPrivateFieldGet2(_entries$1, this).filter((entry) => {
|
|
2427
|
+
if (entry.kind === "leaf") return isActive === void 0 || isActive(entry.leaf);
|
|
2428
|
+
return isActive === void 0 || entry.node.allLeaves.some(isActive);
|
|
2429
|
+
});
|
|
2430
|
+
if (rootBranchEntries.length > 0) {
|
|
2431
|
+
const assigned = [];
|
|
2432
|
+
let current = rootInput;
|
|
2433
|
+
for (let i = 0; i < rootBranchEntries.length; i++) if (i < rootBranchEntries.length - 1) {
|
|
2434
|
+
const [branch, rest] = current.tee();
|
|
2435
|
+
streams.add(branch);
|
|
2436
|
+
streams.add(rest);
|
|
2437
|
+
assigned.push(branch);
|
|
2438
|
+
current = rest;
|
|
2439
|
+
} else assigned.push(current);
|
|
2440
|
+
for (let i = 0; i < rootBranchEntries.length; i++) {
|
|
2441
|
+
const entry = rootBranchEntries[i];
|
|
2442
|
+
const stream = assigned[i];
|
|
2443
|
+
if (entry === void 0 || stream === void 0) throw new Error("分岐の項目またはストリームが存在しません。");
|
|
2444
|
+
if (entry.kind === "leaf") {
|
|
2445
|
+
if (isActive === void 0 || isActive(entry.leaf)) targets.push({
|
|
2446
|
+
key: scope.key,
|
|
2447
|
+
leaf: entry.leaf,
|
|
2448
|
+
stream
|
|
2449
|
+
});
|
|
2450
|
+
} else try {
|
|
2451
|
+
if (await walk(entry.node, stream, scope.key) === null) Promise.try(() => stream.cancel(/* @__PURE__ */ new Error("Skipped branch"))).catch(() => {});
|
|
2452
|
+
} catch (ex) {
|
|
2453
|
+
if (onNodeError) {
|
|
2454
|
+
if (onNodeError(ex, entry.node.allLeaves.filter((leaf) => isActive === void 0 || isActive(leaf)))) {
|
|
2455
|
+
Promise.try(() => stream.cancel(ex)).catch(() => {});
|
|
2456
|
+
continue;
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
throw ex;
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
} catch (ex) {
|
|
2464
|
+
await cancelStreams(streams, ex);
|
|
2465
|
+
throw ex;
|
|
2466
|
+
}
|
|
2467
|
+
targets.sort((a, b) => a.leaf.index - b.leaf.index);
|
|
2468
|
+
return {
|
|
2469
|
+
targets,
|
|
2470
|
+
readStream
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
};
|
|
2474
|
+
//#endregion
|
|
2475
|
+
//#region ../src/_unikvs.schemas.ts
|
|
2476
|
+
const VariablesKeySchema = string();
|
|
2477
|
+
const VariablesInitSchema = pipe(union([custom((input) => typeof input === "object" && input !== null && Symbol.iterator in input, "Expected a Iterable object"), record(VariablesKeySchema, unknown())]), transform((input) => {
|
|
2478
|
+
if (Symbol.iterator in input) return [...input];
|
|
2479
|
+
return Object.entries(input);
|
|
2480
|
+
}));
|
|
2481
|
+
const VariablesArgsSchema = tuple([VariablesInitSchema]);
|
|
2482
|
+
const OpenOptionsSchema = object({
|
|
2483
|
+
/**
|
|
2484
|
+
* 処理の中断を通知するためのシグナルです。
|
|
2485
|
+
*/
|
|
2486
|
+
signal: optional(instance(AbortSignal)),
|
|
2487
|
+
/**
|
|
2488
|
+
* 実行時の変数です。
|
|
2489
|
+
*/
|
|
2490
|
+
vars: optional(VariablesInitSchema)
|
|
2491
|
+
});
|
|
2492
|
+
const OpenArgsSchema = tuple([optional(OpenOptionsSchema)]);
|
|
2493
|
+
const CloseOptionsSchema = object({
|
|
2494
|
+
/**
|
|
2495
|
+
* 処理の中断を通知するためのシグナルです。
|
|
2496
|
+
*/
|
|
2497
|
+
signal: optional(instance(AbortSignal)),
|
|
2498
|
+
/**
|
|
2499
|
+
* 実行時の変数です。
|
|
2500
|
+
*/
|
|
2501
|
+
vars: optional(VariablesInitSchema)
|
|
2502
|
+
});
|
|
2503
|
+
const CloseArgsSchema = tuple([optional(CloseOptionsSchema)]);
|
|
2504
|
+
const SetOptionsSchema = object({
|
|
2505
|
+
key: string(),
|
|
2506
|
+
vars: optional(VariablesInitSchema),
|
|
2507
|
+
value: unknown(),
|
|
2508
|
+
signal: optional(instance(AbortSignal))
|
|
2509
|
+
});
|
|
2510
|
+
const SetArgsSchema = union([tuple([SetOptionsSchema]), pipe(tuple([
|
|
2511
|
+
SetOptionsSchema.entries.key,
|
|
2512
|
+
SetOptionsSchema.entries.value,
|
|
2513
|
+
optional(omit(SetOptionsSchema, ["key", "value"]))
|
|
2514
|
+
]), transform(([key, value, options]) => [{
|
|
2515
|
+
...options,
|
|
2516
|
+
key,
|
|
2517
|
+
value
|
|
2518
|
+
}]))]);
|
|
2519
|
+
const GetOptionsSchema = object({
|
|
2520
|
+
key: string(),
|
|
2521
|
+
vars: optional(VariablesInitSchema),
|
|
2522
|
+
repair: optional(boolean()),
|
|
2523
|
+
signal: optional(instance(AbortSignal)),
|
|
2524
|
+
throwOnRepairDenied: optional(boolean())
|
|
2525
|
+
});
|
|
2526
|
+
const GetArgsSchema = union([tuple([GetOptionsSchema]), pipe(tuple([GetOptionsSchema.entries.key, optional(omit(GetOptionsSchema, ["key"]))]), transform(([key, options]) => [{
|
|
2527
|
+
...options,
|
|
2528
|
+
key
|
|
2529
|
+
}]))]);
|
|
2530
|
+
const StreamOptionsSchema = object({
|
|
2531
|
+
key: string(),
|
|
2532
|
+
vars: optional(VariablesInitSchema),
|
|
2533
|
+
repair: optional(boolean()),
|
|
2534
|
+
signal: optional(instance(AbortSignal)),
|
|
2535
|
+
throwOnRepairDenied: optional(boolean())
|
|
2536
|
+
});
|
|
2537
|
+
const StreamArgsSchema = union([tuple([StreamOptionsSchema]), pipe(tuple([StreamOptionsSchema.entries.key, optional(omit(StreamOptionsSchema, ["key"]))]), transform(([key, options]) => [{
|
|
2538
|
+
...options,
|
|
2539
|
+
key
|
|
2540
|
+
}]))]);
|
|
2541
|
+
const HasOptionsSchema = object({
|
|
2542
|
+
key: string(),
|
|
2543
|
+
vars: optional(VariablesInitSchema),
|
|
2544
|
+
signal: optional(instance(AbortSignal))
|
|
2545
|
+
});
|
|
2546
|
+
const HasArgsSchema = union([tuple([HasOptionsSchema]), pipe(tuple([HasOptionsSchema.entries.key, optional(omit(HasOptionsSchema, ["key"]))]), transform(([key, options]) => [{
|
|
2547
|
+
...options,
|
|
2548
|
+
key
|
|
2549
|
+
}]))]);
|
|
2550
|
+
const DeleteOptionsSchema = object({
|
|
2551
|
+
key: string(),
|
|
2552
|
+
vars: optional(VariablesInitSchema),
|
|
2553
|
+
signal: optional(instance(AbortSignal))
|
|
2554
|
+
});
|
|
2555
|
+
const DeleteArgsSchema = union([tuple([DeleteOptionsSchema]), pipe(tuple([DeleteOptionsSchema.entries.key, optional(omit(DeleteOptionsSchema, ["key"]))]), transform(([key, options]) => [{
|
|
2556
|
+
...options,
|
|
2557
|
+
key
|
|
2558
|
+
}]))]);
|
|
2559
|
+
const ClearOptionsSchema = object({
|
|
2560
|
+
/**
|
|
2561
|
+
* 処理の中断を通知するためのシグナルです。
|
|
2562
|
+
*/
|
|
2563
|
+
signal: optional(instance(AbortSignal)),
|
|
2564
|
+
/**
|
|
2565
|
+
* 実行時の変数です。
|
|
2566
|
+
*/
|
|
2567
|
+
vars: optional(VariablesInitSchema)
|
|
2568
|
+
});
|
|
2569
|
+
const ClearArgsSchema = tuple([optional(ClearOptionsSchema)]);
|
|
2570
|
+
//#endregion
|
|
2571
|
+
//#region ../src/_value-schemas.ts
|
|
2572
|
+
/**
|
|
2573
|
+
* スキーマ付きの値であることを識別するためのブランドです。
|
|
2574
|
+
*
|
|
2575
|
+
* 同じライブラリーが複数読み込まれた環境でも認識できるようにグローバルシンボルを使用します。
|
|
2576
|
+
*/
|
|
2577
|
+
const VALUE_SCHEMA_BRAND = /* #__PURE__ */ Symbol.for("unikvs:VALUE_SCHEMA_BRAND");
|
|
2578
|
+
var _entries = /* @__PURE__ */ new WeakMap();
|
|
2579
|
+
/**
|
|
2580
|
+
* オブジェクト形式のスキーマ定義からスキーマ情報を解決します。
|
|
2581
|
+
*/
|
|
2582
|
+
var RecordValueSchemaResolver = class {
|
|
2583
|
+
constructor(entries) {
|
|
2584
|
+
_classPrivateFieldInitSpec(this, _entries, void 0);
|
|
2585
|
+
_classPrivateFieldSet2(_entries, this, new Map(Object.entries(entries)));
|
|
2586
|
+
}
|
|
2587
|
+
resolve(key) {
|
|
2588
|
+
return _classPrivateFieldGet2(_entries, this).get(key);
|
|
2589
|
+
}
|
|
2590
|
+
};
|
|
2591
|
+
var _entries2 = /* @__PURE__ */ new WeakMap();
|
|
2592
|
+
var _keySchema = /* @__PURE__ */ new WeakMap();
|
|
2593
|
+
/**
|
|
2594
|
+
* 配列形式のスキーマ定義からスキーマ情報を解決します。
|
|
2595
|
+
*
|
|
2596
|
+
* キースキーマに最初に一致した定義を採用します。
|
|
2597
|
+
*/
|
|
2598
|
+
var EntriesValueSchemaResolver = class {
|
|
2599
|
+
constructor(entries) {
|
|
2600
|
+
_classPrivateFieldInitSpec(this, _entries2, void 0);
|
|
2601
|
+
_classPrivateFieldInitSpec(this, _keySchema, void 0);
|
|
2602
|
+
_classPrivateFieldSet2(_entries2, this, entries);
|
|
2603
|
+
if (entries.length > 0) _classPrivateFieldSet2(_keySchema, this, union(entries.map(([keySchema]) => keySchema)));
|
|
2604
|
+
}
|
|
2605
|
+
resolve(key) {
|
|
2606
|
+
let resolved;
|
|
2607
|
+
for (const [keySchema, valueSchema] of _classPrivateFieldGet2(_entries2, this)) if (safeParse$1(keySchema, key).success) {
|
|
2608
|
+
resolved = valueSchema;
|
|
2609
|
+
break;
|
|
2610
|
+
}
|
|
2611
|
+
if (resolved === void 0 && _classPrivateFieldGet2(_keySchema, this)) {
|
|
2612
|
+
const result = safeParse$1(_classPrivateFieldGet2(_keySchema, this), key);
|
|
2613
|
+
if (!result.success) throw new InvalidInputError({
|
|
2614
|
+
value: key,
|
|
2615
|
+
issues: result.issues
|
|
2616
|
+
});
|
|
2617
|
+
}
|
|
2618
|
+
return resolved;
|
|
2619
|
+
}
|
|
2620
|
+
};
|
|
2621
|
+
/**
|
|
2622
|
+
* 検証済みのスキーマ定義からスキーマリゾルバーを生成します。
|
|
2623
|
+
*
|
|
2624
|
+
* @param schema 検証済みのスキーマ定義です。
|
|
2625
|
+
*
|
|
2626
|
+
* @returns スキーマリゾルバーを返します。
|
|
2627
|
+
*/
|
|
2628
|
+
function createValueSchemaResolver(schema) {
|
|
2629
|
+
if (Array.isArray(schema)) return new EntriesValueSchemaResolver(schema);
|
|
2630
|
+
return new RecordValueSchemaResolver(schema);
|
|
2631
|
+
}
|
|
2632
|
+
//#endregion
|
|
2633
|
+
//#region ../src/_to-value-stream.ts
|
|
2634
|
+
/**
|
|
2635
|
+
* 与えられた `IReadableStream` を `IValueStream` に変換します。
|
|
2636
|
+
*
|
|
2637
|
+
* @template T ストリームが保持する値の型です。
|
|
2638
|
+
*
|
|
2639
|
+
* @param readableStream 変換対象となる `IReadableStream` インスタンスです。
|
|
2640
|
+
* @param onAsyncDispose ストリーム破棄時の処理です。
|
|
2641
|
+
* @param onBeforeDispose ソースストリームをキャンセルする前に呼ばれる処理です。
|
|
2642
|
+
*
|
|
2643
|
+
* @returns 非同期イテレーターが付与された `ValueStream` インスタンスを返します。
|
|
2644
|
+
*/
|
|
2645
|
+
function toValueStream(readableStream, onAsyncDispose, onBeforeDispose) {
|
|
2646
|
+
const cacheMap = /* @__PURE__ */ new Map();
|
|
2647
|
+
const reader = readableStream.getReader();
|
|
2648
|
+
async function disposeValueStream() {
|
|
2649
|
+
await callAsyncableFnOnce(cacheMap, "dispose", async () => {
|
|
2650
|
+
try {
|
|
2651
|
+
onBeforeDispose?.();
|
|
2652
|
+
await reader.cancel();
|
|
2653
|
+
} catch (ex) {
|
|
2654
|
+
logger.error`Failed to cancel the source stream: ${ex}`;
|
|
2655
|
+
}
|
|
2656
|
+
await onAsyncDispose();
|
|
2657
|
+
});
|
|
2658
|
+
}
|
|
2659
|
+
const valueStream = new ReadableStream({
|
|
2660
|
+
async pull(controller) {
|
|
2661
|
+
try {
|
|
2662
|
+
const { done, value } = await reader.read();
|
|
2663
|
+
if (done) {
|
|
2664
|
+
await disposeValueStream();
|
|
2665
|
+
controller.close();
|
|
2666
|
+
} else controller.enqueue(value);
|
|
2667
|
+
} catch (ex) {
|
|
2668
|
+
await disposeValueStream().catch((disposeError) => {
|
|
2669
|
+
logger.error`Failed to dispose value stream: ${disposeError}`;
|
|
2670
|
+
});
|
|
2671
|
+
controller.error(ex);
|
|
2672
|
+
}
|
|
2673
|
+
},
|
|
2674
|
+
async cancel() {
|
|
2675
|
+
await disposeValueStream();
|
|
2676
|
+
}
|
|
2677
|
+
});
|
|
2678
|
+
return Object.assign(valueStream, { [Symbol.asyncDispose]: disposeValueStream }, { dispose: disposeValueStream }, { async *[Symbol.asyncIterator]() {
|
|
2679
|
+
const r = this.getReader();
|
|
2680
|
+
try {
|
|
2681
|
+
while (true) {
|
|
2682
|
+
const { done, value } = await r.read();
|
|
2683
|
+
if (done) break;
|
|
2684
|
+
yield value;
|
|
2685
|
+
}
|
|
2686
|
+
} catch (ex) {
|
|
2687
|
+
try {
|
|
2688
|
+
await r.cancel(ex);
|
|
2689
|
+
} catch (cancelError) {
|
|
2690
|
+
logger.error`Failed to cancel reader: ${cancelError}`;
|
|
2691
|
+
}
|
|
2692
|
+
throw ex;
|
|
2693
|
+
} finally {
|
|
2694
|
+
try {
|
|
2695
|
+
await disposeValueStream();
|
|
2696
|
+
} catch (ex) {
|
|
2697
|
+
logger.error`Failed to dispose value stream: ${ex}`;
|
|
2698
|
+
}
|
|
2699
|
+
try {
|
|
2700
|
+
r.releaseLock();
|
|
2701
|
+
} catch (ex) {
|
|
2702
|
+
logger.error`Failed to release reader's lock: ${ex}`;
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
} });
|
|
2706
|
+
}
|
|
2707
|
+
//#endregion
|
|
2708
|
+
//#region ../src/_value-validation.ts
|
|
2709
|
+
/**
|
|
2710
|
+
* プレーン値専用のスキーマに ReadableStream が渡されたことを報告するためのスキーマです。
|
|
2711
|
+
*/
|
|
2712
|
+
const PlainValueInputSchema = pipe(unknown(), check((input) => !isReadableStream(input), "Expected a plain value, but received a ReadableStream"));
|
|
2713
|
+
/**
|
|
2714
|
+
* ストリーム専用のスキーマにプレーン値が渡されたことを報告するためのスキーマです。
|
|
2715
|
+
*/
|
|
2716
|
+
const StreamValueInputSchema = pipe(unknown(), check(isReadableStream, "Expected a ReadableStream, but received a plain value"));
|
|
2717
|
+
/**
|
|
2718
|
+
* スキーマ情報に基づいて `set` の入力値を検証します。
|
|
2719
|
+
*
|
|
2720
|
+
* プレーン値はその場で検証し、ストリームはチャンクごとに検証するストリームに変換します。
|
|
2721
|
+
*
|
|
2722
|
+
* @param info キーに対応するスキーマ情報です。
|
|
2723
|
+
* @param value 検証する入力値です。
|
|
2724
|
+
*
|
|
2725
|
+
* @returns 検証済みの入力値を返します。
|
|
2726
|
+
*/
|
|
2727
|
+
function parseSetValue(info, value) {
|
|
2728
|
+
if (isReadableStream(value)) {
|
|
2729
|
+
if (info.kind === "plain") parseInput(PlainValueInputSchema, value);
|
|
2730
|
+
return value.pipeThrough(new TransformStream({ transform(chunk, controller) {
|
|
2731
|
+
controller.enqueue(parseInput(info.schema, chunk));
|
|
2732
|
+
} }));
|
|
2733
|
+
}
|
|
2734
|
+
if (info.kind === "stream") parseInput(StreamValueInputSchema, value);
|
|
2735
|
+
return parseInput(info.schema, value);
|
|
2736
|
+
}
|
|
2737
|
+
//#endregion
|
|
2738
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/usingCtx.js
|
|
2739
|
+
function _usingCtx() {
|
|
2740
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
2741
|
+
var n = Error();
|
|
2742
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
2743
|
+
}, e = {}, n = [];
|
|
2744
|
+
function using(r, e) {
|
|
2745
|
+
if (null != e) {
|
|
2746
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
2747
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
2748
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
2749
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
2750
|
+
t && (o = function o() {
|
|
2751
|
+
try {
|
|
2752
|
+
t.call(e);
|
|
2753
|
+
} catch (r) {
|
|
2754
|
+
return Promise.reject(r);
|
|
2755
|
+
}
|
|
2756
|
+
}), n.push({
|
|
2757
|
+
v: e,
|
|
2758
|
+
d: o,
|
|
2759
|
+
a: r
|
|
2760
|
+
});
|
|
2761
|
+
} else r && n.push({
|
|
2762
|
+
d: e,
|
|
2763
|
+
a: r
|
|
2764
|
+
});
|
|
2765
|
+
return e;
|
|
2766
|
+
}
|
|
2767
|
+
return {
|
|
2768
|
+
e,
|
|
2769
|
+
u: using.bind(null, !1),
|
|
2770
|
+
a: using.bind(null, !0),
|
|
2771
|
+
d: function d() {
|
|
2772
|
+
var o, t = this.e, s = 0;
|
|
2773
|
+
function next() {
|
|
2774
|
+
for (; o = n.pop();) try {
|
|
2775
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
2776
|
+
if (o.d) {
|
|
2777
|
+
var r = o.d.call(o.v);
|
|
2778
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
2779
|
+
} else s |= 1;
|
|
2780
|
+
} catch (r) {
|
|
2781
|
+
return err(r);
|
|
2782
|
+
}
|
|
2783
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
2784
|
+
if (t !== e) throw t;
|
|
2785
|
+
}
|
|
2786
|
+
function err(n) {
|
|
2787
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
2788
|
+
}
|
|
2789
|
+
return next();
|
|
2790
|
+
}
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
//#endregion
|
|
2794
|
+
//#region ../src/unikvs.ts
|
|
2795
|
+
let _Symbol$asyncDispose;
|
|
2796
|
+
/**
|
|
2797
|
+
* ストリームの読み取りロックを自動解放するための FinalizationRegistry です。
|
|
2798
|
+
*/
|
|
2799
|
+
const ioLockRegistry = typeof FinalizationRegistry !== "function" ? null : new FinalizationRegistry((held) => {
|
|
2800
|
+
if (!held.lock.released) held.lock.release();
|
|
2801
|
+
held.dispose().catch((ex) => {
|
|
2802
|
+
logger.error`Failed to dispose value stream: ${ex}`;
|
|
2803
|
+
});
|
|
2804
|
+
});
|
|
2805
|
+
var _con = /* @__PURE__ */ new WeakMap();
|
|
2806
|
+
var _acSet = /* @__PURE__ */ new WeakMap();
|
|
2807
|
+
var _baseVars = /* @__PURE__ */ new WeakMap();
|
|
2808
|
+
var _pipeline = /* @__PURE__ */ new WeakMap();
|
|
2809
|
+
var _valueSchemaResolver$1 = /* @__PURE__ */ new WeakMap();
|
|
2810
|
+
var _UniKvs_brand = /* @__PURE__ */ new WeakSet();
|
|
2811
|
+
_Symbol$asyncDispose = Symbol.asyncDispose;
|
|
2812
|
+
/**
|
|
2813
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#client-operations)
|
|
2814
|
+
*/
|
|
2815
|
+
var UniKvs = class {
|
|
2816
|
+
/**
|
|
2817
|
+
* @internal
|
|
2818
|
+
*/
|
|
2819
|
+
constructor(vars, pipeline, valueSchemaResolver = null) {
|
|
2820
|
+
_classPrivateMethodInitSpec(this, _UniKvs_brand);
|
|
2821
|
+
_classPrivateFieldInitSpec(this, _con, void 0);
|
|
2822
|
+
_classPrivateFieldInitSpec(this, _acSet, void 0);
|
|
2823
|
+
_classPrivateFieldInitSpec(this, _baseVars, void 0);
|
|
2824
|
+
_classPrivateFieldInitSpec(this, _pipeline, void 0);
|
|
2825
|
+
_classPrivateFieldInitSpec(this, _valueSchemaResolver$1, void 0);
|
|
2826
|
+
_classPrivateFieldSet2(_con, this, null);
|
|
2827
|
+
_classPrivateFieldSet2(_acSet, this, /* @__PURE__ */ new Set());
|
|
2828
|
+
_classPrivateFieldSet2(_baseVars, this, vars);
|
|
2829
|
+
_classPrivateFieldSet2(_pipeline, this, pipeline);
|
|
2830
|
+
_classPrivateFieldSet2(_valueSchemaResolver$1, this, valueSchemaResolver);
|
|
2831
|
+
}
|
|
2832
|
+
setVars(...args) {
|
|
2833
|
+
const [vars] = parseInput(VariablesArgsSchema, args);
|
|
2834
|
+
_classPrivateFieldSet2(_baseVars, this, vars);
|
|
2835
|
+
return this;
|
|
2836
|
+
}
|
|
2837
|
+
assignVars(...args) {
|
|
2838
|
+
const [vars] = parseInput(VariablesArgsSchema, args);
|
|
2839
|
+
const map = new Map(_classPrivateFieldGet2(_baseVars, this));
|
|
2840
|
+
for (const [name, value] of vars) map.set(name, value);
|
|
2841
|
+
_classPrivateFieldSet2(_baseVars, this, [...map]);
|
|
2842
|
+
return this;
|
|
2843
|
+
}
|
|
2844
|
+
defaultsVars(...args) {
|
|
2845
|
+
const [vars] = parseInput(VariablesArgsSchema, args);
|
|
2846
|
+
const map = new Map(vars);
|
|
2847
|
+
for (const [name, value] of _classPrivateFieldGet2(_baseVars, this)) map.set(name, value);
|
|
2848
|
+
_classPrivateFieldSet2(_baseVars, this, [...map]);
|
|
2849
|
+
return this;
|
|
2850
|
+
}
|
|
2851
|
+
get isOpen() {
|
|
2852
|
+
return _classPrivateFieldGet2(_con, this) !== null;
|
|
2853
|
+
}
|
|
2854
|
+
async open(...args) {
|
|
2855
|
+
if (_classPrivateFieldGet2(_con, this) !== null) throw new UniKvsIsOpenError();
|
|
2856
|
+
const [options = {}] = parseInput(OpenArgsSchema, args);
|
|
2857
|
+
const { vars: varsOption, signal: signalOption } = options;
|
|
2858
|
+
const ac = new AbortController();
|
|
2859
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
2860
|
+
const operationVars = _assertClassBrand(_UniKvs_brand, this, _createOperationVars).call(this, varsOption);
|
|
2861
|
+
throwIfAborted(signal);
|
|
2862
|
+
_classPrivateFieldGet2(_acSet, this).add(ac);
|
|
2863
|
+
const dispose = [];
|
|
2864
|
+
try {
|
|
2865
|
+
try {
|
|
2866
|
+
var _usingCtx$1 = _usingCtx();
|
|
2867
|
+
_usingCtx$1.u(await asyncmux(this, signal));
|
|
2868
|
+
try {
|
|
2869
|
+
if (_classPrivateFieldGet2(_con, this) !== null) throw new UniKvsIsOpenError();
|
|
2870
|
+
const openFns = [];
|
|
2871
|
+
for (const [index, leaf] of _classPrivateFieldGet2(_pipeline, this).leaves.entries()) openFns.push([
|
|
2872
|
+
async () => {
|
|
2873
|
+
const pluginVars = new Map(operationVars);
|
|
2874
|
+
const c = new OpenContext({
|
|
2875
|
+
vars: pluginVars.entries(),
|
|
2876
|
+
signal
|
|
2877
|
+
});
|
|
2878
|
+
await leaf.storage.open(c);
|
|
2879
|
+
dispose.push(async () => {
|
|
2880
|
+
try {
|
|
2881
|
+
const cc = new CloseContext({
|
|
2882
|
+
vars: pluginVars.entries(),
|
|
2883
|
+
signal
|
|
2884
|
+
});
|
|
2885
|
+
await leaf.storage.close(cc);
|
|
2886
|
+
} catch (ex) {
|
|
2887
|
+
logger.error`Failed to close storage: ${ex}`;
|
|
2888
|
+
}
|
|
2889
|
+
});
|
|
2890
|
+
},
|
|
2891
|
+
"storage",
|
|
2892
|
+
leaf.name,
|
|
2893
|
+
index
|
|
2894
|
+
]);
|
|
2895
|
+
for (const [index, middleware] of _classPrivateFieldGet2(_pipeline, this).middlewares.entries()) openFns.push([
|
|
2896
|
+
async () => {
|
|
2897
|
+
const pluginVars = new Map(operationVars);
|
|
2898
|
+
const c = new OpenContext({
|
|
2899
|
+
vars: pluginVars.entries(),
|
|
2900
|
+
signal
|
|
2901
|
+
});
|
|
2902
|
+
await middleware.open(c);
|
|
2903
|
+
dispose.push(async () => {
|
|
2904
|
+
try {
|
|
2905
|
+
const cc = new CloseContext({
|
|
2906
|
+
vars: pluginVars.entries(),
|
|
2907
|
+
signal
|
|
2908
|
+
});
|
|
2909
|
+
await middleware.close(cc);
|
|
2910
|
+
} catch (ex) {
|
|
2911
|
+
logger.error`Failed to close middleware: ${ex}`;
|
|
2912
|
+
}
|
|
2913
|
+
});
|
|
2914
|
+
},
|
|
2915
|
+
"middleware",
|
|
2916
|
+
middleware.name,
|
|
2917
|
+
index
|
|
2918
|
+
]);
|
|
2919
|
+
const errors = [];
|
|
2920
|
+
await Promise.all(openFns.map(async ([f, plugin, name, index]) => {
|
|
2921
|
+
try {
|
|
2922
|
+
await f();
|
|
2923
|
+
} catch (ex) {
|
|
2924
|
+
errors.push({
|
|
2925
|
+
name,
|
|
2926
|
+
index,
|
|
2927
|
+
plugin,
|
|
2928
|
+
reason: ex
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2931
|
+
}));
|
|
2932
|
+
if (errors.length > 0) {
|
|
2933
|
+
if (signal.aborted && errors.every((error) => error.reason === signal.reason)) throw signal.reason;
|
|
2934
|
+
throw new PluginOperationAggregateError({
|
|
2935
|
+
action: "open",
|
|
2936
|
+
errors
|
|
2937
|
+
});
|
|
2938
|
+
}
|
|
2939
|
+
throwIfAborted(signal);
|
|
2940
|
+
_classPrivateFieldSet2(_con, this, {
|
|
2941
|
+
ac,
|
|
2942
|
+
io: new Asyncmux()
|
|
2943
|
+
});
|
|
2944
|
+
} catch (ex) {
|
|
2945
|
+
if (dispose.length > 0) await Promise.all(dispose.map(async (f) => {
|
|
2946
|
+
await f();
|
|
2947
|
+
}));
|
|
2948
|
+
throw ex;
|
|
2949
|
+
}
|
|
2950
|
+
} catch (_) {
|
|
2951
|
+
_usingCtx$1.e = _;
|
|
2952
|
+
} finally {
|
|
2953
|
+
_usingCtx$1.d();
|
|
2954
|
+
}
|
|
2955
|
+
} finally {
|
|
2956
|
+
_classPrivateFieldGet2(_acSet, this).delete(ac);
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
close(...args) {
|
|
2960
|
+
try {
|
|
2961
|
+
const [options = {}] = parseInput(CloseArgsSchema, args);
|
|
2962
|
+
const { vars: varsOption, signal = AbortSignal.timeout(1e4) } = options;
|
|
2963
|
+
const operationVars = _assertClassBrand(_UniKvs_brand, this, _createOperationVars).call(this, varsOption);
|
|
2964
|
+
if (_classPrivateFieldGet2(_con, this) === null) {
|
|
2965
|
+
const acArr = [..._classPrivateFieldGet2(_acSet, this)];
|
|
2966
|
+
_classPrivateFieldGet2(_acSet, this).clear();
|
|
2967
|
+
for (const ac of acArr) if (!ac.signal.aborted) ac.abort(new UniKvsIsNotOpenError());
|
|
2968
|
+
throw new UniKvsIsNotOpenError();
|
|
2969
|
+
}
|
|
2970
|
+
const con = _classPrivateFieldGet2(_con, this);
|
|
2971
|
+
const { ac } = con;
|
|
2972
|
+
const acArr = [ac, ..._classPrivateFieldGet2(_acSet, this)];
|
|
2973
|
+
_classPrivateFieldGet2(_acSet, this).clear();
|
|
2974
|
+
for (const targetAc of acArr) if (!targetAc.signal.aborted) targetAc.abort(new UniKvsIsNotOpenError());
|
|
2975
|
+
const progress = { pluginsStarted: false };
|
|
2976
|
+
return _assertClassBrand(_UniKvs_brand, this, _close).call(this, operationVars, signal, con, progress).catch(async (closeError) => {
|
|
2977
|
+
if (_classPrivateFieldGet2(_con, this) === con) {
|
|
2978
|
+
_classPrivateFieldSet2(_con, this, null);
|
|
2979
|
+
if (!progress.pluginsStarted) {
|
|
2980
|
+
const disposeSignal = AbortSignal.timeout(1e4);
|
|
2981
|
+
await Promise.all([..._classPrivateFieldGet2(_pipeline, this).leaves.map((leaf) => leaf.storage), ..._classPrivateFieldGet2(_pipeline, this).middlewares].map(async (plugin) => {
|
|
2982
|
+
try {
|
|
2983
|
+
const c = new CloseContext({
|
|
2984
|
+
vars: new Map(operationVars).entries(),
|
|
2985
|
+
signal: disposeSignal
|
|
2986
|
+
});
|
|
2987
|
+
await plugin.close(c);
|
|
2988
|
+
} catch (disposeError) {
|
|
2989
|
+
logger.error`Failed to close plugin after close failure: ${disposeError}`;
|
|
2990
|
+
}
|
|
2991
|
+
}));
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
throw closeError;
|
|
2995
|
+
});
|
|
2996
|
+
} catch (ex) {
|
|
2997
|
+
return Promise.reject(ex);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
3000
|
+
async [_Symbol$asyncDispose]() {
|
|
3001
|
+
if (!this.isOpen) return;
|
|
3002
|
+
await this.close({ signal: AbortSignal.timeout(1e4) });
|
|
3003
|
+
}
|
|
3004
|
+
async set(...args) {
|
|
3005
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3006
|
+
const [options] = parseInput(SetArgsSchema, args);
|
|
3007
|
+
const { key, vars: varsOption, signal: signalOption } = options;
|
|
3008
|
+
const valueSchema = _assertClassBrand(_UniKvs_brand, this, _resolveValueSchema).call(this, key);
|
|
3009
|
+
const value = valueSchema ? parseSetValue(valueSchema, options.value) : options.value;
|
|
3010
|
+
const { ac, io } = _classPrivateFieldGet2(_con, this);
|
|
3011
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
3012
|
+
const store = _assertClassBrand(_UniKvs_brand, this, _createOperationStore).call(this, varsOption);
|
|
3013
|
+
const stream = isReadableStream(value) ? value : null;
|
|
3014
|
+
let ownsStream = stream !== null;
|
|
3015
|
+
try {
|
|
3016
|
+
try {
|
|
3017
|
+
var _usingCtx6 = _usingCtx();
|
|
3018
|
+
_usingCtx6.u(await asyncmux.readonly(this, signal));
|
|
3019
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3020
|
+
const useContext = new SetContext({
|
|
3021
|
+
key,
|
|
3022
|
+
store,
|
|
3023
|
+
signal
|
|
3024
|
+
});
|
|
3025
|
+
await _assertClassBrand(_UniKvs_brand, this, _use).call(this, "write", useContext);
|
|
3026
|
+
throwIfAborted(signal);
|
|
3027
|
+
if (stream !== null) {
|
|
3028
|
+
ownsStream = false;
|
|
3029
|
+
await _assertClassBrand(_UniKvs_brand, this, _setStream).call(this, io, signal, key, store, stream);
|
|
3030
|
+
} else await _assertClassBrand(_UniKvs_brand, this, _setPlain).call(this, io, signal, key, store, value);
|
|
3031
|
+
} catch (_) {
|
|
3032
|
+
_usingCtx6.e = _;
|
|
3033
|
+
} finally {
|
|
3034
|
+
_usingCtx6.d();
|
|
3035
|
+
}
|
|
3036
|
+
} catch (ex) {
|
|
3037
|
+
if (ownsStream && stream !== null) try {
|
|
3038
|
+
await stream.cancel(ex);
|
|
3039
|
+
} catch {}
|
|
3040
|
+
throw ex;
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
async get(...args) {
|
|
3044
|
+
try {
|
|
3045
|
+
var _usingCtx7 = _usingCtx();
|
|
3046
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3047
|
+
const [options] = parseInput(GetArgsSchema, args);
|
|
3048
|
+
const { key, vars: varsOption, repair = false, signal: signalOption, throwOnRepairDenied = false } = options;
|
|
3049
|
+
const valueSchema = _assertClassBrand(_UniKvs_brand, this, _resolveValueSchema).call(this, key);
|
|
3050
|
+
const { ac, io } = _classPrivateFieldGet2(_con, this);
|
|
3051
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
3052
|
+
const store = _assertClassBrand(_UniKvs_brand, this, _createOperationStore).call(this, varsOption);
|
|
3053
|
+
_usingCtx7.u(await asyncmux.readonly(this, signal));
|
|
3054
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3055
|
+
const leafNames = _classPrivateFieldGet2(_pipeline, this).leaves.map((leaf) => leaf.name);
|
|
3056
|
+
const useContext = new GetContext({
|
|
3057
|
+
key,
|
|
3058
|
+
store,
|
|
3059
|
+
repair: repair ? {
|
|
3060
|
+
enabled: true,
|
|
3061
|
+
targets: leafNames
|
|
3062
|
+
} : {
|
|
3063
|
+
enabled: false,
|
|
3064
|
+
targets: []
|
|
3065
|
+
},
|
|
3066
|
+
signal
|
|
3067
|
+
});
|
|
3068
|
+
await _assertClassBrand(_UniKvs_brand, this, _use).call(this, "read", useContext);
|
|
3069
|
+
throwIfAborted(signal);
|
|
3070
|
+
let data = void 0;
|
|
3071
|
+
let hit = null;
|
|
3072
|
+
const missing = [];
|
|
3073
|
+
const errors = [];
|
|
3074
|
+
try {
|
|
3075
|
+
var _usingCtx8 = _usingCtx();
|
|
3076
|
+
_usingCtx8.u(await (repair ? io.lock({
|
|
3077
|
+
key,
|
|
3078
|
+
signal
|
|
3079
|
+
}) : io.rLock({
|
|
3080
|
+
key,
|
|
3081
|
+
signal
|
|
3082
|
+
})));
|
|
3083
|
+
const resolver = _classPrivateFieldGet2(_pipeline, this).createResolver({
|
|
3084
|
+
key,
|
|
3085
|
+
store,
|
|
3086
|
+
signal
|
|
3087
|
+
});
|
|
3088
|
+
for (const leaf of _classPrivateFieldGet2(_pipeline, this)) {
|
|
3089
|
+
const resolved = resolver.resolve(leaf);
|
|
3090
|
+
const existsContext = new HasContext({
|
|
3091
|
+
key: resolved.key,
|
|
3092
|
+
store,
|
|
3093
|
+
signal
|
|
3094
|
+
});
|
|
3095
|
+
const readRepair = repair ? {
|
|
3096
|
+
enabled: true,
|
|
3097
|
+
targets: leafNames
|
|
3098
|
+
} : {
|
|
3099
|
+
enabled: false,
|
|
3100
|
+
targets: []
|
|
3101
|
+
};
|
|
3102
|
+
const readContext = new GetContext({
|
|
3103
|
+
key: resolved.key,
|
|
3104
|
+
store,
|
|
3105
|
+
repair: readRepair,
|
|
3106
|
+
signal
|
|
3107
|
+
});
|
|
3108
|
+
try {
|
|
3109
|
+
if (!await leaf.storage.exists(existsContext)) {
|
|
3110
|
+
missing.push(leaf);
|
|
3111
|
+
continue;
|
|
3112
|
+
}
|
|
3113
|
+
data = await leaf.storage.read(readContext);
|
|
3114
|
+
hit = resolved;
|
|
3115
|
+
break;
|
|
3116
|
+
} catch (ex) {
|
|
3117
|
+
if (signal.aborted) throw ex;
|
|
3118
|
+
errors.push({
|
|
3119
|
+
name: leaf.name,
|
|
3120
|
+
index: leaf.index,
|
|
3121
|
+
reason: ex
|
|
3122
|
+
});
|
|
3123
|
+
logger.error`Failed to read from a storage: ${ex}`;
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
if (hit === null) throw _assertClassBrand(_UniKvs_brand, this, _notFound).call(this, key, errors);
|
|
3127
|
+
if (repair) data = await _assertClassBrand(_UniKvs_brand, this, _repairPlain).call(this, data, hit, missing, store, key, signal, throwOnRepairDenied);
|
|
3128
|
+
} catch (_) {
|
|
3129
|
+
_usingCtx8.e = _;
|
|
3130
|
+
} finally {
|
|
3131
|
+
_usingCtx8.d();
|
|
3132
|
+
}
|
|
3133
|
+
if (!repair) data = await _classPrivateFieldGet2(_pipeline, this).decode(hit.leaf, {
|
|
3134
|
+
key,
|
|
3135
|
+
store,
|
|
3136
|
+
signal
|
|
3137
|
+
}, data);
|
|
3138
|
+
if (valueSchema) data = parseOutput(valueSchema.schema, data);
|
|
3139
|
+
return data;
|
|
3140
|
+
} catch (_) {
|
|
3141
|
+
_usingCtx7.e = _;
|
|
3142
|
+
} finally {
|
|
3143
|
+
_usingCtx7.d();
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
async stream(...args) {
|
|
3147
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3148
|
+
const [options] = parseInput(StreamArgsSchema, args);
|
|
3149
|
+
const { key, vars: varsOption, repair = false, signal: signalOption, throwOnRepairDenied = false } = options;
|
|
3150
|
+
const valueSchema = _assertClassBrand(_UniKvs_brand, this, _resolveValueSchema).call(this, key);
|
|
3151
|
+
const { ac, io } = _classPrivateFieldGet2(_con, this);
|
|
3152
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
3153
|
+
const store = _assertClassBrand(_UniKvs_brand, this, _createOperationStore).call(this, varsOption);
|
|
3154
|
+
try {
|
|
3155
|
+
var _usingCtx9 = _usingCtx();
|
|
3156
|
+
_usingCtx9.u(await asyncmux.readonly(this, signal));
|
|
3157
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3158
|
+
const leafNames = _classPrivateFieldGet2(_pipeline, this).leaves.map((leaf) => leaf.name);
|
|
3159
|
+
const useContext = new StreamContext({
|
|
3160
|
+
key,
|
|
3161
|
+
store,
|
|
3162
|
+
repair: repair ? {
|
|
3163
|
+
enabled: true,
|
|
3164
|
+
targets: leafNames
|
|
3165
|
+
} : {
|
|
3166
|
+
enabled: false,
|
|
3167
|
+
targets: []
|
|
3168
|
+
},
|
|
3169
|
+
signal
|
|
3170
|
+
});
|
|
3171
|
+
await _assertClassBrand(_UniKvs_brand, this, _use).call(this, "read", useContext);
|
|
3172
|
+
throwIfAborted(signal);
|
|
3173
|
+
const NONE = {};
|
|
3174
|
+
let r = NONE;
|
|
3175
|
+
let hit = null;
|
|
3176
|
+
const missing = [];
|
|
3177
|
+
const errors = [];
|
|
3178
|
+
const fillBranches = [];
|
|
3179
|
+
const fillTasks = [];
|
|
3180
|
+
let repairAc = null;
|
|
3181
|
+
let cancelFills = null;
|
|
3182
|
+
const ioLock = await (repair ? io.lock({
|
|
3183
|
+
key,
|
|
3184
|
+
signal
|
|
3185
|
+
}) : io.rLock({
|
|
3186
|
+
key,
|
|
3187
|
+
signal
|
|
3188
|
+
}));
|
|
3189
|
+
try {
|
|
3190
|
+
const resolver = _classPrivateFieldGet2(_pipeline, this).createResolver({
|
|
3191
|
+
key,
|
|
3192
|
+
store,
|
|
3193
|
+
signal
|
|
3194
|
+
});
|
|
3195
|
+
for (const leaf of _classPrivateFieldGet2(_pipeline, this)) {
|
|
3196
|
+
const resolved = resolver.resolve(leaf);
|
|
3197
|
+
const existsContext = new HasContext({
|
|
3198
|
+
key: resolved.key,
|
|
3199
|
+
store,
|
|
3200
|
+
signal
|
|
3201
|
+
});
|
|
3202
|
+
const readableRepair = repair ? {
|
|
3203
|
+
enabled: true,
|
|
3204
|
+
targets: leafNames
|
|
3205
|
+
} : {
|
|
3206
|
+
enabled: false,
|
|
3207
|
+
targets: []
|
|
3208
|
+
};
|
|
3209
|
+
const readableContext = new StreamContext({
|
|
3210
|
+
key: resolved.key,
|
|
3211
|
+
store,
|
|
3212
|
+
repair: readableRepair,
|
|
3213
|
+
signal
|
|
3214
|
+
});
|
|
3215
|
+
try {
|
|
3216
|
+
if (!await leaf.storage.exists(existsContext)) {
|
|
3217
|
+
missing.push(leaf);
|
|
3218
|
+
continue;
|
|
3219
|
+
}
|
|
3220
|
+
r = await leaf.storage.getReadable(readableContext);
|
|
3221
|
+
hit = resolved;
|
|
3222
|
+
break;
|
|
3223
|
+
} catch (ex) {
|
|
3224
|
+
if (signal.aborted) throw ex;
|
|
3225
|
+
errors.push({
|
|
3226
|
+
name: leaf.name,
|
|
3227
|
+
index: leaf.index,
|
|
3228
|
+
reason: ex
|
|
3229
|
+
});
|
|
3230
|
+
logger.error`Failed to read from a storage: ${ex}`;
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
if (hit === null) throw _assertClassBrand(_UniKvs_brand, this, _notFound).call(this, key, errors);
|
|
3234
|
+
repairAc = repair ? new AbortController() : null;
|
|
3235
|
+
const repairSignal = repairAc ? combineSignals([signal, repairAc.signal]) : signal;
|
|
3236
|
+
const fill = (target) => {
|
|
3237
|
+
fillBranches.push(target.stream);
|
|
3238
|
+
fillTasks.push((async () => {
|
|
3239
|
+
try {
|
|
3240
|
+
const wc = new SetContext({
|
|
3241
|
+
key: target.key,
|
|
3242
|
+
store,
|
|
3243
|
+
signal: repairSignal
|
|
3244
|
+
});
|
|
3245
|
+
const w = await target.leaf.storage.getWritable(wc);
|
|
3246
|
+
await target.stream.pipeTo(w, { signal: repairSignal });
|
|
3247
|
+
} catch (ex) {
|
|
3248
|
+
try {
|
|
3249
|
+
await target.stream.cancel(ex);
|
|
3250
|
+
} catch {}
|
|
3251
|
+
if (repairSignal.aborted) return;
|
|
3252
|
+
if (ex instanceof RepairNotAllowedError) {
|
|
3253
|
+
repairLogger.warn`Failed to repair a storage: ${ex}`;
|
|
3254
|
+
return;
|
|
3255
|
+
}
|
|
3256
|
+
logger.error`Failed to repair a storage: ${ex}`;
|
|
3257
|
+
}
|
|
3258
|
+
})());
|
|
3259
|
+
};
|
|
3260
|
+
cancelFills = async (reason) => {
|
|
3261
|
+
repairAc?.abort(reason);
|
|
3262
|
+
await Promise.all(fillBranches.map(async (branch) => {
|
|
3263
|
+
try {
|
|
3264
|
+
await branch.cancel(reason);
|
|
3265
|
+
} catch {}
|
|
3266
|
+
}));
|
|
3267
|
+
await Promise.all(fillTasks);
|
|
3268
|
+
};
|
|
3269
|
+
r = await _classPrivateFieldGet2(_pipeline, this).decodeStream(hit.leaf, {
|
|
3270
|
+
key,
|
|
3271
|
+
store,
|
|
3272
|
+
signal
|
|
3273
|
+
}, r);
|
|
3274
|
+
if (repair) {
|
|
3275
|
+
const repairSet = /* @__PURE__ */ new Set();
|
|
3276
|
+
for (const leaf of missing) {
|
|
3277
|
+
if (!leaf.canRepair) {
|
|
3278
|
+
if (signal.aborted) continue;
|
|
3279
|
+
repairLogger.warn`Skipped repair for a storage without AllowRepair: ${leaf.name}`;
|
|
3280
|
+
if (throwOnRepairDenied) throw new RepairNotAllowedError({ names: [leaf.name] });
|
|
3281
|
+
continue;
|
|
3282
|
+
}
|
|
3283
|
+
repairSet.add(leaf);
|
|
3284
|
+
}
|
|
3285
|
+
if (repairSet.size > 0) {
|
|
3286
|
+
const streams = /* @__PURE__ */ new Set([r]);
|
|
3287
|
+
const tree = await _classPrivateFieldGet2(_pipeline, this).buildEncodeTree({
|
|
3288
|
+
key,
|
|
3289
|
+
store,
|
|
3290
|
+
signal
|
|
3291
|
+
}, r, streams, {
|
|
3292
|
+
isActive: (leaf) => repairSet.has(leaf),
|
|
3293
|
+
splitRead: true,
|
|
3294
|
+
onNodeError: (ex, activeLeaves) => {
|
|
3295
|
+
throwIfAborted(signal);
|
|
3296
|
+
if (ex instanceof RepairNotAllowedError) {
|
|
3297
|
+
repairLogger.warn`Failed to repair a storage: ${ex}`;
|
|
3298
|
+
if (throwOnRepairDenied) throw new RepairNotAllowedError({
|
|
3299
|
+
cause: ex,
|
|
3300
|
+
names: activeLeaves.map((leaf) => leaf.name)
|
|
3301
|
+
});
|
|
3302
|
+
return true;
|
|
3303
|
+
}
|
|
3304
|
+
logger.error`Failed to repair a storage: ${ex}`;
|
|
3305
|
+
throw ex;
|
|
3306
|
+
}
|
|
3307
|
+
});
|
|
3308
|
+
r = tree.readStream;
|
|
3309
|
+
for (const target of tree.targets) fill(target);
|
|
3310
|
+
}
|
|
3311
|
+
throwIfAborted(signal);
|
|
3312
|
+
}
|
|
3313
|
+
if (valueSchema) r = r.pipeThrough(new TransformStream({ transform(chunk, controller) {
|
|
3314
|
+
controller.enqueue(parseOutput(valueSchema.schema, chunk));
|
|
3315
|
+
} }));
|
|
3316
|
+
let completed = false;
|
|
3317
|
+
if (repairAc) r = r.pipeThrough(new TransformStream({
|
|
3318
|
+
flush() {
|
|
3319
|
+
completed = true;
|
|
3320
|
+
},
|
|
3321
|
+
transform(chunk, controller) {
|
|
3322
|
+
controller.enqueue(chunk);
|
|
3323
|
+
}
|
|
3324
|
+
}));
|
|
3325
|
+
const beforeDispose = () => {
|
|
3326
|
+
if (!completed) repairAc?.abort(signal.reason);
|
|
3327
|
+
};
|
|
3328
|
+
const dispose = async () => {
|
|
3329
|
+
try {
|
|
3330
|
+
await Promise.all(fillTasks);
|
|
3331
|
+
} finally {
|
|
3332
|
+
try {
|
|
3333
|
+
ioLock.release();
|
|
3334
|
+
} catch {}
|
|
3335
|
+
}
|
|
3336
|
+
};
|
|
3337
|
+
if (!ioLockRegistry) return toValueStream(r, dispose, beforeDispose);
|
|
3338
|
+
const unregisterToken = {};
|
|
3339
|
+
const valueStream = toValueStream(r, async () => {
|
|
3340
|
+
try {
|
|
3341
|
+
ioLockRegistry.unregister(unregisterToken);
|
|
3342
|
+
} catch {}
|
|
3343
|
+
await dispose();
|
|
3344
|
+
}, beforeDispose);
|
|
3345
|
+
ioLockRegistry.register(valueStream, {
|
|
3346
|
+
lock: ioLock,
|
|
3347
|
+
dispose: valueStream.dispose
|
|
3348
|
+
}, unregisterToken);
|
|
3349
|
+
return valueStream;
|
|
3350
|
+
} catch (ex) {
|
|
3351
|
+
await cancelFills?.(ex);
|
|
3352
|
+
if (r !== NONE) try {
|
|
3353
|
+
await r.cancel(ex);
|
|
3354
|
+
} catch {}
|
|
3355
|
+
ioLock.release();
|
|
3356
|
+
throw ex;
|
|
3357
|
+
}
|
|
3358
|
+
} catch (_) {
|
|
3359
|
+
_usingCtx9.e = _;
|
|
3360
|
+
} finally {
|
|
3361
|
+
_usingCtx9.d();
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
async has(...args) {
|
|
3365
|
+
try {
|
|
3366
|
+
var _usingCtx10 = _usingCtx();
|
|
3367
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3368
|
+
const [options] = parseInput(HasArgsSchema, args);
|
|
3369
|
+
const { key, vars: varsOption, signal: signalOption } = options;
|
|
3370
|
+
_assertClassBrand(_UniKvs_brand, this, _resolveValueSchema).call(this, key);
|
|
3371
|
+
const { ac, io } = _classPrivateFieldGet2(_con, this);
|
|
3372
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
3373
|
+
const store = _assertClassBrand(_UniKvs_brand, this, _createOperationStore).call(this, varsOption);
|
|
3374
|
+
_usingCtx10.u(await asyncmux.readonly(this, signal));
|
|
3375
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3376
|
+
const useContext = new HasContext({
|
|
3377
|
+
key,
|
|
3378
|
+
store,
|
|
3379
|
+
signal
|
|
3380
|
+
});
|
|
3381
|
+
await _assertClassBrand(_UniKvs_brand, this, _use).call(this, "read", useContext);
|
|
3382
|
+
throwIfAborted(signal);
|
|
3383
|
+
_usingCtx10.u(await io.rLock({
|
|
3384
|
+
key,
|
|
3385
|
+
signal
|
|
3386
|
+
}));
|
|
3387
|
+
const errors = [];
|
|
3388
|
+
const resolver = _classPrivateFieldGet2(_pipeline, this).createResolver({
|
|
3389
|
+
key,
|
|
3390
|
+
store,
|
|
3391
|
+
signal
|
|
3392
|
+
});
|
|
3393
|
+
for (const leaf of _classPrivateFieldGet2(_pipeline, this)) {
|
|
3394
|
+
const resolved = resolver.resolve(leaf);
|
|
3395
|
+
try {
|
|
3396
|
+
const c = new HasContext({
|
|
3397
|
+
key: resolved.key,
|
|
3398
|
+
store,
|
|
3399
|
+
signal
|
|
3400
|
+
});
|
|
3401
|
+
if (await leaf.storage.exists(c)) return true;
|
|
3402
|
+
} catch (ex) {
|
|
3403
|
+
if (signal.aborted) throw ex;
|
|
3404
|
+
errors.push({
|
|
3405
|
+
name: leaf.name,
|
|
3406
|
+
index: leaf.index,
|
|
3407
|
+
reason: ex
|
|
3408
|
+
});
|
|
3409
|
+
logger.error`Failed to check existence in a storage: ${ex}`;
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
if (errors.length > 0) throw _assertClassBrand(_UniKvs_brand, this, _notFound).call(this, key, errors);
|
|
3413
|
+
return false;
|
|
3414
|
+
} catch (_) {
|
|
3415
|
+
_usingCtx10.e = _;
|
|
3416
|
+
} finally {
|
|
3417
|
+
_usingCtx10.d();
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
async delete(...args) {
|
|
3421
|
+
try {
|
|
3422
|
+
var _usingCtx11 = _usingCtx();
|
|
3423
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3424
|
+
const [options] = parseInput(DeleteArgsSchema, args);
|
|
3425
|
+
const { key, vars: varsOption, signal: signalOption } = options;
|
|
3426
|
+
_assertClassBrand(_UniKvs_brand, this, _resolveValueSchema).call(this, key);
|
|
3427
|
+
const { ac, io } = _classPrivateFieldGet2(_con, this);
|
|
3428
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
3429
|
+
const store = _assertClassBrand(_UniKvs_brand, this, _createOperationStore).call(this, varsOption);
|
|
3430
|
+
_usingCtx11.u(await asyncmux.readonly(this, signal));
|
|
3431
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3432
|
+
const useContext = new DeleteContext({
|
|
3433
|
+
key,
|
|
3434
|
+
store,
|
|
3435
|
+
signal
|
|
3436
|
+
});
|
|
3437
|
+
await _assertClassBrand(_UniKvs_brand, this, _use).call(this, "delete", useContext);
|
|
3438
|
+
_usingCtx11.u(await io.lock({
|
|
3439
|
+
key,
|
|
3440
|
+
signal
|
|
3441
|
+
}));
|
|
3442
|
+
const errors = [];
|
|
3443
|
+
const resolver = _classPrivateFieldGet2(_pipeline, this).createResolver({
|
|
3444
|
+
key,
|
|
3445
|
+
store,
|
|
3446
|
+
signal
|
|
3447
|
+
});
|
|
3448
|
+
await Promise.all(_classPrivateFieldGet2(_pipeline, this).leaves.map(async (leaf) => {
|
|
3449
|
+
const resolved = resolver.resolve(leaf);
|
|
3450
|
+
const existsContext = new HasContext({
|
|
3451
|
+
key: resolved.key,
|
|
3452
|
+
store,
|
|
3453
|
+
signal
|
|
3454
|
+
});
|
|
3455
|
+
const deleteContext = new DeleteContext({
|
|
3456
|
+
key: resolved.key,
|
|
3457
|
+
store,
|
|
3458
|
+
signal
|
|
3459
|
+
});
|
|
3460
|
+
try {
|
|
3461
|
+
if (await leaf.storage.exists(existsContext)) await leaf.storage.delete(deleteContext);
|
|
3462
|
+
} catch (ex) {
|
|
3463
|
+
errors.push({
|
|
3464
|
+
name: leaf.name,
|
|
3465
|
+
index: leaf.index,
|
|
3466
|
+
reason: ex
|
|
3467
|
+
});
|
|
3468
|
+
}
|
|
3469
|
+
}));
|
|
3470
|
+
if (errors.length > 0) throw new PluginOperationAggregateError({
|
|
3471
|
+
action: "delete",
|
|
3472
|
+
errors,
|
|
3473
|
+
plugin: "storage"
|
|
3474
|
+
});
|
|
3475
|
+
} catch (_) {
|
|
3476
|
+
_usingCtx11.e = _;
|
|
3477
|
+
} finally {
|
|
3478
|
+
_usingCtx11.d();
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
async clear(...args) {
|
|
3482
|
+
try {
|
|
3483
|
+
var _usingCtx12 = _usingCtx();
|
|
3484
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3485
|
+
const [options = {}] = parseInput(ClearArgsSchema, args);
|
|
3486
|
+
const { vars: varsOption, signal: signalOption } = options;
|
|
3487
|
+
const { ac, io } = _classPrivateFieldGet2(_con, this);
|
|
3488
|
+
const signal = combineSignals([ac.signal, signalOption]);
|
|
3489
|
+
const store = _assertClassBrand(_UniKvs_brand, this, _createOperationStore).call(this, varsOption);
|
|
3490
|
+
_usingCtx12.u(await asyncmux.readonly(this, signal));
|
|
3491
|
+
if (_classPrivateFieldGet2(_con, this) === null) throw new UniKvsIsNotOpenError();
|
|
3492
|
+
_usingCtx12.u(await io.lock({ signal }));
|
|
3493
|
+
const useContext = new ClearContext({
|
|
3494
|
+
store,
|
|
3495
|
+
signal
|
|
3496
|
+
});
|
|
3497
|
+
await _assertClassBrand(_UniKvs_brand, this, _use).call(this, "clear", useContext);
|
|
3498
|
+
throwIfAborted(signal);
|
|
3499
|
+
const errors = [];
|
|
3500
|
+
await Promise.all(_classPrivateFieldGet2(_pipeline, this).leaves.map(async (leaf, index) => {
|
|
3501
|
+
try {
|
|
3502
|
+
const c = new ClearContext({
|
|
3503
|
+
store,
|
|
3504
|
+
signal
|
|
3505
|
+
});
|
|
3506
|
+
await leaf.storage.clear(c);
|
|
3507
|
+
} catch (ex) {
|
|
3508
|
+
errors.push({
|
|
3509
|
+
name: leaf.name,
|
|
3510
|
+
index,
|
|
3511
|
+
reason: ex
|
|
3512
|
+
});
|
|
3513
|
+
}
|
|
3514
|
+
}));
|
|
3515
|
+
if (errors.length > 0) throw new PluginOperationAggregateError({
|
|
3516
|
+
action: "clear",
|
|
3517
|
+
errors,
|
|
3518
|
+
plugin: "storage"
|
|
3519
|
+
});
|
|
3520
|
+
} catch (_) {
|
|
3521
|
+
_usingCtx12.e = _;
|
|
3522
|
+
} finally {
|
|
3523
|
+
_usingCtx12.d();
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
};
|
|
3527
|
+
/**
|
|
3528
|
+
* 基本変数と操作固有変数を結合した実行時変数マップを作成します。
|
|
3529
|
+
*
|
|
3530
|
+
* @param vars 操作固有の変数です。
|
|
3531
|
+
*
|
|
3532
|
+
* @returns 結合した変数マップを返します。
|
|
3533
|
+
*/
|
|
3534
|
+
function _createOperationVars(vars) {
|
|
3535
|
+
const map = new Map(_classPrivateFieldGet2(_baseVars, this));
|
|
3536
|
+
if (vars) for (const [k, v] of vars) map.set(k, v);
|
|
3537
|
+
return map;
|
|
3538
|
+
}
|
|
3539
|
+
/**
|
|
3540
|
+
* 操作内で共有される変数ストアを作成します。
|
|
3541
|
+
*
|
|
3542
|
+
* 同一操作内の全コンテキスト (`use`/`encode`/`decode`/ ストレージ) で共有され、下流の `set` が上流の `await next()` 後の `get` に見えます。
|
|
3543
|
+
*
|
|
3544
|
+
* @param vars 操作固有の変数です。
|
|
3545
|
+
*
|
|
3546
|
+
* @returns 共有ストアを返します。
|
|
3547
|
+
*/
|
|
3548
|
+
function _createOperationStore(vars) {
|
|
3549
|
+
return createVariablesStore([..._classPrivateFieldGet2(_baseVars, this), ...vars ?? []]);
|
|
3550
|
+
}
|
|
3551
|
+
/**
|
|
3552
|
+
* キーに対応する値のスキーマ情報を解決します。
|
|
3553
|
+
*
|
|
3554
|
+
* @param key 解決するキーです。
|
|
3555
|
+
*
|
|
3556
|
+
* @returns 対応するスキーマ情報を返します。スキーマ未設定または対応する定義がない場合は `undefined` を返します。
|
|
3557
|
+
*/
|
|
3558
|
+
function _resolveValueSchema(key) {
|
|
3559
|
+
return _classPrivateFieldGet2(_valueSchemaResolver$1, this)?.resolve(key);
|
|
3560
|
+
}
|
|
3561
|
+
/**
|
|
3562
|
+
* すべての宛先で読み取りに失敗したときのエラーを組み立てます。
|
|
3563
|
+
*
|
|
3564
|
+
* @param key 読み取ったキーです。
|
|
3565
|
+
* @param errors 収集した失敗です。
|
|
3566
|
+
*
|
|
3567
|
+
* @returns `KeyNotFoundError` を返します。
|
|
3568
|
+
*/
|
|
3569
|
+
function _notFound(key, errors) {
|
|
3570
|
+
const args = { key };
|
|
3571
|
+
switch (errors.length) {
|
|
3572
|
+
case 0: break;
|
|
3573
|
+
case 1: {
|
|
3574
|
+
const [firstError] = errors;
|
|
3575
|
+
if (firstError !== void 0) args.cause = firstError.reason;
|
|
3576
|
+
break;
|
|
3577
|
+
}
|
|
3578
|
+
default: args.cause = new PluginOperationAggregateError({
|
|
3579
|
+
action: "read",
|
|
3580
|
+
errors,
|
|
3581
|
+
plugin: "storage"
|
|
3582
|
+
});
|
|
3583
|
+
}
|
|
3584
|
+
return new KeyNotFoundError(args);
|
|
3585
|
+
}
|
|
3586
|
+
async function _close(operationVars, signal, con, progress) {
|
|
3587
|
+
try {
|
|
3588
|
+
var _usingCtx3 = _usingCtx();
|
|
3589
|
+
_usingCtx3.u(await asyncmux(this, signal));
|
|
3590
|
+
if (_classPrivateFieldGet2(_con, this) !== con) throw new UniKvsIsNotOpenError();
|
|
3591
|
+
const { io } = _classPrivateFieldGet2(_con, this);
|
|
3592
|
+
_usingCtx3.u(await io.lock({ signal }));
|
|
3593
|
+
const closeFns = [];
|
|
3594
|
+
for (const [index, leaf] of _classPrivateFieldGet2(_pipeline, this).leaves.entries()) {
|
|
3595
|
+
const createContext = () => new CloseContext({
|
|
3596
|
+
vars: new Map(operationVars).entries(),
|
|
3597
|
+
signal
|
|
3598
|
+
});
|
|
3599
|
+
const createRetryContext = () => new CloseContext({
|
|
3600
|
+
vars: new Map(operationVars).entries(),
|
|
3601
|
+
signal: AbortSignal.timeout(1e4)
|
|
3602
|
+
});
|
|
3603
|
+
closeFns.push([
|
|
3604
|
+
() => leaf.storage.close(createContext()),
|
|
3605
|
+
() => leaf.storage.retryClose(createRetryContext()),
|
|
3606
|
+
"storage",
|
|
3607
|
+
leaf.name,
|
|
3608
|
+
index
|
|
3609
|
+
]);
|
|
3610
|
+
}
|
|
3611
|
+
for (const [index, plugin] of _classPrivateFieldGet2(_pipeline, this).middlewares.entries()) {
|
|
3612
|
+
const createContext = () => new CloseContext({
|
|
3613
|
+
vars: new Map(operationVars).entries(),
|
|
3614
|
+
signal
|
|
3615
|
+
});
|
|
3616
|
+
const createRetryContext = () => new CloseContext({
|
|
3617
|
+
vars: new Map(operationVars).entries(),
|
|
3618
|
+
signal: AbortSignal.timeout(1e4)
|
|
3619
|
+
});
|
|
3620
|
+
closeFns.push([
|
|
3621
|
+
() => plugin.close(createContext()),
|
|
3622
|
+
() => plugin.retryClose(createRetryContext()),
|
|
3623
|
+
"middleware",
|
|
3624
|
+
plugin.name,
|
|
3625
|
+
index
|
|
3626
|
+
]);
|
|
3627
|
+
}
|
|
3628
|
+
progress.pluginsStarted = true;
|
|
3629
|
+
const errors = [];
|
|
3630
|
+
const retries = [];
|
|
3631
|
+
await Promise.all(closeFns.map(async ([f, retry, plugin, name, index]) => {
|
|
3632
|
+
try {
|
|
3633
|
+
await f();
|
|
3634
|
+
} catch (ex) {
|
|
3635
|
+
errors.push({
|
|
3636
|
+
name,
|
|
3637
|
+
index,
|
|
3638
|
+
plugin,
|
|
3639
|
+
reason: ex
|
|
3640
|
+
});
|
|
3641
|
+
retries.push(retry);
|
|
3642
|
+
}
|
|
3643
|
+
}));
|
|
3644
|
+
if (errors.length > 0) {
|
|
3645
|
+
await Promise.all(retries.map(async (f) => {
|
|
3646
|
+
try {
|
|
3647
|
+
await f();
|
|
3648
|
+
} catch (ex) {
|
|
3649
|
+
logger.error`Failed to retry closing a plugin: ${ex}`;
|
|
3650
|
+
}
|
|
3651
|
+
}));
|
|
3652
|
+
throw new PluginOperationAggregateError({
|
|
3653
|
+
action: "close",
|
|
3654
|
+
errors
|
|
3655
|
+
});
|
|
3656
|
+
}
|
|
3657
|
+
_classPrivateFieldSet2(_con, this, null);
|
|
3658
|
+
} catch (_) {
|
|
3659
|
+
_usingCtx3.e = _;
|
|
3660
|
+
} finally {
|
|
3661
|
+
_usingCtx3.d();
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
/**
|
|
3665
|
+
* 書き込み失敗の集約と、成功した宛先への通知を行います。
|
|
3666
|
+
*
|
|
3667
|
+
* @param targets 書き込みを試みた対象です。
|
|
3668
|
+
* @param failed 失敗した葉の集合です。
|
|
3669
|
+
* @param errors 集約する失敗です。
|
|
3670
|
+
* @param signal 中断シグナルです。
|
|
3671
|
+
*/
|
|
3672
|
+
async function _finishWrites(targets, store, failed, errors, signal) {
|
|
3673
|
+
if (errors.length === 0) return;
|
|
3674
|
+
const error = new PluginOperationAggregateError({
|
|
3675
|
+
action: "write",
|
|
3676
|
+
errors,
|
|
3677
|
+
plugin: "storage"
|
|
3678
|
+
});
|
|
3679
|
+
const notifyErrors = [];
|
|
3680
|
+
await Promise.all(targets.map(async (target) => {
|
|
3681
|
+
if (failed.has(target.leaf)) return;
|
|
3682
|
+
try {
|
|
3683
|
+
const c = new SetContext({
|
|
3684
|
+
key: target.key,
|
|
3685
|
+
store,
|
|
3686
|
+
signal
|
|
3687
|
+
});
|
|
3688
|
+
await target.leaf.storage.onOtherWriteError(c, error);
|
|
3689
|
+
} catch (ex) {
|
|
3690
|
+
notifyErrors.push(ex);
|
|
3691
|
+
}
|
|
3692
|
+
}));
|
|
3693
|
+
if (notifyErrors.length > 0) logger.error(new AggregateError(notifyErrors, "Failed to handle error"));
|
|
3694
|
+
throw error;
|
|
3695
|
+
}
|
|
3696
|
+
/**
|
|
3697
|
+
* ミドルウェアの `use` をオニオン実行し、失敗時は集約して投げます。
|
|
3698
|
+
*
|
|
3699
|
+
* 同一コンテキストオブジェクトを全ミドルウェアで共有し、`next` で下流をネスト実行するため、下流の `set` が上流の `await next()` 後の `get` に見えます。
|
|
3700
|
+
* `encode`/`decode` と同じく `next()` の呼び出し規約を検証し、違反したときは操作を実行せず失敗させます (fail-close)。
|
|
3701
|
+
* いずれかのミドルウェアが投げたときは即時に確定し、後段は実行しません (fail-fast)。
|
|
3702
|
+
* 失敗は集約エラー (単一件) として投げます。
|
|
3703
|
+
*
|
|
3704
|
+
* @param action 集約エラーに付与する操作名です。
|
|
3705
|
+
* @param c 共有の `use` コンテキストです。
|
|
3706
|
+
*/
|
|
3707
|
+
async function _use(action, c) {
|
|
3708
|
+
throwIfAborted(c.signal);
|
|
3709
|
+
const middlewares = _classPrivateFieldGet2(_pipeline, this).middlewares;
|
|
3710
|
+
const dispatch = async (index) => {
|
|
3711
|
+
const maybeMiddleware = middlewares[index];
|
|
3712
|
+
if (maybeMiddleware === void 0) return;
|
|
3713
|
+
const middleware = maybeMiddleware;
|
|
3714
|
+
let nextCalled = false;
|
|
3715
|
+
let nextSettled = false;
|
|
3716
|
+
let downstreamError;
|
|
3717
|
+
let hasDownstreamError = false;
|
|
3718
|
+
function next() {
|
|
3719
|
+
if (nextCalled) {
|
|
3720
|
+
const rejection = Promise.reject(new MiddlewareNextCalledMultipleTimesError({
|
|
3721
|
+
name: middleware.name,
|
|
3722
|
+
operation: "use"
|
|
3723
|
+
}));
|
|
3724
|
+
rejection.catch(() => {});
|
|
3725
|
+
return rejection;
|
|
3726
|
+
}
|
|
3727
|
+
nextCalled = true;
|
|
3728
|
+
const promise = Promise.try(async () => {
|
|
3729
|
+
try {
|
|
3730
|
+
await dispatch(index + 1);
|
|
3731
|
+
} catch (ex) {
|
|
3732
|
+
downstreamError = ex;
|
|
3733
|
+
hasDownstreamError = true;
|
|
3734
|
+
throw ex;
|
|
3735
|
+
} finally {
|
|
3736
|
+
nextSettled = true;
|
|
3737
|
+
}
|
|
3738
|
+
});
|
|
3739
|
+
promise.catch(() => {});
|
|
3740
|
+
return promise;
|
|
3741
|
+
}
|
|
3742
|
+
try {
|
|
3743
|
+
await middleware.use(c, next);
|
|
3744
|
+
throwIfAborted(c.signal);
|
|
3745
|
+
if (!nextCalled) throw new MiddlewareNextNotCalledError({
|
|
3746
|
+
name: middleware.name,
|
|
3747
|
+
operation: "use"
|
|
3748
|
+
});
|
|
3749
|
+
if (!nextSettled) throw new MiddlewareNextNotAwaitedError({
|
|
3750
|
+
name: middleware.name,
|
|
3751
|
+
operation: "use"
|
|
3752
|
+
});
|
|
3753
|
+
} catch (ex) {
|
|
3754
|
+
if (c.signal.aborted && ex === c.signal.reason) throw ex;
|
|
3755
|
+
if (ex instanceof MiddlewareNextNotCalledError || ex instanceof MiddlewareNextNotAwaitedError || ex instanceof MiddlewareNextCalledMultipleTimesError) throw ex;
|
|
3756
|
+
if (hasDownstreamError && ex === downstreamError) throw ex;
|
|
3757
|
+
throw new PluginOperationAggregateError({
|
|
3758
|
+
action,
|
|
3759
|
+
errors: [{
|
|
3760
|
+
name: middleware.name,
|
|
3761
|
+
index,
|
|
3762
|
+
reason: ex
|
|
3763
|
+
}],
|
|
3764
|
+
plugin: "middleware"
|
|
3765
|
+
});
|
|
3766
|
+
}
|
|
3767
|
+
};
|
|
3768
|
+
await dispatch(0);
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* プレーン値の並列書き込みを行います。
|
|
3772
|
+
*
|
|
3773
|
+
* @param io 多重化インスタンスです。
|
|
3774
|
+
* @param signal 中断シグナルです。
|
|
3775
|
+
* @param key 書き込みキーです。
|
|
3776
|
+
* @param store 操作内で共有される変数ストアです。
|
|
3777
|
+
* @param value 書き込む値です.
|
|
3778
|
+
*/
|
|
3779
|
+
async function _setPlain(io, signal, key, store, value) {
|
|
3780
|
+
try {
|
|
3781
|
+
var _usingCtx4 = _usingCtx();
|
|
3782
|
+
const targets = await _classPrivateFieldGet2(_pipeline, this).encode({
|
|
3783
|
+
key,
|
|
3784
|
+
store,
|
|
3785
|
+
signal
|
|
3786
|
+
}, value);
|
|
3787
|
+
_usingCtx4.u(await io.lock({
|
|
3788
|
+
key,
|
|
3789
|
+
signal
|
|
3790
|
+
}));
|
|
3791
|
+
const errors = [];
|
|
3792
|
+
const failed = /* @__PURE__ */ new Set();
|
|
3793
|
+
await Promise.all(targets.map(async (target) => {
|
|
3794
|
+
try {
|
|
3795
|
+
const c = new SetContext({
|
|
3796
|
+
key: target.key,
|
|
3797
|
+
store,
|
|
3798
|
+
signal
|
|
3799
|
+
});
|
|
3800
|
+
await target.leaf.storage.write(c, target.data);
|
|
3801
|
+
} catch (ex) {
|
|
3802
|
+
errors.push({
|
|
3803
|
+
name: target.leaf.name,
|
|
3804
|
+
index: target.leaf.index,
|
|
3805
|
+
reason: ex
|
|
3806
|
+
});
|
|
3807
|
+
failed.add(target.leaf);
|
|
3808
|
+
}
|
|
3809
|
+
}));
|
|
3810
|
+
await _assertClassBrand(_UniKvs_brand, this, _finishWrites).call(this, targets, store, failed, errors, signal);
|
|
3811
|
+
} catch (_) {
|
|
3812
|
+
_usingCtx4.e = _;
|
|
3813
|
+
} finally {
|
|
3814
|
+
_usingCtx4.d();
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
/**
|
|
3818
|
+
* ストリーム値の並列書き込みを行います。
|
|
3819
|
+
*
|
|
3820
|
+
* @param io 多重化インスタンスです。
|
|
3821
|
+
* @param signal 中断シグナルです。
|
|
3822
|
+
* @param key 書き込みキーです。
|
|
3823
|
+
* @param store 操作内で共有される変数ストアです。
|
|
3824
|
+
* @param value 書き込むストリームです。
|
|
3825
|
+
*/
|
|
3826
|
+
async function _setStream(io, signal, key, store, value) {
|
|
3827
|
+
try {
|
|
3828
|
+
var _usingCtx5 = _usingCtx();
|
|
3829
|
+
const streams = /* @__PURE__ */ new Set([value]);
|
|
3830
|
+
let tree;
|
|
3831
|
+
try {
|
|
3832
|
+
tree = await _classPrivateFieldGet2(_pipeline, this).buildEncodeTree({
|
|
3833
|
+
key,
|
|
3834
|
+
store,
|
|
3835
|
+
signal
|
|
3836
|
+
}, value, streams);
|
|
3837
|
+
} catch (ex) {
|
|
3838
|
+
await cancelStreams(streams, ex);
|
|
3839
|
+
throw ex;
|
|
3840
|
+
}
|
|
3841
|
+
_usingCtx5.u(await io.lock({
|
|
3842
|
+
key,
|
|
3843
|
+
signal
|
|
3844
|
+
}).catch(async (ex) => {
|
|
3845
|
+
await cancelStreams(streams, ex);
|
|
3846
|
+
throw ex;
|
|
3847
|
+
}));
|
|
3848
|
+
const errors = [];
|
|
3849
|
+
const failed = /* @__PURE__ */ new Set();
|
|
3850
|
+
await Promise.all(tree.targets.map(async (target) => {
|
|
3851
|
+
try {
|
|
3852
|
+
const c = new SetContext({
|
|
3853
|
+
key: target.key,
|
|
3854
|
+
store,
|
|
3855
|
+
signal
|
|
3856
|
+
});
|
|
3857
|
+
const w = await target.leaf.storage.getWritable(c);
|
|
3858
|
+
await target.stream.pipeTo(w, { signal });
|
|
3859
|
+
} catch (ex) {
|
|
3860
|
+
try {
|
|
3861
|
+
await target.stream.cancel(ex);
|
|
3862
|
+
} catch {}
|
|
3863
|
+
errors.push({
|
|
3864
|
+
name: target.leaf.name,
|
|
3865
|
+
index: target.leaf.index,
|
|
3866
|
+
reason: ex
|
|
3867
|
+
});
|
|
3868
|
+
failed.add(target.leaf);
|
|
3869
|
+
}
|
|
3870
|
+
}));
|
|
3871
|
+
await _assertClassBrand(_UniKvs_brand, this, _finishWrites).call(this, tree.targets, store, failed, errors, signal);
|
|
3872
|
+
} catch (_) {
|
|
3873
|
+
_usingCtx5.e = _;
|
|
3874
|
+
} finally {
|
|
3875
|
+
_usingCtx5.d();
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
/**
|
|
3879
|
+
* 読み取り元のチェーン全体を逆順にデコードし、書き戻し対象向けに再エンコードして書き込みます。
|
|
3880
|
+
*
|
|
3881
|
+
* @param data 読み取ったデータです。
|
|
3882
|
+
* @param hit 読み取り元の葉です。
|
|
3883
|
+
* @param missing 読み取りに失敗または不在だった葉です。
|
|
3884
|
+
* @param store 操作内で共有される変数ストアです。
|
|
3885
|
+
* @param key キーです。
|
|
3886
|
+
* @param signal 中断シグナルです。
|
|
3887
|
+
* @param throwOnRepairDenied 書き戻し拒否をエラーとして投げるかどうかです。
|
|
3888
|
+
*
|
|
3889
|
+
* @returns デコード済みの原データを返します。
|
|
3890
|
+
*/
|
|
3891
|
+
async function _repairPlain(data, hit, missing, store, key, signal, throwOnRepairDenied) {
|
|
3892
|
+
const raw = await _classPrivateFieldGet2(_pipeline, this).decode(hit.leaf, {
|
|
3893
|
+
key,
|
|
3894
|
+
store,
|
|
3895
|
+
signal
|
|
3896
|
+
}, data);
|
|
3897
|
+
await _classPrivateFieldGet2(_pipeline, this).repair({
|
|
3898
|
+
key,
|
|
3899
|
+
store,
|
|
3900
|
+
signal
|
|
3901
|
+
}, missing, throwOnRepairDenied, raw, async (leaf, writeKey, input) => {
|
|
3902
|
+
const c = new SetContext({
|
|
3903
|
+
key: writeKey,
|
|
3904
|
+
store,
|
|
3905
|
+
signal
|
|
3906
|
+
});
|
|
3907
|
+
await leaf.storage.write(c, input);
|
|
3908
|
+
});
|
|
3909
|
+
throwIfAborted(signal);
|
|
3910
|
+
return raw;
|
|
3911
|
+
}
|
|
3912
|
+
//#endregion
|
|
3913
|
+
//#region ../src/unikvs-builder.ts
|
|
3914
|
+
/**
|
|
3915
|
+
* 値が Valibot のスキーマであるかどうかを判定します。
|
|
3916
|
+
*/
|
|
3917
|
+
function isGenericSchema(input) {
|
|
3918
|
+
return typeof input === "object" && input !== null && "~run" in input && typeof input["~run"] === "function";
|
|
3919
|
+
}
|
|
3920
|
+
/**
|
|
3921
|
+
* 値がスキーマ情報であるかどうかを判定します。
|
|
3922
|
+
*/
|
|
3923
|
+
function isValueSchemaInfo(input) {
|
|
3924
|
+
return typeof input === "object" && input !== null && VALUE_SCHEMA_BRAND in input && input[VALUE_SCHEMA_BRAND] === true;
|
|
3925
|
+
}
|
|
3926
|
+
const UniKvsBuilderOptionsSchema = object({
|
|
3927
|
+
/**
|
|
3928
|
+
* キーと値のスキーマ定義です。
|
|
3929
|
+
*/
|
|
3930
|
+
schema: optional(union([array(tuple([custom(isGenericSchema), custom(isValueSchemaInfo)])), record(string(), custom(isValueSchemaInfo))])),
|
|
3931
|
+
/**
|
|
3932
|
+
* 基本となる実行時変数です。
|
|
3933
|
+
*/
|
|
3934
|
+
vars: optional(VariablesInitSchema)
|
|
3935
|
+
});
|
|
3936
|
+
const UniKvsBuilderArgsSchema = tuple([optional(UniKvsBuilderOptionsSchema)]);
|
|
3937
|
+
var _destinations = /* @__PURE__ */ new WeakMap();
|
|
3938
|
+
var _middlewares = /* @__PURE__ */ new WeakMap();
|
|
3939
|
+
var _valueSchemaResolver = /* @__PURE__ */ new WeakMap();
|
|
3940
|
+
var _vars = /* @__PURE__ */ new WeakMap();
|
|
3941
|
+
/**
|
|
3942
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#builder)
|
|
3943
|
+
*/
|
|
3944
|
+
var UniKvsBuilder = class {
|
|
3945
|
+
constructor(...args) {
|
|
3946
|
+
_classPrivateFieldInitSpec(this, _destinations, void 0);
|
|
3947
|
+
_classPrivateFieldInitSpec(this, _middlewares, void 0);
|
|
3948
|
+
_classPrivateFieldInitSpec(this, _valueSchemaResolver, void 0);
|
|
3949
|
+
_classPrivateFieldInitSpec(this, _vars, void 0);
|
|
3950
|
+
const [options = {}] = parseInput(UniKvsBuilderArgsSchema, args);
|
|
3951
|
+
const { vars, schema } = options;
|
|
3952
|
+
_classPrivateFieldSet2(_destinations, this, []);
|
|
3953
|
+
_classPrivateFieldSet2(_middlewares, this, []);
|
|
3954
|
+
_classPrivateFieldSet2(_valueSchemaResolver, this, null);
|
|
3955
|
+
_classPrivateFieldSet2(_vars, this, new Map(vars));
|
|
3956
|
+
if (schema) _classPrivateFieldSet2(_valueSchemaResolver, this, createValueSchemaResolver(schema));
|
|
3957
|
+
}
|
|
3958
|
+
fork(branch) {
|
|
3959
|
+
appendForkDestinations(_classPrivateFieldGet2(_destinations, this), _classPrivateFieldGet2(_middlewares, this), branch);
|
|
3960
|
+
return this;
|
|
3961
|
+
}
|
|
3962
|
+
use(middleware) {
|
|
3963
|
+
_classPrivateFieldGet2(_middlewares, this).push(UniKvsMiddleware.from(middleware));
|
|
3964
|
+
return this;
|
|
3965
|
+
}
|
|
3966
|
+
persist(storage) {
|
|
3967
|
+
_classPrivateFieldGet2(_destinations, this).push({
|
|
3968
|
+
storage: UniKvsStorage.from(storage),
|
|
3969
|
+
middlewares: [..._classPrivateFieldGet2(_middlewares, this)]
|
|
3970
|
+
});
|
|
3971
|
+
return this;
|
|
3972
|
+
}
|
|
3973
|
+
setVars(...args) {
|
|
3974
|
+
const [vars] = parseInput(VariablesArgsSchema, args);
|
|
3975
|
+
_classPrivateFieldGet2(_vars, this).clear();
|
|
3976
|
+
for (const [name, value] of vars) _classPrivateFieldGet2(_vars, this).set(name, value);
|
|
3977
|
+
return this;
|
|
3978
|
+
}
|
|
3979
|
+
assignVars(...args) {
|
|
3980
|
+
const [vars] = parseInput(VariablesArgsSchema, args);
|
|
3981
|
+
const target = _classPrivateFieldGet2(_vars, this);
|
|
3982
|
+
const source = vars;
|
|
3983
|
+
for (const [name, value] of source) target.set(name, value);
|
|
3984
|
+
return this;
|
|
3985
|
+
}
|
|
3986
|
+
defaultsVars(...args) {
|
|
3987
|
+
const [vars] = parseInput(VariablesArgsSchema, args);
|
|
3988
|
+
const target = new Map(vars);
|
|
3989
|
+
const source = _classPrivateFieldGet2(_vars, this);
|
|
3990
|
+
for (const [name, value] of source) target.set(name, value);
|
|
3991
|
+
this.setVars(target);
|
|
3992
|
+
return this;
|
|
3993
|
+
}
|
|
3994
|
+
build() {
|
|
3995
|
+
if (_classPrivateFieldGet2(_destinations, this).length === 0) throw new MissingStorageError();
|
|
3996
|
+
return new UniKvs([..._classPrivateFieldGet2(_vars, this).entries()], PipelineGraph.compile([..._classPrivateFieldGet2(_destinations, this)]), _classPrivateFieldGet2(_valueSchemaResolver, this));
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3999
|
+
//#endregion
|
|
4000
|
+
//#region ../src/value-schemas.ts
|
|
4001
|
+
/**
|
|
4002
|
+
* スキーマ情報を内部オブジェクトとして生成します。
|
|
4003
|
+
*/
|
|
4004
|
+
function createValueSchemaDescriptor(kind, schema) {
|
|
4005
|
+
return {
|
|
4006
|
+
[VALUE_SCHEMA_BRAND]: true,
|
|
4007
|
+
kind,
|
|
4008
|
+
schema
|
|
4009
|
+
};
|
|
4010
|
+
}
|
|
4011
|
+
/**
|
|
4012
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#value-types)
|
|
4013
|
+
*/
|
|
4014
|
+
function PlainValue(schema) {
|
|
4015
|
+
return createValueSchemaDescriptor("plain", schema);
|
|
4016
|
+
}
|
|
4017
|
+
/**
|
|
4018
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#value-types)
|
|
4019
|
+
*/
|
|
4020
|
+
function StreamValue(schema) {
|
|
4021
|
+
return createValueSchemaDescriptor("stream", schema);
|
|
4022
|
+
}
|
|
4023
|
+
/**
|
|
4024
|
+
* [API Reference](https://tai-kun.github.io/unikvs/packages/unikvs#value-types)
|
|
4025
|
+
*/
|
|
4026
|
+
function Value(schema) {
|
|
4027
|
+
return createValueSchemaDescriptor("any", schema);
|
|
4028
|
+
}
|
|
4029
|
+
//#endregion
|
|
4030
|
+
export { UniKvsBranch as Branch, UniKvsBranch, UniKvsBuilder as Builder, UniKvsBuilder, InvalidInputError, InvalidOutputError, InvalidUsageErrorBase, KeyNotFoundError, MiddlewareDestinationFrozenError, MiddlewareDestinationMissingError, MiddlewareIsNotOpenError, MiddlewareNextCalledMultipleTimesError, MiddlewareNextNotAwaitedError, MiddlewareNextNotCalledError, MissingStorageError, MultipartWriteNotSupportedError, PlainValue, PluginOperationAggregateError, ReadableStreamNotSupportedError, StorageIsNotOpenError, StreamDecodingNotSupportedError, StreamEncodingNotSupportedError, StreamValue, UniKvs, UniKvsIsNotOpenError, UniKvsIsOpenError, Value, WritableStreamNotSupportedError };
|
|
4031
|
+
|
|
4032
|
+
//# sourceMappingURL=index.js.map
|