@zudojs/adapters 1.2.2 → 1.3.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 +25 -5
- package/dist/adapter/adapter.health.d.ts +0 -1
- package/dist/adapter/adapter.health.js +7 -6
- package/dist/adapter/adapter.registry.d.ts +30 -27
- package/dist/adapter/adapter.registry.js +30 -64
- package/dist/adapter/adapter.retry.d.ts +0 -1
- package/dist/adapter/adapter.retry.js +0 -1
- package/dist/adapter/adapter.type.d.ts +0 -1
- package/dist/adapter/adapter.type.js +0 -1
- package/dist/adapter/adapterLifecycle/adapterLifecycle.all.d.ts +28 -0
- package/dist/adapter/adapterLifecycle/adapterLifecycle.all.js +60 -0
- package/dist/adapter/adapterLifecycle/adapterLifecycle.ops.d.ts +38 -0
- package/dist/adapter/adapterLifecycle/adapterLifecycle.ops.js +95 -0
- package/dist/adapter/adapterLifecycle/index.d.ts +9 -0
- package/dist/adapter/adapterLifecycle/index.js +8 -0
- package/dist/adapter/index.d.ts +3 -1
- package/dist/adapter/index.js +2 -1
- package/dist/capabilities/capabilities.type.d.ts +16 -2
- package/dist/capabilities/capabilities.type.js +0 -1
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/index.js +0 -1
- package/dist/cli/cliAdapter.type.d.ts +0 -1
- package/dist/cli/cliAdapter.type.js +0 -1
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +0 -1
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/http/httpAdapter.type.d.ts +0 -1
- package/dist/http/httpAdapter.type.js +0 -1
- package/dist/http/index.d.ts +0 -1
- package/dist/http/index.js +0 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.js +1 -2
- package/dist/lifecycle/index.d.ts +0 -1
- package/dist/lifecycle/index.js +0 -1
- package/dist/lifecycle/lifecycle.type.d.ts +0 -1
- package/dist/lifecycle/lifecycle.type.js +0 -1
- package/dist/messaging/index.d.ts +0 -1
- package/dist/messaging/index.js +0 -1
- package/dist/messaging/messageAdapter.type.d.ts +0 -1
- package/dist/messaging/messageAdapter.type.js +0 -1
- package/dist/metadata/index.d.ts +0 -1
- package/dist/metadata/index.js +0 -1
- package/dist/metadata/metadata.type.d.ts +0 -1
- package/dist/metadata/metadata.type.js +0 -1
- package/dist/queue/index.d.ts +0 -1
- package/dist/queue/index.js +0 -1
- package/dist/queue/queueAdapter.type.d.ts +0 -1
- package/dist/queue/queueAdapter.type.js +0 -1
- package/dist/runtime/index.d.ts +0 -1
- package/dist/runtime/index.js +0 -1
- package/dist/runtime/runtimeAdapter.type.d.ts +0 -1
- package/dist/runtime/runtimeAdapter.type.js +0 -1
- package/dist/scheduler/index.d.ts +0 -1
- package/dist/scheduler/index.js +0 -1
- package/dist/scheduler/schedulerAdapter.type.d.ts +0 -1
- package/dist/scheduler/schedulerAdapter.type.js +0 -1
- package/dist/storage/index.d.ts +0 -1
- package/dist/storage/index.js +0 -1
- package/dist/storage/storageAdapter.type.d.ts +0 -1
- package/dist/storage/storageAdapter.type.js +0 -1
- package/dist/testing/adapterTesting.helper.d.ts +0 -1
- package/dist/testing/adapterTesting.helper.js +0 -1
- package/dist/testing/index.d.ts +0 -1
- package/dist/testing/index.js +0 -1
- package/dist/websocket/index.d.ts +0 -1
- package/dist/websocket/index.js +0 -1
- package/dist/websocket/websocketAdapter.type.d.ts +0 -1
- package/dist/websocket/websocketAdapter.type.js +0 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -61,7 +61,22 @@ await registry.disposeAll(); // stop, dispose, and empty the registry
|
|
|
61
61
|
|
|
62
62
|
Each of these attempts every adapter and then throws an `AggregateError`
|
|
63
63
|
carrying the failures, rather than stopping at the first one — a half-applied
|
|
64
|
-
transition leaves resources nobody is tracking.
|
|
64
|
+
transition leaves resources nobody is tracking. From `initializeAll()`,
|
|
65
|
+
`startAll()` and `stopAll()` every entry in `errors` is typed and names its
|
|
66
|
+
adapter — `AdapterInitializationError`, `AdapterOperationError` (operation
|
|
67
|
+
`"start"` or `"stop"`), or `AdapterTimeoutError` when the hook exceeded
|
|
68
|
+
`timeout` — with the hook's own error as `cause`. `disposeAll()` and
|
|
69
|
+
`removeAndDispose()` rethrow the hooks' own errors (an `AggregateError` of
|
|
70
|
+
both when `stop()` and `dispose()` both failed).
|
|
71
|
+
|
|
72
|
+
`initializeAll()` and `startAll()` run in registration order; `stopAll()` and
|
|
73
|
+
`disposeAll()` run in reverse, so an adapter is torn down before the ones
|
|
74
|
+
registered ahead of it that it may depend on. `initializeAll()`,
|
|
75
|
+
`startAll()` and `stopAll()` take the same `AdapterOperationOptions` as
|
|
76
|
+
`healthAll()`: `timeout` bounds each hook, `retry: { attempts, delay }`
|
|
77
|
+
re-runs a failed one, and `signal` stops the pass.
|
|
78
|
+
`runAdapterLifecycle(adapter, "start", options)` runs one hook the same way,
|
|
79
|
+
and `withRetry` is exported for your own operations.
|
|
65
80
|
|
|
66
81
|
`remove()` and `clear()` only drop references; `removeAndDispose()` and
|
|
67
82
|
`disposeAll()` also release resources.
|
|
@@ -77,9 +92,12 @@ registry.supports("postgres", "gracefulShutdown"); // boolean, never throws
|
|
|
77
92
|
registry.requireCapability("edge", "streaming"); // throws AdapterCapabilityMissingError
|
|
78
93
|
```
|
|
79
94
|
|
|
80
|
-
|
|
81
|
-
`
|
|
82
|
-
`gracefulShutdown`, `abortSignal`.
|
|
95
|
+
Well-known capabilities (`KnownAdapterCapabilities`): `http`, `websocket`,
|
|
96
|
+
`streaming`, `filesystem`, `tcp`, `udp`, `backgroundTasks`, `longRunning`,
|
|
97
|
+
`edgeRuntime`, `serverless`, `gracefulShutdown`, `abortSignal`.
|
|
98
|
+
`AdapterCapabilities` is open: an adapter may declare any other name
|
|
99
|
+
(`capabilities: { refunds: true }`) and `findByCapability("refunds")`,
|
|
100
|
+
`supports()` and `requireCapability()` look it up like any other.
|
|
83
101
|
|
|
84
102
|
## Health
|
|
85
103
|
|
|
@@ -118,7 +136,9 @@ report.status; // worst of the per-adapter statuses: "healthy" | "degraded" | "u
|
|
|
118
136
|
report.adapters.db; // AdapterHealth; throwing, timed-out or aborted checks are "unhealthy"
|
|
119
137
|
```
|
|
120
138
|
|
|
121
|
-
Adapters without `health()` are left out of `report.adapters
|
|
139
|
+
Adapters without `health()` are left out of `report.adapters`; the rest appear
|
|
140
|
+
in registration order, whichever check finished first. `collectAdapterHealth`
|
|
141
|
+
and `configureAdapter` are exported for registries of your own.
|
|
122
142
|
|
|
123
143
|
`healthAll({ retry: { attempts, delay } })` re-runs a check that reports
|
|
124
144
|
`unhealthy`, up to `attempts` tries in total, pausing `delay` ms between
|
|
@@ -28,4 +28,3 @@ export declare function collectAdapterHealth(entries: ReadonlyArray<readonly [st
|
|
|
28
28
|
* @throws {AdapterConfigurationError} If the adapter has no `configure()` hook.
|
|
29
29
|
*/
|
|
30
30
|
export declare function configureAdapter(name: string, adapter: Adapter, options: unknown): Promise<void>;
|
|
31
|
-
//# sourceMappingURL=adapter.health.d.ts.map
|
|
@@ -66,11 +66,13 @@ export async function collectAdapterHealth(entries, options = {}) {
|
|
|
66
66
|
// ordinary object runs the inherited prototype setter, so the entry would
|
|
67
67
|
// vanish from the report and an unhealthy adapter would be invisible.
|
|
68
68
|
const adapters = Object.create(null);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
const checked = entries.filter(([, adapter]) => typeof adapter.health === "function");
|
|
70
|
+
// Checks run concurrently but are recorded in registration order, so the
|
|
71
|
+
// report's key order does not depend on which check finished first.
|
|
72
|
+
const results = await Promise.all(checked.map(([, adapter]) => checkOne(adapter, options)));
|
|
73
|
+
checked.forEach(([name], index) => {
|
|
74
|
+
adapters[name] = results[index];
|
|
75
|
+
});
|
|
74
76
|
let status = "healthy";
|
|
75
77
|
for (const health of Object.values(adapters)) {
|
|
76
78
|
const rank = RANK[health.status] ?? RANK.unhealthy;
|
|
@@ -91,4 +93,3 @@ export async function configureAdapter(name, adapter, options) {
|
|
|
91
93
|
}
|
|
92
94
|
await configurable.configure(options);
|
|
93
95
|
}
|
|
94
|
-
//# sourceMappingURL=adapter.health.js.map
|
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
* `removeAndDispose()` / `disposeAll()` to also release adapter resources.
|
|
13
13
|
*/
|
|
14
14
|
import type { Adapter } from "./adapter.type.js";
|
|
15
|
-
import type {
|
|
15
|
+
import type { KnownAdapterCapabilities } from "../capabilities/capabilities.type.js";
|
|
16
16
|
import type { AdapterHealthReport } from "./adapter.health.js";
|
|
17
17
|
import type { AdapterOperationOptions } from "../lifecycle/lifecycle.type.js";
|
|
18
|
-
/**
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* A capability an adapter can declare: one of the well-known names, with
|
|
20
|
+
* completion, or any other string (a business capability such as
|
|
21
|
+
* `"refunds"`).
|
|
22
|
+
*/
|
|
23
|
+
export type AdapterCapabilityName = (keyof KnownAdapterCapabilities & string) | (string & {});
|
|
20
24
|
/**
|
|
21
25
|
* Registry for Zudojs adapters.
|
|
22
26
|
*
|
|
@@ -104,21 +108,34 @@ export declare class AdapterRegistry {
|
|
|
104
108
|
* part of the adapter contract with nothing in the package that ever called
|
|
105
109
|
* them, so an adapter could only be torn down, never brought up.
|
|
106
110
|
*
|
|
111
|
+
* `options.timeout` bounds each adapter's hook, `options.retry` re-runs a
|
|
112
|
+
* failed one and `options.signal` stops the whole pass, as for
|
|
113
|
+
* {@link healthAll}.
|
|
114
|
+
*
|
|
107
115
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
116
|
+
* Each entry is an `AdapterInitializationError` (or `AdapterTimeoutError`)
|
|
117
|
+
* naming its adapter, with the hook's own error as `cause`.
|
|
108
118
|
*/
|
|
109
|
-
initializeAll(): Promise<void>;
|
|
119
|
+
initializeAll(options?: AdapterOperationOptions): Promise<void>;
|
|
110
120
|
/**
|
|
111
121
|
* Starts every registered adapter, in registration order.
|
|
112
122
|
*
|
|
113
123
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
124
|
+
* Each entry is an `AdapterOperationError` (or `AdapterTimeoutError`)
|
|
125
|
+
* naming its adapter, with the hook's own error as `cause`.
|
|
114
126
|
*/
|
|
115
|
-
startAll(): Promise<void>;
|
|
127
|
+
startAll(options?: AdapterOperationOptions): Promise<void>;
|
|
116
128
|
/**
|
|
117
|
-
* Stops every registered adapter without disposing or unregistering them
|
|
129
|
+
* Stops every registered adapter without disposing or unregistering them,
|
|
130
|
+
* in reverse registration order — the mirror of {@link startAll}, so an
|
|
131
|
+
* adapter is stopped before anything registered ahead of it that it may
|
|
132
|
+
* depend on.
|
|
118
133
|
*
|
|
119
134
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
135
|
+
* Each entry is an `AdapterOperationError` (or `AdapterTimeoutError`)
|
|
136
|
+
* naming its adapter, with the hook's own error as `cause`.
|
|
120
137
|
*/
|
|
121
|
-
stopAll(): Promise<void>;
|
|
138
|
+
stopAll(options?: AdapterOperationOptions): Promise<void>;
|
|
122
139
|
/**
|
|
123
140
|
* Checks the health of every adapter that implements `health()`. Failures,
|
|
124
141
|
* timeouts (`options.timeout`) and aborts (`options.signal`) are reported
|
|
@@ -143,29 +160,15 @@ export declare class AdapterRegistry {
|
|
|
143
160
|
*/
|
|
144
161
|
clear(): void;
|
|
145
162
|
/**
|
|
146
|
-
* Clears the registry and releases every adapter's resources
|
|
147
|
-
*
|
|
163
|
+
* Clears the registry and releases every adapter's resources (calls
|
|
164
|
+
* `stop()` then `dispose()` when defined, best-effort), in reverse
|
|
165
|
+
* registration order like {@link stopAll}.
|
|
148
166
|
*
|
|
149
167
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
168
|
+
* Each entry is what {@link removeAndDispose} would have thrown for that
|
|
169
|
+
* adapter: the hook's own error, or an `AggregateError` of both when its
|
|
170
|
+
* `stop()` and `dispose()` both failed.
|
|
150
171
|
*/
|
|
151
172
|
disposeAll(): Promise<void>;
|
|
152
|
-
/**
|
|
153
|
-
* Stops, then disposes, one adapter.
|
|
154
|
-
*
|
|
155
|
-
* `dispose()` runs even when `stop()` throws: the adapter has already
|
|
156
|
-
* left the registry by the time this is called, so skipping disposal
|
|
157
|
-
* would orphan its connections and timers with nothing left holding a
|
|
158
|
-
* reference to release them. A `stop()` failure is still reported — on
|
|
159
|
-
* its own when disposal succeeds, alongside the disposal error when
|
|
160
|
-
* both fail.
|
|
161
|
-
*/
|
|
162
|
-
private teardown;
|
|
163
|
-
/**
|
|
164
|
-
* Runs an operation against every adapter, collecting failures rather than
|
|
165
|
-
* stopping at the first one — a half-applied lifecycle transition leaves
|
|
166
|
-
* resources in a state nobody tracked.
|
|
167
|
-
*/
|
|
168
|
-
private forEachAdapter;
|
|
169
173
|
private normalizeName;
|
|
170
174
|
}
|
|
171
|
-
//# sourceMappingURL=adapter.registry.d.ts.map
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { AdapterAlreadyRegisteredError, AdapterCapabilityMissingError, AdapterConfigurationError, AdapterNotFoundError, } from "@zudojs/errors";
|
|
15
15
|
import { collectAdapterHealth, configureAdapter } from "./adapter.health.js";
|
|
16
|
+
import { runAdapterLifecycleAll, teardownAdapter, } from "./adapterLifecycle/index.js";
|
|
16
17
|
/** Names that are unsafe as a plain-object key, so no adapter may claim them. */
|
|
17
18
|
const RESERVED_NAMES = new Set([
|
|
18
19
|
"__proto__",
|
|
@@ -99,7 +100,7 @@ export class AdapterRegistry {
|
|
|
99
100
|
return false;
|
|
100
101
|
}
|
|
101
102
|
this.adapters.delete(key);
|
|
102
|
-
await
|
|
103
|
+
await teardownAdapter(adapter);
|
|
103
104
|
return true;
|
|
104
105
|
}
|
|
105
106
|
/**
|
|
@@ -153,26 +154,39 @@ export class AdapterRegistry {
|
|
|
153
154
|
* part of the adapter contract with nothing in the package that ever called
|
|
154
155
|
* them, so an adapter could only be torn down, never brought up.
|
|
155
156
|
*
|
|
157
|
+
* `options.timeout` bounds each adapter's hook, `options.retry` re-runs a
|
|
158
|
+
* failed one and `options.signal` stops the whole pass, as for
|
|
159
|
+
* {@link healthAll}.
|
|
160
|
+
*
|
|
156
161
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
162
|
+
* Each entry is an `AdapterInitializationError` (or `AdapterTimeoutError`)
|
|
163
|
+
* naming its adapter, with the hook's own error as `cause`.
|
|
157
164
|
*/
|
|
158
|
-
async initializeAll() {
|
|
159
|
-
await this.
|
|
165
|
+
async initializeAll(options = {}) {
|
|
166
|
+
await runAdapterLifecycleAll([...this.adapters.values()], "initialize", options, "One or more adapters failed to initialize.");
|
|
160
167
|
}
|
|
161
168
|
/**
|
|
162
169
|
* Starts every registered adapter, in registration order.
|
|
163
170
|
*
|
|
164
171
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
172
|
+
* Each entry is an `AdapterOperationError` (or `AdapterTimeoutError`)
|
|
173
|
+
* naming its adapter, with the hook's own error as `cause`.
|
|
165
174
|
*/
|
|
166
|
-
async startAll() {
|
|
167
|
-
await this.
|
|
175
|
+
async startAll(options = {}) {
|
|
176
|
+
await runAdapterLifecycleAll([...this.adapters.values()], "start", options, "One or more adapters failed to start.");
|
|
168
177
|
}
|
|
169
178
|
/**
|
|
170
|
-
* Stops every registered adapter without disposing or unregistering them
|
|
179
|
+
* Stops every registered adapter without disposing or unregistering them,
|
|
180
|
+
* in reverse registration order — the mirror of {@link startAll}, so an
|
|
181
|
+
* adapter is stopped before anything registered ahead of it that it may
|
|
182
|
+
* depend on.
|
|
171
183
|
*
|
|
172
184
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
185
|
+
* Each entry is an `AdapterOperationError` (or `AdapterTimeoutError`)
|
|
186
|
+
* naming its adapter, with the hook's own error as `cause`.
|
|
173
187
|
*/
|
|
174
|
-
async stopAll() {
|
|
175
|
-
await this.
|
|
188
|
+
async stopAll(options = {}) {
|
|
189
|
+
await runAdapterLifecycleAll([...this.adapters.values()].reverse(), "stop", options, "One or more adapters failed to stop.");
|
|
176
190
|
}
|
|
177
191
|
/**
|
|
178
192
|
* Checks the health of every adapter that implements `health()`. Failures,
|
|
@@ -206,18 +220,22 @@ export class AdapterRegistry {
|
|
|
206
220
|
this.adapters.clear();
|
|
207
221
|
}
|
|
208
222
|
/**
|
|
209
|
-
* Clears the registry and releases every adapter's resources
|
|
210
|
-
*
|
|
223
|
+
* Clears the registry and releases every adapter's resources (calls
|
|
224
|
+
* `stop()` then `dispose()` when defined, best-effort), in reverse
|
|
225
|
+
* registration order like {@link stopAll}.
|
|
211
226
|
*
|
|
212
227
|
* @throws {AggregateError} After attempting all adapters, if any failed.
|
|
228
|
+
* Each entry is what {@link removeAndDispose} would have thrown for that
|
|
229
|
+
* adapter: the hook's own error, or an `AggregateError` of both when its
|
|
230
|
+
* `stop()` and `dispose()` both failed.
|
|
213
231
|
*/
|
|
214
232
|
async disposeAll() {
|
|
215
|
-
const adapters = [...this.adapters.values()];
|
|
233
|
+
const adapters = [...this.adapters.values()].reverse();
|
|
216
234
|
this.adapters.clear();
|
|
217
235
|
const failures = [];
|
|
218
236
|
for (const adapter of adapters) {
|
|
219
237
|
try {
|
|
220
|
-
await
|
|
238
|
+
await teardownAdapter(adapter);
|
|
221
239
|
}
|
|
222
240
|
catch (error) {
|
|
223
241
|
failures.push(error);
|
|
@@ -227,59 +245,7 @@ export class AdapterRegistry {
|
|
|
227
245
|
throw new AggregateError(failures, "One or more adapters failed to dispose.");
|
|
228
246
|
}
|
|
229
247
|
}
|
|
230
|
-
/**
|
|
231
|
-
* Stops, then disposes, one adapter.
|
|
232
|
-
*
|
|
233
|
-
* `dispose()` runs even when `stop()` throws: the adapter has already
|
|
234
|
-
* left the registry by the time this is called, so skipping disposal
|
|
235
|
-
* would orphan its connections and timers with nothing left holding a
|
|
236
|
-
* reference to release them. A `stop()` failure is still reported — on
|
|
237
|
-
* its own when disposal succeeds, alongside the disposal error when
|
|
238
|
-
* both fail.
|
|
239
|
-
*/
|
|
240
|
-
async teardown(adapter) {
|
|
241
|
-
let stopError;
|
|
242
|
-
let stopFailed = false;
|
|
243
|
-
try {
|
|
244
|
-
await adapter.stop?.();
|
|
245
|
-
}
|
|
246
|
-
catch (error) {
|
|
247
|
-
stopFailed = true;
|
|
248
|
-
stopError = error;
|
|
249
|
-
}
|
|
250
|
-
try {
|
|
251
|
-
await adapter.dispose?.();
|
|
252
|
-
}
|
|
253
|
-
catch (error) {
|
|
254
|
-
if (stopFailed) {
|
|
255
|
-
throw new AggregateError([stopError, error], `Adapter "${adapter.name}" failed to stop and to dispose.`);
|
|
256
|
-
}
|
|
257
|
-
throw error;
|
|
258
|
-
}
|
|
259
|
-
if (stopFailed)
|
|
260
|
-
throw stopError;
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Runs an operation against every adapter, collecting failures rather than
|
|
264
|
-
* stopping at the first one — a half-applied lifecycle transition leaves
|
|
265
|
-
* resources in a state nobody tracked.
|
|
266
|
-
*/
|
|
267
|
-
async forEachAdapter(operation, message) {
|
|
268
|
-
const failures = [];
|
|
269
|
-
for (const adapter of [...this.adapters.values()]) {
|
|
270
|
-
try {
|
|
271
|
-
await operation(adapter);
|
|
272
|
-
}
|
|
273
|
-
catch (error) {
|
|
274
|
-
failures.push(error);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
if (failures.length > 0) {
|
|
278
|
-
throw new AggregateError(failures, message);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
248
|
normalizeName(name) {
|
|
282
249
|
return name.trim().toLowerCase();
|
|
283
250
|
}
|
|
284
251
|
}
|
|
285
|
-
//# sourceMappingURL=adapter.registry.js.map
|
|
@@ -32,4 +32,3 @@ export declare function wait(ms: number, signal?: AbortSignal): Promise<void>;
|
|
|
32
32
|
* @returns The first accepted result, or the last one produced.
|
|
33
33
|
*/
|
|
34
34
|
export declare function withRetry<T>(attempt: () => Promise<T>, accept: (result: T) => boolean, options: AdapterOperationOptions): Promise<T>;
|
|
35
|
-
//# sourceMappingURL=adapter.retry.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/adapters/adapter
|
|
3
|
+
*
|
|
4
|
+
* Lifecycle operations over a set of adapters: every adapter is attempted
|
|
5
|
+
* and the failures are collected, because stopping at the first one leaves a
|
|
6
|
+
* half-applied transition nobody tracks.
|
|
7
|
+
*/
|
|
8
|
+
import type { Adapter } from "../adapter.type.js";
|
|
9
|
+
import { type AdapterLifecycleOperation } from "./adapterLifecycle.ops.js";
|
|
10
|
+
import type { AdapterOperationOptions } from "../../lifecycle/lifecycle.type.js";
|
|
11
|
+
/**
|
|
12
|
+
* Runs one lifecycle hook on every adapter, in the order given, and throws
|
|
13
|
+
* an `AggregateError` of the typed per-adapter failures once all have been
|
|
14
|
+
* attempted.
|
|
15
|
+
*/
|
|
16
|
+
export declare function runAdapterLifecycleAll(adapters: readonly Adapter[], operation: AdapterLifecycleOperation, options: AdapterOperationOptions, message: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Stops, then disposes, one adapter, rethrowing the hooks' own errors.
|
|
19
|
+
*
|
|
20
|
+
* `dispose()` runs even when `stop()` throws: by the time this is called the
|
|
21
|
+
* adapter has left the registry, so skipping disposal would orphan its
|
|
22
|
+
* connections and timers with nothing left holding a reference to release
|
|
23
|
+
* them. A `stop()` failure is still reported — on its own when disposal
|
|
24
|
+
* succeeds, alongside the disposal error when both fail.
|
|
25
|
+
*
|
|
26
|
+
* @throws {AggregateError} of the stop and dispose errors when both failed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function teardownAdapter(adapter: Adapter): Promise<void>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/adapters/adapter
|
|
3
|
+
*
|
|
4
|
+
* Lifecycle operations over a set of adapters: every adapter is attempted
|
|
5
|
+
* and the failures are collected, because stopping at the first one leaves a
|
|
6
|
+
* half-applied transition nobody tracks.
|
|
7
|
+
*/
|
|
8
|
+
import { runAdapterLifecycle, } from "./adapterLifecycle.ops.js";
|
|
9
|
+
/**
|
|
10
|
+
* Runs one lifecycle hook on every adapter, in the order given, and throws
|
|
11
|
+
* an `AggregateError` of the typed per-adapter failures once all have been
|
|
12
|
+
* attempted.
|
|
13
|
+
*/
|
|
14
|
+
export async function runAdapterLifecycleAll(adapters, operation, options, message) {
|
|
15
|
+
const failures = [];
|
|
16
|
+
for (const adapter of adapters) {
|
|
17
|
+
try {
|
|
18
|
+
await runAdapterLifecycle(adapter, operation, options);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
failures.push(error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (failures.length > 0) {
|
|
25
|
+
throw new AggregateError(failures, message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Stops, then disposes, one adapter, rethrowing the hooks' own errors.
|
|
30
|
+
*
|
|
31
|
+
* `dispose()` runs even when `stop()` throws: by the time this is called the
|
|
32
|
+
* adapter has left the registry, so skipping disposal would orphan its
|
|
33
|
+
* connections and timers with nothing left holding a reference to release
|
|
34
|
+
* them. A `stop()` failure is still reported — on its own when disposal
|
|
35
|
+
* succeeds, alongside the disposal error when both fail.
|
|
36
|
+
*
|
|
37
|
+
* @throws {AggregateError} of the stop and dispose errors when both failed.
|
|
38
|
+
*/
|
|
39
|
+
export async function teardownAdapter(adapter) {
|
|
40
|
+
let stopError;
|
|
41
|
+
let stopFailed = false;
|
|
42
|
+
try {
|
|
43
|
+
await adapter.stop?.();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
stopFailed = true;
|
|
47
|
+
stopError = error;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
await adapter.dispose?.();
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (stopFailed) {
|
|
54
|
+
throw new AggregateError([stopError, error], `Adapter "${adapter.name}" failed to stop and to dispose.`);
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
if (stopFailed)
|
|
59
|
+
throw stopError;
|
|
60
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/adapters/adapter
|
|
3
|
+
*
|
|
4
|
+
* Bounded execution of one adapter lifecycle hook.
|
|
5
|
+
*
|
|
6
|
+
* `initializeAll()`, `startAll()` and `stopAll()` used to run each hook bare:
|
|
7
|
+
* no timeout, no retry, no abort, and a failure surfaced as whatever the hook
|
|
8
|
+
* threw, so an `AggregateError` from `initializeAll()` never said which
|
|
9
|
+
* adapter had failed. Every hook now runs under the same
|
|
10
|
+
* `AdapterOperationOptions` as `healthAll()`, and a failure is wrapped in the
|
|
11
|
+
* typed error for its operation, naming the adapter and keeping the original
|
|
12
|
+
* as `cause`.
|
|
13
|
+
*/
|
|
14
|
+
import { AdapterError } from "@zudojs/errors";
|
|
15
|
+
import type { Adapter } from "../adapter.type.js";
|
|
16
|
+
import type { AdapterOperationOptions } from "../../lifecycle/lifecycle.type.js";
|
|
17
|
+
/** The lifecycle hooks of {@link Adapter}. */
|
|
18
|
+
export type AdapterLifecycleOperation = "initialize" | "start" | "stop" | "dispose";
|
|
19
|
+
/**
|
|
20
|
+
* Wraps a hook's failure in the typed error for `operation`, naming the
|
|
21
|
+
* adapter. An `AdapterError` — an `AdapterTimeoutError` from the timeout
|
|
22
|
+
* here, or one the adapter threw on purpose — already does, so it passes
|
|
23
|
+
* through unchanged.
|
|
24
|
+
*/
|
|
25
|
+
export declare function toAdapterLifecycleError(adapter: Adapter, operation: AdapterLifecycleOperation, error: unknown): AdapterError;
|
|
26
|
+
/**
|
|
27
|
+
* Runs one lifecycle hook of `adapter` under `options` — `timeout` bounds
|
|
28
|
+
* each try, `retry` re-runs a failed try, `signal` stops the whole thing —
|
|
29
|
+
* and throws the typed error for the operation when the last try failed.
|
|
30
|
+
* An adapter without the hook succeeds immediately.
|
|
31
|
+
*
|
|
32
|
+
* @throws {AdapterInitializationError} when `initialize()` failed.
|
|
33
|
+
* @throws {AdapterOperationError} when `start()` or `stop()` failed, or the
|
|
34
|
+
* signal aborted.
|
|
35
|
+
* @throws {AdapterDisposeError} when `dispose()` failed.
|
|
36
|
+
* @throws {AdapterTimeoutError} when the last try exceeded `timeout`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runAdapterLifecycle(adapter: Adapter, operation: AdapterLifecycleOperation, options?: AdapterOperationOptions): Promise<void>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/adapters/adapter
|
|
3
|
+
*
|
|
4
|
+
* Bounded execution of one adapter lifecycle hook.
|
|
5
|
+
*
|
|
6
|
+
* `initializeAll()`, `startAll()` and `stopAll()` used to run each hook bare:
|
|
7
|
+
* no timeout, no retry, no abort, and a failure surfaced as whatever the hook
|
|
8
|
+
* threw, so an `AggregateError` from `initializeAll()` never said which
|
|
9
|
+
* adapter had failed. Every hook now runs under the same
|
|
10
|
+
* `AdapterOperationOptions` as `healthAll()`, and a failure is wrapped in the
|
|
11
|
+
* typed error for its operation, naming the adapter and keeping the original
|
|
12
|
+
* as `cause`.
|
|
13
|
+
*/
|
|
14
|
+
import { AdapterDisposeError, AdapterError, AdapterInitializationError, AdapterOperationError, AdapterTimeoutError, } from "@zudojs/errors";
|
|
15
|
+
import { withRetry } from "../adapter.retry.js";
|
|
16
|
+
const OK = Object.freeze({ ok: true });
|
|
17
|
+
/**
|
|
18
|
+
* Wraps a hook's failure in the typed error for `operation`, naming the
|
|
19
|
+
* adapter. An `AdapterError` — an `AdapterTimeoutError` from the timeout
|
|
20
|
+
* here, or one the adapter threw on purpose — already does, so it passes
|
|
21
|
+
* through unchanged.
|
|
22
|
+
*/
|
|
23
|
+
export function toAdapterLifecycleError(adapter, operation, error) {
|
|
24
|
+
if (error instanceof AdapterError)
|
|
25
|
+
return error;
|
|
26
|
+
switch (operation) {
|
|
27
|
+
case "initialize":
|
|
28
|
+
return new AdapterInitializationError(adapter.name, error);
|
|
29
|
+
case "dispose":
|
|
30
|
+
return new AdapterDisposeError(adapter.name, error);
|
|
31
|
+
default:
|
|
32
|
+
return new AdapterOperationError(adapter.name, operation, error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** One attempt at the hook, bounded by `timeout` and `signal`. */
|
|
36
|
+
async function attemptOnce(adapter, operation, options) {
|
|
37
|
+
const abortError = () => ({
|
|
38
|
+
ok: false,
|
|
39
|
+
error: new AdapterOperationError(adapter.name, operation, options.signal?.reason),
|
|
40
|
+
});
|
|
41
|
+
if (options.signal?.aborted)
|
|
42
|
+
return abortError();
|
|
43
|
+
const hook = adapter[operation];
|
|
44
|
+
if (typeof hook !== "function")
|
|
45
|
+
return OK;
|
|
46
|
+
let timer;
|
|
47
|
+
let onAbort;
|
|
48
|
+
const guards = [];
|
|
49
|
+
if (options.timeout !== undefined) {
|
|
50
|
+
const timeout = options.timeout;
|
|
51
|
+
guards.push(new Promise((resolve) => {
|
|
52
|
+
timer = setTimeout(() => resolve({
|
|
53
|
+
ok: false,
|
|
54
|
+
error: new AdapterTimeoutError(adapter.name, operation, timeout),
|
|
55
|
+
}), timeout);
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
if (options.signal) {
|
|
59
|
+
const signal = options.signal;
|
|
60
|
+
guards.push(new Promise((resolve) => {
|
|
61
|
+
onAbort = () => resolve(abortError());
|
|
62
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const run = Promise.resolve()
|
|
67
|
+
.then(() => hook.call(adapter))
|
|
68
|
+
.then(() => OK, (error) => ({ ok: false, error }));
|
|
69
|
+
return await Promise.race([run, ...guards]);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
if (timer !== undefined)
|
|
73
|
+
clearTimeout(timer);
|
|
74
|
+
if (onAbort)
|
|
75
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Runs one lifecycle hook of `adapter` under `options` — `timeout` bounds
|
|
80
|
+
* each try, `retry` re-runs a failed try, `signal` stops the whole thing —
|
|
81
|
+
* and throws the typed error for the operation when the last try failed.
|
|
82
|
+
* An adapter without the hook succeeds immediately.
|
|
83
|
+
*
|
|
84
|
+
* @throws {AdapterInitializationError} when `initialize()` failed.
|
|
85
|
+
* @throws {AdapterOperationError} when `start()` or `stop()` failed, or the
|
|
86
|
+
* signal aborted.
|
|
87
|
+
* @throws {AdapterDisposeError} when `dispose()` failed.
|
|
88
|
+
* @throws {AdapterTimeoutError} when the last try exceeded `timeout`.
|
|
89
|
+
*/
|
|
90
|
+
export async function runAdapterLifecycle(adapter, operation, options = {}) {
|
|
91
|
+
const outcome = await withRetry(() => attemptOnce(adapter, operation, options), (result) => result.ok, options);
|
|
92
|
+
if (!outcome.ok) {
|
|
93
|
+
throw toAdapterLifecycleError(adapter, operation, outcome.error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/adapters/adapter/adapterLifecycle
|
|
3
|
+
*
|
|
4
|
+
* Bounded, typed execution of adapter lifecycle hooks, singly and across a
|
|
5
|
+
* registry's adapters.
|
|
6
|
+
*/
|
|
7
|
+
export { runAdapterLifecycle, toAdapterLifecycleError, } from "./adapterLifecycle.ops.js";
|
|
8
|
+
export type { AdapterLifecycleOperation } from "./adapterLifecycle.ops.js";
|
|
9
|
+
export { runAdapterLifecycleAll, teardownAdapter, } from "./adapterLifecycle.all.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/adapters/adapter/adapterLifecycle
|
|
3
|
+
*
|
|
4
|
+
* Bounded, typed execution of adapter lifecycle hooks, singly and across a
|
|
5
|
+
* registry's adapters.
|
|
6
|
+
*/
|
|
7
|
+
export { runAdapterLifecycle, toAdapterLifecycleError, } from "./adapterLifecycle.ops.js";
|
|
8
|
+
export { runAdapterLifecycleAll, teardownAdapter, } from "./adapterLifecycle.all.js";
|
package/dist/adapter/index.d.ts
CHANGED
|
@@ -8,4 +8,6 @@ export { AdapterRegistry } from "./adapter.registry.js";
|
|
|
8
8
|
export type { AdapterCapabilityName } from "./adapter.registry.js";
|
|
9
9
|
export { collectAdapterHealth, configureAdapter } from "./adapter.health.js";
|
|
10
10
|
export type { AdapterHealthReport } from "./adapter.health.js";
|
|
11
|
-
|
|
11
|
+
export { withRetry } from "./adapter.retry.js";
|
|
12
|
+
export { runAdapterLifecycle, toAdapterLifecycleError, } from "./adapterLifecycle/index.js";
|
|
13
|
+
export type { AdapterLifecycleOperation } from "./adapterLifecycle/index.js";
|
package/dist/adapter/index.js
CHANGED
|
@@ -5,4 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { AdapterRegistry } from "./adapter.registry.js";
|
|
7
7
|
export { collectAdapterHealth, configureAdapter } from "./adapter.health.js";
|
|
8
|
-
|
|
8
|
+
export { withRetry } from "./adapter.retry.js";
|
|
9
|
+
export { runAdapterLifecycle, toAdapterLifecycleError, } from "./adapterLifecycle/index.js";
|
|
@@ -8,8 +8,23 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Not every platform supports every feature. Adapters declare their
|
|
10
10
|
* capabilities so runtime code can adapt behavior accordingly.
|
|
11
|
+
*
|
|
12
|
+
* The well-known keys are listed in {@link KnownAdapterCapabilities}; any
|
|
13
|
+
* other name (`refunds`, `bulkExport`, …) is a business capability an
|
|
14
|
+
* adapter may declare and `findByCapability` / `supports` /
|
|
15
|
+
* `requireCapability` can look up. The interface used to be closed, so a
|
|
16
|
+
* capability outside the list was a compile error and could never be
|
|
17
|
+
* queried.
|
|
18
|
+
*/
|
|
19
|
+
export interface AdapterCapabilities extends KnownAdapterCapabilities {
|
|
20
|
+
readonly [capability: string]: boolean | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The capability names this package defines. Kept separate from
|
|
24
|
+
* {@link AdapterCapabilities} so `AdapterCapabilityName` can still offer
|
|
25
|
+
* them for completion while accepting any string.
|
|
11
26
|
*/
|
|
12
|
-
export interface
|
|
27
|
+
export interface KnownAdapterCapabilities {
|
|
13
28
|
/** Supports HTTP request/response handling. */
|
|
14
29
|
readonly http?: boolean;
|
|
15
30
|
/** Supports WebSocket connections. */
|
|
@@ -35,4 +50,3 @@ export interface AdapterCapabilities {
|
|
|
35
50
|
/** Supports request cancellation via AbortSignal. */
|
|
36
51
|
readonly abortSignal?: boolean;
|
|
37
52
|
}
|
|
38
|
-
//# sourceMappingURL=capabilities.type.d.ts.map
|
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
package/dist/errors/index.d.ts
CHANGED
|
@@ -5,4 +5,3 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { AdapterError, AdapterNotFoundError, AdapterAlreadyRegisteredError, AdapterNotSupportedError, AdapterCapabilityMissingError, AdapterConnectionError, AdapterOperationError, AdapterTimeoutError, AdapterDisposeError, AdapterInitializationError, AdapterConfigurationError, createAdapterError, isAdapterError, } from "@zudojs/errors";
|
|
7
7
|
export type { AdapterErrorOptions } from "@zudojs/errors";
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/errors/index.js
CHANGED
|
@@ -4,4 +4,3 @@
|
|
|
4
4
|
* Adapter error types — re-exported from @zudojs/errors.
|
|
5
5
|
*/
|
|
6
6
|
export { AdapterError, AdapterNotFoundError, AdapterAlreadyRegisteredError, AdapterNotSupportedError, AdapterCapabilityMissingError, AdapterConnectionError, AdapterOperationError, AdapterTimeoutError, AdapterDisposeError, AdapterInitializationError, AdapterConfigurationError, createAdapterError, isAdapterError, } from "@zudojs/errors";
|
|
7
|
-
//# sourceMappingURL=index.js.map
|
package/dist/http/index.d.ts
CHANGED
package/dist/http/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
* @module @zudojs/adapters
|
|
17
17
|
*/
|
|
18
18
|
export type { Adapter } from "./adapter/index.js";
|
|
19
|
-
export { AdapterRegistry } from "./adapter/index.js";
|
|
20
|
-
export type { AdapterCapabilityName } from "./adapter/index.js";
|
|
21
|
-
export type {
|
|
22
|
-
export type { AdapterCapabilities } from "./capabilities/index.js";
|
|
19
|
+
export { AdapterRegistry, collectAdapterHealth, configureAdapter, withRetry, runAdapterLifecycle, toAdapterLifecycleError, } from "./adapter/index.js";
|
|
20
|
+
export type { AdapterCapabilityName, AdapterHealthReport, AdapterLifecycleOperation, } from "./adapter/index.js";
|
|
21
|
+
export type { AdapterCapabilities, KnownAdapterCapabilities, } from "./capabilities/index.js";
|
|
23
22
|
export type { AdapterMetadata } from "./metadata/index.js";
|
|
24
23
|
export type { AdapterHealthStatus, AdapterHealth, AdapterOperationOptions, LifecycleAdapter, } from "./lifecycle/index.js";
|
|
25
24
|
export { createHealthyHealth, createDegradedHealth, createUnhealthyHealth, } from "./lifecycle/index.js";
|
|
@@ -37,4 +36,3 @@ export type { Adapter as MockAdapter } from "./testing/index.js";
|
|
|
37
36
|
export type { AdapterHealth as MockAdapterHealth } from "./testing/index.js";
|
|
38
37
|
export type { AdapterRegistry as MockAdapterRegistry } from "./testing/index.js";
|
|
39
38
|
export { createMockAdapter, createMockAdapterRegistry, createMockHealth, } from "./testing/index.js";
|
|
40
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @module @zudojs/adapters
|
|
17
17
|
*/
|
|
18
|
-
export { AdapterRegistry } from "./adapter/index.js";
|
|
18
|
+
export { AdapterRegistry, collectAdapterHealth, configureAdapter, withRetry, runAdapterLifecycle, toAdapterLifecycleError, } from "./adapter/index.js";
|
|
19
19
|
export { createHealthyHealth, createDegradedHealth, createUnhealthyHealth, } from "./lifecycle/index.js";
|
|
20
20
|
// Errors
|
|
21
21
|
export { AdapterError, AdapterNotFoundError, AdapterAlreadyRegisteredError, AdapterNotSupportedError, AdapterCapabilityMissingError, AdapterConnectionError, AdapterOperationError, AdapterTimeoutError, AdapterDisposeError, AdapterInitializationError, AdapterConfigurationError, createAdapterError, isAdapterError, } from "./errors/index.js";
|
|
22
22
|
export { createMockAdapter, createMockAdapterRegistry, createMockHealth, } from "./testing/index.js";
|
|
23
|
-
//# sourceMappingURL=index.js.map
|
package/dist/lifecycle/index.js
CHANGED
package/dist/messaging/index.js
CHANGED
package/dist/metadata/index.d.ts
CHANGED
package/dist/metadata/index.js
CHANGED
package/dist/queue/index.d.ts
CHANGED
package/dist/queue/index.js
CHANGED
package/dist/runtime/index.d.ts
CHANGED
package/dist/runtime/index.js
CHANGED
package/dist/scheduler/index.js
CHANGED
package/dist/storage/index.d.ts
CHANGED
package/dist/storage/index.js
CHANGED
package/dist/testing/index.d.ts
CHANGED
|
@@ -8,4 +8,3 @@ export type { AdapterCapabilities } from "../capabilities/capabilities.type.js";
|
|
|
8
8
|
export type { AdapterRegistry } from "../adapter/adapter.registry.js";
|
|
9
9
|
export type { AdapterHealth } from "../lifecycle/lifecycle.type.js";
|
|
10
10
|
export { createMockAdapter, createMockAdapterRegistry, createMockHealth, } from "./adapterTesting.helper.js";
|
|
11
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/testing/index.js
CHANGED
package/dist/websocket/index.js
CHANGED
|
@@ -13,4 +13,3 @@ export var WebSocketReadyState;
|
|
|
13
13
|
WebSocketReadyState[WebSocketReadyState["CLOSING"] = 2] = "CLOSING";
|
|
14
14
|
WebSocketReadyState[WebSocketReadyState["CLOSED"] = 3] = "CLOSED";
|
|
15
15
|
})(WebSocketReadyState || (WebSocketReadyState = {}));
|
|
16
|
-
//# sourceMappingURL=websocketAdapter.type.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/adapters",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Boundary layer between Zudojs and external platforms — adapter contracts, registry, capabilities, and transport abstractions.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node": ">=24.0.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@zudojs/errors": "1.
|
|
30
|
+
"@zudojs/errors": "1.4.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"typescript": "7.0.2",
|