abxbus 2.4.1
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 +647 -0
- package/dist/cjs/async_context.d.ts +12 -0
- package/dist/cjs/async_context.js +70 -0
- package/dist/cjs/async_context.js.map +7 -0
- package/dist/cjs/base_event.d.ts +207 -0
- package/dist/cjs/base_event.js +871 -0
- package/dist/cjs/base_event.js.map +7 -0
- package/dist/cjs/bridge_jsonl.d.ts +26 -0
- package/dist/cjs/bridge_jsonl.js +170 -0
- package/dist/cjs/bridge_jsonl.js.map +7 -0
- package/dist/cjs/bridge_nats.d.ts +20 -0
- package/dist/cjs/bridge_nats.js +108 -0
- package/dist/cjs/bridge_nats.js.map +7 -0
- package/dist/cjs/bridge_postgres.d.ts +31 -0
- package/dist/cjs/bridge_postgres.js +251 -0
- package/dist/cjs/bridge_postgres.js.map +7 -0
- package/dist/cjs/bridge_redis.d.ts +34 -0
- package/dist/cjs/bridge_redis.js +175 -0
- package/dist/cjs/bridge_redis.js.map +7 -0
- package/dist/cjs/bridge_sqlite.d.ts +30 -0
- package/dist/cjs/bridge_sqlite.js +255 -0
- package/dist/cjs/bridge_sqlite.js.map +7 -0
- package/dist/cjs/bridges.d.ts +49 -0
- package/dist/cjs/bridges.js +326 -0
- package/dist/cjs/bridges.js.map +7 -0
- package/dist/cjs/event_bus.d.ts +127 -0
- package/dist/cjs/event_bus.js +1058 -0
- package/dist/cjs/event_bus.js.map +7 -0
- package/dist/cjs/event_handler.d.ts +139 -0
- package/dist/cjs/event_handler.js +299 -0
- package/dist/cjs/event_handler.js.map +7 -0
- package/dist/cjs/event_history.d.ts +45 -0
- package/dist/cjs/event_history.js +192 -0
- package/dist/cjs/event_history.js.map +7 -0
- package/dist/cjs/event_result.d.ts +86 -0
- package/dist/cjs/event_result.js +446 -0
- package/dist/cjs/event_result.js.map +7 -0
- package/dist/cjs/events_suck.d.ts +40 -0
- package/dist/cjs/events_suck.js +59 -0
- package/dist/cjs/events_suck.js.map +7 -0
- package/dist/cjs/helpers.d.ts +1 -0
- package/dist/cjs/helpers.js +84 -0
- package/dist/cjs/helpers.js.map +7 -0
- package/dist/cjs/index.d.ts +17 -0
- package/dist/cjs/index.js +54 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/lock_manager.d.ts +70 -0
- package/dist/cjs/lock_manager.js +343 -0
- package/dist/cjs/lock_manager.js.map +7 -0
- package/dist/cjs/logging.d.ts +16 -0
- package/dist/cjs/logging.js +216 -0
- package/dist/cjs/logging.js.map +7 -0
- package/dist/cjs/middlewares.d.ts +13 -0
- package/dist/cjs/middlewares.js +17 -0
- package/dist/cjs/middlewares.js.map +7 -0
- package/dist/cjs/optional_deps.d.ts +3 -0
- package/dist/cjs/optional_deps.js +64 -0
- package/dist/cjs/optional_deps.js.map +7 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/retry.d.ts +52 -0
- package/dist/cjs/retry.js +257 -0
- package/dist/cjs/retry.js.map +7 -0
- package/dist/cjs/timing.d.ts +3 -0
- package/dist/cjs/timing.js +76 -0
- package/dist/cjs/timing.js.map +7 -0
- package/dist/cjs/type_inference.test.d.ts +1 -0
- package/dist/cjs/types.d.ts +36 -0
- package/dist/cjs/types.js +104 -0
- package/dist/cjs/types.js.map +7 -0
- package/dist/esm/async_context.js +50 -0
- package/dist/esm/async_context.js.map +7 -0
- package/dist/esm/base_event.js +857 -0
- package/dist/esm/base_event.js.map +7 -0
- package/dist/esm/bridge_jsonl.js +150 -0
- package/dist/esm/bridge_jsonl.js.map +7 -0
- package/dist/esm/bridge_nats.js +88 -0
- package/dist/esm/bridge_nats.js.map +7 -0
- package/dist/esm/bridge_postgres.js +231 -0
- package/dist/esm/bridge_postgres.js.map +7 -0
- package/dist/esm/bridge_redis.js +155 -0
- package/dist/esm/bridge_redis.js.map +7 -0
- package/dist/esm/bridge_sqlite.js +235 -0
- package/dist/esm/bridge_sqlite.js.map +7 -0
- package/dist/esm/bridges.js +306 -0
- package/dist/esm/bridges.js.map +7 -0
- package/dist/esm/event_bus.js +1046 -0
- package/dist/esm/event_bus.js.map +7 -0
- package/dist/esm/event_handler.js +279 -0
- package/dist/esm/event_handler.js.map +7 -0
- package/dist/esm/event_history.js +172 -0
- package/dist/esm/event_history.js.map +7 -0
- package/dist/esm/event_result.js +426 -0
- package/dist/esm/event_result.js.map +7 -0
- package/dist/esm/events_suck.js +39 -0
- package/dist/esm/events_suck.js.map +7 -0
- package/dist/esm/helpers.js +64 -0
- package/dist/esm/helpers.js.map +7 -0
- package/dist/esm/index.js +47 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/lock_manager.js +323 -0
- package/dist/esm/lock_manager.js.map +7 -0
- package/dist/esm/logging.js +196 -0
- package/dist/esm/logging.js.map +7 -0
- package/dist/esm/middlewares.js +1 -0
- package/dist/esm/middlewares.js.map +7 -0
- package/dist/esm/optional_deps.js +44 -0
- package/dist/esm/optional_deps.js.map +7 -0
- package/dist/esm/retry.js +237 -0
- package/dist/esm/retry.js.map +7 -0
- package/dist/esm/timing.js +56 -0
- package/dist/esm/timing.js.map +7 -0
- package/dist/esm/types.js +84 -0
- package/dist/esm/types.js.map +7 -0
- package/dist/types/async_context.d.ts +12 -0
- package/dist/types/base_event.d.ts +207 -0
- package/dist/types/bridge_jsonl.d.ts +26 -0
- package/dist/types/bridge_nats.d.ts +20 -0
- package/dist/types/bridge_postgres.d.ts +31 -0
- package/dist/types/bridge_redis.d.ts +34 -0
- package/dist/types/bridge_sqlite.d.ts +30 -0
- package/dist/types/bridges.d.ts +49 -0
- package/dist/types/event_bus.d.ts +127 -0
- package/dist/types/event_handler.d.ts +139 -0
- package/dist/types/event_history.d.ts +45 -0
- package/dist/types/event_result.d.ts +86 -0
- package/dist/types/events_suck.d.ts +40 -0
- package/dist/types/helpers.d.ts +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/lock_manager.d.ts +70 -0
- package/dist/types/logging.d.ts +16 -0
- package/dist/types/middlewares.d.ts +13 -0
- package/dist/types/optional_deps.d.ts +3 -0
- package/dist/types/retry.d.ts +52 -0
- package/dist/types/timing.d.ts +3 -0
- package/dist/types/type_inference.test.d.ts +1 -0
- package/dist/types/types.d.ts +36 -0
- package/package.json +87 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var retry_exports = {};
|
|
20
|
+
__export(retry_exports, {
|
|
21
|
+
RetryTimeoutError: () => RetryTimeoutError,
|
|
22
|
+
SemaphoreTimeoutError: () => SemaphoreTimeoutError,
|
|
23
|
+
clearSemaphoreRegistry: () => clearSemaphoreRegistry,
|
|
24
|
+
retry: () => retry
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(retry_exports);
|
|
27
|
+
var import_async_context = require("./async_context.js");
|
|
28
|
+
class RetryTimeoutError extends Error {
|
|
29
|
+
timeout_seconds;
|
|
30
|
+
attempt;
|
|
31
|
+
constructor(message, params) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "RetryTimeoutError";
|
|
34
|
+
this.timeout_seconds = params.timeout_seconds;
|
|
35
|
+
this.attempt = params.attempt;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class SemaphoreTimeoutError extends Error {
|
|
39
|
+
semaphore_name;
|
|
40
|
+
semaphore_limit;
|
|
41
|
+
timeout_seconds;
|
|
42
|
+
constructor(message, params) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = "SemaphoreTimeoutError";
|
|
45
|
+
this.semaphore_name = params.semaphore_name;
|
|
46
|
+
this.semaphore_limit = params.semaphore_limit;
|
|
47
|
+
this.timeout_seconds = params.timeout_seconds;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const retry_context_storage = (0, import_async_context.createAsyncLocalStorage)();
|
|
51
|
+
function getHeldSemaphores() {
|
|
52
|
+
return retry_context_storage?.getStore() ?? /* @__PURE__ */ new Set();
|
|
53
|
+
}
|
|
54
|
+
function runWithHeldSemaphores(held, fn) {
|
|
55
|
+
if (!retry_context_storage) return fn();
|
|
56
|
+
return retry_context_storage.run(held, fn);
|
|
57
|
+
}
|
|
58
|
+
let _next_instance_id = 1;
|
|
59
|
+
const _instance_ids = /* @__PURE__ */ new WeakMap();
|
|
60
|
+
function scopedSemaphoreKey(base_name, scope, context) {
|
|
61
|
+
if (scope === "class" && context && typeof context === "object") {
|
|
62
|
+
return `${context.constructor?.name ?? "Object"}.${base_name}`;
|
|
63
|
+
}
|
|
64
|
+
if (scope === "instance" && context && typeof context === "object") {
|
|
65
|
+
let id = _instance_ids.get(context);
|
|
66
|
+
if (id === void 0) {
|
|
67
|
+
id = _next_instance_id++;
|
|
68
|
+
_instance_ids.set(context, id);
|
|
69
|
+
}
|
|
70
|
+
return `${id}.${base_name}`;
|
|
71
|
+
}
|
|
72
|
+
return base_name;
|
|
73
|
+
}
|
|
74
|
+
class RetrySemaphore {
|
|
75
|
+
size;
|
|
76
|
+
inUse;
|
|
77
|
+
waiters;
|
|
78
|
+
constructor(size) {
|
|
79
|
+
this.size = size;
|
|
80
|
+
this.inUse = 0;
|
|
81
|
+
this.waiters = [];
|
|
82
|
+
}
|
|
83
|
+
async acquire() {
|
|
84
|
+
if (this.size === Infinity) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (this.inUse < this.size) {
|
|
88
|
+
this.inUse += 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
await new Promise((resolve) => {
|
|
92
|
+
this.waiters.push(resolve);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
release() {
|
|
96
|
+
if (this.size === Infinity) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const next = this.waiters.shift();
|
|
100
|
+
if (next) {
|
|
101
|
+
next();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.inUse = Math.max(0, this.inUse - 1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const SEMAPHORE_REGISTRY = /* @__PURE__ */ new Map();
|
|
108
|
+
function getOrCreateSemaphore(name, limit) {
|
|
109
|
+
const existing = SEMAPHORE_REGISTRY.get(name);
|
|
110
|
+
if (existing && existing.size === limit) return existing;
|
|
111
|
+
const sem = new RetrySemaphore(limit);
|
|
112
|
+
SEMAPHORE_REGISTRY.set(name, sem);
|
|
113
|
+
return sem;
|
|
114
|
+
}
|
|
115
|
+
function clearSemaphoreRegistry() {
|
|
116
|
+
SEMAPHORE_REGISTRY.clear();
|
|
117
|
+
}
|
|
118
|
+
function retry(options = {}) {
|
|
119
|
+
const {
|
|
120
|
+
max_attempts = 1,
|
|
121
|
+
retry_after = 0,
|
|
122
|
+
retry_backoff_factor = 1,
|
|
123
|
+
retry_on_errors,
|
|
124
|
+
timeout,
|
|
125
|
+
semaphore_limit,
|
|
126
|
+
semaphore_name: semaphore_name_option,
|
|
127
|
+
semaphore_lax = true,
|
|
128
|
+
semaphore_scope = "global",
|
|
129
|
+
semaphore_timeout
|
|
130
|
+
} = options;
|
|
131
|
+
return function decorator(target, _context) {
|
|
132
|
+
const fn_name = target.name || _context?.name || "anonymous";
|
|
133
|
+
const effective_max_attempts = Math.max(1, max_attempts);
|
|
134
|
+
const effective_retry_after = Math.max(0, retry_after);
|
|
135
|
+
async function retryWrapper(...args) {
|
|
136
|
+
const base_name = typeof semaphore_name_option === "function" ? semaphore_name_option(...args) : semaphore_name_option ?? fn_name;
|
|
137
|
+
const sem_name = typeof base_name === "string" ? base_name : String(base_name);
|
|
138
|
+
const scoped_key = scopedSemaphoreKey(sem_name, semaphore_scope, this);
|
|
139
|
+
const held = getHeldSemaphores();
|
|
140
|
+
const needs_semaphore = semaphore_limit != null && semaphore_limit > 0;
|
|
141
|
+
const is_reentrant = needs_semaphore && held.has(scoped_key);
|
|
142
|
+
let semaphore = null;
|
|
143
|
+
let semaphore_acquired = false;
|
|
144
|
+
if (needs_semaphore && !is_reentrant) {
|
|
145
|
+
semaphore = getOrCreateSemaphore(scoped_key, semaphore_limit);
|
|
146
|
+
const effective_sem_timeout = semaphore_timeout != null ? semaphore_timeout : timeout != null ? timeout * Math.max(1, semaphore_limit - 1) : null;
|
|
147
|
+
if (effective_sem_timeout != null && effective_sem_timeout > 0) {
|
|
148
|
+
semaphore_acquired = await acquireWithTimeout(semaphore, effective_sem_timeout * 1e3);
|
|
149
|
+
if (!semaphore_acquired) {
|
|
150
|
+
if (!semaphore_lax) {
|
|
151
|
+
throw new SemaphoreTimeoutError(
|
|
152
|
+
`Failed to acquire semaphore "${scoped_key}" within ${effective_sem_timeout}s (limit=${semaphore_limit})`,
|
|
153
|
+
{ semaphore_name: scoped_key, semaphore_limit, timeout_seconds: effective_sem_timeout }
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
await semaphore.acquire();
|
|
159
|
+
semaphore_acquired = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const new_held = new Set(held);
|
|
163
|
+
if (semaphore_acquired) {
|
|
164
|
+
new_held.add(scoped_key);
|
|
165
|
+
}
|
|
166
|
+
const runRetryLoop = async () => {
|
|
167
|
+
for (let attempt = 1; attempt <= effective_max_attempts; attempt++) {
|
|
168
|
+
try {
|
|
169
|
+
if (timeout != null && timeout > 0) {
|
|
170
|
+
return await _runWithTimeout(() => Promise.resolve(target.apply(this, args)), timeout * 1e3, attempt);
|
|
171
|
+
} else {
|
|
172
|
+
return await Promise.resolve(target.apply(this, args));
|
|
173
|
+
}
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (retry_on_errors && retry_on_errors.length > 0) {
|
|
176
|
+
const is_retryable = retry_on_errors.some(
|
|
177
|
+
(matcher) => typeof matcher === "string" ? error?.name === matcher : matcher instanceof RegExp ? matcher.test(String(error)) : error instanceof matcher
|
|
178
|
+
);
|
|
179
|
+
if (!is_retryable) throw error;
|
|
180
|
+
}
|
|
181
|
+
if (attempt >= effective_max_attempts) throw error;
|
|
182
|
+
const delay_seconds = effective_retry_after * Math.pow(retry_backoff_factor, attempt - 1);
|
|
183
|
+
if (delay_seconds > 0) {
|
|
184
|
+
await sleep(delay_seconds * 1e3);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
throw new Error(`retry(${fn_name}): unexpected end of retry loop`);
|
|
189
|
+
};
|
|
190
|
+
try {
|
|
191
|
+
return await runWithHeldSemaphores(new_held, runRetryLoop);
|
|
192
|
+
} finally {
|
|
193
|
+
if (semaphore_acquired && semaphore) {
|
|
194
|
+
semaphore.release();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
Object.defineProperty(retryWrapper, "name", { value: fn_name, configurable: true });
|
|
199
|
+
return retryWrapper;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
async function acquireWithTimeout(semaphore, timeout_ms) {
|
|
203
|
+
return new Promise((resolve) => {
|
|
204
|
+
let settled = false;
|
|
205
|
+
const timer = setTimeout(() => {
|
|
206
|
+
if (!settled) {
|
|
207
|
+
settled = true;
|
|
208
|
+
resolve(false);
|
|
209
|
+
}
|
|
210
|
+
}, timeout_ms);
|
|
211
|
+
semaphore.acquire().then(() => {
|
|
212
|
+
if (!settled) {
|
|
213
|
+
settled = true;
|
|
214
|
+
clearTimeout(timer);
|
|
215
|
+
resolve(true);
|
|
216
|
+
} else {
|
|
217
|
+
semaphore.release();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
async function _runWithTimeout(fn, timeout_ms, attempt) {
|
|
223
|
+
return new Promise((resolve, reject) => {
|
|
224
|
+
let settled = false;
|
|
225
|
+
const timer = setTimeout(() => {
|
|
226
|
+
if (!settled) {
|
|
227
|
+
settled = true;
|
|
228
|
+
reject(
|
|
229
|
+
new RetryTimeoutError(`Timed out after ${timeout_ms / 1e3}s (attempt ${attempt})`, {
|
|
230
|
+
timeout_seconds: timeout_ms / 1e3,
|
|
231
|
+
attempt
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}, timeout_ms);
|
|
236
|
+
fn().then(
|
|
237
|
+
(value) => {
|
|
238
|
+
if (!settled) {
|
|
239
|
+
settled = true;
|
|
240
|
+
clearTimeout(timer);
|
|
241
|
+
resolve(value);
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
(error) => {
|
|
245
|
+
if (!settled) {
|
|
246
|
+
settled = true;
|
|
247
|
+
clearTimeout(timer);
|
|
248
|
+
reject(error);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function sleep(ms) {
|
|
255
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/retry.ts"],
|
|
4
|
+
"sourcesContent": ["import { createAsyncLocalStorage, type AsyncLocalStorageLike } from './async_context.js'\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RetryOptions {\n /** Total number of attempts including the initial call (1 = no retry, 3 = up to 2 retries). Default: 1 */\n max_attempts?: number\n\n /** Seconds to wait between retries. Default: 0 */\n retry_after?: number\n\n /** Multiplier applied to retry_after after each attempt for exponential backoff. Default: 1.0 (constant delay) */\n retry_backoff_factor?: number\n\n /** Only retry when the thrown error matches one of these matchers. Accepts error class constructors,\n * string error names (matched against error.name), or RegExp patterns (tested against String(error)).\n * Default: undefined (retry on any error) */\n retry_on_errors?: Array<(new (...args: any[]) => Error) | string | RegExp>\n\n /** Per-attempt timeout in seconds. Default: undefined (no per-attempt timeout) */\n timeout?: number | null\n\n /** Maximum concurrent executions sharing this semaphore. Default: undefined (no concurrency limit) */\n semaphore_limit?: number | null\n\n /** Semaphore identifier. Functions with the same name share the same concurrency slot pool. Default: function name.\n * If a function is provided, it receives the same arguments as the wrapped function. */\n semaphore_name?: string | ((...args: any[]) => string) | null\n\n /** If true, proceed without concurrency limit when semaphore acquisition times out. Default: true */\n semaphore_lax?: boolean\n\n /** Semaphore scoping strategy. Default: 'global'\n * - 'global': all calls share one semaphore (keyed by semaphore_name)\n * - 'class': all instances of the same class share one semaphore (keyed by className.semaphore_name)\n * - 'instance': each object instance gets its own semaphore (keyed by instanceId.semaphore_name)\n * 'class' and 'instance' require `this` to be an object; they fall back to 'global' for standalone calls. */\n semaphore_scope?: 'global' | 'class' | 'instance'\n\n /** Maximum seconds to wait for semaphore acquisition. Default: undefined \u2192 timeout * max(1, limit - 1) */\n semaphore_timeout?: number | null\n}\n\n// \u2500\u2500\u2500 Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Thrown when a single attempt exceeds the per-attempt timeout. */\nexport class RetryTimeoutError extends Error {\n timeout_seconds: number\n attempt: number\n\n constructor(message: string, params: { timeout_seconds: number; attempt: number }) {\n super(message)\n this.name = 'RetryTimeoutError'\n this.timeout_seconds = params.timeout_seconds\n this.attempt = params.attempt\n }\n}\n\n/** Thrown (when semaphore_lax=false) if the semaphore cannot be acquired within the timeout. */\nexport class SemaphoreTimeoutError extends Error {\n semaphore_name: string\n semaphore_limit: number\n timeout_seconds: number\n\n constructor(message: string, params: { semaphore_name: string; semaphore_limit: number; timeout_seconds: number }) {\n super(message)\n this.name = 'SemaphoreTimeoutError'\n this.semaphore_name = params.semaphore_name\n this.semaphore_limit = params.semaphore_limit\n this.timeout_seconds = params.timeout_seconds\n }\n}\n\n// \u2500\u2500\u2500 Re-entrancy tracking via AsyncLocalStorage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Prevents deadlocks when a retry()-wrapped function calls another retry()-wrapped\n// function that shares the same semaphore (or calls itself recursively).\n//\n// Each async call stack tracks which semaphore names it currently holds. When a\n// nested call encounters a semaphore it already holds, it skips acquisition and\n// runs directly within the parent's slot.\n//\n// Uses the same AsyncLocalStorage polyfill as the rest of abxbus (see async_context.ts)\n// so it works in Node.js and gracefully degrades to a no-op in browsers.\n\ntype ReentrantStore = Set<string>\n\n// Separate AsyncLocalStorage instance for retry re-entrancy tracking.\n// Created via the shared factory in async_context.ts (returns null in browsers).\nconst retry_context_storage: AsyncLocalStorageLike | null = createAsyncLocalStorage()\n\nfunction getHeldSemaphores(): ReentrantStore {\n return (retry_context_storage?.getStore() as ReentrantStore | undefined) ?? new Set()\n}\n\nfunction runWithHeldSemaphores<T>(held: ReentrantStore, fn: () => T): T {\n if (!retry_context_storage) return fn()\n return retry_context_storage.run(held, fn)\n}\n\n// \u2500\u2500\u2500 Semaphore scope helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet _next_instance_id = 1\nconst _instance_ids = new WeakMap<object, number>()\n\nfunction scopedSemaphoreKey(base_name: string, scope: 'global' | 'class' | 'instance', context: unknown): string {\n if (scope === 'class' && context && typeof context === 'object') {\n return `${(context as object).constructor?.name ?? 'Object'}.${base_name}`\n }\n if (scope === 'instance' && context && typeof context === 'object') {\n let id = _instance_ids.get(context as object)\n if (id === undefined) {\n id = _next_instance_id++\n _instance_ids.set(context as object, id)\n }\n return `${id}.${base_name}`\n }\n return base_name\n}\n\n// \u2500\u2500\u2500 Global semaphore registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nclass RetrySemaphore {\n readonly size: number\n private inUse: number\n private waiters: Array<() => void>\n\n constructor(size: number) {\n this.size = size\n this.inUse = 0\n this.waiters = []\n }\n\n async acquire(): Promise<void> {\n if (this.size === Infinity) {\n return\n }\n if (this.inUse < this.size) {\n this.inUse += 1\n return\n }\n await new Promise<void>((resolve) => {\n this.waiters.push(resolve)\n })\n }\n\n release(): void {\n if (this.size === Infinity) {\n return\n }\n const next = this.waiters.shift()\n if (next) {\n // Handoff: keep the permit accounted for and transfer it directly to the waiter.\n next()\n return\n }\n this.inUse = Math.max(0, this.inUse - 1)\n }\n}\n\nconst SEMAPHORE_REGISTRY = new Map<string, RetrySemaphore>()\n\nfunction getOrCreateSemaphore(name: string, limit: number): RetrySemaphore {\n const existing = SEMAPHORE_REGISTRY.get(name)\n if (existing && existing.size === limit) return existing\n const sem = new RetrySemaphore(limit)\n SEMAPHORE_REGISTRY.set(name, sem)\n return sem\n}\n\n/** Reset the global semaphore registry. Useful in tests. */\nexport function clearSemaphoreRegistry(): void {\n SEMAPHORE_REGISTRY.clear()\n}\n\n// \u2500\u2500\u2500 retry() decorator / higher-order wrapper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Usage as a higher-order function (works on any async function):\n//\n// const fetchWithRetry = retry({ max_attempts: 3, retry_after: 1 })(async (url: string) => {\n// return await fetch(url)\n// })\n//\n// Usage as a TC39 Stage 3 decorator on class methods (TS 5.0+):\n//\n// class ApiClient {\n// @retry({ max_attempts: 3, retry_after: 1 })\n// async fetchData(): Promise<Data> { ... }\n// }\n//\n// Usage on event bus handlers:\n//\n// bus.on(MyEvent, retry({ max_attempts: 3 })(async (event) => {\n// await riskyOperation(event.data)\n// }))\n\nexport function retry(options: RetryOptions = {}) {\n const {\n max_attempts = 1,\n retry_after = 0,\n retry_backoff_factor = 1.0,\n retry_on_errors,\n timeout,\n semaphore_limit,\n semaphore_name: semaphore_name_option,\n semaphore_lax = true,\n semaphore_scope = 'global',\n semaphore_timeout,\n } = options\n\n return function decorator<T extends (...args: any[]) => any>(target: T, _context?: ClassMethodDecoratorContext): T {\n const fn_name = target.name || (_context?.name as string) || 'anonymous'\n const effective_max_attempts = Math.max(1, max_attempts)\n const effective_retry_after = Math.max(0, retry_after)\n\n async function retryWrapper(this: any, ...args: any[]): Promise<any> {\n const base_name = typeof semaphore_name_option === 'function' ? semaphore_name_option(...args) : (semaphore_name_option ?? fn_name)\n const sem_name = typeof base_name === 'string' ? base_name : String(base_name)\n // \u2500\u2500 Resolve scoped semaphore key at call time (uses `this` for class/instance scopes) \u2500\u2500\n const scoped_key = scopedSemaphoreKey(sem_name, semaphore_scope, this)\n\n // \u2500\u2500 Check re-entrancy: skip semaphore if we already hold it in this async context \u2500\u2500\n const held = getHeldSemaphores()\n const needs_semaphore = semaphore_limit != null && semaphore_limit > 0\n const is_reentrant = needs_semaphore && held.has(scoped_key)\n\n // \u2500\u2500 Semaphore acquisition (held across all retry attempts, skipped if re-entrant) \u2500\u2500\n let semaphore: RetrySemaphore | null = null\n let semaphore_acquired = false\n\n if (needs_semaphore && !is_reentrant) {\n semaphore = getOrCreateSemaphore(scoped_key, semaphore_limit!)\n\n const effective_sem_timeout =\n semaphore_timeout != null ? semaphore_timeout : timeout != null ? timeout * Math.max(1, semaphore_limit! - 1) : null\n\n if (effective_sem_timeout != null && effective_sem_timeout > 0) {\n semaphore_acquired = await acquireWithTimeout(semaphore, effective_sem_timeout * 1000)\n if (!semaphore_acquired) {\n if (!semaphore_lax) {\n throw new SemaphoreTimeoutError(\n `Failed to acquire semaphore \"${scoped_key}\" within ${effective_sem_timeout}s (limit=${semaphore_limit})`,\n { semaphore_name: scoped_key, semaphore_limit: semaphore_limit!, timeout_seconds: effective_sem_timeout }\n )\n }\n // lax mode: proceed without concurrency limit\n }\n } else {\n // No timeout configured: wait indefinitely for a slot\n await semaphore.acquire()\n semaphore_acquired = true\n }\n }\n\n // \u2500\u2500 Build the set of held semaphores for nested calls \u2500\u2500\n const new_held = new Set(held)\n if (semaphore_acquired) {\n new_held.add(scoped_key)\n }\n\n // \u2500\u2500 Retry loop (runs inside the semaphore and re-entrancy context) \u2500\u2500\n const runRetryLoop = async (): Promise<any> => {\n for (let attempt = 1; attempt <= effective_max_attempts; attempt++) {\n try {\n if (timeout != null && timeout > 0) {\n return await _runWithTimeout(() => Promise.resolve(target.apply(this, args)), timeout * 1000, attempt)\n } else {\n return await Promise.resolve(target.apply(this, args))\n }\n } catch (error) {\n // Check if this error type should trigger a retry\n if (retry_on_errors && retry_on_errors.length > 0) {\n const is_retryable = retry_on_errors.some((matcher) =>\n typeof matcher === 'string'\n ? (error as Error)?.name === matcher\n : matcher instanceof RegExp\n ? matcher.test(String(error))\n : error instanceof matcher\n )\n if (!is_retryable) throw error\n }\n\n // Last attempt: rethrow\n if (attempt >= effective_max_attempts) throw error\n\n // Wait before next attempt with exponential backoff\n const delay_seconds = effective_retry_after * Math.pow(retry_backoff_factor, attempt - 1)\n if (delay_seconds > 0) {\n await sleep(delay_seconds * 1000)\n }\n }\n }\n\n // Unreachable, but satisfies the type checker\n throw new Error(`retry(${fn_name}): unexpected end of retry loop`)\n }\n\n try {\n return await runWithHeldSemaphores(new_held, runRetryLoop)\n } finally {\n if (semaphore_acquired && semaphore) {\n semaphore.release()\n }\n }\n }\n\n Object.defineProperty(retryWrapper, 'name', { value: fn_name, configurable: true })\n return retryWrapper as unknown as T\n }\n}\n\n// \u2500\u2500\u2500 Internal helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Try to acquire a semaphore within a timeout. Returns true if acquired, false if timed out.\n * If the semaphore is acquired after the timeout (due to the waiter remaining queued),\n * it is immediately released to avoid leaking slots.\n */\nasync function acquireWithTimeout(semaphore: RetrySemaphore, timeout_ms: number): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n let settled = false\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true\n resolve(false)\n }\n }, timeout_ms)\n\n semaphore.acquire().then(() => {\n if (!settled) {\n settled = true\n clearTimeout(timer)\n resolve(true)\n } else {\n // Acquired after timeout fired \u2014 release immediately to avoid slot leak\n semaphore.release()\n }\n })\n })\n}\n\n/** Run fn() with a timeout. Rejects with RetryTimeoutError if the timeout fires first. */\nasync function _runWithTimeout<T>(fn: () => Promise<T>, timeout_ms: number, attempt: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let settled = false\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true\n reject(\n new RetryTimeoutError(`Timed out after ${timeout_ms / 1000}s (attempt ${attempt})`, {\n timeout_seconds: timeout_ms / 1000,\n attempt,\n })\n )\n }\n }, timeout_ms)\n\n fn().then(\n (value) => {\n if (!settled) {\n settled = true\n clearTimeout(timer)\n resolve(value)\n }\n },\n (error) => {\n if (!settled) {\n settled = true\n clearTimeout(timer)\n reject(error)\n }\n }\n )\n })\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function _runWithTimeout<T>(timeout_seconds: number | null, on_timeout: () => Error, fn: () => Promise<T>): Promise<T>;
|
|
2
|
+
export declare function _runWithSlowMonitor<T>(slow_timer: ReturnType<typeof setTimeout> | null, fn: () => Promise<T>): Promise<T>;
|
|
3
|
+
export declare function _runWithAbortMonitor<T>(fn: () => T | Promise<T>, abort_signal: Promise<never>): Promise<T>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var timing_exports = {};
|
|
20
|
+
__export(timing_exports, {
|
|
21
|
+
_runWithAbortMonitor: () => _runWithAbortMonitor,
|
|
22
|
+
_runWithSlowMonitor: () => _runWithSlowMonitor,
|
|
23
|
+
_runWithTimeout: () => _runWithTimeout
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(timing_exports);
|
|
26
|
+
async function _runWithTimeout(timeout_seconds, on_timeout, fn) {
|
|
27
|
+
const task = Promise.resolve().then(fn);
|
|
28
|
+
if (timeout_seconds === null) {
|
|
29
|
+
return await task;
|
|
30
|
+
}
|
|
31
|
+
const timeout_ms = timeout_seconds * 1e3;
|
|
32
|
+
return await new Promise((resolve, reject) => {
|
|
33
|
+
let settled = false;
|
|
34
|
+
const finishResolve = (value) => {
|
|
35
|
+
if (settled) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
settled = true;
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
resolve(value);
|
|
41
|
+
};
|
|
42
|
+
const finishReject = (error) => {
|
|
43
|
+
if (settled) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
settled = true;
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
reject(error);
|
|
49
|
+
};
|
|
50
|
+
const timer = setTimeout(() => {
|
|
51
|
+
if (settled) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
settled = true;
|
|
55
|
+
reject(on_timeout());
|
|
56
|
+
void task.catch(() => void 0);
|
|
57
|
+
}, timeout_ms);
|
|
58
|
+
task.then(finishResolve).catch(finishReject);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async function _runWithSlowMonitor(slow_timer, fn) {
|
|
62
|
+
try {
|
|
63
|
+
return await fn();
|
|
64
|
+
} finally {
|
|
65
|
+
if (slow_timer) {
|
|
66
|
+
clearTimeout(slow_timer);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function _runWithAbortMonitor(fn, abort_signal) {
|
|
71
|
+
const task = Promise.resolve().then(fn);
|
|
72
|
+
const raced = Promise.race([task, abort_signal]);
|
|
73
|
+
void task.catch(() => void 0);
|
|
74
|
+
return await raced;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=timing.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/timing.ts"],
|
|
4
|
+
"sourcesContent": ["export async function _runWithTimeout<T>(timeout_seconds: number | null, on_timeout: () => Error, fn: () => Promise<T>): Promise<T> {\n const task = Promise.resolve().then(fn)\n if (timeout_seconds === null) {\n return await task\n }\n const timeout_ms = timeout_seconds * 1000\n return await new Promise<T>((resolve, reject) => {\n let settled = false\n const finishResolve = (value: T) => {\n if (settled) {\n return\n }\n settled = true\n clearTimeout(timer)\n resolve(value)\n }\n const finishReject = (error: unknown) => {\n if (settled) {\n return\n }\n settled = true\n clearTimeout(timer)\n reject(error)\n }\n const timer = setTimeout(() => {\n if (settled) {\n return\n }\n settled = true\n reject(on_timeout())\n void task.catch(() => undefined)\n }, timeout_ms)\n task.then(finishResolve).catch(finishReject)\n })\n}\n\nexport async function _runWithSlowMonitor<T>(slow_timer: ReturnType<typeof setTimeout> | null, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn()\n } finally {\n if (slow_timer) {\n clearTimeout(slow_timer)\n }\n }\n}\n\nexport async function _runWithAbortMonitor<T>(fn: () => T | Promise<T>, abort_signal: Promise<never>): Promise<T> {\n const task = Promise.resolve().then(fn)\n const raced = Promise.race([task, abort_signal])\n void task.catch(() => undefined)\n return await raced\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAsB,gBAAmB,iBAAgC,YAAyB,IAAkC;AAClI,QAAM,OAAO,QAAQ,QAAQ,EAAE,KAAK,EAAE;AACtC,MAAI,oBAAoB,MAAM;AAC5B,WAAO,MAAM;AAAA,EACf;AACA,QAAM,aAAa,kBAAkB;AACrC,SAAO,MAAM,IAAI,QAAW,CAAC,SAAS,WAAW;AAC/C,QAAI,UAAU;AACd,UAAM,gBAAgB,CAAC,UAAa;AAClC,UAAI,SAAS;AACX;AAAA,MACF;AACA,gBAAU;AACV,mBAAa,KAAK;AAClB,cAAQ,KAAK;AAAA,IACf;AACA,UAAM,eAAe,CAAC,UAAmB;AACvC,UAAI,SAAS;AACX;AAAA,MACF;AACA,gBAAU;AACV,mBAAa,KAAK;AAClB,aAAO,KAAK;AAAA,IACd;AACA,UAAM,QAAQ,WAAW,MAAM;AAC7B,UAAI,SAAS;AACX;AAAA,MACF;AACA,gBAAU;AACV,aAAO,WAAW,CAAC;AACnB,WAAK,KAAK,MAAM,MAAM,MAAS;AAAA,IACjC,GAAG,UAAU;AACb,SAAK,KAAK,aAAa,EAAE,MAAM,YAAY;AAAA,EAC7C,CAAC;AACH;AAEA,eAAsB,oBAAuB,YAAkD,IAAkC;AAC/H,MAAI;AACF,WAAO,MAAM,GAAG;AAAA,EAClB,UAAE;AACA,QAAI,YAAY;AACd,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF;AACF;AAEA,eAAsB,qBAAwB,IAA0B,cAA0C;AAChH,QAAM,OAAO,QAAQ,QAAQ,EAAE,KAAK,EAAE;AACtC,QAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,YAAY,CAAC;AAC/C,OAAK,KAAK,MAAM,MAAM,MAAS;AAC/B,SAAO,MAAM;AACf;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { BaseEvent } from './base_event.js';
|
|
3
|
+
export type EventStatus = 'pending' | 'started' | 'completed';
|
|
4
|
+
export type EventClass<T extends BaseEvent = BaseEvent> = {
|
|
5
|
+
event_type?: string;
|
|
6
|
+
} & (new (...args: any[]) => T);
|
|
7
|
+
export type EventPattern<T extends BaseEvent = BaseEvent> = string | EventClass<T>;
|
|
8
|
+
export type EventWithResultSchema<TResult> = BaseEvent & {
|
|
9
|
+
__event_result_type__?: TResult;
|
|
10
|
+
};
|
|
11
|
+
export type EventResultType<TEvent extends BaseEvent> = TEvent extends {
|
|
12
|
+
__event_result_type__?: infer TResult;
|
|
13
|
+
} ? TResult : unknown;
|
|
14
|
+
export type EventResultTypeConstructor = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor;
|
|
15
|
+
export type EventResultTypeInput = z.ZodTypeAny | EventResultTypeConstructor | unknown;
|
|
16
|
+
export type EventHandlerReturn<T extends BaseEvent = BaseEvent> = EventResultType<T> | BaseEvent | null | void;
|
|
17
|
+
export type EventHandlerCallable<T extends BaseEvent = BaseEvent> = (event: T) => EventHandlerReturn<T> | Promise<EventHandlerReturn<T>>;
|
|
18
|
+
export type UntypedEventHandlerFunction<T extends BaseEvent = BaseEvent> = (event: T) => EventHandlerReturn<T> | unknown | Promise<EventHandlerReturn<T> | unknown>;
|
|
19
|
+
export type FindWindow = boolean | number;
|
|
20
|
+
type FindReservedOptionKeys = 'past' | 'future' | 'child_of';
|
|
21
|
+
type EventFilterFields<T extends BaseEvent> = {
|
|
22
|
+
[K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K extends FindReservedOptionKeys ? never : T[K] extends (...args: any[]) => any ? never : K]?: T[K];
|
|
23
|
+
};
|
|
24
|
+
export type FindOptions<T extends BaseEvent = BaseEvent> = {
|
|
25
|
+
past?: FindWindow;
|
|
26
|
+
future?: FindWindow;
|
|
27
|
+
child_of?: BaseEvent | null;
|
|
28
|
+
} & EventFilterFields<T> & Record<string, unknown>;
|
|
29
|
+
export declare const normalizeEventPattern: (event_pattern: EventPattern | "*") => string | "*";
|
|
30
|
+
export declare const isZodSchema: (value: unknown) => value is z.ZodTypeAny;
|
|
31
|
+
export declare const eventResultTypeFromConstructor: (value: unknown) => z.ZodTypeAny | undefined;
|
|
32
|
+
export declare const extractZodShape: (raw: Record<string, unknown>) => z.ZodRawShape;
|
|
33
|
+
export declare const toJsonSchema: (schema: unknown) => unknown;
|
|
34
|
+
export declare const fromJsonSchema: (schema: unknown) => z.ZodTypeAny;
|
|
35
|
+
export declare const normalizeEventResultType: (value: EventResultTypeInput) => z.ZodTypeAny | undefined;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var types_exports = {};
|
|
20
|
+
__export(types_exports, {
|
|
21
|
+
eventResultTypeFromConstructor: () => eventResultTypeFromConstructor,
|
|
22
|
+
extractZodShape: () => extractZodShape,
|
|
23
|
+
fromJsonSchema: () => fromJsonSchema,
|
|
24
|
+
isZodSchema: () => isZodSchema,
|
|
25
|
+
normalizeEventPattern: () => normalizeEventPattern,
|
|
26
|
+
normalizeEventResultType: () => normalizeEventResultType,
|
|
27
|
+
toJsonSchema: () => toJsonSchema
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(types_exports);
|
|
30
|
+
var import_zod = require("zod");
|
|
31
|
+
const normalizeEventPattern = (event_pattern) => {
|
|
32
|
+
if (event_pattern === "*") {
|
|
33
|
+
return "*";
|
|
34
|
+
}
|
|
35
|
+
if (typeof event_pattern === "string") {
|
|
36
|
+
return event_pattern;
|
|
37
|
+
}
|
|
38
|
+
const event_type = event_pattern.event_type;
|
|
39
|
+
if (typeof event_type === "string" && event_type.length > 0 && event_type !== "BaseEvent") {
|
|
40
|
+
return event_type;
|
|
41
|
+
}
|
|
42
|
+
const class_name = event_pattern.name;
|
|
43
|
+
if (typeof class_name === "string" && class_name.length > 0 && class_name !== "BaseEvent") {
|
|
44
|
+
return class_name;
|
|
45
|
+
}
|
|
46
|
+
let preview;
|
|
47
|
+
try {
|
|
48
|
+
const encoded = JSON.stringify(event_pattern);
|
|
49
|
+
preview = typeof encoded === "string" ? encoded.slice(0, 30) : String(event_pattern).slice(0, 30);
|
|
50
|
+
} catch {
|
|
51
|
+
preview = String(event_pattern).slice(0, 30);
|
|
52
|
+
}
|
|
53
|
+
throw new Error('bus.on(match_pattern, ...) must be a string event type, "*", or a BaseEvent class, got: ' + preview);
|
|
54
|
+
};
|
|
55
|
+
const isZodSchema = (value) => !!value && typeof value.safeParse === "function";
|
|
56
|
+
const eventResultTypeFromConstructor = (value) => {
|
|
57
|
+
if (value === String) {
|
|
58
|
+
return import_zod.z.string();
|
|
59
|
+
}
|
|
60
|
+
if (value === Number) {
|
|
61
|
+
return import_zod.z.number();
|
|
62
|
+
}
|
|
63
|
+
if (value === Boolean) {
|
|
64
|
+
return import_zod.z.boolean();
|
|
65
|
+
}
|
|
66
|
+
if (value === Array) {
|
|
67
|
+
return import_zod.z.array(import_zod.z.unknown());
|
|
68
|
+
}
|
|
69
|
+
if (value === Object) {
|
|
70
|
+
return import_zod.z.record(import_zod.z.string(), import_zod.z.unknown());
|
|
71
|
+
}
|
|
72
|
+
return void 0;
|
|
73
|
+
};
|
|
74
|
+
const extractZodShape = (raw) => {
|
|
75
|
+
const shape = {};
|
|
76
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
77
|
+
if (key === "event_result_type") continue;
|
|
78
|
+
if (isZodSchema(value)) shape[key] = value;
|
|
79
|
+
}
|
|
80
|
+
return shape;
|
|
81
|
+
};
|
|
82
|
+
const toJsonSchema = (schema) => {
|
|
83
|
+
if (!schema || !isZodSchema(schema)) return schema;
|
|
84
|
+
const zod_any = import_zod.z;
|
|
85
|
+
return zod_any.toJSONSchema(schema);
|
|
86
|
+
};
|
|
87
|
+
const fromJsonSchema = (schema) => {
|
|
88
|
+
const zod_any = import_zod.z;
|
|
89
|
+
return zod_any.fromJSONSchema(schema);
|
|
90
|
+
};
|
|
91
|
+
const normalizeEventResultType = (value) => {
|
|
92
|
+
if (value === void 0 || value === null) {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
if (isZodSchema(value)) {
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
const constructor_schema = eventResultTypeFromConstructor(value);
|
|
99
|
+
if (constructor_schema) {
|
|
100
|
+
return constructor_schema;
|
|
101
|
+
}
|
|
102
|
+
return fromJsonSchema(value);
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/types.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport type { BaseEvent } from './base_event.js'\n\nexport type EventStatus = 'pending' | 'started' | 'completed'\n\nexport type EventClass<T extends BaseEvent = BaseEvent> = { event_type?: string } & (new (...args: any[]) => T)\n\nexport type EventPattern<T extends BaseEvent = BaseEvent> = string | EventClass<T>\n\nexport type EventWithResultSchema<TResult> = BaseEvent & { __event_result_type__?: TResult }\n\nexport type EventResultType<TEvent extends BaseEvent> = TEvent extends { __event_result_type__?: infer TResult } ? TResult : unknown\n\nexport type EventResultTypeConstructor = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor\n\nexport type EventResultTypeInput = z.ZodTypeAny | EventResultTypeConstructor | unknown\n\nexport type EventHandlerReturn<T extends BaseEvent = BaseEvent> = EventResultType<T> | BaseEvent | null | void\n\nexport type EventHandlerCallable<T extends BaseEvent = BaseEvent> = (event: T) => EventHandlerReturn<T> | Promise<EventHandlerReturn<T>>\n\n// For string and wildcard subscriptions we cannot reliably infer which event\n// type will arrive, so return type checking intentionally degrades to unknown.\nexport type UntypedEventHandlerFunction<T extends BaseEvent = BaseEvent> = (\n event: T\n) => EventHandlerReturn<T> | unknown | Promise<EventHandlerReturn<T> | unknown>\n\nexport type FindWindow = boolean | number\n\ntype FindReservedOptionKeys = 'past' | 'future' | 'child_of'\n\ntype EventFilterFields<T extends BaseEvent> = {\n [K in keyof T as string extends K\n ? never\n : number extends K\n ? never\n : symbol extends K\n ? never\n : K extends FindReservedOptionKeys\n ? never\n : T[K] extends (...args: any[]) => any\n ? never\n : K]?: T[K]\n}\n\nexport type FindOptions<T extends BaseEvent = BaseEvent> = {\n past?: FindWindow\n future?: FindWindow\n child_of?: BaseEvent | null\n} & EventFilterFields<T> &\n Record<string, unknown>\n\nexport const normalizeEventPattern = (event_pattern: EventPattern | '*'): string | '*' => {\n if (event_pattern === '*') {\n return '*'\n }\n if (typeof event_pattern === 'string') {\n return event_pattern\n }\n const event_type = (event_pattern as { event_type?: unknown }).event_type\n if (typeof event_type === 'string' && event_type.length > 0 && event_type !== 'BaseEvent') {\n return event_type\n }\n const class_name = (event_pattern as { name?: unknown }).name\n if (typeof class_name === 'string' && class_name.length > 0 && class_name !== 'BaseEvent') {\n return class_name\n }\n let preview: string\n try {\n const encoded = JSON.stringify(event_pattern)\n preview = typeof encoded === 'string' ? encoded.slice(0, 30) : String(event_pattern).slice(0, 30)\n } catch {\n preview = String(event_pattern).slice(0, 30)\n }\n throw new Error('bus.on(match_pattern, ...) must be a string event type, \"*\", or a BaseEvent class, got: ' + preview)\n}\n\nexport const isZodSchema = (value: unknown): value is z.ZodTypeAny => !!value && typeof (value as z.ZodTypeAny).safeParse === 'function'\n\nexport const eventResultTypeFromConstructor = (value: unknown): z.ZodTypeAny | undefined => {\n if (value === String) {\n return z.string()\n }\n if (value === Number) {\n return z.number()\n }\n if (value === Boolean) {\n return z.boolean()\n }\n if (value === Array) {\n return z.array(z.unknown())\n }\n if (value === Object) {\n return z.record(z.string(), z.unknown())\n }\n return undefined\n}\n\nexport const extractZodShape = (raw: Record<string, unknown>): z.ZodRawShape => {\n const shape: Record<string, z.ZodTypeAny> = {}\n for (const [key, value] of Object.entries(raw)) {\n if (key === 'event_result_type') continue\n if (isZodSchema(value)) shape[key] = value\n }\n return shape as z.ZodRawShape\n}\n\nexport const toJsonSchema = (schema: unknown): unknown => {\n if (!schema || !isZodSchema(schema)) return schema\n const zod_any = z as unknown as { toJSONSchema: (input: z.ZodTypeAny) => unknown }\n // Cross-language roundtrips preserve core structural types; constraint keywords may not roundtrip exactly.\n return zod_any.toJSONSchema(schema)\n}\n\nexport const fromJsonSchema = (schema: unknown): z.ZodTypeAny => {\n const zod_any = z as unknown as { fromJSONSchema: (input: unknown) => z.ZodTypeAny }\n return zod_any.fromJSONSchema(schema)\n}\n\nexport const normalizeEventResultType = (value: EventResultTypeInput): z.ZodTypeAny | undefined => {\n if (value === undefined || value === null) {\n return undefined\n }\n if (isZodSchema(value)) {\n return value\n }\n const constructor_schema = eventResultTypeFromConstructor(value)\n if (constructor_schema) {\n return constructor_schema\n }\n return fromJsonSchema(value)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAkB;AAoDX,MAAM,wBAAwB,CAAC,kBAAoD;AACxF,MAAI,kBAAkB,KAAK;AACzB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,kBAAkB,UAAU;AACrC,WAAO;AAAA,EACT;AACA,QAAM,aAAc,cAA2C;AAC/D,MAAI,OAAO,eAAe,YAAY,WAAW,SAAS,KAAK,eAAe,aAAa;AACzF,WAAO;AAAA,EACT;AACA,QAAM,aAAc,cAAqC;AACzD,MAAI,OAAO,eAAe,YAAY,WAAW,SAAS,KAAK,eAAe,aAAa;AACzF,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI;AACF,UAAM,UAAU,KAAK,UAAU,aAAa;AAC5C,cAAU,OAAO,YAAY,WAAW,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAO,aAAa,EAAE,MAAM,GAAG,EAAE;AAAA,EAClG,QAAQ;AACN,cAAU,OAAO,aAAa,EAAE,MAAM,GAAG,EAAE;AAAA,EAC7C;AACA,QAAM,IAAI,MAAM,6FAA6F,OAAO;AACtH;AAEO,MAAM,cAAc,CAAC,UAA0C,CAAC,CAAC,SAAS,OAAQ,MAAuB,cAAc;AAEvH,MAAM,iCAAiC,CAAC,UAA6C;AAC1F,MAAI,UAAU,QAAQ;AACpB,WAAO,aAAE,OAAO;AAAA,EAClB;AACA,MAAI,UAAU,QAAQ;AACpB,WAAO,aAAE,OAAO;AAAA,EAClB;AACA,MAAI,UAAU,SAAS;AACrB,WAAO,aAAE,QAAQ;AAAA,EACnB;AACA,MAAI,UAAU,OAAO;AACnB,WAAO,aAAE,MAAM,aAAE,QAAQ,CAAC;AAAA,EAC5B;AACA,MAAI,UAAU,QAAQ;AACpB,WAAO,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC;AAAA,EACzC;AACA,SAAO;AACT;AAEO,MAAM,kBAAkB,CAAC,QAAgD;AAC9E,QAAM,QAAsC,CAAC;AAC7C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,QAAI,QAAQ,oBAAqB;AACjC,QAAI,YAAY,KAAK,EAAG,OAAM,GAAG,IAAI;AAAA,EACvC;AACA,SAAO;AACT;AAEO,MAAM,eAAe,CAAC,WAA6B;AACxD,MAAI,CAAC,UAAU,CAAC,YAAY,MAAM,EAAG,QAAO;AAC5C,QAAM,UAAU;AAEhB,SAAO,QAAQ,aAAa,MAAM;AACpC;AAEO,MAAM,iBAAiB,CAAC,WAAkC;AAC/D,QAAM,UAAU;AAChB,SAAO,QAAQ,eAAe,MAAM;AACtC;AAEO,MAAM,2BAA2B,CAAC,UAA0D;AACjG,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAO;AAAA,EACT;AACA,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,qBAAqB,+BAA+B,KAAK;AAC/D,MAAI,oBAAoB;AACtB,WAAO;AAAA,EACT;AACA,SAAO,eAAe,KAAK;AAC7B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
let _AsyncLocalStorageClass = null;
|
|
2
|
+
const is_node = typeof process !== "undefined" && typeof process.versions !== "undefined" && typeof process.versions.node === "string";
|
|
3
|
+
const loadAsyncLocalStorageClass = () => {
|
|
4
|
+
if (!is_node) return null;
|
|
5
|
+
const maybe_process = globalThis.process;
|
|
6
|
+
const get_builtin_module = maybe_process?.getBuiltinModule;
|
|
7
|
+
if (typeof get_builtin_module === "function") {
|
|
8
|
+
const mod = get_builtin_module("node:async_hooks");
|
|
9
|
+
if (mod?.AsyncLocalStorage) {
|
|
10
|
+
return mod.AsyncLocalStorage;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const maybe_require = Function('return typeof require === "function" ? require : undefined')();
|
|
15
|
+
const mod = maybe_require?.("node:async_hooks");
|
|
16
|
+
if (mod?.AsyncLocalStorage) {
|
|
17
|
+
return mod.AsyncLocalStorage;
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
_AsyncLocalStorageClass = loadAsyncLocalStorageClass();
|
|
25
|
+
const createAsyncLocalStorage = () => {
|
|
26
|
+
if (!_AsyncLocalStorageClass) return null;
|
|
27
|
+
return new _AsyncLocalStorageClass();
|
|
28
|
+
};
|
|
29
|
+
let async_local_storage = _AsyncLocalStorageClass ? new _AsyncLocalStorageClass() : null;
|
|
30
|
+
const captureAsyncContext = () => {
|
|
31
|
+
if (!async_local_storage) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return async_local_storage.getStore() ?? null;
|
|
35
|
+
};
|
|
36
|
+
const _runWithAsyncContext = (context, fn) => {
|
|
37
|
+
if (!async_local_storage) {
|
|
38
|
+
return fn();
|
|
39
|
+
}
|
|
40
|
+
return async_local_storage.run(context ?? void 0, fn);
|
|
41
|
+
};
|
|
42
|
+
const hasAsyncLocalStorage = () => async_local_storage !== null;
|
|
43
|
+
export {
|
|
44
|
+
_runWithAsyncContext,
|
|
45
|
+
async_local_storage,
|
|
46
|
+
captureAsyncContext,
|
|
47
|
+
createAsyncLocalStorage,
|
|
48
|
+
hasAsyncLocalStorage
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=async_context.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/async_context.ts"],
|
|
4
|
+
"sourcesContent": ["declare const process: { versions?: { node?: string } } | undefined\n\ntype AsyncLocalStorageLike = {\n getStore(): unknown\n run<T>(store: unknown, callback: () => T): T\n enterWith?(store: unknown): void\n}\n\nexport type { AsyncLocalStorageLike }\n\n// Cache the AsyncLocalStorage constructor so multiple modules can create separate instances.\nlet _AsyncLocalStorageClass: (new () => AsyncLocalStorageLike) | null = null\n\nconst is_node = typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.node === 'string'\n\nconst loadAsyncLocalStorageClass = (): (new () => AsyncLocalStorageLike) | null => {\n if (!is_node) return null\n\n // Prefer process.getBuiltinModule when available (works in ESM and CJS without top-level await).\n const maybe_process = (globalThis as { process?: { getBuiltinModule?: (name: string) => unknown } }).process\n const get_builtin_module = maybe_process?.getBuiltinModule\n if (typeof get_builtin_module === 'function') {\n const mod = get_builtin_module('node:async_hooks') as { AsyncLocalStorage?: new () => AsyncLocalStorageLike } | undefined\n if (mod?.AsyncLocalStorage) {\n return mod.AsyncLocalStorage\n }\n }\n\n // Fallback for older Node runtimes where require is available.\n try {\n const maybe_require = Function('return typeof require === \"function\" ? require : undefined')() as\n | ((specifier: string) => { AsyncLocalStorage?: new () => AsyncLocalStorageLike })\n | undefined\n const mod = maybe_require?.('node:async_hooks')\n if (mod?.AsyncLocalStorage) {\n return mod.AsyncLocalStorage\n }\n } catch {\n return null\n }\n\n return null\n}\n\n_AsyncLocalStorageClass = loadAsyncLocalStorageClass()\n\n/** Create a new AsyncLocalStorage instance, or null if unavailable (e.g. in browsers). */\nexport const createAsyncLocalStorage = (): AsyncLocalStorageLike | null => {\n if (!_AsyncLocalStorageClass) return null\n return new _AsyncLocalStorageClass()\n}\n\n// The primary AsyncLocalStorage instance used for event dispatch context propagation.\nexport let async_local_storage: AsyncLocalStorageLike | null = _AsyncLocalStorageClass ? new _AsyncLocalStorageClass() : null\n\nexport const captureAsyncContext = (): unknown | null => {\n if (!async_local_storage) {\n return null\n }\n return async_local_storage.getStore() ?? null\n}\n\nexport const _runWithAsyncContext = <T>(context: unknown | null, fn: () => T): T => {\n if (!async_local_storage) {\n return fn()\n }\n return async_local_storage.run(context ?? undefined, fn)\n}\n\nexport const hasAsyncLocalStorage = (): boolean => async_local_storage !== null\n"],
|
|
5
|
+
"mappings": "AAWA,IAAI,0BAAoE;AAExE,MAAM,UAAU,OAAO,YAAY,eAAe,OAAO,QAAQ,aAAa,eAAe,OAAO,QAAQ,SAAS,SAAS;AAE9H,MAAM,6BAA6B,MAAgD;AACjF,MAAI,CAAC,QAAS,QAAO;AAGrB,QAAM,gBAAiB,WAA8E;AACrG,QAAM,qBAAqB,eAAe;AAC1C,MAAI,OAAO,uBAAuB,YAAY;AAC5C,UAAM,MAAM,mBAAmB,kBAAkB;AACjD,QAAI,KAAK,mBAAmB;AAC1B,aAAO,IAAI;AAAA,IACb;AAAA,EACF;AAGA,MAAI;AACF,UAAM,gBAAgB,SAAS,4DAA4D,EAAE;AAG7F,UAAM,MAAM,gBAAgB,kBAAkB;AAC9C,QAAI,KAAK,mBAAmB;AAC1B,aAAO,IAAI;AAAA,IACb;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,0BAA0B,2BAA2B;AAG9C,MAAM,0BAA0B,MAAoC;AACzE,MAAI,CAAC,wBAAyB,QAAO;AACrC,SAAO,IAAI,wBAAwB;AACrC;AAGO,IAAI,sBAAoD,0BAA0B,IAAI,wBAAwB,IAAI;AAElH,MAAM,sBAAsB,MAAsB;AACvD,MAAI,CAAC,qBAAqB;AACxB,WAAO;AAAA,EACT;AACA,SAAO,oBAAoB,SAAS,KAAK;AAC3C;AAEO,MAAM,uBAAuB,CAAI,SAAyB,OAAmB;AAClF,MAAI,CAAC,qBAAqB;AACxB,WAAO,GAAG;AAAA,EACZ;AACA,SAAO,oBAAoB,IAAI,WAAW,QAAW,EAAE;AACzD;AAEO,MAAM,uBAAuB,MAAe,wBAAwB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|