rockbed 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -0
- package/dist/assert/index.d.ts +6 -0
- package/dist/assert/index.js +27 -0
- package/dist/assert/index.js.map +1 -0
- package/dist/async/index.d.ts +105 -0
- package/dist/async/index.js +380 -0
- package/dist/async/index.js.map +1 -0
- package/dist/dispose/index.d.ts +47 -0
- package/dist/dispose/index.js +166 -0
- package/dist/dispose/index.js.map +1 -0
- package/dist/dispose-base-CAeXDpjg.d.ts +6 -0
- package/dist/error/index.d.ts +46 -0
- package/dist/error/index.js +150 -0
- package/dist/error/index.js.map +1 -0
- package/dist/error-base-BWuBlS2k.d.ts +28 -0
- package/dist/event/index.d.ts +57 -0
- package/dist/event/index.js +167 -0
- package/dist/event/index.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +989 -0
- package/dist/index.js.map +1 -0
- package/dist/json/index.d.ts +4 -0
- package/dist/json/index.js +20 -0
- package/dist/json/index.js.map +1 -0
- package/dist/lock/index.d.ts +106 -0
- package/dist/lock/index.js +404 -0
- package/dist/lock/index.js.map +1 -0
- package/dist/response/index.d.ts +17 -0
- package/dist/response/index.js +19 -0
- package/dist/response/index.js.map +1 -0
- package/package.json +80 -0
- package/src/assert/assert.ts +24 -0
- package/src/assert/index.ts +2 -0
- package/src/async/barrier.ts +47 -0
- package/src/async/index.ts +8 -0
- package/src/async/promise.ts +316 -0
- package/src/async/wait.ts +7 -0
- package/src/dispose/disposable-store.ts +68 -0
- package/src/dispose/disposable-t.ts +85 -0
- package/src/dispose/disposable-utils.ts +13 -0
- package/src/dispose/dispose-base.ts +9 -0
- package/src/dispose/index.ts +8 -0
- package/src/dispose/logger.ts +41 -0
- package/src/error/error-base.ts +39 -0
- package/src/error/error-code.ts +48 -0
- package/src/error/error-const.ts +16 -0
- package/src/error/error-or.ts +2 -0
- package/src/error/error-t.ts +93 -0
- package/src/error/index.ts +5 -0
- package/src/event/emitter.ts +193 -0
- package/src/event/index.ts +10 -0
- package/src/index.ts +8 -0
- package/src/json/index.ts +1 -0
- package/src/json/json.ts +15 -0
- package/src/lock/README.md +11 -0
- package/src/lock/capability.ts +89 -0
- package/src/lock/index.ts +2 -0
- package/src/lock/semaphore.ts +21 -0
- package/src/lock/shared-mutex.ts +256 -0
- package/src/response/index.ts +1 -0
- package/src/response/response.ts +27 -0
- package/tsconfig.json +23 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,989 @@
|
|
|
1
|
+
// src/assert/assert.ts
|
|
2
|
+
function abort(reason) {
|
|
3
|
+
throw new Error(`lvAssert(${reason})`);
|
|
4
|
+
}
|
|
5
|
+
function lvAssert(expr, reason) {
|
|
6
|
+
if (!expr) {
|
|
7
|
+
abort(reason ?? "#expr is false");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function lvAssertNotHere(reason) {
|
|
11
|
+
abort(reason ?? "unreachable code flow");
|
|
12
|
+
}
|
|
13
|
+
function lvAssertNever(member, message = "Illegal value:") {
|
|
14
|
+
abort(`${message}: ${member}`);
|
|
15
|
+
}
|
|
16
|
+
function lvAssertNotNil(val, reason) {
|
|
17
|
+
if (val === null || val === void 0) {
|
|
18
|
+
abort(reason ?? "#val is nil");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/error/error-base.ts
|
|
23
|
+
var ILvErrorRef = /* @__PURE__ */ Symbol.for("rockbed.ILvErrorRef");
|
|
24
|
+
var ILvRealErrorRef = /* @__PURE__ */ Symbol.for("rockbed.ILvRealErrorRef");
|
|
25
|
+
var ILvValueRef = /* @__PURE__ */ Symbol.for("rockbed.ILvValueRef");
|
|
26
|
+
var ILvErrorOr = /* @__PURE__ */ Symbol.for("rockbed.ILvErrorOr");
|
|
27
|
+
|
|
28
|
+
// src/error/error-t.ts
|
|
29
|
+
var lvErrorRefSymbol = /* @__PURE__ */ Symbol("lvErrorRef");
|
|
30
|
+
function makeOk() {
|
|
31
|
+
return {
|
|
32
|
+
ok: true,
|
|
33
|
+
value: null,
|
|
34
|
+
pair() {
|
|
35
|
+
return [null, null];
|
|
36
|
+
},
|
|
37
|
+
code: 0,
|
|
38
|
+
msg: "",
|
|
39
|
+
...{ [lvErrorRefSymbol]: true }
|
|
40
|
+
// 跳过类型检测
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function makeOkWith(value) {
|
|
44
|
+
return {
|
|
45
|
+
ok: true,
|
|
46
|
+
value,
|
|
47
|
+
pair() {
|
|
48
|
+
return [null, value];
|
|
49
|
+
},
|
|
50
|
+
code: 0,
|
|
51
|
+
msg: "",
|
|
52
|
+
...{ [lvErrorRefSymbol]: true }
|
|
53
|
+
// 跳过类型检测
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function printCause(cause) {
|
|
57
|
+
if (cause === void 0) {
|
|
58
|
+
return "";
|
|
59
|
+
} else if (cause instanceof Error) {
|
|
60
|
+
return `
|
|
61
|
+
caused by [jsError]${cause.name}-${cause.message}`;
|
|
62
|
+
} else {
|
|
63
|
+
return `
|
|
64
|
+
caused by [${cause.code}]${cause.msg}${cause.ok ? "" : printCause(cause.cause)}`;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function internalMakeError(code, msg, cause, errorInfo) {
|
|
68
|
+
const errorRef = {
|
|
69
|
+
ok: false,
|
|
70
|
+
code,
|
|
71
|
+
msg,
|
|
72
|
+
cause,
|
|
73
|
+
errorInfo,
|
|
74
|
+
toString() {
|
|
75
|
+
return `[${code}]${msg}.${cause ? printCause(cause) : ""}`;
|
|
76
|
+
},
|
|
77
|
+
pair() {
|
|
78
|
+
return [errorRef, null];
|
|
79
|
+
},
|
|
80
|
+
...{ [lvErrorRefSymbol]: true }
|
|
81
|
+
// 跳过类型检测
|
|
82
|
+
};
|
|
83
|
+
return errorRef;
|
|
84
|
+
}
|
|
85
|
+
function makeError(code, msg, errorInfo) {
|
|
86
|
+
return internalMakeError(code, msg, void 0, errorInfo);
|
|
87
|
+
}
|
|
88
|
+
function makeErrorBy(code, msg, cause, errorInfo) {
|
|
89
|
+
return internalMakeError(code, msg, cause, errorInfo);
|
|
90
|
+
}
|
|
91
|
+
function isLvErrorRef(val) {
|
|
92
|
+
return typeof val === "object" && val !== null && lvErrorRefSymbol in val;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/error/error-const.ts
|
|
96
|
+
function lvErrorConst(code, msg) {
|
|
97
|
+
return (rewrite) => {
|
|
98
|
+
if (!rewrite) {
|
|
99
|
+
return makeError(code, msg);
|
|
100
|
+
}
|
|
101
|
+
if (typeof rewrite === "string") {
|
|
102
|
+
return makeError(code, rewrite);
|
|
103
|
+
}
|
|
104
|
+
return makeErrorBy(code, rewrite.message, rewrite);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/error/error-code.ts
|
|
109
|
+
var GenericError = /* @__PURE__ */ ((GenericError2) => {
|
|
110
|
+
GenericError2[GenericError2["Ok"] = 0] = "Ok";
|
|
111
|
+
GenericError2[GenericError2["Cancelled"] = 1] = "Cancelled";
|
|
112
|
+
GenericError2[GenericError2["TimedOut"] = 2] = "TimedOut";
|
|
113
|
+
GenericError2[GenericError2["PermissionDenied"] = 3] = "PermissionDenied";
|
|
114
|
+
GenericError2[GenericError2["AlreadyExists"] = 4] = "AlreadyExists";
|
|
115
|
+
GenericError2[GenericError2["NotSupported"] = 5] = "NotSupported";
|
|
116
|
+
GenericError2[GenericError2["ResourceUnavailable"] = 6] = "ResourceUnavailable";
|
|
117
|
+
GenericError2[GenericError2["OutOfRange"] = 7] = "OutOfRange";
|
|
118
|
+
GenericError2[GenericError2["InvalidArgument"] = 8] = "InvalidArgument";
|
|
119
|
+
GenericError2[GenericError2["NetworkFailed"] = 9] = "NetworkFailed";
|
|
120
|
+
GenericError2[GenericError2["Interrupted"] = 10] = "Interrupted";
|
|
121
|
+
GenericError2[GenericError2["ResultNil"] = 11] = "ResultNil";
|
|
122
|
+
return GenericError2;
|
|
123
|
+
})(GenericError || {});
|
|
124
|
+
var cancelledError = lvErrorConst(1 /* Cancelled */, "operation(s) cancelled.");
|
|
125
|
+
var timeoutError = lvErrorConst(2 /* TimedOut */, "operation(s) timed out.");
|
|
126
|
+
var permissionDeniedError = lvErrorConst(
|
|
127
|
+
3 /* PermissionDenied */,
|
|
128
|
+
"permission denied."
|
|
129
|
+
);
|
|
130
|
+
var alreadyExistsError = lvErrorConst(4 /* AlreadyExists */, "already exists.");
|
|
131
|
+
var notSupportedError = lvErrorConst(
|
|
132
|
+
5 /* NotSupported */,
|
|
133
|
+
"operation(s) not supported."
|
|
134
|
+
);
|
|
135
|
+
var resourceUnavailableError = lvErrorConst(
|
|
136
|
+
6 /* ResourceUnavailable */,
|
|
137
|
+
"resource is unavailable."
|
|
138
|
+
);
|
|
139
|
+
var outOfRangeError = lvErrorConst(7 /* OutOfRange */, "out of range.");
|
|
140
|
+
var invalidArgumentError = lvErrorConst(
|
|
141
|
+
8 /* InvalidArgument */,
|
|
142
|
+
"invalid arguments."
|
|
143
|
+
);
|
|
144
|
+
var networkFailedError = lvErrorConst(9 /* NetworkFailed */, "network failed.");
|
|
145
|
+
var interruptedError = lvErrorConst(10 /* Interrupted */, "interrupted.");
|
|
146
|
+
var resultNilError = lvErrorConst(11 /* ResultNil */, "result is nil.");
|
|
147
|
+
|
|
148
|
+
// src/dispose/dispose-base.ts
|
|
149
|
+
var EmptyDispose = Object.freeze({ dispose() {
|
|
150
|
+
} });
|
|
151
|
+
|
|
152
|
+
// src/dispose/logger.ts
|
|
153
|
+
var disposableLogger = null;
|
|
154
|
+
function setDisposableLogger(logger) {
|
|
155
|
+
disposableLogger = logger;
|
|
156
|
+
}
|
|
157
|
+
function makeDefaultLogger() {
|
|
158
|
+
return new class {
|
|
159
|
+
_dep = [];
|
|
160
|
+
branch(from, to) {
|
|
161
|
+
this._dep.push([from, to]);
|
|
162
|
+
}
|
|
163
|
+
end() {
|
|
164
|
+
}
|
|
165
|
+
}();
|
|
166
|
+
}
|
|
167
|
+
function BRANCH_DISPOSE(from, to) {
|
|
168
|
+
disposableLogger?.branch(from, to);
|
|
169
|
+
}
|
|
170
|
+
function disposeWithLog(x, logger = makeDefaultLogger()) {
|
|
171
|
+
setDisposableLogger(logger);
|
|
172
|
+
x.dispose();
|
|
173
|
+
logger.end();
|
|
174
|
+
setDisposableLogger(null);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/dispose/disposable-store.ts
|
|
178
|
+
var DisposableStore = class _DisposableStore {
|
|
179
|
+
static DISABLE_DISPOSED_WARNING = false;
|
|
180
|
+
_toDispose = /* @__PURE__ */ new Set();
|
|
181
|
+
_isDisposed = false;
|
|
182
|
+
get isDisposed() {
|
|
183
|
+
return this._isDisposed;
|
|
184
|
+
}
|
|
185
|
+
dispose() {
|
|
186
|
+
if (this._isDisposed) {
|
|
187
|
+
console.warn(new Error("DisposableStore has disposed.").stack);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
this._isDisposed = true;
|
|
191
|
+
this.clear();
|
|
192
|
+
}
|
|
193
|
+
clear() {
|
|
194
|
+
if (this._toDispose.size === 0) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
for (const disposable of this._toDispose) {
|
|
198
|
+
BRANCH_DISPOSE(this.constructor.name, disposable.constructor.name);
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
for (const disposable of this._toDispose) {
|
|
202
|
+
disposable.dispose();
|
|
203
|
+
}
|
|
204
|
+
} finally {
|
|
205
|
+
this._toDispose.clear();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
add(o) {
|
|
209
|
+
if (!o) {
|
|
210
|
+
return o;
|
|
211
|
+
}
|
|
212
|
+
if (o === this) {
|
|
213
|
+
throw new Error("Cannot register a disposable on itself.");
|
|
214
|
+
}
|
|
215
|
+
if (this._isDisposed) {
|
|
216
|
+
if (!_DisposableStore.DISABLE_DISPOSED_WARNING) {
|
|
217
|
+
console.warn(
|
|
218
|
+
new Error(
|
|
219
|
+
"Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!"
|
|
220
|
+
).stack
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
this._toDispose.add(o);
|
|
225
|
+
}
|
|
226
|
+
return o;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// src/dispose/disposable-t.ts
|
|
231
|
+
var Disposable = class {
|
|
232
|
+
_store = new DisposableStore();
|
|
233
|
+
// 销毁该节点和所有的子节点
|
|
234
|
+
dispose() {
|
|
235
|
+
BRANCH_DISPOSE(this.constructor.name, this._store.constructor.name);
|
|
236
|
+
this._store.dispose();
|
|
237
|
+
}
|
|
238
|
+
// 挂载子节点
|
|
239
|
+
_register(o) {
|
|
240
|
+
if (o === this) {
|
|
241
|
+
throw new Error("Cannot register a disposable on itself!");
|
|
242
|
+
}
|
|
243
|
+
return this._store.add(o);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
var MutableDisposable = class {
|
|
247
|
+
_value;
|
|
248
|
+
_isDisposed = false;
|
|
249
|
+
constructor(value) {
|
|
250
|
+
this.value = value;
|
|
251
|
+
}
|
|
252
|
+
get value() {
|
|
253
|
+
return this._isDisposed ? void 0 : this._value;
|
|
254
|
+
}
|
|
255
|
+
set value(value) {
|
|
256
|
+
if (this._isDisposed || value === this._value) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this._value?.dispose();
|
|
260
|
+
this._value = value;
|
|
261
|
+
}
|
|
262
|
+
clear() {
|
|
263
|
+
this.value = void 0;
|
|
264
|
+
}
|
|
265
|
+
dispose() {
|
|
266
|
+
this._isDisposed = true;
|
|
267
|
+
this._value?.dispose();
|
|
268
|
+
this._value = void 0;
|
|
269
|
+
}
|
|
270
|
+
release() {
|
|
271
|
+
const oldValue = this._value;
|
|
272
|
+
this._value = void 0;
|
|
273
|
+
return oldValue;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
var SafeDisposable = class {
|
|
277
|
+
_value = null;
|
|
278
|
+
constructor(value) {
|
|
279
|
+
this._value = value;
|
|
280
|
+
}
|
|
281
|
+
isEmpty() {
|
|
282
|
+
return this._value === null;
|
|
283
|
+
}
|
|
284
|
+
dispose() {
|
|
285
|
+
if (!this._value) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
this._value.dispose();
|
|
289
|
+
this._value = null;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// src/dispose/disposable-utils.ts
|
|
294
|
+
function makeSafeDisposable(fn) {
|
|
295
|
+
const disposable = new SafeDisposable({
|
|
296
|
+
dispose: fn
|
|
297
|
+
});
|
|
298
|
+
return disposable;
|
|
299
|
+
}
|
|
300
|
+
function makeEmptyDisposable() {
|
|
301
|
+
return EmptyDispose;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/async/promise.ts
|
|
305
|
+
var shortcutCancellationEvent = (callback, context) => {
|
|
306
|
+
const handle = setTimeout(callback.bind(context), 0);
|
|
307
|
+
return makeSafeDisposable(() => clearTimeout(handle));
|
|
308
|
+
};
|
|
309
|
+
var MutableToken = class {
|
|
310
|
+
_isCancelled = false;
|
|
311
|
+
_reason;
|
|
312
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
313
|
+
get isCancellationRequested() {
|
|
314
|
+
return this._isCancelled;
|
|
315
|
+
}
|
|
316
|
+
get reason() {
|
|
317
|
+
return this._reason;
|
|
318
|
+
}
|
|
319
|
+
onCancellationRequested(listener, thisArgs) {
|
|
320
|
+
if (this._isCancelled) {
|
|
321
|
+
return shortcutCancellationEvent(listener, thisArgs);
|
|
322
|
+
}
|
|
323
|
+
const wrappedListener = listener.bind(thisArgs);
|
|
324
|
+
this._listeners.add(wrappedListener);
|
|
325
|
+
return makeSafeDisposable(() => {
|
|
326
|
+
this._listeners.delete(wrappedListener);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
cancel(reason) {
|
|
330
|
+
if (this._isCancelled) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
this._reason = reason;
|
|
334
|
+
this._isCancelled = true;
|
|
335
|
+
for (const listener of this._listeners) {
|
|
336
|
+
listener();
|
|
337
|
+
}
|
|
338
|
+
this._listeners.clear();
|
|
339
|
+
}
|
|
340
|
+
dispose() {
|
|
341
|
+
this._listeners.clear();
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
var CancellationToken = class {
|
|
345
|
+
static None = Object.freeze({
|
|
346
|
+
isCancellationRequested: false,
|
|
347
|
+
onCancellationRequested: () => EmptyDispose
|
|
348
|
+
});
|
|
349
|
+
static Cancelled = Object.freeze({
|
|
350
|
+
isCancellationRequested: true,
|
|
351
|
+
onCancellationRequested: shortcutCancellationEvent
|
|
352
|
+
});
|
|
353
|
+
static Make(reason) {
|
|
354
|
+
return Object.freeze({
|
|
355
|
+
isCancellationRequested: true,
|
|
356
|
+
onCancellationRequested: shortcutCancellationEvent,
|
|
357
|
+
reason
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
var CancellationTokenSource = class {
|
|
362
|
+
_token;
|
|
363
|
+
_abortController;
|
|
364
|
+
get token() {
|
|
365
|
+
if (!this._token) {
|
|
366
|
+
this._token = new MutableToken();
|
|
367
|
+
}
|
|
368
|
+
return this._token;
|
|
369
|
+
}
|
|
370
|
+
get signal() {
|
|
371
|
+
if (!this._abortController) {
|
|
372
|
+
this._abortController = new AbortController();
|
|
373
|
+
}
|
|
374
|
+
if (this._token?.isCancellationRequested) {
|
|
375
|
+
this._abortController.abort(this._token.reason);
|
|
376
|
+
}
|
|
377
|
+
return this._abortController.signal;
|
|
378
|
+
}
|
|
379
|
+
cancel(reason) {
|
|
380
|
+
if (!this._token) {
|
|
381
|
+
this._token = reason === void 0 ? CancellationToken.Cancelled : CancellationToken.Make(reason);
|
|
382
|
+
} else if (this._token instanceof MutableToken) {
|
|
383
|
+
this._token.cancel(reason);
|
|
384
|
+
}
|
|
385
|
+
this._abortController?.abort(reason);
|
|
386
|
+
}
|
|
387
|
+
dispose(cancel = false) {
|
|
388
|
+
if (cancel) {
|
|
389
|
+
this.cancel();
|
|
390
|
+
}
|
|
391
|
+
if (!this._token) {
|
|
392
|
+
this._token = CancellationToken.None;
|
|
393
|
+
} else if (this._token instanceof MutableToken) {
|
|
394
|
+
this._token.dispose();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
function makeCancelablePromise(callback) {
|
|
399
|
+
const source = new CancellationTokenSource();
|
|
400
|
+
const thenable = callback(source.token);
|
|
401
|
+
const promise = new Promise((resolve, reject) => {
|
|
402
|
+
const subscription = source.token.onCancellationRequested(() => {
|
|
403
|
+
subscription.dispose();
|
|
404
|
+
source.dispose();
|
|
405
|
+
resolve(cancelledError());
|
|
406
|
+
});
|
|
407
|
+
Promise.resolve(thenable).then(
|
|
408
|
+
(value) => {
|
|
409
|
+
subscription.dispose();
|
|
410
|
+
source.dispose();
|
|
411
|
+
if (isLvErrorRef(value)) {
|
|
412
|
+
resolve(value);
|
|
413
|
+
} else {
|
|
414
|
+
resolve(makeOkWith(value));
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
(err) => {
|
|
418
|
+
subscription.dispose();
|
|
419
|
+
source.dispose();
|
|
420
|
+
reject(err);
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
});
|
|
424
|
+
return new class {
|
|
425
|
+
cancel() {
|
|
426
|
+
source.cancel();
|
|
427
|
+
}
|
|
428
|
+
then(resolve, reject) {
|
|
429
|
+
return promise.then(resolve, reject);
|
|
430
|
+
}
|
|
431
|
+
catch(reject) {
|
|
432
|
+
return this.then(void 0, reject);
|
|
433
|
+
}
|
|
434
|
+
finally(onfinally) {
|
|
435
|
+
return promise.finally(onfinally);
|
|
436
|
+
}
|
|
437
|
+
}();
|
|
438
|
+
}
|
|
439
|
+
function parallelPromise(promiseList) {
|
|
440
|
+
if (promiseList.length === 0) {
|
|
441
|
+
return Promise.resolve(makeOk());
|
|
442
|
+
}
|
|
443
|
+
let todo = promiseList.length;
|
|
444
|
+
const finish = () => {
|
|
445
|
+
todo = -1;
|
|
446
|
+
for (const promise of promiseList) {
|
|
447
|
+
promise.cancel?.();
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
return new Promise((resolve, reject) => {
|
|
451
|
+
for (const promise of promiseList) {
|
|
452
|
+
promise.then((res) => {
|
|
453
|
+
if (isLvErrorRef(res) && !res.ok) {
|
|
454
|
+
finish();
|
|
455
|
+
resolve(res);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
todo--;
|
|
459
|
+
if (todo === 0) {
|
|
460
|
+
resolve(makeOk());
|
|
461
|
+
}
|
|
462
|
+
}).catch((err) => {
|
|
463
|
+
finish();
|
|
464
|
+
reject(err);
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
function makePromiseWithTimeout(callback, timeout, defaultValue) {
|
|
470
|
+
const cancellable = makeCancelablePromise(callback);
|
|
471
|
+
const timer = setTimeout(() => {
|
|
472
|
+
cancellable.cancel();
|
|
473
|
+
}, timeout);
|
|
474
|
+
return cancellable.then((res) => {
|
|
475
|
+
clearTimeout(timer);
|
|
476
|
+
if (res.ok) {
|
|
477
|
+
return res;
|
|
478
|
+
}
|
|
479
|
+
if (res.code === 1 /* Cancelled */) {
|
|
480
|
+
if (defaultValue !== void 0) {
|
|
481
|
+
return makeOkWith(defaultValue);
|
|
482
|
+
}
|
|
483
|
+
return timeoutError();
|
|
484
|
+
} else {
|
|
485
|
+
return res;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
function defer() {
|
|
490
|
+
let resolve;
|
|
491
|
+
let reject;
|
|
492
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
493
|
+
resolve = _resolve;
|
|
494
|
+
reject = _reject;
|
|
495
|
+
});
|
|
496
|
+
return { resolve, reject, promise };
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/async/wait.ts
|
|
500
|
+
function wait(ms) {
|
|
501
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// src/async/barrier.ts
|
|
505
|
+
var Barrier = class {
|
|
506
|
+
_isOpen;
|
|
507
|
+
_promise;
|
|
508
|
+
_completePromise;
|
|
509
|
+
constructor() {
|
|
510
|
+
this._isOpen = false;
|
|
511
|
+
this._promise = new Promise((c, e) => {
|
|
512
|
+
this._completePromise = c;
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
isOpen() {
|
|
516
|
+
return this._isOpen;
|
|
517
|
+
}
|
|
518
|
+
open() {
|
|
519
|
+
this._isOpen = true;
|
|
520
|
+
this._completePromise(true);
|
|
521
|
+
}
|
|
522
|
+
wait() {
|
|
523
|
+
return this._promise;
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
function makeBarrierByPromise(promise, openWhenReject = false) {
|
|
527
|
+
const barrier = new Barrier();
|
|
528
|
+
promise.then(() => barrier.open());
|
|
529
|
+
if (openWhenReject) {
|
|
530
|
+
promise.catch((err) => {
|
|
531
|
+
barrier.open();
|
|
532
|
+
throw err;
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
return barrier;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// src/event/emitter.ts
|
|
539
|
+
function asyncUnexpectedErrorHandler(e) {
|
|
540
|
+
setTimeout(() => {
|
|
541
|
+
throw e;
|
|
542
|
+
}, 0);
|
|
543
|
+
}
|
|
544
|
+
function syncUnexpectedError(e) {
|
|
545
|
+
throw e;
|
|
546
|
+
}
|
|
547
|
+
function ignoreUnexpectedError(_e) {
|
|
548
|
+
}
|
|
549
|
+
var Listener = class {
|
|
550
|
+
_callback;
|
|
551
|
+
_callbackThis;
|
|
552
|
+
constructor(callback, callbackThis) {
|
|
553
|
+
this._callback = callback;
|
|
554
|
+
this._callbackThis = callbackThis;
|
|
555
|
+
}
|
|
556
|
+
invoke(...args) {
|
|
557
|
+
this._callback.call(this._callbackThis, ...args);
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
var EventDeliveryQueueElement = class {
|
|
561
|
+
emitter;
|
|
562
|
+
listener;
|
|
563
|
+
event;
|
|
564
|
+
constructor(emitter, listener, event) {
|
|
565
|
+
this.emitter = emitter;
|
|
566
|
+
this.listener = listener;
|
|
567
|
+
this.event = event;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
var EventDeliveryQueue = class {
|
|
571
|
+
constructor(_onListenerError = asyncUnexpectedErrorHandler) {
|
|
572
|
+
this._onListenerError = _onListenerError;
|
|
573
|
+
}
|
|
574
|
+
_onListenerError;
|
|
575
|
+
_queue = [];
|
|
576
|
+
get size() {
|
|
577
|
+
return this._queue.length;
|
|
578
|
+
}
|
|
579
|
+
push(emitter, listener, event) {
|
|
580
|
+
this._queue.push(new EventDeliveryQueueElement(emitter, listener, event));
|
|
581
|
+
}
|
|
582
|
+
clear(emitter) {
|
|
583
|
+
this._queue = this._queue.filter((element) => element.emitter !== emitter);
|
|
584
|
+
}
|
|
585
|
+
deliver() {
|
|
586
|
+
while (this._queue.length > 0) {
|
|
587
|
+
const element = this._queue.shift();
|
|
588
|
+
try {
|
|
589
|
+
element.listener.invoke(...element.event);
|
|
590
|
+
} catch (e) {
|
|
591
|
+
this._onListenerError(e);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
var Emitter = class {
|
|
597
|
+
_listeners;
|
|
598
|
+
_options;
|
|
599
|
+
_disposed = false;
|
|
600
|
+
_event;
|
|
601
|
+
_deliveryQueue;
|
|
602
|
+
constructor(options) {
|
|
603
|
+
this._options = options;
|
|
604
|
+
}
|
|
605
|
+
get event() {
|
|
606
|
+
if (this._event) {
|
|
607
|
+
return this._event;
|
|
608
|
+
}
|
|
609
|
+
this._event = (callback, thisArgs) => {
|
|
610
|
+
if (!this._listeners) {
|
|
611
|
+
this._listeners = /* @__PURE__ */ new Set();
|
|
612
|
+
}
|
|
613
|
+
const listener = new Listener(callback, thisArgs);
|
|
614
|
+
this._listeners.add(listener);
|
|
615
|
+
if (this._options?.onAddListener) {
|
|
616
|
+
this._options.onAddListener(this, callback, thisArgs);
|
|
617
|
+
}
|
|
618
|
+
const result = () => {
|
|
619
|
+
if (!this._disposed) {
|
|
620
|
+
this._listeners?.delete(listener);
|
|
621
|
+
if (this._options?.onRemoveListener) {
|
|
622
|
+
this._options.onRemoveListener(this, callback, thisArgs);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
return makeSafeDisposable(result);
|
|
627
|
+
};
|
|
628
|
+
return this._event;
|
|
629
|
+
}
|
|
630
|
+
dispose() {
|
|
631
|
+
if (this._disposed) {
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
this._disposed = true;
|
|
635
|
+
this._listeners?.clear();
|
|
636
|
+
this._deliveryQueue?.clear(this);
|
|
637
|
+
}
|
|
638
|
+
fire(...event) {
|
|
639
|
+
if (!this._listeners) {
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
this._deliveryQueue ??= new EventDeliveryQueue(this._options?.onListenerError);
|
|
643
|
+
for (const listener of this._listeners) {
|
|
644
|
+
this._deliveryQueue.push(this, listener, event);
|
|
645
|
+
}
|
|
646
|
+
this._deliveryQueue.deliver();
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
function listenOnce(event) {
|
|
650
|
+
return (listener, thisArgs = null) => {
|
|
651
|
+
let didFire = false;
|
|
652
|
+
let result = void 0;
|
|
653
|
+
result = event((...args) => {
|
|
654
|
+
if (didFire) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
if (result) {
|
|
658
|
+
result.dispose();
|
|
659
|
+
} else {
|
|
660
|
+
didFire = true;
|
|
661
|
+
}
|
|
662
|
+
return listener.call(thisArgs, ...args);
|
|
663
|
+
}, null);
|
|
664
|
+
if (didFire) {
|
|
665
|
+
result.dispose();
|
|
666
|
+
}
|
|
667
|
+
return result;
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// src/json/json.ts
|
|
672
|
+
function safeJsonParse(value) {
|
|
673
|
+
try {
|
|
674
|
+
return JSON.parse(value);
|
|
675
|
+
} catch (error) {
|
|
676
|
+
return {};
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function safeJsonStringify(value) {
|
|
680
|
+
try {
|
|
681
|
+
return JSON.stringify(value);
|
|
682
|
+
} catch (error) {
|
|
683
|
+
return "{}";
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// src/lock/capability.ts
|
|
688
|
+
var Capability = class {
|
|
689
|
+
onUnlocked;
|
|
690
|
+
_onUnlocked = new Emitter();
|
|
691
|
+
_status = 0 /* Unlocked */;
|
|
692
|
+
constructor() {
|
|
693
|
+
this.onUnlocked = this._onUnlocked.event;
|
|
694
|
+
}
|
|
695
|
+
get status() {
|
|
696
|
+
return this._status;
|
|
697
|
+
}
|
|
698
|
+
acquire() {
|
|
699
|
+
lvAssert(this._status === 0 /* Unlocked */);
|
|
700
|
+
this._status = 1 /* Locked */;
|
|
701
|
+
}
|
|
702
|
+
release() {
|
|
703
|
+
lvAssert(this._status === 1 /* Locked */);
|
|
704
|
+
this._status = 0 /* Unlocked */;
|
|
705
|
+
this._onUnlocked.fire();
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
var SharedCapability = class {
|
|
709
|
+
onUnlocked;
|
|
710
|
+
_onUnlocked = new Emitter();
|
|
711
|
+
_status = 0 /* Unlocked */;
|
|
712
|
+
_counter = 0;
|
|
713
|
+
constructor() {
|
|
714
|
+
this.onUnlocked = this._onUnlocked.event;
|
|
715
|
+
}
|
|
716
|
+
get status() {
|
|
717
|
+
return this._status;
|
|
718
|
+
}
|
|
719
|
+
get counter() {
|
|
720
|
+
return this._counter;
|
|
721
|
+
}
|
|
722
|
+
acquire() {
|
|
723
|
+
if (this._status === 0 /* Unlocked */) {
|
|
724
|
+
this._status = 1 /* Locked */;
|
|
725
|
+
}
|
|
726
|
+
this._counter++;
|
|
727
|
+
}
|
|
728
|
+
release() {
|
|
729
|
+
lvAssert(this._counter > 0);
|
|
730
|
+
this._counter--;
|
|
731
|
+
if (this._counter === 0) {
|
|
732
|
+
this._status = 0 /* Unlocked */;
|
|
733
|
+
this._onUnlocked.fire();
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
// src/lock/semaphore.ts
|
|
739
|
+
var Semaphore = class {
|
|
740
|
+
onActive;
|
|
741
|
+
_onActive = new Emitter();
|
|
742
|
+
constructor() {
|
|
743
|
+
this.onActive = this._onActive.event;
|
|
744
|
+
}
|
|
745
|
+
notify() {
|
|
746
|
+
this._onActive.fire();
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
// src/lock/shared-mutex.ts
|
|
751
|
+
var SharedMutex = class {
|
|
752
|
+
// 在第一道门外等待的写者
|
|
753
|
+
_waitingWriters = [];
|
|
754
|
+
// 已经通过了第一道门的写者
|
|
755
|
+
// 如果在第二道门外等待,状态为sharedLocked
|
|
756
|
+
// 如果已经进入到第二道门内拿到了锁,状态为locked
|
|
757
|
+
_writer;
|
|
758
|
+
// 在第一道门外等待的读者
|
|
759
|
+
_waitingReader;
|
|
760
|
+
// 拿到锁的读者
|
|
761
|
+
_reader;
|
|
762
|
+
/**
|
|
763
|
+
* 是否被锁住
|
|
764
|
+
*/
|
|
765
|
+
isLocked() {
|
|
766
|
+
return Boolean(this._writer) || this._readerCount !== 0;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* 等待并获取写锁
|
|
770
|
+
*/
|
|
771
|
+
lock() {
|
|
772
|
+
return new Promise((resolve) => {
|
|
773
|
+
if (this._writer) {
|
|
774
|
+
const token = new Semaphore();
|
|
775
|
+
this._waitingWriters.push(token);
|
|
776
|
+
token.onActive(() => {
|
|
777
|
+
this._writerEnterGate1(resolve);
|
|
778
|
+
});
|
|
779
|
+
} else {
|
|
780
|
+
this._writerEnterGate1(resolve);
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* 尝试获取写锁,立刻返回结果
|
|
786
|
+
*/
|
|
787
|
+
tryLock() {
|
|
788
|
+
if (this._writer || this._readerCount > 0) {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
791
|
+
this.lock();
|
|
792
|
+
return true;
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* 解除写锁
|
|
796
|
+
*/
|
|
797
|
+
unLock() {
|
|
798
|
+
lvAssertNotNil(this._writer);
|
|
799
|
+
this._writer.release();
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* 解除写锁。`unLock` 的常规拼写别名。
|
|
803
|
+
*/
|
|
804
|
+
unlock() {
|
|
805
|
+
this.unLock();
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* 等待并获取读锁
|
|
809
|
+
*/
|
|
810
|
+
lockShared() {
|
|
811
|
+
return new Promise((resolve) => {
|
|
812
|
+
if (this._writer) {
|
|
813
|
+
if (!this._waitingReader) {
|
|
814
|
+
this._waitingReader = new Semaphore();
|
|
815
|
+
}
|
|
816
|
+
this._waitingReader.onActive(() => {
|
|
817
|
+
this._readerEnterGate1(resolve);
|
|
818
|
+
});
|
|
819
|
+
} else {
|
|
820
|
+
this._readerEnterGate1(resolve);
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* 尝试获取读锁,立刻返回结果
|
|
826
|
+
*/
|
|
827
|
+
tryLockShared() {
|
|
828
|
+
if (this._writer) {
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
this.lockShared();
|
|
832
|
+
return true;
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* 解除读锁
|
|
836
|
+
*/
|
|
837
|
+
unLockShared() {
|
|
838
|
+
lvAssertNotNil(this._reader);
|
|
839
|
+
if (this._writer) {
|
|
840
|
+
lvAssert(this._writer.status === 0 /* Unlocked */);
|
|
841
|
+
}
|
|
842
|
+
this._reader.release();
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* 解除读锁。`unLockShared` 的常规拼写别名。
|
|
846
|
+
*/
|
|
847
|
+
unlockShared() {
|
|
848
|
+
this.unLockShared();
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* 获取当前读者数量
|
|
852
|
+
*/
|
|
853
|
+
get _readerCount() {
|
|
854
|
+
return this._reader ? this._reader.counter : 0;
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* 写者进入第一道门
|
|
858
|
+
*/
|
|
859
|
+
_writerEnterGate1(resolve) {
|
|
860
|
+
lvAssert(!this._writer);
|
|
861
|
+
this._writer = new Capability();
|
|
862
|
+
if (this._readerCount > 0) {
|
|
863
|
+
listenOnce(this._reader.onUnlocked)(() => {
|
|
864
|
+
this._writerEnterGate2(resolve);
|
|
865
|
+
});
|
|
866
|
+
} else {
|
|
867
|
+
this._writerEnterGate2(resolve);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* 写者进入第二道门
|
|
872
|
+
*/
|
|
873
|
+
_writerEnterGate2(resolve) {
|
|
874
|
+
lvAssertNotNil(this._writer);
|
|
875
|
+
lvAssert(this._readerCount === 0);
|
|
876
|
+
this._writer.acquire();
|
|
877
|
+
listenOnce(this._writer.onUnlocked)(() => {
|
|
878
|
+
lvAssertNotNil(this._writer);
|
|
879
|
+
this._writer = void 0;
|
|
880
|
+
this._moveForward();
|
|
881
|
+
});
|
|
882
|
+
resolve();
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* 读者进入第一道门
|
|
886
|
+
*/
|
|
887
|
+
_readerEnterGate1(resolve) {
|
|
888
|
+
lvAssert(!this._writer);
|
|
889
|
+
this._waitingReader = void 0;
|
|
890
|
+
if (!this._reader) {
|
|
891
|
+
this._reader = new SharedCapability();
|
|
892
|
+
this._reader.acquire();
|
|
893
|
+
listenOnce(this._reader.onUnlocked)(() => {
|
|
894
|
+
this._moveForward();
|
|
895
|
+
});
|
|
896
|
+
} else {
|
|
897
|
+
this._reader.acquire();
|
|
898
|
+
}
|
|
899
|
+
resolve();
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* 锁释放时推进流程
|
|
903
|
+
*/
|
|
904
|
+
_moveForward() {
|
|
905
|
+
if (this._writer) {
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
if (this._waitingWriters.length > 0) {
|
|
909
|
+
const semaphore = this._waitingWriters.shift();
|
|
910
|
+
semaphore.notify();
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (this._waitingReader) {
|
|
914
|
+
this._waitingReader.notify();
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
|
|
919
|
+
// src/response/response.ts
|
|
920
|
+
function makeSuccessResponse(data) {
|
|
921
|
+
return {
|
|
922
|
+
code: 0,
|
|
923
|
+
data,
|
|
924
|
+
msg: "success"
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
function makeErrorResponse(code, msg) {
|
|
928
|
+
return {
|
|
929
|
+
code,
|
|
930
|
+
msg
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
export {
|
|
934
|
+
Barrier,
|
|
935
|
+
CancellationToken,
|
|
936
|
+
CancellationTokenSource,
|
|
937
|
+
Disposable,
|
|
938
|
+
DisposableStore,
|
|
939
|
+
Emitter,
|
|
940
|
+
EmptyDispose,
|
|
941
|
+
EventDeliveryQueue,
|
|
942
|
+
GenericError,
|
|
943
|
+
ILvErrorOr,
|
|
944
|
+
ILvErrorRef,
|
|
945
|
+
ILvRealErrorRef,
|
|
946
|
+
ILvValueRef,
|
|
947
|
+
MutableDisposable,
|
|
948
|
+
SafeDisposable,
|
|
949
|
+
SharedMutex,
|
|
950
|
+
alreadyExistsError,
|
|
951
|
+
asyncUnexpectedErrorHandler,
|
|
952
|
+
cancelledError,
|
|
953
|
+
defer,
|
|
954
|
+
disposeWithLog,
|
|
955
|
+
ignoreUnexpectedError,
|
|
956
|
+
interruptedError,
|
|
957
|
+
invalidArgumentError,
|
|
958
|
+
isLvErrorRef,
|
|
959
|
+
listenOnce,
|
|
960
|
+
lvAssert,
|
|
961
|
+
lvAssertNever,
|
|
962
|
+
lvAssertNotHere,
|
|
963
|
+
lvAssertNotNil,
|
|
964
|
+
lvErrorConst,
|
|
965
|
+
makeBarrierByPromise,
|
|
966
|
+
makeCancelablePromise,
|
|
967
|
+
makeEmptyDisposable,
|
|
968
|
+
makeError,
|
|
969
|
+
makeErrorBy,
|
|
970
|
+
makeErrorResponse,
|
|
971
|
+
makeOk,
|
|
972
|
+
makeOkWith,
|
|
973
|
+
makePromiseWithTimeout,
|
|
974
|
+
makeSafeDisposable,
|
|
975
|
+
makeSuccessResponse,
|
|
976
|
+
networkFailedError,
|
|
977
|
+
notSupportedError,
|
|
978
|
+
outOfRangeError,
|
|
979
|
+
parallelPromise,
|
|
980
|
+
permissionDeniedError,
|
|
981
|
+
resourceUnavailableError,
|
|
982
|
+
resultNilError,
|
|
983
|
+
safeJsonParse,
|
|
984
|
+
safeJsonStringify,
|
|
985
|
+
syncUnexpectedError,
|
|
986
|
+
timeoutError,
|
|
987
|
+
wait
|
|
988
|
+
};
|
|
989
|
+
//# sourceMappingURL=index.js.map
|